@clerk/expo 3.0.0-snapshot.v20251215212157 → 3.0.0-snapshot.v20251216175437
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/android/build.gradle +64 -0
- package/android/src/main/AndroidManifest.xml +2 -0
- package/android/src/main/java/expo/modules/clerk/googlesignin/ClerkGoogleSignInModule.kt +264 -0
- package/app.plugin.js +1 -0
- package/dist/errorThrower.d.ts +1 -1
- package/dist/google-one-tap/ClerkGoogleOneTapSignIn.d.ts +104 -0
- package/dist/google-one-tap/ClerkGoogleOneTapSignIn.d.ts.map +1 -0
- package/dist/google-one-tap/ClerkGoogleOneTapSignIn.js +153 -0
- package/dist/google-one-tap/ClerkGoogleOneTapSignIn.js.map +1 -0
- package/dist/google-one-tap/index.d.ts +3 -0
- package/dist/google-one-tap/index.d.ts.map +1 -0
- package/dist/google-one-tap/index.js +37 -0
- package/dist/google-one-tap/index.js.map +1 -0
- package/dist/google-one-tap/types.d.ts +139 -0
- package/dist/google-one-tap/types.d.ts.map +1 -0
- package/dist/google-one-tap/types.js +17 -0
- package/dist/google-one-tap/types.js.map +1 -0
- package/dist/hooks/index.d.ts +1 -0
- package/dist/hooks/index.d.ts.map +1 -1
- package/dist/hooks/index.js +2 -0
- package/dist/hooks/index.js.map +1 -1
- package/dist/hooks/useSignInWithGoogle.android.d.ts +47 -0
- package/dist/hooks/useSignInWithGoogle.android.d.ts.map +1 -0
- package/dist/hooks/useSignInWithGoogle.android.js +65 -0
- package/dist/hooks/useSignInWithGoogle.android.js.map +1 -0
- package/dist/hooks/useSignInWithGoogle.d.ts +52 -0
- package/dist/hooks/useSignInWithGoogle.d.ts.map +1 -0
- package/dist/hooks/useSignInWithGoogle.ios.d.ts +47 -0
- package/dist/hooks/useSignInWithGoogle.ios.d.ts.map +1 -0
- package/dist/hooks/useSignInWithGoogle.ios.js +70 -0
- package/dist/hooks/useSignInWithGoogle.ios.js.map +1 -0
- package/dist/hooks/useSignInWithGoogle.js +39 -0
- package/dist/hooks/useSignInWithGoogle.js.map +1 -0
- package/dist/hooks/useSignInWithGoogle.shared.d.ts +17 -0
- package/dist/hooks/useSignInWithGoogle.shared.d.ts.map +1 -0
- package/dist/hooks/useSignInWithGoogle.shared.js +112 -0
- package/dist/hooks/useSignInWithGoogle.shared.js.map +1 -0
- package/dist/hooks/useSignInWithGoogle.types.d.ts +12 -0
- package/dist/hooks/useSignInWithGoogle.types.d.ts.map +1 -0
- package/dist/hooks/useSignInWithGoogle.types.js +17 -0
- package/dist/hooks/useSignInWithGoogle.types.js.map +1 -0
- package/dist/index.d.ts +0 -1
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +0 -3
- package/dist/index.js.map +1 -1
- package/dist/provider/ClerkProvider.js +1 -1
- package/dist/utils/errors.d.ts +1 -1
- package/expo-module.config.json +9 -0
- package/ios/ClerkGoogleSignIn.podspec +22 -0
- package/ios/ClerkGoogleSignInModule.swift +229 -0
- package/package.json +31 -10
- package/plugin/build/withClerkExpo.d.ts +3 -0
- package/plugin/build/withClerkExpo.js +36 -0
- package/plugin/src/withClerkExpo.ts +45 -0
- package/plugin/tsconfig.json +15 -0
|
@@ -0,0 +1,112 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __create = Object.create;
|
|
3
|
+
var __defProp = Object.defineProperty;
|
|
4
|
+
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
|
|
5
|
+
var __getOwnPropNames = Object.getOwnPropertyNames;
|
|
6
|
+
var __getProtoOf = Object.getPrototypeOf;
|
|
7
|
+
var __hasOwnProp = Object.prototype.hasOwnProperty;
|
|
8
|
+
var __export = (target, all) => {
|
|
9
|
+
for (var name in all)
|
|
10
|
+
__defProp(target, name, { get: all[name], enumerable: true });
|
|
11
|
+
};
|
|
12
|
+
var __copyProps = (to, from, except, desc) => {
|
|
13
|
+
if (from && typeof from === "object" || typeof from === "function") {
|
|
14
|
+
for (let key of __getOwnPropNames(from))
|
|
15
|
+
if (!__hasOwnProp.call(to, key) && key !== except)
|
|
16
|
+
__defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
|
|
17
|
+
}
|
|
18
|
+
return to;
|
|
19
|
+
};
|
|
20
|
+
var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__getProtoOf(mod)) : {}, __copyProps(
|
|
21
|
+
// If the importer is in node compatibility mode or this is not an ESM
|
|
22
|
+
// file that has been converted to a CommonJS file using a Babel-
|
|
23
|
+
// compatible transform (i.e. "__esModule" has not been set), then set
|
|
24
|
+
// "default" to the CommonJS "module.exports" for node compatibility.
|
|
25
|
+
isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", { value: mod, enumerable: true }) : target,
|
|
26
|
+
mod
|
|
27
|
+
));
|
|
28
|
+
var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
|
|
29
|
+
var useSignInWithGoogle_shared_exports = {};
|
|
30
|
+
__export(useSignInWithGoogle_shared_exports, {
|
|
31
|
+
executeGoogleAuthenticationFlow: () => executeGoogleAuthenticationFlow
|
|
32
|
+
});
|
|
33
|
+
module.exports = __toCommonJS(useSignInWithGoogle_shared_exports);
|
|
34
|
+
var import_error = require("@clerk/shared/error");
|
|
35
|
+
var import_google_one_tap = require("../google-one-tap");
|
|
36
|
+
async function executeGoogleAuthenticationFlow(context, clientIds, params) {
|
|
37
|
+
var _a;
|
|
38
|
+
const { client, setActive } = context;
|
|
39
|
+
const { signIn, signUp } = client;
|
|
40
|
+
import_google_one_tap.ClerkGoogleOneTapSignIn.configure(clientIds);
|
|
41
|
+
const { randomUUID } = await import("expo-crypto");
|
|
42
|
+
const nonce = randomUUID();
|
|
43
|
+
try {
|
|
44
|
+
const response = await import_google_one_tap.ClerkGoogleOneTapSignIn.presentExplicitSignIn({
|
|
45
|
+
nonce
|
|
46
|
+
});
|
|
47
|
+
if (!(0, import_google_one_tap.isSuccessResponse)(response)) {
|
|
48
|
+
return {
|
|
49
|
+
createdSessionId: null,
|
|
50
|
+
setActive,
|
|
51
|
+
signIn,
|
|
52
|
+
signUp
|
|
53
|
+
};
|
|
54
|
+
}
|
|
55
|
+
const { idToken } = response.data;
|
|
56
|
+
try {
|
|
57
|
+
await signIn.create({
|
|
58
|
+
strategy: "google_one_tap",
|
|
59
|
+
token: idToken
|
|
60
|
+
});
|
|
61
|
+
const userNeedsToBeCreated = signIn.firstFactorVerification.status === "transferable";
|
|
62
|
+
if (userNeedsToBeCreated) {
|
|
63
|
+
await signUp.create({
|
|
64
|
+
transfer: true,
|
|
65
|
+
unsafeMetadata: params == null ? void 0 : params.unsafeMetadata
|
|
66
|
+
});
|
|
67
|
+
return {
|
|
68
|
+
createdSessionId: signUp.createdSessionId,
|
|
69
|
+
setActive,
|
|
70
|
+
signIn,
|
|
71
|
+
signUp
|
|
72
|
+
};
|
|
73
|
+
}
|
|
74
|
+
return {
|
|
75
|
+
createdSessionId: signIn.createdSessionId,
|
|
76
|
+
setActive,
|
|
77
|
+
signIn,
|
|
78
|
+
signUp
|
|
79
|
+
};
|
|
80
|
+
} catch (signInError) {
|
|
81
|
+
if ((0, import_error.isClerkAPIResponseError)(signInError) && ((_a = signInError.errors) == null ? void 0 : _a.some((err) => err.code === "external_account_not_found"))) {
|
|
82
|
+
await signUp.create({
|
|
83
|
+
strategy: "google_one_tap",
|
|
84
|
+
token: idToken,
|
|
85
|
+
unsafeMetadata: params == null ? void 0 : params.unsafeMetadata
|
|
86
|
+
});
|
|
87
|
+
return {
|
|
88
|
+
createdSessionId: signUp.createdSessionId,
|
|
89
|
+
setActive,
|
|
90
|
+
signIn,
|
|
91
|
+
signUp
|
|
92
|
+
};
|
|
93
|
+
}
|
|
94
|
+
throw signInError;
|
|
95
|
+
}
|
|
96
|
+
} catch (error) {
|
|
97
|
+
if ((0, import_google_one_tap.isErrorWithCode)(error) && error.code === "SIGN_IN_CANCELLED") {
|
|
98
|
+
return {
|
|
99
|
+
createdSessionId: null,
|
|
100
|
+
setActive,
|
|
101
|
+
signIn,
|
|
102
|
+
signUp
|
|
103
|
+
};
|
|
104
|
+
}
|
|
105
|
+
throw error;
|
|
106
|
+
}
|
|
107
|
+
}
|
|
108
|
+
// Annotate the CommonJS export names for ESM import in node:
|
|
109
|
+
0 && (module.exports = {
|
|
110
|
+
executeGoogleAuthenticationFlow
|
|
111
|
+
});
|
|
112
|
+
//# sourceMappingURL=useSignInWithGoogle.shared.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../../src/hooks/useSignInWithGoogle.shared.ts"],"sourcesContent":["import { isClerkAPIResponseError } from '@clerk/shared/error';\nimport type { ClientResource, SetActive } from '@clerk/shared/types';\n\nimport { ClerkGoogleOneTapSignIn, isErrorWithCode, isSuccessResponse } from '../google-one-tap';\nimport type {\n StartGoogleAuthenticationFlowParams,\n StartGoogleAuthenticationFlowReturnType,\n} from './useSignInWithGoogle.types';\n\nexport type GoogleClientIds = {\n webClientId: string;\n iosClientId?: string;\n};\n\nexport type GoogleAuthenticationFlowContext = {\n client: ClientResource;\n setActive: SetActive;\n};\n\n/**\n * Core implementation of Google Authentication flow shared between iOS and Android.\n *\n * @internal\n */\nexport async function executeGoogleAuthenticationFlow(\n context: GoogleAuthenticationFlowContext,\n clientIds: GoogleClientIds,\n params?: StartGoogleAuthenticationFlowParams,\n): Promise<StartGoogleAuthenticationFlowReturnType> {\n const { client, setActive } = context;\n const { signIn, signUp } = client;\n\n // Configure Google Sign-In with client IDs\n ClerkGoogleOneTapSignIn.configure(clientIds);\n\n // Generate a cryptographic nonce for replay attack protection\n const { randomUUID } = await import('expo-crypto');\n const nonce = randomUUID();\n\n try {\n // Present Google Sign-In UI with nonce\n const response = await ClerkGoogleOneTapSignIn.presentExplicitSignIn({\n nonce,\n });\n\n // User cancelled\n if (!isSuccessResponse(response)) {\n return {\n createdSessionId: null,\n setActive,\n signIn,\n signUp,\n };\n }\n\n const { idToken } = response.data;\n\n try {\n // Try to sign in with the Google One Tap strategy\n await signIn.create({\n strategy: 'google_one_tap',\n token: idToken,\n });\n\n // Check if we need to transfer to SignUp (user doesn't exist yet)\n const userNeedsToBeCreated = signIn.firstFactorVerification.status === 'transferable';\n\n if (userNeedsToBeCreated) {\n // User doesn't exist - create a new SignUp with transfer\n await signUp.create({\n transfer: true,\n unsafeMetadata: params?.unsafeMetadata,\n });\n\n return {\n createdSessionId: signUp.createdSessionId,\n setActive,\n signIn,\n signUp,\n };\n }\n\n // User exists - return the SignIn session\n return {\n createdSessionId: signIn.createdSessionId,\n setActive,\n signIn,\n signUp,\n };\n } catch (signInError: unknown) {\n // Handle the case where the user doesn't exist (external_account_not_found)\n if (\n isClerkAPIResponseError(signInError) &&\n signInError.errors?.some(err => err.code === 'external_account_not_found')\n ) {\n // User doesn't exist - create a new SignUp with the token\n await signUp.create({\n strategy: 'google_one_tap',\n token: idToken,\n unsafeMetadata: params?.unsafeMetadata,\n });\n\n return {\n createdSessionId: signUp.createdSessionId,\n setActive,\n signIn,\n signUp,\n };\n }\n\n // Re-throw if it's a different error\n throw signInError;\n }\n } catch (error: unknown) {\n // Handle Google Sign-In cancellation errors\n if (isErrorWithCode(error) && error.code === 'SIGN_IN_CANCELLED') {\n return {\n createdSessionId: null,\n setActive,\n signIn,\n signUp,\n };\n }\n\n // Re-throw other errors\n throw error;\n }\n}\n"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,mBAAwC;AAGxC,4BAA4E;AAqB5E,eAAsB,gCACpB,SACA,WACA,QACkD;AA5BpD;AA6BE,QAAM,EAAE,QAAQ,UAAU,IAAI;AAC9B,QAAM,EAAE,QAAQ,OAAO,IAAI;AAG3B,gDAAwB,UAAU,SAAS;AAG3C,QAAM,EAAE,WAAW,IAAI,MAAM,OAAO,aAAa;AACjD,QAAM,QAAQ,WAAW;AAEzB,MAAI;AAEF,UAAM,WAAW,MAAM,8CAAwB,sBAAsB;AAAA,MACnE;AAAA,IACF,CAAC;AAGD,QAAI,KAAC,yCAAkB,QAAQ,GAAG;AAChC,aAAO;AAAA,QACL,kBAAkB;AAAA,QAClB;AAAA,QACA;AAAA,QACA;AAAA,MACF;AAAA,IACF;AAEA,UAAM,EAAE,QAAQ,IAAI,SAAS;AAE7B,QAAI;AAEF,YAAM,OAAO,OAAO;AAAA,QAClB,UAAU;AAAA,QACV,OAAO;AAAA,MACT,CAAC;AAGD,YAAM,uBAAuB,OAAO,wBAAwB,WAAW;AAEvE,UAAI,sBAAsB;AAExB,cAAM,OAAO,OAAO;AAAA,UAClB,UAAU;AAAA,UACV,gBAAgB,iCAAQ;AAAA,QAC1B,CAAC;AAED,eAAO;AAAA,UACL,kBAAkB,OAAO;AAAA,UACzB;AAAA,UACA;AAAA,UACA;AAAA,QACF;AAAA,MACF;AAGA,aAAO;AAAA,QACL,kBAAkB,OAAO;AAAA,QACzB;AAAA,QACA;AAAA,QACA;AAAA,MACF;AAAA,IACF,SAAS,aAAsB;AAE7B,cACE,sCAAwB,WAAW,OACnC,iBAAY,WAAZ,mBAAoB,KAAK,SAAO,IAAI,SAAS,gCAC7C;AAEA,cAAM,OAAO,OAAO;AAAA,UAClB,UAAU;AAAA,UACV,OAAO;AAAA,UACP,gBAAgB,iCAAQ;AAAA,QAC1B,CAAC;AAED,eAAO;AAAA,UACL,kBAAkB,OAAO;AAAA,UACzB;AAAA,UACA;AAAA,UACA;AAAA,QACF;AAAA,MACF;AAGA,YAAM;AAAA,IACR;AAAA,EACF,SAAS,OAAgB;AAEvB,YAAI,uCAAgB,KAAK,KAAK,MAAM,SAAS,qBAAqB;AAChE,aAAO;AAAA,QACL,kBAAkB;AAAA,QAClB;AAAA,QACA;AAAA,QACA;AAAA,MACF;AAAA,IACF;AAGA,UAAM;AAAA,EACR;AACF;","names":[]}
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
import type { SetActive, SignInResource, SignUpResource } from '@clerk/shared/types';
|
|
2
|
+
export type SignUpUnsafeMetadata = Record<string, unknown>;
|
|
3
|
+
export type StartGoogleAuthenticationFlowParams = {
|
|
4
|
+
unsafeMetadata?: SignUpUnsafeMetadata;
|
|
5
|
+
};
|
|
6
|
+
export type StartGoogleAuthenticationFlowReturnType = {
|
|
7
|
+
createdSessionId: string | null;
|
|
8
|
+
setActive?: SetActive;
|
|
9
|
+
signIn?: SignInResource;
|
|
10
|
+
signUp?: SignUpResource;
|
|
11
|
+
};
|
|
12
|
+
//# sourceMappingURL=useSignInWithGoogle.types.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"useSignInWithGoogle.types.d.ts","sourceRoot":"","sources":["../../src/hooks/useSignInWithGoogle.types.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,SAAS,EAAE,cAAc,EAAE,cAAc,EAAE,MAAM,qBAAqB,CAAC;AAErF,MAAM,MAAM,oBAAoB,GAAG,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;AAE3D,MAAM,MAAM,mCAAmC,GAAG;IAChD,cAAc,CAAC,EAAE,oBAAoB,CAAC;CACvC,CAAC;AAEF,MAAM,MAAM,uCAAuC,GAAG;IACpD,gBAAgB,EAAE,MAAM,GAAG,IAAI,CAAC;IAChC,SAAS,CAAC,EAAE,SAAS,CAAC;IACtB,MAAM,CAAC,EAAE,cAAc,CAAC;IACxB,MAAM,CAAC,EAAE,cAAc,CAAC;CACzB,CAAC"}
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __defProp = Object.defineProperty;
|
|
3
|
+
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
|
|
4
|
+
var __getOwnPropNames = Object.getOwnPropertyNames;
|
|
5
|
+
var __hasOwnProp = Object.prototype.hasOwnProperty;
|
|
6
|
+
var __copyProps = (to, from, except, desc) => {
|
|
7
|
+
if (from && typeof from === "object" || typeof from === "function") {
|
|
8
|
+
for (let key of __getOwnPropNames(from))
|
|
9
|
+
if (!__hasOwnProp.call(to, key) && key !== except)
|
|
10
|
+
__defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
|
|
11
|
+
}
|
|
12
|
+
return to;
|
|
13
|
+
};
|
|
14
|
+
var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
|
|
15
|
+
var useSignInWithGoogle_types_exports = {};
|
|
16
|
+
module.exports = __toCommonJS(useSignInWithGoogle_types_exports);
|
|
17
|
+
//# sourceMappingURL=useSignInWithGoogle.types.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../../src/hooks/useSignInWithGoogle.types.ts"],"sourcesContent":["import type { SetActive, SignInResource, SignUpResource } from '@clerk/shared/types';\n\nexport type SignUpUnsafeMetadata = Record<string, unknown>;\n\nexport type StartGoogleAuthenticationFlowParams = {\n unsafeMetadata?: SignUpUnsafeMetadata;\n};\n\nexport type StartGoogleAuthenticationFlowReturnType = {\n createdSessionId: string | null;\n setActive?: SetActive;\n signIn?: SignInResource;\n signUp?: SignUpResource;\n};\n"],"mappings":";;;;;;;;;;;;;;AAAA;AAAA;","names":[]}
|
package/dist/index.d.ts
CHANGED
|
@@ -7,6 +7,5 @@ export { getClerkInstance } from './provider/singleton';
|
|
|
7
7
|
export * from './provider/ClerkProvider';
|
|
8
8
|
export * from './hooks';
|
|
9
9
|
export * from './components';
|
|
10
|
-
export { UNSAFE_PortalProvider } from '@clerk/react';
|
|
11
10
|
export type { TokenCache } from './cache/types';
|
|
12
11
|
//# sourceMappingURL=index.d.ts.map
|
package/dist/index.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAEA,OAAO,EACL,uBAAuB,EACvB,gBAAgB,EAChB,YAAY,EACZ,eAAe,EACf,mBAAmB,GACpB,MAAM,qBAAqB,CAAC;AAE7B;;GAEG;AACH,OAAO,EAAE,KAAK,IAAI,KAAK,EAAE,MAAM,sBAAsB,CAAC;AACtD,OAAO,EAAE,gBAAgB,EAAE,MAAM,sBAAsB,CAAC;AAExD,cAAc,0BAA0B,CAAC;AACzC,cAAc,SAAS,CAAC;AACxB,cAAc,cAAc,CAAC;
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAEA,OAAO,EACL,uBAAuB,EACvB,gBAAgB,EAChB,YAAY,EACZ,eAAe,EACf,mBAAmB,GACpB,MAAM,qBAAqB,CAAC;AAE7B;;GAEG;AACH,OAAO,EAAE,KAAK,IAAI,KAAK,EAAE,MAAM,sBAAsB,CAAC;AACtD,OAAO,EAAE,gBAAgB,EAAE,MAAM,sBAAsB,CAAC;AAExD,cAAc,0BAA0B,CAAC;AACzC,cAAc,SAAS,CAAC;AACxB,cAAc,cAAc,CAAC;AAK7B,YAAY,EAAE,UAAU,EAAE,MAAM,eAAe,CAAC"}
|
package/dist/index.js
CHANGED
|
@@ -20,7 +20,6 @@ var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: tru
|
|
|
20
20
|
var index_exports = {};
|
|
21
21
|
__export(index_exports, {
|
|
22
22
|
Clerk: () => import_singleton.clerk,
|
|
23
|
-
UNSAFE_PortalProvider: () => import_react.UNSAFE_PortalProvider,
|
|
24
23
|
getClerkInstance: () => import_singleton2.getClerkInstance,
|
|
25
24
|
isClerkAPIResponseError: () => import_errors.isClerkAPIResponseError,
|
|
26
25
|
isClerkRuntimeError: () => import_errors.isClerkRuntimeError,
|
|
@@ -36,12 +35,10 @@ var import_singleton2 = require("./provider/singleton");
|
|
|
36
35
|
__reExport(index_exports, require("./provider/ClerkProvider"), module.exports);
|
|
37
36
|
__reExport(index_exports, require("./hooks"), module.exports);
|
|
38
37
|
__reExport(index_exports, require("./components"), module.exports);
|
|
39
|
-
var import_react = require("@clerk/react");
|
|
40
38
|
(0, import_internal.setErrorThrowerOptions)({ packageName: "@clerk/expo" });
|
|
41
39
|
// Annotate the CommonJS export names for ESM import in node:
|
|
42
40
|
0 && (module.exports = {
|
|
43
41
|
Clerk,
|
|
44
|
-
UNSAFE_PortalProvider,
|
|
45
42
|
getClerkInstance,
|
|
46
43
|
isClerkAPIResponseError,
|
|
47
44
|
isClerkRuntimeError,
|
package/dist/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/index.ts"],"sourcesContent":["import { setErrorThrowerOptions } from '@clerk/react/internal';\n\nexport {\n isClerkAPIResponseError,\n isEmailLinkError,\n isKnownError,\n isMetamaskError,\n isClerkRuntimeError,\n} from '@clerk/react/errors';\n\n/**\n * @deprecated Use `getClerkInstance()` instead.\n */\nexport { clerk as Clerk } from './provider/singleton';\nexport { getClerkInstance } from './provider/singleton';\n\nexport * from './provider/ClerkProvider';\nexport * from './hooks';\nexport * from './components';\
|
|
1
|
+
{"version":3,"sources":["../src/index.ts"],"sourcesContent":["import { setErrorThrowerOptions } from '@clerk/react/internal';\n\nexport {\n isClerkAPIResponseError,\n isEmailLinkError,\n isKnownError,\n isMetamaskError,\n isClerkRuntimeError,\n} from '@clerk/react/errors';\n\n/**\n * @deprecated Use `getClerkInstance()` instead.\n */\nexport { clerk as Clerk } from './provider/singleton';\nexport { getClerkInstance } from './provider/singleton';\n\nexport * from './provider/ClerkProvider';\nexport * from './hooks';\nexport * from './components';\n\n// Override Clerk React error thrower to show that errors come from @clerk/expo\nsetErrorThrowerOptions({ packageName: PACKAGE_NAME });\n\nexport type { TokenCache } from './cache/types';\n"],"mappings":";;;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,sBAAuC;AAEvC,oBAMO;AAKP,uBAA+B;AAC/B,IAAAA,oBAAiC;AAEjC,0BAAc,qCAhBd;AAiBA,0BAAc,oBAjBd;AAkBA,0BAAc,yBAlBd;AAAA,IAqBA,wCAAuB,EAAE,aAAa,cAAa,CAAC;","names":["import_singleton"]}
|
|
@@ -39,7 +39,7 @@ var import_runtime = require("../utils/runtime");
|
|
|
39
39
|
var import_singleton = require("./singleton");
|
|
40
40
|
const SDK_METADATA = {
|
|
41
41
|
name: "@clerk/expo",
|
|
42
|
-
version: "3.0.0-snapshot.
|
|
42
|
+
version: "3.0.0-snapshot.v20251216175437"
|
|
43
43
|
};
|
|
44
44
|
function ClerkProvider(props) {
|
|
45
45
|
const {
|
package/dist/utils/errors.d.ts
CHANGED
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
export declare const errorThrower: import("@clerk/shared/error-
|
|
1
|
+
export declare const errorThrower: import("@clerk/shared/error-uvNWuzfd").y;
|
|
2
2
|
//# sourceMappingURL=errors.d.ts.map
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
require 'json'
|
|
2
|
+
|
|
3
|
+
package = JSON.parse(File.read(File.join(__dir__, '..', 'package.json')))
|
|
4
|
+
|
|
5
|
+
Pod::Spec.new do |s|
|
|
6
|
+
s.name = 'ClerkGoogleSignIn'
|
|
7
|
+
s.version = package['version']
|
|
8
|
+
s.summary = 'Native Google Sign-In module for Clerk Expo'
|
|
9
|
+
s.description = 'Native Google Sign-In functionality using Google Sign-In SDK with nonce support for Clerk authentication'
|
|
10
|
+
s.license = package['license']
|
|
11
|
+
s.author = package['author']
|
|
12
|
+
s.homepage = package['homepage']
|
|
13
|
+
s.platforms = { :ios => '13.4' }
|
|
14
|
+
s.swift_version = '5.4'
|
|
15
|
+
s.source = { :git => 'https://github.com/clerk/javascript.git' }
|
|
16
|
+
s.static_framework = true
|
|
17
|
+
|
|
18
|
+
s.dependency 'ExpoModulesCore'
|
|
19
|
+
s.dependency 'GoogleSignIn', '~> 9.0'
|
|
20
|
+
|
|
21
|
+
s.source_files = '*.swift'
|
|
22
|
+
end
|
|
@@ -0,0 +1,229 @@
|
|
|
1
|
+
import ExpoModulesCore
|
|
2
|
+
import GoogleSignIn
|
|
3
|
+
|
|
4
|
+
public class ClerkGoogleSignInModule: Module {
|
|
5
|
+
private var clientId: String?
|
|
6
|
+
private var hostedDomain: String?
|
|
7
|
+
|
|
8
|
+
public func definition() -> ModuleDefinition {
|
|
9
|
+
Name("ClerkGoogleSignIn")
|
|
10
|
+
|
|
11
|
+
// Configure the module
|
|
12
|
+
Function("configure") { (params: ConfigureParams) in
|
|
13
|
+
self.clientId = params.iosClientId ?? params.webClientId
|
|
14
|
+
self.hostedDomain = params.hostedDomain
|
|
15
|
+
|
|
16
|
+
// Set the configuration globally
|
|
17
|
+
// clientID: iOS client ID for OAuth flow
|
|
18
|
+
// serverClientID: Web client ID for token audience (what Clerk backend verifies)
|
|
19
|
+
if let clientId = self.clientId {
|
|
20
|
+
let config = GIDConfiguration(
|
|
21
|
+
clientID: clientId,
|
|
22
|
+
serverClientID: params.webClientId
|
|
23
|
+
)
|
|
24
|
+
GIDSignIn.sharedInstance.configuration = config
|
|
25
|
+
}
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
// Sign in - attempts sign-in with hint if available
|
|
29
|
+
AsyncFunction("signIn") { (params: SignInParams?, promise: Promise) in
|
|
30
|
+
guard self.clientId != nil else {
|
|
31
|
+
promise.reject(NotConfiguredException())
|
|
32
|
+
return
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
DispatchQueue.main.async {
|
|
36
|
+
guard let presentingVC = self.getPresentingViewController() else {
|
|
37
|
+
promise.reject(GoogleSignInException(message: "No presenting view controller available"))
|
|
38
|
+
return
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
// Build sign-in hint if filtering by authorized accounts
|
|
42
|
+
let hint: String? = params?.filterByAuthorizedAccounts == true
|
|
43
|
+
? GIDSignIn.sharedInstance.currentUser?.profile?.email
|
|
44
|
+
: nil
|
|
45
|
+
|
|
46
|
+
GIDSignIn.sharedInstance.signIn(
|
|
47
|
+
withPresenting: presentingVC,
|
|
48
|
+
hint: hint,
|
|
49
|
+
additionalScopes: nil,
|
|
50
|
+
nonce: params?.nonce
|
|
51
|
+
) { result, error in
|
|
52
|
+
self.handleSignInResult(result: result, error: error, promise: promise)
|
|
53
|
+
}
|
|
54
|
+
}
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
// Create account - shows account creation UI (same as sign in on iOS)
|
|
58
|
+
AsyncFunction("createAccount") { (params: CreateAccountParams?, promise: Promise) in
|
|
59
|
+
guard self.clientId != nil else {
|
|
60
|
+
promise.reject(NotConfiguredException())
|
|
61
|
+
return
|
|
62
|
+
}
|
|
63
|
+
|
|
64
|
+
DispatchQueue.main.async {
|
|
65
|
+
guard let presentingVC = self.getPresentingViewController() else {
|
|
66
|
+
promise.reject(GoogleSignInException(message: "No presenting view controller available"))
|
|
67
|
+
return
|
|
68
|
+
}
|
|
69
|
+
|
|
70
|
+
GIDSignIn.sharedInstance.signIn(
|
|
71
|
+
withPresenting: presentingVC,
|
|
72
|
+
hint: nil,
|
|
73
|
+
additionalScopes: nil,
|
|
74
|
+
nonce: params?.nonce
|
|
75
|
+
) { result, error in
|
|
76
|
+
self.handleSignInResult(result: result, error: error, promise: promise)
|
|
77
|
+
}
|
|
78
|
+
}
|
|
79
|
+
}
|
|
80
|
+
|
|
81
|
+
// Explicit sign-in - uses standard Google Sign-In flow
|
|
82
|
+
AsyncFunction("presentExplicitSignIn") { (params: ExplicitSignInParams?, promise: Promise) in
|
|
83
|
+
guard self.clientId != nil else {
|
|
84
|
+
promise.reject(NotConfiguredException())
|
|
85
|
+
return
|
|
86
|
+
}
|
|
87
|
+
|
|
88
|
+
DispatchQueue.main.async {
|
|
89
|
+
guard let presentingVC = self.getPresentingViewController() else {
|
|
90
|
+
promise.reject(GoogleSignInException(message: "No presenting view controller available"))
|
|
91
|
+
return
|
|
92
|
+
}
|
|
93
|
+
|
|
94
|
+
GIDSignIn.sharedInstance.signIn(
|
|
95
|
+
withPresenting: presentingVC,
|
|
96
|
+
hint: nil,
|
|
97
|
+
additionalScopes: nil,
|
|
98
|
+
nonce: params?.nonce
|
|
99
|
+
) { result, error in
|
|
100
|
+
self.handleSignInResult(result: result, error: error, promise: promise)
|
|
101
|
+
}
|
|
102
|
+
}
|
|
103
|
+
}
|
|
104
|
+
|
|
105
|
+
// Sign out - clears credential state
|
|
106
|
+
AsyncFunction("signOut") { (promise: Promise) in
|
|
107
|
+
GIDSignIn.sharedInstance.signOut()
|
|
108
|
+
promise.resolve(nil)
|
|
109
|
+
}
|
|
110
|
+
}
|
|
111
|
+
|
|
112
|
+
private func getPresentingViewController() -> UIViewController? {
|
|
113
|
+
guard let scene = UIApplication.shared.connectedScenes.first as? UIWindowScene,
|
|
114
|
+
let window = scene.windows.first,
|
|
115
|
+
let rootVC = window.rootViewController else {
|
|
116
|
+
return nil
|
|
117
|
+
}
|
|
118
|
+
|
|
119
|
+
var topVC = rootVC
|
|
120
|
+
while let presentedVC = topVC.presentedViewController {
|
|
121
|
+
topVC = presentedVC
|
|
122
|
+
}
|
|
123
|
+
return topVC
|
|
124
|
+
}
|
|
125
|
+
|
|
126
|
+
private func handleSignInResult(result: GIDSignInResult?, error: Error?, promise: Promise) {
|
|
127
|
+
if let error = error {
|
|
128
|
+
let nsError = error as NSError
|
|
129
|
+
|
|
130
|
+
// Check for user cancellation
|
|
131
|
+
if nsError.domain == kGIDSignInErrorDomain && nsError.code == GIDSignInError.canceled.rawValue {
|
|
132
|
+
promise.reject(SignInCancelledException())
|
|
133
|
+
return
|
|
134
|
+
}
|
|
135
|
+
|
|
136
|
+
promise.reject(GoogleSignInException(message: error.localizedDescription))
|
|
137
|
+
return
|
|
138
|
+
}
|
|
139
|
+
|
|
140
|
+
guard let result = result,
|
|
141
|
+
let idToken = result.user.idToken?.tokenString else {
|
|
142
|
+
promise.reject(GoogleSignInException(message: "No ID token received"))
|
|
143
|
+
return
|
|
144
|
+
}
|
|
145
|
+
|
|
146
|
+
let user = result.user
|
|
147
|
+
let profile = user.profile
|
|
148
|
+
|
|
149
|
+
let response: [String: Any] = [
|
|
150
|
+
"type": "success",
|
|
151
|
+
"data": [
|
|
152
|
+
"idToken": idToken,
|
|
153
|
+
"user": [
|
|
154
|
+
"id": user.userID ?? "",
|
|
155
|
+
"email": profile?.email ?? "",
|
|
156
|
+
"name": profile?.name ?? "",
|
|
157
|
+
"givenName": profile?.givenName ?? "",
|
|
158
|
+
"familyName": profile?.familyName ?? "",
|
|
159
|
+
"photo": profile?.imageURL(withDimension: 200)?.absoluteString ?? NSNull()
|
|
160
|
+
] as [String: Any]
|
|
161
|
+
] as [String: Any]
|
|
162
|
+
]
|
|
163
|
+
|
|
164
|
+
promise.resolve(response)
|
|
165
|
+
}
|
|
166
|
+
}
|
|
167
|
+
|
|
168
|
+
// MARK: - Records
|
|
169
|
+
|
|
170
|
+
struct ConfigureParams: Record {
|
|
171
|
+
@Field
|
|
172
|
+
var webClientId: String = ""
|
|
173
|
+
|
|
174
|
+
@Field
|
|
175
|
+
var iosClientId: String?
|
|
176
|
+
|
|
177
|
+
@Field
|
|
178
|
+
var hostedDomain: String?
|
|
179
|
+
|
|
180
|
+
@Field
|
|
181
|
+
var autoSelectEnabled: Bool?
|
|
182
|
+
}
|
|
183
|
+
|
|
184
|
+
struct SignInParams: Record {
|
|
185
|
+
@Field
|
|
186
|
+
var nonce: String?
|
|
187
|
+
|
|
188
|
+
@Field
|
|
189
|
+
var filterByAuthorizedAccounts: Bool?
|
|
190
|
+
}
|
|
191
|
+
|
|
192
|
+
struct CreateAccountParams: Record {
|
|
193
|
+
@Field
|
|
194
|
+
var nonce: String?
|
|
195
|
+
}
|
|
196
|
+
|
|
197
|
+
struct ExplicitSignInParams: Record {
|
|
198
|
+
@Field
|
|
199
|
+
var nonce: String?
|
|
200
|
+
}
|
|
201
|
+
|
|
202
|
+
// MARK: - Exceptions
|
|
203
|
+
|
|
204
|
+
class SignInCancelledException: Exception {
|
|
205
|
+
override var code: String { "SIGN_IN_CANCELLED" }
|
|
206
|
+
override var reason: String { "User cancelled the sign-in flow" }
|
|
207
|
+
}
|
|
208
|
+
|
|
209
|
+
class NoSavedCredentialException: Exception {
|
|
210
|
+
override var code: String { "NO_SAVED_CREDENTIAL_FOUND" }
|
|
211
|
+
override var reason: String { "No saved credential found" }
|
|
212
|
+
}
|
|
213
|
+
|
|
214
|
+
class NotConfiguredException: Exception {
|
|
215
|
+
override var code: String { "NOT_CONFIGURED" }
|
|
216
|
+
override var reason: String { "Google Sign-In is not configured. Call configure() first." }
|
|
217
|
+
}
|
|
218
|
+
|
|
219
|
+
class GoogleSignInException: Exception {
|
|
220
|
+
private let errorMessage: String
|
|
221
|
+
|
|
222
|
+
init(message: String) {
|
|
223
|
+
self.errorMessage = message
|
|
224
|
+
super.init()
|
|
225
|
+
}
|
|
226
|
+
|
|
227
|
+
override var code: String { "GOOGLE_SIGN_IN_ERROR" }
|
|
228
|
+
override var reason: String { errorMessage }
|
|
229
|
+
}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@clerk/expo",
|
|
3
|
-
"version": "3.0.0-snapshot.
|
|
3
|
+
"version": "3.0.0-snapshot.v20251216175437",
|
|
4
4
|
"description": "Clerk React Native/Expo library",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"react",
|
|
@@ -59,40 +59,57 @@
|
|
|
59
59
|
"./legacy": {
|
|
60
60
|
"types": "./dist/legacy.d.ts",
|
|
61
61
|
"default": "./dist/legacy.js"
|
|
62
|
-
}
|
|
62
|
+
},
|
|
63
|
+
"./app.plugin.js": "./app.plugin.js",
|
|
64
|
+
"./package.json": "./package.json"
|
|
63
65
|
},
|
|
64
66
|
"main": "./dist/index.js",
|
|
65
67
|
"source": "./src/index.ts",
|
|
66
68
|
"types": "./dist/index.d.ts",
|
|
67
69
|
"files": [
|
|
68
|
-
"dist"
|
|
70
|
+
"dist",
|
|
71
|
+
"android",
|
|
72
|
+
"ios",
|
|
73
|
+
"expo-module.config.json",
|
|
74
|
+
"app.plugin.js",
|
|
75
|
+
"plugin",
|
|
76
|
+
"web",
|
|
77
|
+
"local-credentials",
|
|
78
|
+
"passkeys",
|
|
79
|
+
"secure-store",
|
|
80
|
+
"resource-cache",
|
|
81
|
+
"token-cache"
|
|
69
82
|
],
|
|
70
83
|
"dependencies": {
|
|
71
84
|
"base-64": "^1.0.0",
|
|
72
85
|
"react-native-url-polyfill": "2.0.0",
|
|
73
86
|
"tslib": "2.8.1",
|
|
74
|
-
"@clerk/
|
|
75
|
-
"@clerk/
|
|
76
|
-
"@clerk/
|
|
87
|
+
"@clerk/clerk-js": "3.0.0-snapshot.v20251216175437",
|
|
88
|
+
"@clerk/react": "6.0.0-snapshot.v20251216175437",
|
|
89
|
+
"@clerk/shared": "4.0.0-snapshot.v20251216175437"
|
|
77
90
|
},
|
|
78
91
|
"devDependencies": {
|
|
92
|
+
"@expo/config-plugins": "^54.0.4",
|
|
79
93
|
"@types/base-64": "^1.0.2",
|
|
80
94
|
"expo-apple-authentication": "^7.2.4",
|
|
81
95
|
"expo-auth-session": "^5.4.0",
|
|
96
|
+
"expo-constants": "^18.0.0",
|
|
82
97
|
"expo-crypto": "^15.0.7",
|
|
83
98
|
"expo-local-authentication": "^13.8.0",
|
|
99
|
+
"expo-modules-core": "^3.0.0",
|
|
84
100
|
"expo-secure-store": "^12.8.1",
|
|
85
101
|
"expo-web-browser": "^12.8.2",
|
|
86
102
|
"react-native": "^0.81.4",
|
|
87
|
-
"@clerk/expo-passkeys": "1.0.0-snapshot.
|
|
103
|
+
"@clerk/expo-passkeys": "1.0.0-snapshot.v20251216175437"
|
|
88
104
|
},
|
|
89
105
|
"peerDependencies": {
|
|
90
|
-
"@clerk/expo-passkeys": "1.0.0-snapshot.
|
|
91
|
-
"expo": ">=53 <55",
|
|
106
|
+
"@clerk/expo-passkeys": "1.0.0-snapshot.v20251216175437",
|
|
92
107
|
"expo-apple-authentication": ">=7.0.0",
|
|
93
108
|
"expo-auth-session": ">=5",
|
|
109
|
+
"expo-constants": ">=12",
|
|
94
110
|
"expo-crypto": ">=12",
|
|
95
111
|
"expo-local-authentication": ">=13.5.0",
|
|
112
|
+
"expo-modules-core": ">=3.0.0",
|
|
96
113
|
"expo-secure-store": ">=12.4.0",
|
|
97
114
|
"expo-web-browser": ">=12.5.0",
|
|
98
115
|
"react": "^18.0.0 || ^19.0.0 || ^19.0.0-0",
|
|
@@ -106,6 +123,9 @@
|
|
|
106
123
|
"expo-apple-authentication": {
|
|
107
124
|
"optional": true
|
|
108
125
|
},
|
|
126
|
+
"expo-constants": {
|
|
127
|
+
"optional": true
|
|
128
|
+
},
|
|
109
129
|
"expo-crypto": {
|
|
110
130
|
"optional": true
|
|
111
131
|
},
|
|
@@ -123,8 +143,9 @@
|
|
|
123
143
|
"access": "public"
|
|
124
144
|
},
|
|
125
145
|
"scripts": {
|
|
126
|
-
"build": "tsup",
|
|
146
|
+
"build": "tsup && pnpm build:plugin",
|
|
127
147
|
"build:declarations": "tsc -p tsconfig.declarations.json",
|
|
148
|
+
"build:plugin": "tsc -p plugin/tsconfig.json",
|
|
128
149
|
"clean": "rimraf ./dist",
|
|
129
150
|
"dev": "tsup --watch",
|
|
130
151
|
"dev:publish": "pnpm dev -- --env.publish",
|
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
const config_plugins_1 = require("@expo/config-plugins");
|
|
4
|
+
const pkg = require('@clerk/expo/package.json');
|
|
5
|
+
/**
|
|
6
|
+
* Expo config plugin for @clerk/expo.
|
|
7
|
+
*
|
|
8
|
+
* This plugin configures the iOS URL scheme required for Google Sign-In.
|
|
9
|
+
* The native Android module is automatically linked via expo-module.config.json.
|
|
10
|
+
*/
|
|
11
|
+
const withClerkGoogleSignIn = config => {
|
|
12
|
+
// Get the iOS URL scheme from environment or config.extra
|
|
13
|
+
// We capture it here before entering the mod callback
|
|
14
|
+
const iosUrlScheme = process.env.EXPO_PUBLIC_CLERK_GOOGLE_IOS_URL_SCHEME ||
|
|
15
|
+
config.extra?.EXPO_PUBLIC_CLERK_GOOGLE_IOS_URL_SCHEME;
|
|
16
|
+
if (!iosUrlScheme) {
|
|
17
|
+
// No URL scheme configured, skip iOS configuration
|
|
18
|
+
return config;
|
|
19
|
+
}
|
|
20
|
+
// Add iOS URL scheme for Google Sign-In
|
|
21
|
+
return (0, config_plugins_1.withInfoPlist)(config, modConfig => {
|
|
22
|
+
if (!Array.isArray(modConfig.modResults.CFBundleURLTypes)) {
|
|
23
|
+
modConfig.modResults.CFBundleURLTypes = [];
|
|
24
|
+
}
|
|
25
|
+
// Check if the scheme is already added to avoid duplicates
|
|
26
|
+
const schemeExists = modConfig.modResults.CFBundleURLTypes.some(urlType => urlType.CFBundleURLSchemes?.includes(iosUrlScheme));
|
|
27
|
+
if (!schemeExists) {
|
|
28
|
+
// Add Google Sign-In URL scheme
|
|
29
|
+
modConfig.modResults.CFBundleURLTypes.push({
|
|
30
|
+
CFBundleURLSchemes: [iosUrlScheme],
|
|
31
|
+
});
|
|
32
|
+
}
|
|
33
|
+
return modConfig;
|
|
34
|
+
});
|
|
35
|
+
};
|
|
36
|
+
exports.default = (0, config_plugins_1.createRunOncePlugin)(withClerkGoogleSignIn, pkg.name, pkg.version);
|
|
@@ -0,0 +1,45 @@
|
|
|
1
|
+
import { createRunOncePlugin, withInfoPlist, type ConfigPlugin } from '@expo/config-plugins';
|
|
2
|
+
|
|
3
|
+
const pkg = require('@clerk/expo/package.json');
|
|
4
|
+
|
|
5
|
+
/**
|
|
6
|
+
* Expo config plugin for @clerk/expo.
|
|
7
|
+
*
|
|
8
|
+
* This plugin configures the iOS URL scheme required for Google Sign-In.
|
|
9
|
+
* The native Android module is automatically linked via expo-module.config.json.
|
|
10
|
+
*/
|
|
11
|
+
const withClerkGoogleSignIn: ConfigPlugin = config => {
|
|
12
|
+
// Get the iOS URL scheme from environment or config.extra
|
|
13
|
+
// We capture it here before entering the mod callback
|
|
14
|
+
const iosUrlScheme =
|
|
15
|
+
process.env.EXPO_PUBLIC_CLERK_GOOGLE_IOS_URL_SCHEME ||
|
|
16
|
+
(config as { extra?: Record<string, string> }).extra?.EXPO_PUBLIC_CLERK_GOOGLE_IOS_URL_SCHEME;
|
|
17
|
+
|
|
18
|
+
if (!iosUrlScheme) {
|
|
19
|
+
// No URL scheme configured, skip iOS configuration
|
|
20
|
+
return config;
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
// Add iOS URL scheme for Google Sign-In
|
|
24
|
+
return withInfoPlist(config, modConfig => {
|
|
25
|
+
if (!Array.isArray(modConfig.modResults.CFBundleURLTypes)) {
|
|
26
|
+
modConfig.modResults.CFBundleURLTypes = [];
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
// Check if the scheme is already added to avoid duplicates
|
|
30
|
+
const schemeExists = modConfig.modResults.CFBundleURLTypes.some(urlType =>
|
|
31
|
+
urlType.CFBundleURLSchemes?.includes(iosUrlScheme),
|
|
32
|
+
);
|
|
33
|
+
|
|
34
|
+
if (!schemeExists) {
|
|
35
|
+
// Add Google Sign-In URL scheme
|
|
36
|
+
modConfig.modResults.CFBundleURLTypes.push({
|
|
37
|
+
CFBundleURLSchemes: [iosUrlScheme],
|
|
38
|
+
});
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
return modConfig;
|
|
42
|
+
});
|
|
43
|
+
};
|
|
44
|
+
|
|
45
|
+
export default createRunOncePlugin(withClerkGoogleSignIn, pkg.name, pkg.version);
|