@thoughtbot/react-native-social-auth 0.1.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 (52) hide show
  1. package/LICENSE +20 -0
  2. package/README.md +316 -0
  3. package/ReactNativeSocialAuth.podspec +22 -0
  4. package/android/build.gradle +70 -0
  5. package/android/src/main/AndroidManifest.xml +2 -0
  6. package/android/src/main/java/com/thoughtbot/reactnativesocialauth/GoogleSignInModule.kt +188 -0
  7. package/android/src/main/java/com/thoughtbot/reactnativesocialauth/ReactNativeSocialAuthPackage.kt +31 -0
  8. package/ios/GoogleSignIn.h +7 -0
  9. package/ios/GoogleSignIn.mm +213 -0
  10. package/lib/module/google/GoogleLogo.js +41 -0
  11. package/lib/module/google/GoogleLogo.js.map +1 -0
  12. package/lib/module/google/GoogleSignIn.js +124 -0
  13. package/lib/module/google/GoogleSignIn.js.map +1 -0
  14. package/lib/module/google/GoogleSignInButton.js +176 -0
  15. package/lib/module/google/GoogleSignInButton.js.map +1 -0
  16. package/lib/module/google/NativeGoogleSignIn.js +5 -0
  17. package/lib/module/google/NativeGoogleSignIn.js.map +1 -0
  18. package/lib/module/google/errors.js +69 -0
  19. package/lib/module/google/errors.js.map +1 -0
  20. package/lib/module/google/index.js +6 -0
  21. package/lib/module/google/index.js.map +1 -0
  22. package/lib/module/google/types.js +2 -0
  23. package/lib/module/google/types.js.map +1 -0
  24. package/lib/module/index.js +4 -0
  25. package/lib/module/index.js.map +1 -0
  26. package/lib/module/package.json +1 -0
  27. package/lib/typescript/package.json +1 -0
  28. package/lib/typescript/src/google/GoogleLogo.d.ts +6 -0
  29. package/lib/typescript/src/google/GoogleLogo.d.ts.map +1 -0
  30. package/lib/typescript/src/google/GoogleSignIn.d.ts +89 -0
  31. package/lib/typescript/src/google/GoogleSignIn.d.ts.map +1 -0
  32. package/lib/typescript/src/google/GoogleSignInButton.d.ts +74 -0
  33. package/lib/typescript/src/google/GoogleSignInButton.d.ts.map +1 -0
  34. package/lib/typescript/src/google/NativeGoogleSignIn.d.ts +12 -0
  35. package/lib/typescript/src/google/NativeGoogleSignIn.d.ts.map +1 -0
  36. package/lib/typescript/src/google/errors.d.ts +57 -0
  37. package/lib/typescript/src/google/errors.d.ts.map +1 -0
  38. package/lib/typescript/src/google/index.d.ts +6 -0
  39. package/lib/typescript/src/google/index.d.ts.map +1 -0
  40. package/lib/typescript/src/google/types.d.ts +93 -0
  41. package/lib/typescript/src/google/types.d.ts.map +1 -0
  42. package/lib/typescript/src/index.d.ts +3 -0
  43. package/lib/typescript/src/index.d.ts.map +1 -0
  44. package/package.json +180 -0
  45. package/src/google/GoogleLogo.tsx +35 -0
  46. package/src/google/GoogleSignIn.ts +131 -0
  47. package/src/google/GoogleSignInButton.tsx +224 -0
  48. package/src/google/NativeGoogleSignIn.ts +12 -0
  49. package/src/google/errors.ts +72 -0
  50. package/src/google/index.ts +19 -0
  51. package/src/google/types.ts +100 -0
  52. package/src/index.tsx +18 -0
@@ -0,0 +1,213 @@
1
+ #import "GoogleSignIn.h"
2
+ #import <React/RCTUtils.h>
3
+
4
+ #import <GoogleSignIn/GoogleSignIn.h>
5
+
6
+ static NSString *const kErrCancelled = @"SIGN_IN_CANCELLED";
7
+ static NSString *const kErrFailed = @"SIGN_IN_FAILED";
8
+ static NSString *const kErrNoCreds = @"NO_CREDENTIALS";
9
+ static NSString *const kErrNotConfigured = @"NOT_CONFIGURED";
10
+ static NSString *const kErrNetwork = @"NETWORK_ERROR";
11
+ static NSString *const kErrSignOut = @"SIGN_OUT_FAILED";
12
+ static NSString *const kErrRevoke = @"REVOKE_FAILED";
13
+
14
+ @implementation GoogleSignIn {
15
+ NSString *_webClientId;
16
+ NSString *_iosClientId;
17
+ NSString *_hostedDomain;
18
+ NSString *_nonce;
19
+ NSArray<NSString *> *_scopes;
20
+ BOOL _autoSelect;
21
+ }
22
+
23
+ #pragma mark - Public URL handler (for AppDelegate forwarding)
24
+
25
+ + (BOOL)handleURL:(NSURL *)url {
26
+ return [GIDSignIn.sharedInstance handleURL:url];
27
+ }
28
+
29
+ #pragma mark - NativeGoogleSignInSpec
30
+
31
+ - (void)configure:(NSDictionary *)config {
32
+ _webClientId = [self stringOrNil:config[@"webClientId"]];
33
+ _iosClientId = [self stringOrNil:config[@"iosClientId"]];
34
+ _hostedDomain = [self stringOrNil:config[@"hostedDomain"]];
35
+ _nonce = [self stringOrNil:config[@"nonce"]];
36
+ _autoSelect = [config[@"autoSelect"] boolValue];
37
+
38
+ id rawScopes = config[@"scopes"];
39
+ _scopes = [rawScopes isKindOfClass:[NSArray class]] ? rawScopes : @[];
40
+
41
+ if (_iosClientId.length > 0) {
42
+ GIDConfiguration *gidConfig =
43
+ [[GIDConfiguration alloc] initWithClientID:_iosClientId
44
+ serverClientID:_webClientId
45
+ hostedDomain:_hostedDomain
46
+ openIDRealm:nil];
47
+ GIDSignIn.sharedInstance.configuration = gidConfig;
48
+ }
49
+ }
50
+
51
+ - (void)signIn:(RCTPromiseResolveBlock)resolve reject:(RCTPromiseRejectBlock)reject {
52
+ if (_iosClientId.length == 0) {
53
+ reject(kErrNotConfigured,
54
+ @"GoogleSignIn.configure() must be called with an iosClientId before signIn()",
55
+ nil);
56
+ return;
57
+ }
58
+
59
+ dispatch_async(dispatch_get_main_queue(), ^{
60
+ [GIDSignIn.sharedInstance restorePreviousSignInWithCompletion:^(GIDGoogleUser * _Nullable user, NSError * _Nullable error) {
61
+ if (user != nil && error == nil) {
62
+ resolve([self credentialToDict:user]);
63
+ return;
64
+ }
65
+ [self presentInteractiveSignInResolve:resolve reject:reject];
66
+ }];
67
+ });
68
+ }
69
+
70
+ - (void)presentInteractiveSignInResolve:(RCTPromiseResolveBlock)resolve
71
+ reject:(RCTPromiseRejectBlock)reject {
72
+ UIViewController *presenter = RCTPresentedViewController();
73
+ if (presenter == nil) {
74
+ reject(kErrFailed, @"No view controller available to present sign-in", nil);
75
+ return;
76
+ }
77
+
78
+ __weak GoogleSignIn *weakSelf = self;
79
+ // Note: GoogleSignIn-iOS 7.x does not expose a `nonce` parameter on its public
80
+ // sign-in API; if a nonce is required, it must be enforced server-side when
81
+ // verifying the ID token. `_nonce` is captured here for forward compatibility.
82
+ if (_scopes.count > 0) {
83
+ [GIDSignIn.sharedInstance signInWithPresentingViewController:presenter
84
+ hint:nil
85
+ additionalScopes:_scopes
86
+ completion:^(GIDSignInResult *result, NSError *error) {
87
+ [weakSelf handleSignInResult:result error:error resolve:resolve reject:reject];
88
+ }];
89
+ } else {
90
+ [GIDSignIn.sharedInstance signInWithPresentingViewController:presenter
91
+ completion:^(GIDSignInResult *result, NSError *error) {
92
+ [weakSelf handleSignInResult:result error:error resolve:resolve reject:reject];
93
+ }];
94
+ }
95
+ }
96
+
97
+ - (void)handleSignInResult:(GIDSignInResult *)result
98
+ error:(NSError *)error
99
+ resolve:(RCTPromiseResolveBlock)resolve
100
+ reject:(RCTPromiseRejectBlock)reject {
101
+ if (error != nil) {
102
+ [self rejectWithError:error reject:reject];
103
+ return;
104
+ }
105
+ if (result.user == nil) {
106
+ reject(kErrFailed, @"Sign-in returned no user", nil);
107
+ return;
108
+ }
109
+ resolve([self credentialToDict:result.user]);
110
+ }
111
+
112
+ - (void)signOut:(RCTPromiseResolveBlock)resolve reject:(RCTPromiseRejectBlock)reject {
113
+ @try {
114
+ [GIDSignIn.sharedInstance signOut];
115
+ resolve(nil);
116
+ } @catch (NSException *e) {
117
+ reject(kErrSignOut, e.reason, nil);
118
+ }
119
+ }
120
+
121
+ - (void)getCurrentUser:(RCTPromiseResolveBlock)resolve reject:(RCTPromiseRejectBlock)reject {
122
+ GIDGoogleUser *user = GIDSignIn.sharedInstance.currentUser;
123
+ resolve(user != nil ? [self userToDict:user] : (id)kCFNull);
124
+ }
125
+
126
+ - (void)revokeAccess:(RCTPromiseResolveBlock)resolve reject:(RCTPromiseRejectBlock)reject {
127
+ [GIDSignIn.sharedInstance disconnectWithCompletion:^(NSError * _Nullable error) {
128
+ if (error != nil) {
129
+ reject(kErrRevoke, error.localizedDescription, error);
130
+ return;
131
+ }
132
+ resolve(nil);
133
+ }];
134
+ }
135
+
136
+ - (NSNumber *)isSignedIn {
137
+ return @(GIDSignIn.sharedInstance.currentUser != nil);
138
+ }
139
+
140
+ #pragma mark - TurboModule plumbing
141
+
142
+ - (std::shared_ptr<facebook::react::TurboModule>)getTurboModule:
143
+ (const facebook::react::ObjCTurboModule::InitParams &)params
144
+ {
145
+ return std::make_shared<facebook::react::NativeGoogleSignInSpecJSI>(params);
146
+ }
147
+
148
+ + (NSString *)moduleName {
149
+ return @"GoogleSignIn";
150
+ }
151
+
152
+ #pragma mark - Marshalling helpers
153
+
154
+ - (NSDictionary *)userToDict:(GIDGoogleUser *)user {
155
+ GIDProfileData *profile = user.profile;
156
+ NSString *photoUrl = nil;
157
+ if (profile.hasImage) {
158
+ NSURL *imageURL = [profile imageURLWithDimension:200];
159
+ photoUrl = imageURL.absoluteString;
160
+ }
161
+ return @{
162
+ @"id": user.userID ?: (id)kCFNull,
163
+ @"email": profile.email ?: (id)kCFNull,
164
+ @"displayName": profile.name ?: (id)kCFNull,
165
+ @"givenName": profile.givenName ?: (id)kCFNull,
166
+ @"familyName": profile.familyName ?: (id)kCFNull,
167
+ @"photoUrl": photoUrl ?: (id)kCFNull,
168
+ };
169
+ }
170
+
171
+ - (NSDictionary *)credentialToDict:(GIDGoogleUser *)user {
172
+ return @{
173
+ @"idToken": user.idToken.tokenString ?: (id)kCFNull,
174
+ @"accessToken": user.accessToken.tokenString ?: (id)kCFNull,
175
+ @"serverAuthCode": (id)kCFNull,
176
+ @"user": [self userToDict:user],
177
+ };
178
+ }
179
+
180
+ #pragma mark - Error mapping
181
+
182
+ - (void)rejectWithError:(NSError *)error reject:(RCTPromiseRejectBlock)reject {
183
+ NSString *code = kErrFailed;
184
+
185
+ if ([error.domain isEqualToString:kGIDSignInErrorDomain]) {
186
+ switch (error.code) {
187
+ case kGIDSignInErrorCodeCanceled:
188
+ code = kErrCancelled;
189
+ break;
190
+ case kGIDSignInErrorCodeHasNoAuthInKeychain:
191
+ code = kErrNoCreds;
192
+ break;
193
+ default:
194
+ code = kErrFailed;
195
+ break;
196
+ }
197
+ } else if ([error.domain isEqualToString:NSURLErrorDomain]) {
198
+ code = kErrNetwork;
199
+ }
200
+
201
+ reject(code, error.localizedDescription, error);
202
+ }
203
+
204
+ #pragma mark - Utilities
205
+
206
+ - (NSString *)stringOrNil:(id)value {
207
+ if ([value isKindOfClass:[NSString class]] && ((NSString *)value).length > 0) {
208
+ return (NSString *)value;
209
+ }
210
+ return nil;
211
+ }
212
+
213
+ @end
@@ -0,0 +1,41 @@
1
+ "use strict";
2
+
3
+ import Svg, { Path, ClipPath, Rect, Defs, G } from 'react-native-svg';
4
+ import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
5
+ export function GoogleLogo({
6
+ size = 20
7
+ }) {
8
+ return /*#__PURE__*/_jsxs(Svg, {
9
+ width: size,
10
+ height: size,
11
+ viewBox: "10 10 20 20",
12
+ fill: "none",
13
+ children: [/*#__PURE__*/_jsx(Defs, {
14
+ children: /*#__PURE__*/_jsx(ClipPath, {
15
+ id: "g-clip",
16
+ children: /*#__PURE__*/_jsx(Rect, {
17
+ width: "20",
18
+ height: "20",
19
+ x: "10",
20
+ y: "10"
21
+ })
22
+ })
23
+ }), /*#__PURE__*/_jsxs(G, {
24
+ clipPath: "url(#g-clip)",
25
+ children: [/*#__PURE__*/_jsx(Path, {
26
+ d: "M29.6 20.2273C29.6 19.5182 29.5364 18.8364 29.4182 18.1818H20V22.05H25.3818C25.15 23.3 24.4455 24.3591 23.3864 25.0682V27.5773H26.6182C28.5091 25.8364 29.6 23.2727 29.6 20.2273Z",
27
+ fill: "#4285F4"
28
+ }), /*#__PURE__*/_jsx(Path, {
29
+ d: "M20 30C22.7 30 24.9636 29.1045 26.6181 27.5773L23.3863 25.0682C22.4909 25.6682 21.3454 26.0227 20 26.0227C17.3954 26.0227 15.1909 24.2636 14.4045 21.9H11.0636V24.4909C12.7091 27.7591 16.0909 30 20 30Z",
30
+ fill: "#34A853"
31
+ }), /*#__PURE__*/_jsx(Path, {
32
+ d: "M14.4045 21.9C14.2045 21.3 14.0909 20.6591 14.0909 20C14.0909 19.3409 14.2045 18.7 14.4045 18.1V15.5091H11.0636C10.3864 16.8591 10 18.3864 10 20C10 21.6136 10.3864 23.1409 11.0636 24.4909L14.4045 21.9Z",
33
+ fill: "#FBBC04"
34
+ }), /*#__PURE__*/_jsx(Path, {
35
+ d: "M20 13.9773C21.4681 13.9773 22.7863 14.4818 23.8227 15.4727L26.6909 12.6045C24.9591 10.9909 22.6954 10 20 10C16.0909 10 12.7091 12.2409 11.0636 15.5091L14.4045 18.1C15.1909 15.7364 17.3954 13.9773 20 13.9773Z",
36
+ fill: "#E94235"
37
+ })]
38
+ })]
39
+ });
40
+ }
41
+ //# sourceMappingURL=GoogleLogo.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"names":["Svg","Path","ClipPath","Rect","Defs","G","jsx","_jsx","jsxs","_jsxs","GoogleLogo","size","width","height","viewBox","fill","children","id","x","y","clipPath","d"],"sourceRoot":"../../../src","sources":["google/GoogleLogo.tsx"],"mappings":";;AAAA,OAAOA,GAAG,IAAIC,IAAI,EAAEC,QAAQ,EAAEC,IAAI,EAAEC,IAAI,EAAEC,CAAC,QAAQ,kBAAkB;AAAC,SAAAC,GAAA,IAAAC,IAAA,EAAAC,IAAA,IAAAC,KAAA;AAMtE,OAAO,SAASC,UAAUA,CAAC;EAAEC,IAAI,GAAG;AAAoB,CAAC,EAAE;EACzD,oBACEF,KAAA,CAACT,GAAG;IAACY,KAAK,EAAED,IAAK;IAACE,MAAM,EAAEF,IAAK;IAACG,OAAO,EAAC,aAAa;IAACC,IAAI,EAAC,MAAM;IAAAC,QAAA,gBAC/DT,IAAA,CAACH,IAAI;MAAAY,QAAA,eACHT,IAAA,CAACL,QAAQ;QAACe,EAAE,EAAC,QAAQ;QAAAD,QAAA,eACnBT,IAAA,CAACJ,IAAI;UAACS,KAAK,EAAC,IAAI;UAACC,MAAM,EAAC,IAAI;UAACK,CAAC,EAAC,IAAI;UAACC,CAAC,EAAC;QAAI,CAAE;MAAC,CACrC;IAAC,CACP,CAAC,eACPV,KAAA,CAACJ,CAAC;MAACe,QAAQ,EAAC,cAAc;MAAAJ,QAAA,gBACxBT,IAAA,CAACN,IAAI;QACHoB,CAAC,EAAC,mLAAmL;QACrLN,IAAI,EAAC;MAAS,CACf,CAAC,eACFR,IAAA,CAACN,IAAI;QACHoB,CAAC,EAAC,0MAA0M;QAC5MN,IAAI,EAAC;MAAS,CACf,CAAC,eACFR,IAAA,CAACN,IAAI;QACHoB,CAAC,EAAC,2MAA2M;QAC7MN,IAAI,EAAC;MAAS,CACf,CAAC,eACFR,IAAA,CAACN,IAAI;QACHoB,CAAC,EAAC,kNAAkN;QACpNN,IAAI,EAAC;MAAS,CACf,CAAC;IAAA,CACD,CAAC;EAAA,CACD,CAAC;AAEV","ignoreList":[]}
@@ -0,0 +1,124 @@
1
+ "use strict";
2
+
3
+ import { GoogleSignInError, GoogleSignInErrorCode } from "./errors.js";
4
+ import NativeGoogleSignIn from "./NativeGoogleSignIn.js";
5
+ let _configured = false;
6
+ function ensureConfigured() {
7
+ if (!_configured) {
8
+ throw new GoogleSignInError(GoogleSignInErrorCode.NOT_CONFIGURED, 'GoogleSignIn.configure() must be called before using other methods.');
9
+ }
10
+ }
11
+
12
+ /**
13
+ * Initialize the native Google Sign-In SDK. Must be called once at app startup
14
+ * (or before any other method) — subsequent calls overwrite the prior config.
15
+ *
16
+ * @param config - See {@link GoogleSignInConfig}.
17
+ *
18
+ * @example
19
+ * ```ts
20
+ * GoogleSignIn.configure({
21
+ * webClientId: 'WEB_CLIENT_ID.apps.googleusercontent.com',
22
+ * iosClientId: 'IOS_CLIENT_ID.apps.googleusercontent.com',
23
+ * });
24
+ * ```
25
+ */
26
+ function configure(config) {
27
+ NativeGoogleSignIn.configure(config);
28
+ _configured = true;
29
+ }
30
+
31
+ /**
32
+ * Trigger the Google sign-in flow.
33
+ *
34
+ * @remarks
35
+ * On both platforms, the SDK attempts silent restore of a previously authorized
36
+ * account first, then falls back to the interactive bottom sheet / system sheet
37
+ * if no authorized account is found.
38
+ *
39
+ * @returns A {@link GoogleAuthCredential} containing the ID token, optional
40
+ * access token, and user profile.
41
+ *
42
+ * @throws A {@link GoogleSignInError} with one of the
43
+ * {@link GoogleSignInErrorCode} values — most commonly `SIGN_IN_CANCELLED`
44
+ * when the user dismisses the sheet, or `NOT_CONFIGURED` when called before
45
+ * {@link configure}.
46
+ */
47
+ async function signIn() {
48
+ ensureConfigured();
49
+ const result = await NativeGoogleSignIn.signIn();
50
+ return result;
51
+ }
52
+
53
+ /**
54
+ * Clear the local credential state so the next {@link signIn} call requires
55
+ * fresh user interaction. The user remains signed into Google itself.
56
+ *
57
+ * @throws A {@link GoogleSignInError} with code `NOT_CONFIGURED` when called
58
+ * before {@link configure}.
59
+ */
60
+ async function signOut() {
61
+ ensureConfigured();
62
+ await NativeGoogleSignIn.signOut();
63
+ }
64
+
65
+ /**
66
+ * Return the in-memory authenticated user, or `null` if nobody has signed in
67
+ * since app launch.
68
+ *
69
+ * @returns The current {@link GoogleUser}, or `null`.
70
+ *
71
+ * @throws A {@link GoogleSignInError} with code `NOT_CONFIGURED` when called
72
+ * before {@link configure}.
73
+ */
74
+ async function getCurrentUser() {
75
+ ensureConfigured();
76
+ const result = await NativeGoogleSignIn.getCurrentUser();
77
+ return result;
78
+ }
79
+
80
+ /**
81
+ * Revoke the app's access to the user's Google account. The user will see a
82
+ * fresh consent screen on the next {@link signIn}.
83
+ *
84
+ * @throws A {@link GoogleSignInError} with code `NOT_CONFIGURED` when called
85
+ * before {@link configure}.
86
+ */
87
+ async function revokeAccess() {
88
+ ensureConfigured();
89
+ await NativeGoogleSignIn.revokeAccess();
90
+ }
91
+
92
+ /**
93
+ * Synchronous check for whether a user is currently signed in (in memory).
94
+ *
95
+ * @returns `true` when {@link getCurrentUser} would resolve to a non-null user.
96
+ *
97
+ * @throws A {@link GoogleSignInError} with code `NOT_CONFIGURED` when called
98
+ * before {@link configure}.
99
+ */
100
+ function isSignedIn() {
101
+ ensureConfigured();
102
+ return NativeGoogleSignIn.isSignedIn();
103
+ }
104
+
105
+ /**
106
+ * The Google Sign-In runtime API. Call {@link GoogleSignIn.configure} once at
107
+ * app startup, then drive the flow with the other methods.
108
+ *
109
+ * @example
110
+ * ```ts
111
+ * GoogleSignIn.configure({ webClientId: '...' });
112
+ * const credential = await GoogleSignIn.signIn();
113
+ * console.log(credential.user.email);
114
+ * ```
115
+ */
116
+ export const GoogleSignIn = {
117
+ configure,
118
+ signIn,
119
+ signOut,
120
+ getCurrentUser,
121
+ revokeAccess,
122
+ isSignedIn
123
+ };
124
+ //# sourceMappingURL=GoogleSignIn.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"names":["GoogleSignInError","GoogleSignInErrorCode","NativeGoogleSignIn","_configured","ensureConfigured","NOT_CONFIGURED","configure","config","signIn","result","signOut","getCurrentUser","revokeAccess","isSignedIn","GoogleSignIn"],"sourceRoot":"../../../src","sources":["google/GoogleSignIn.ts"],"mappings":";;AAKA,SAASA,iBAAiB,EAAEC,qBAAqB,QAAQ,aAAU;AACnE,OAAOC,kBAAkB,MAAM,yBAAsB;AAErD,IAAIC,WAAW,GAAG,KAAK;AAEvB,SAASC,gBAAgBA,CAAA,EAAS;EAChC,IAAI,CAACD,WAAW,EAAE;IAChB,MAAM,IAAIH,iBAAiB,CACzBC,qBAAqB,CAACI,cAAc,EACpC,qEACF,CAAC;EACH;AACF;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,SAASC,SAASA,CAACC,MAA0B,EAAQ;EACnDL,kBAAkB,CAACI,SAAS,CAACC,MAAM,CAAC;EACpCJ,WAAW,GAAG,IAAI;AACpB;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,eAAeK,MAAMA,CAAA,EAAkC;EACrDJ,gBAAgB,CAAC,CAAC;EAClB,MAAMK,MAAM,GAAG,MAAMP,kBAAkB,CAACM,MAAM,CAAC,CAAC;EAChD,OAAOC,MAAM;AACf;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,eAAeC,OAAOA,CAAA,EAAkB;EACtCN,gBAAgB,CAAC,CAAC;EAClB,MAAMF,kBAAkB,CAACQ,OAAO,CAAC,CAAC;AACpC;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,eAAeC,cAAcA,CAAA,EAA+B;EAC1DP,gBAAgB,CAAC,CAAC;EAClB,MAAMK,MAAM,GAAG,MAAMP,kBAAkB,CAACS,cAAc,CAAC,CAAC;EACxD,OAAOF,MAAM;AACf;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,eAAeG,YAAYA,CAAA,EAAkB;EAC3CR,gBAAgB,CAAC,CAAC;EAClB,MAAMF,kBAAkB,CAACU,YAAY,CAAC,CAAC;AACzC;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,SAASC,UAAUA,CAAA,EAAY;EAC7BT,gBAAgB,CAAC,CAAC;EAClB,OAAOF,kBAAkB,CAACW,UAAU,CAAC,CAAC;AACxC;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,OAAO,MAAMC,YAAY,GAAG;EAC1BR,SAAS;EACTE,MAAM;EACNE,OAAO;EACPC,cAAc;EACdC,YAAY;EACZC;AACF,CAAU","ignoreList":[]}
@@ -0,0 +1,176 @@
1
+ "use strict";
2
+
3
+ import { Pressable, View, Text, StyleSheet } from 'react-native';
4
+ import { GoogleLogo } from "./GoogleLogo.js";
5
+
6
+ // Layout dimensions
7
+ import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
8
+ const BUTTON_HEIGHT = 40;
9
+ const ICON_BUTTON_SIZE = 40;
10
+ const BORDER_RADIUS_ROUNDED = 20;
11
+ const BORDER_RADIUS_SQUARE = 4;
12
+ const GOOGLE_LOGO_SIZE = 20;
13
+
14
+ // Spacing
15
+ const LOGO_MARGIN_START = 12;
16
+ const LOGO_MARGIN_END = 10;
17
+
18
+ // Typography
19
+ const LABEL_FONT_SIZE = 14;
20
+ const LABEL_LINE_HEIGHT = 20;
21
+ const LABEL_FONT_WEIGHT = '500';
22
+
23
+ // Effects
24
+ const DISABLED_OPACITY = 0.38;
25
+ const BORDER_WIDTH_THEMED = 1;
26
+ const BORDER_WIDTH_NEUTRAL = 0;
27
+
28
+ /**
29
+ * One of the three button themes defined by Google's branding guidelines.
30
+ *
31
+ * - `light` — white background, dark text, gray border
32
+ * - `dark` — near-black background, light text, gray border
33
+ * - `neutral` — light gray background, dark text, no border
34
+ */
35
+
36
+ /**
37
+ * Button corner radius:
38
+ *
39
+ * - `rounded` — pill shape (`borderRadius: 20`)
40
+ * - `square` — slightly rounded rectangle (`borderRadius: 4`)
41
+ */
42
+
43
+ /**
44
+ * The call-to-action label. Only these three strings are permitted by Google.
45
+ *
46
+ * - `signin` — "Sign in with Google"
47
+ * - `signup` — "Sign up with Google"
48
+ * - `continue` — "Continue with Google"
49
+ */
50
+
51
+ /**
52
+ * Button size:
53
+ *
54
+ * - `standard` — full button with logo + text
55
+ * - `icon` — 40×40 logo-only button for compact layouts
56
+ */
57
+
58
+ /** Props for {@link GoogleSignInButton}. */
59
+
60
+ const BUTTON_LABELS = {
61
+ signin: 'Sign in with Google',
62
+ signup: 'Sign up with Google',
63
+ continue: 'Continue with Google'
64
+ };
65
+ const THEME_STYLES = {
66
+ light: {
67
+ backgroundColor: '#FFFFFF',
68
+ borderColor: '#747775',
69
+ borderWidth: BORDER_WIDTH_THEMED,
70
+ textColor: '#1F1F1F'
71
+ },
72
+ dark: {
73
+ backgroundColor: '#131314',
74
+ borderColor: '#8E918F',
75
+ borderWidth: BORDER_WIDTH_THEMED,
76
+ textColor: '#E3E3E3'
77
+ },
78
+ neutral: {
79
+ backgroundColor: '#F2F2F2',
80
+ borderColor: 'transparent',
81
+ borderWidth: BORDER_WIDTH_NEUTRAL,
82
+ textColor: '#1F1F1F'
83
+ }
84
+ };
85
+
86
+ /**
87
+ * A pre-built button conforming to Google's official branding guidelines.
88
+ *
89
+ * @remarks
90
+ * The Google "G" is rendered via `react-native-svg` so the button stays crisp
91
+ * at any density without bundled raster assets. Colors, typography, padding,
92
+ * and the permitted CTA strings all follow the official spec — do not
93
+ * restyle the logo or override theme colors, or Google may reject your app
94
+ * during brand review.
95
+ *
96
+ * @example
97
+ * ```tsx
98
+ * <GoogleSignInButton
99
+ * theme="dark"
100
+ * text="continue"
101
+ * onPress={() => GoogleSignIn.signIn()}
102
+ * />
103
+ * ```
104
+ */
105
+ export function GoogleSignInButton({
106
+ theme = 'light',
107
+ shape = 'rounded',
108
+ text = 'signin',
109
+ size = 'standard',
110
+ onPress,
111
+ disabled = false,
112
+ style,
113
+ testID
114
+ }) {
115
+ const themeStyle = THEME_STYLES[theme];
116
+ const isIcon = size === 'icon';
117
+ const borderRadius = shape === 'rounded' ? BORDER_RADIUS_ROUNDED : BORDER_RADIUS_SQUARE;
118
+ const label = BUTTON_LABELS[text];
119
+ return /*#__PURE__*/_jsxs(Pressable, {
120
+ style: [styles.button, {
121
+ backgroundColor: themeStyle.backgroundColor,
122
+ borderColor: themeStyle.borderColor,
123
+ borderWidth: themeStyle.borderWidth,
124
+ borderRadius
125
+ }, isIcon && styles.iconButton, disabled && styles.disabled, style],
126
+ onPress: onPress,
127
+ disabled: disabled,
128
+ accessibilityRole: "button",
129
+ accessibilityLabel: label,
130
+ testID: testID,
131
+ children: [/*#__PURE__*/_jsx(View, {
132
+ style: isIcon ? styles.iconLogoContainer : styles.logoContainer,
133
+ children: /*#__PURE__*/_jsx(GoogleLogo, {
134
+ size: GOOGLE_LOGO_SIZE
135
+ })
136
+ }), !isIcon && /*#__PURE__*/_jsx(Text, {
137
+ style: [styles.label, {
138
+ color: themeStyle.textColor
139
+ }],
140
+ numberOfLines: 1,
141
+ children: label
142
+ })]
143
+ });
144
+ }
145
+ const styles = StyleSheet.create({
146
+ button: {
147
+ flexDirection: 'row',
148
+ alignItems: 'center',
149
+ height: BUTTON_HEIGHT,
150
+ alignSelf: 'flex-start'
151
+ },
152
+ iconButton: {
153
+ width: ICON_BUTTON_SIZE,
154
+ justifyContent: 'center'
155
+ },
156
+ logoContainer: {
157
+ marginStart: LOGO_MARGIN_START,
158
+ marginEnd: LOGO_MARGIN_END
159
+ },
160
+ iconLogoContainer: {
161
+ alignItems: 'center',
162
+ justifyContent: 'center',
163
+ flex: 1
164
+ },
165
+ label: {
166
+ fontFamily: 'Roboto-Medium',
167
+ fontSize: LABEL_FONT_SIZE,
168
+ lineHeight: LABEL_LINE_HEIGHT,
169
+ fontWeight: LABEL_FONT_WEIGHT,
170
+ marginEnd: LOGO_MARGIN_END
171
+ },
172
+ disabled: {
173
+ opacity: DISABLED_OPACITY
174
+ }
175
+ });
176
+ //# sourceMappingURL=GoogleSignInButton.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"names":["Pressable","View","Text","StyleSheet","GoogleLogo","jsx","_jsx","jsxs","_jsxs","BUTTON_HEIGHT","ICON_BUTTON_SIZE","BORDER_RADIUS_ROUNDED","BORDER_RADIUS_SQUARE","GOOGLE_LOGO_SIZE","LOGO_MARGIN_START","LOGO_MARGIN_END","LABEL_FONT_SIZE","LABEL_LINE_HEIGHT","LABEL_FONT_WEIGHT","DISABLED_OPACITY","BORDER_WIDTH_THEMED","BORDER_WIDTH_NEUTRAL","BUTTON_LABELS","signin","signup","continue","THEME_STYLES","light","backgroundColor","borderColor","borderWidth","textColor","dark","neutral","GoogleSignInButton","theme","shape","text","size","onPress","disabled","style","testID","themeStyle","isIcon","borderRadius","label","styles","button","iconButton","accessibilityRole","accessibilityLabel","children","iconLogoContainer","logoContainer","color","numberOfLines","create","flexDirection","alignItems","height","alignSelf","width","justifyContent","marginStart","marginEnd","flex","fontFamily","fontSize","lineHeight","fontWeight","opacity"],"sourceRoot":"../../../src","sources":["google/GoogleSignInButton.tsx"],"mappings":"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","ignoreList":[]}
@@ -0,0 +1,5 @@
1
+ "use strict";
2
+
3
+ import { TurboModuleRegistry } from 'react-native';
4
+ export default TurboModuleRegistry.getEnforcing('GoogleSignIn');
5
+ //# sourceMappingURL=NativeGoogleSignIn.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"names":["TurboModuleRegistry","getEnforcing"],"sourceRoot":"../../../src","sources":["google/NativeGoogleSignIn.ts"],"mappings":";;AAAA,SAASA,mBAAmB,QAA0B,cAAc;AAWpE,eAAeA,mBAAmB,CAACC,YAAY,CAAO,cAAc,CAAC","ignoreList":[]}
@@ -0,0 +1,69 @@
1
+ "use strict";
2
+
3
+ /**
4
+ * Discriminator for {@link GoogleSignInError.code}. Identical on Android and
5
+ * iOS so error-handling code is platform-agnostic.
6
+ */
7
+ export let GoogleSignInErrorCode = /*#__PURE__*/function (GoogleSignInErrorCode) {
8
+ /** The user dismissed the sign-in sheet. Don't surface an error. */
9
+ GoogleSignInErrorCode["SIGN_IN_CANCELLED"] = "SIGN_IN_CANCELLED";
10
+ /** A generic native failure; inspect `message` and `nativeErrorCode` for details. */
11
+ GoogleSignInErrorCode["SIGN_IN_FAILED"] = "SIGN_IN_FAILED";
12
+ /** No Google accounts are available on the device. */
13
+ GoogleSignInErrorCode["NO_CREDENTIALS"] = "NO_CREDENTIALS";
14
+ /** Google Play Services is missing or out of date (Android only). */
15
+ GoogleSignInErrorCode["PLAY_SERVICES_NOT_AVAILABLE"] = "PLAY_SERVICES_NOT_AVAILABLE";
16
+ /** The device could not reach Google's auth servers. */
17
+ GoogleSignInErrorCode["NETWORK_ERROR"] = "NETWORK_ERROR";
18
+ /** A method was called before {@link GoogleSignIn.configure}. */
19
+ GoogleSignInErrorCode["NOT_CONFIGURED"] = "NOT_CONFIGURED";
20
+ return GoogleSignInErrorCode;
21
+ }({});
22
+
23
+ /**
24
+ * Typed error thrown / rejected by every {@link GoogleSignIn} method.
25
+ *
26
+ * @example
27
+ * ```ts
28
+ * try {
29
+ * await GoogleSignIn.signIn();
30
+ * } catch (error) {
31
+ * if (isGoogleSignInError(error) && error.code === GoogleSignInErrorCode.SIGN_IN_CANCELLED) {
32
+ * return;
33
+ * }
34
+ * throw error;
35
+ * }
36
+ * ```
37
+ */
38
+ export class GoogleSignInError extends Error {
39
+ /** The platform-agnostic error code. */
40
+
41
+ /**
42
+ * The underlying native error code (e.g. Android `28444`, iOS
43
+ * `kGIDSignInErrorCode...`). Useful for telemetry; do not branch on it from
44
+ * application code — branch on {@link code} instead.
45
+ */
46
+
47
+ /**
48
+ * @param code - A {@link GoogleSignInErrorCode} value.
49
+ * @param message - Human-readable description, suitable for logs.
50
+ * @param nativeErrorCode - Optional native-side code for diagnostics.
51
+ */
52
+ constructor(code, message, nativeErrorCode) {
53
+ super(message);
54
+ this.name = 'GoogleSignInError';
55
+ this.code = code;
56
+ this.nativeErrorCode = nativeErrorCode;
57
+ }
58
+ }
59
+
60
+ /**
61
+ * Type guard that narrows `unknown` to {@link GoogleSignInError}.
62
+ *
63
+ * @param error - Any caught value.
64
+ * @returns `true` when `error` is a {@link GoogleSignInError} instance.
65
+ */
66
+ export function isGoogleSignInError(error) {
67
+ return error instanceof GoogleSignInError;
68
+ }
69
+ //# sourceMappingURL=errors.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"names":["GoogleSignInErrorCode","GoogleSignInError","Error","constructor","code","message","nativeErrorCode","name","isGoogleSignInError","error"],"sourceRoot":"../../../src","sources":["google/errors.ts"],"mappings":";;AAAA;AACA;AACA;AACA;AACA,WAAYA,qBAAqB,0BAArBA,qBAAqB;EAC/B;EADUA,qBAAqB;EAG/B;EAHUA,qBAAqB;EAK/B;EALUA,qBAAqB;EAO/B;EAPUA,qBAAqB;EAS/B;EATUA,qBAAqB;EAW/B;EAXUA,qBAAqB;EAAA,OAArBA,qBAAqB;AAAA;;AAejC;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,OAAO,MAAMC,iBAAiB,SAASC,KAAK,CAAC;EAC3C;;EAEA;AACF;AACA;AACA;AACA;;EAGE;AACF;AACA;AACA;AACA;EACEC,WAAWA,CACTC,IAA2B,EAC3BC,OAAe,EACfC,eAAwB,EACxB;IACA,KAAK,CAACD,OAAO,CAAC;IACd,IAAI,CAACE,IAAI,GAAG,mBAAmB;IAC/B,IAAI,CAACH,IAAI,GAAGA,IAAI;IAChB,IAAI,CAACE,eAAe,GAAGA,eAAe;EACxC;AACF;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA,OAAO,SAASE,mBAAmBA,CACjCC,KAAc,EACc;EAC5B,OAAOA,KAAK,YAAYR,iBAAiB;AAC3C","ignoreList":[]}
@@ -0,0 +1,6 @@
1
+ "use strict";
2
+
3
+ export { GoogleSignIn } from "./GoogleSignIn.js";
4
+ export { GoogleSignInError, GoogleSignInErrorCode, isGoogleSignInError } from "./errors.js";
5
+ export { GoogleSignInButton } from "./GoogleSignInButton.js";
6
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"names":["GoogleSignIn","GoogleSignInError","GoogleSignInErrorCode","isGoogleSignInError","GoogleSignInButton"],"sourceRoot":"../../../src","sources":["google/index.ts"],"mappings":";;AAAA,SAASA,YAAY,QAAQ,mBAAgB;AAC7C,SACEC,iBAAiB,EACjBC,qBAAqB,EACrBC,mBAAmB,QACd,aAAU;AACjB,SAASC,kBAAkB,QAAQ,yBAAsB","ignoreList":[]}
@@ -0,0 +1,2 @@
1
+ "use strict";
2
+ //# sourceMappingURL=types.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"names":[],"sourceRoot":"../../../src","sources":["google/types.ts"],"mappings":"","ignoreList":[]}