@octane-xplat/auth 0.0.1 → 0.9.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 (47) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +37 -2
  3. package/dist/native/AppleSignInButton.tsrx.js +63 -0
  4. package/dist/native/GoogleSignInButton.tsrx.js +35 -0
  5. package/dist/native/apple.js +63 -0
  6. package/dist/native/google.js +50 -0
  7. package/dist/native/index.js +5 -0
  8. package/dist/native/octane-client-build.json +8 -0
  9. package/dist/web/AppleSignInButton.web.tsrx.js +71 -0
  10. package/dist/web/GoogleSignInButton.web.tsrx.js +47 -0
  11. package/dist/web/apple.web.js +86 -0
  12. package/dist/web/google.web.js +130 -0
  13. package/dist/web/index.js +5 -0
  14. package/dist/web/octane-client-build.json +8 -0
  15. package/package.json +77 -10
  16. package/src/AppleSignInButton.macos.tsrx +36 -0
  17. package/src/AppleSignInButton.tsrx +46 -0
  18. package/src/AppleSignInButton.web.tsrx +54 -0
  19. package/src/GoogleSignInButton.macos.tsrx +7 -0
  20. package/src/GoogleSignInButton.tsrx +31 -0
  21. package/src/GoogleSignInButton.web.tsrx +23 -0
  22. package/src/apple.macos.ts +320 -0
  23. package/src/apple.ts +95 -0
  24. package/src/apple.web.ts +114 -0
  25. package/src/google.macos.ts +18 -0
  26. package/src/google.ts +61 -0
  27. package/src/google.web.ts +167 -0
  28. package/src/index.macos.ts +19 -0
  29. package/src/index.ts +21 -0
  30. package/src/index.web.ts +21 -0
  31. package/src/native-elements.d.ts +10 -0
  32. package/src/types.ts +147 -0
  33. package/types/generated/.tsrx-typegen-manifest.json +16 -0
  34. package/types/generated/AppleSignInButton.d.ts +5 -0
  35. package/types/generated/AppleSignInButton.web.d.ts +6 -0
  36. package/types/generated/GoogleSignInButton.d.ts +5 -0
  37. package/types/generated/GoogleSignInButton.web.d.ts +6 -0
  38. package/types/generated/apple.d.ts +2 -0
  39. package/types/generated/apple.web.d.ts +2 -0
  40. package/types/generated/google.d.ts +2 -0
  41. package/types/generated/google.web.d.ts +8 -0
  42. package/types/generated/index.d.ts +5 -0
  43. package/types/generated/index.web.d.ts +5 -0
  44. package/types/generated/types.d.ts +133 -0
  45. package/types/index.macos.d.ts +36 -0
  46. package/index.d.ts +0 -1
  47. package/index.js +0 -2
package/LICENSE ADDED
@@ -0,0 +1,21 @@
1
+ The MIT License (MIT)
2
+
3
+ Copyright (c) 2026 Alec Larson
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in
13
+ all copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
21
+ THE SOFTWARE.
package/README.md CHANGED
@@ -1,3 +1,38 @@
1
- # @octane-xplat/auth
1
+ # `@octane-xplat/auth`
2
2
 
3
- Version 0.0.1 is a reservation stub so the automated release can publish this package name. It has no supported API. Use a later release for the implementation.
3
+ Sign in with Apple and Google Sign-In for Octane xplat apps — the native
4
+ SDKs (`@nativescript/apple-sign-in`, `@nativescript/google-signin`) on
5
+ iOS/Android, the providers' web SDKs (Apple JS / Google Identity Services)
6
+ in the browser, and AuthenticationServices through the ObjC bridge plus a
7
+ Google flow on the macOS AppKit host. One `AuthUser`/`AuthCredential`
8
+ contract everywhere.
9
+
10
+ ```sh
11
+ pnpm add @octane-xplat/auth
12
+ ```
13
+
14
+ ```tsx
15
+ import { appleAuth, googleAuth, AppleSignInButton } from '@octane-xplat/auth'
16
+
17
+ appleAuth.configure({ clientId: 'com.example.app.web' }) // web-only fields
18
+
19
+ const result = await appleAuth.signIn({ scopes: ['email', 'name'] })
20
+ if (result.status === 'success') {
21
+ const { idToken, user } = result.credential // hand idToken to your backend
22
+ }
23
+ ```
24
+
25
+ Each provider object reports `supported` — Apple is `false` on Android —
26
+ and exposes `configure`, `signIn`, and provider extras
27
+ (`appleAuth.getCredentialState`, `googleAuth.signOut`). `SignInResult`
28
+ distinguishes `success` / `cancelled` / `error`; a dismissed sheet is
29
+ `cancelled`, not a throw. The sign-in buttons are platform-authentic
30
+ components, so render them from platform-suffixed files or accept each
31
+ target's native styling.
32
+
33
+ Web needs registered client IDs; iOS needs the `applesignin` entitlement
34
+ and Google's `GoogleService-Info.plist`/reversed-client-id URL scheme;
35
+ Android needs `google-services.json` and a `serverClientId` for
36
+ `serverAuthCode`. Guide: [Using device
37
+ features](../../docs/platform-services.md). Exercised by
38
+ [`AuthDemo`](../demos/src/AuthDemo.tsrx).
@@ -0,0 +1,63 @@
1
+ import { appleAuth } from "./apple.js";
2
+ import * as applePlugin from "@nativescript/apple-sign-in";
3
+ import { defineUniversalComponent, registerElement, universalIf, universalPlan, universalValue } from "@nativescript-community/octane";
4
+ //#region src/AppleSignInButton.tsrx
5
+ var __octaneUniversalPlan0 = universalPlan("nativescript", {
6
+ "kind": "host",
7
+ "type": "applesigninbutton",
8
+ "bindings": [
9
+ ["id", 0],
10
+ ["className", 1],
11
+ ["style", 2],
12
+ ["type", 3],
13
+ ["buttonStyle", 4],
14
+ ["isEnabled", 5],
15
+ ["onTap", 6]
16
+ ]
17
+ });
18
+ var __octaneUniversalPlan1 = universalPlan("nativescript", {
19
+ "kind": "host",
20
+ "type": "button",
21
+ "bindings": [
22
+ ["id", 0],
23
+ ["className", 1],
24
+ ["style", 2],
25
+ ["text", 3],
26
+ ["isEnabled", 4],
27
+ ["onTap", 5]
28
+ ]
29
+ });
30
+ var __octaneUniversalPlan2 = universalPlan("nativescript", {
31
+ "kind": "slot",
32
+ "slot": 0
33
+ });
34
+ var PluginButton = applePlugin.SignInButton;
35
+ if (PluginButton) registerElement("applesigninbutton", PluginButton);
36
+ var AppleSignInButton = defineUniversalComponent("nativescript", function AppleSignInButton(props) {
37
+ const run = () => {
38
+ props.onPress?.();
39
+ if (props.onResult) appleAuth.signIn().then((result) => props.onResult?.(result));
40
+ };
41
+ return universalValue(__octaneUniversalPlan2, [universalIf(PluginButton && appleAuth.supported, () => {
42
+ return universalValue(__octaneUniversalPlan0, [
43
+ props.id,
44
+ props.className,
45
+ props.style,
46
+ props.type ?? "default",
47
+ props.theme ?? "black",
48
+ props.disabled !== true,
49
+ run
50
+ ]);
51
+ }, () => {
52
+ return universalValue(__octaneUniversalPlan1, [
53
+ props.id,
54
+ props.className,
55
+ props.style,
56
+ props.type === "signUp" ? "Sign up with Apple" : props.type === "continue" ? "Continue with Apple" : "Sign in with Apple",
57
+ props.disabled !== true,
58
+ run
59
+ ]);
60
+ })]);
61
+ }, { "module": "@nativescript-community/octane" });
62
+ //#endregion
63
+ export { AppleSignInButton };
@@ -0,0 +1,35 @@
1
+ import { googleAuth } from "./google.js";
2
+ import { GoogleSignInButton } from "@nativescript/google-signin";
3
+ import { defineUniversalComponent, registerElement, universalPlan, universalValue } from "@nativescript-community/octane";
4
+ //#region src/GoogleSignInButton.tsrx
5
+ var __octaneUniversalPlan0 = universalPlan("nativescript", {
6
+ "kind": "host",
7
+ "type": "googlesigninbutton",
8
+ "bindings": [
9
+ ["id", 0],
10
+ ["className", 1],
11
+ ["style", 2],
12
+ ["colorScheme", 3],
13
+ ["colorStyle", 4],
14
+ ["isEnabled", 5],
15
+ ["onTap", 6]
16
+ ]
17
+ });
18
+ registerElement("googlesigninbutton", GoogleSignInButton);
19
+ var GoogleSignInButton$1 = defineUniversalComponent("nativescript", function GoogleSignInButton(props) {
20
+ const run = () => {
21
+ props.onPress?.();
22
+ if (props.onResult) googleAuth.signIn().then((result) => props.onResult?.(result));
23
+ };
24
+ return universalValue(__octaneUniversalPlan0, [
25
+ props.id,
26
+ props.className,
27
+ props.style,
28
+ props.theme ?? "auto",
29
+ props.variant ?? "standard",
30
+ props.disabled !== true,
31
+ run
32
+ ]);
33
+ }, { "module": "@nativescript-community/octane" });
34
+ //#endregion
35
+ export { GoogleSignInButton$1 as GoogleSignInButton };
@@ -0,0 +1,63 @@
1
+ import { SignIn } from "@nativescript/apple-sign-in";
2
+ //#region src/apple.ts
3
+ function isCancel(error) {
4
+ if ((error?.native?.code ?? error?.code) === 1001) return true;
5
+ return /cancel/i.test(String(error?.message ?? error));
6
+ }
7
+ function toCredential(user) {
8
+ const fullName = user.fullName;
9
+ const name = [fullName?.givenName, fullName?.familyName].filter(Boolean).join(" ") || void 0;
10
+ return {
11
+ provider: "apple",
12
+ idToken: user.identityToken ?? void 0,
13
+ authorizationCode: user.authorizationCode ?? void 0,
14
+ scopes: (user.authorizedScopes ?? []).map((s) => s === "EMAIL" ? "email" : s === "FULL_NAME" ? "name" : s),
15
+ user: {
16
+ id: user.user,
17
+ email: user.email ?? void 0,
18
+ name,
19
+ givenName: fullName?.givenName ?? void 0,
20
+ familyName: fullName?.familyName ?? void 0
21
+ }
22
+ };
23
+ }
24
+ var appleAuth = {
25
+ supported: SignIn.isSupported(),
26
+ configure(_config) {},
27
+ async signIn(options) {
28
+ if (!SignIn.isSupported()) return {
29
+ status: "error",
30
+ message: "Sign in with Apple needs iOS 13+ (unsupported on Android)"
31
+ };
32
+ try {
33
+ return {
34
+ status: "success",
35
+ credential: toCredential(await SignIn.signIn({
36
+ scopes: options?.scopes?.map((s) => s === "email" ? "EMAIL" : "FULL_NAME"),
37
+ useNonce: options?.nonce !== void 0,
38
+ nonce: options?.nonce
39
+ }))
40
+ };
41
+ } catch (error) {
42
+ return isCancel(error) ? { status: "cancelled" } : {
43
+ status: "error",
44
+ message: String(error?.message ?? error)
45
+ };
46
+ }
47
+ },
48
+ async getCredentialState(userId) {
49
+ if (!SignIn.isSupported()) return "unknown";
50
+ try {
51
+ switch (await SignIn.getState(userId)) {
52
+ case "Authorized": return "authorized";
53
+ case "Revoked": return "revoked";
54
+ case "Transferred": return "transferred";
55
+ default: return "notFound";
56
+ }
57
+ } catch {
58
+ return "unknown";
59
+ }
60
+ }
61
+ };
62
+ //#endregion
63
+ export { appleAuth };
@@ -0,0 +1,50 @@
1
+ import { GoogleSignin } from "@nativescript/google-signin";
2
+ //#region src/google.ts
3
+ function isCancel(error) {
4
+ const code = error?.native?.code ?? error?.native?.getStatusCode?.() ?? error?.code;
5
+ if (code === -5 || code === 12501) return true;
6
+ return /cancel/i.test(String(error?.message ?? error));
7
+ }
8
+ function toCredential(user) {
9
+ return {
10
+ provider: "google",
11
+ idToken: user.idToken || void 0,
12
+ accessToken: user.accessToken || void 0,
13
+ authorizationCode: user.serverAuthCode || void 0,
14
+ scopes: user.grantedScopes ?? [],
15
+ user: {
16
+ id: user.id,
17
+ email: user.email || void 0,
18
+ name: user.displayName || void 0,
19
+ givenName: user.givenName || void 0,
20
+ familyName: user.familyName || void 0,
21
+ photoUrl: user.photoUrl || void 0
22
+ }
23
+ };
24
+ }
25
+ var googleAuth = {
26
+ supported: true,
27
+ async configure(config) {
28
+ await GoogleSignin.configure(config);
29
+ },
30
+ async signIn() {
31
+ try {
32
+ return {
33
+ status: "success",
34
+ credential: toCredential(await GoogleSignin.signIn())
35
+ };
36
+ } catch (error) {
37
+ return isCancel(error) ? { status: "cancelled" } : {
38
+ status: "error",
39
+ message: String(error?.message ?? error)
40
+ };
41
+ }
42
+ },
43
+ async signOut() {
44
+ try {
45
+ await GoogleSignin.signOut();
46
+ } catch {}
47
+ }
48
+ };
49
+ //#endregion
50
+ export { googleAuth };
@@ -0,0 +1,5 @@
1
+ import { appleAuth } from "./apple.js";
2
+ import { googleAuth } from "./google.js";
3
+ import { AppleSignInButton } from "./AppleSignInButton.tsrx.js";
4
+ import { GoogleSignInButton } from "./GoogleSignInButton.tsrx.js";
5
+ export { AppleSignInButton, GoogleSignInButton, appleAuth, googleAuth };
@@ -0,0 +1,8 @@
1
+ {
2
+ "version": 1,
3
+ "buildId": "2924c745-ebe0-4012-9aea-c8c26eeb7458",
4
+ "mode": "production",
5
+ "capabilities": {
6
+ "independentHydration": false
7
+ }
8
+ }
@@ -0,0 +1,71 @@
1
+ import { appleAuth } from "./apple.web.js";
2
+ import { __s, bag9, child, clone, delegateEvents, evt1e, evt1u, setBooleanAttribute, setStyle, sibling, template } from "octane";
3
+ import { bindSignalAttribute, bindSignalChild, enableSignalBindings, setPlainAttribute } from "octane/internal/client";
4
+ //#region src/AppleSignInButton.web.tsrx
5
+ enableSignalBindings(1, true);
6
+ delegateEvents(["click"]);
7
+ var _t$0 = /* @__PURE__ */ template("<button type=\"button\"><svg width=\"15\" height=\"18\" viewBox=\"0 0 24 24\" fill=\"currentColor\" aria-hidden=\"true\"><path d=\"M15.53 3.83c.843-1.012 1.4-2.427 1.245-3.83-1.207.052-2.662.805-3.532 1.818-.78.896-1.454 2.338-1.273 3.714 1.338.104 2.715-.688 3.559-1.701M12.152 6.896c-.948 0-2.415-1.078-3.96-1.04-2.04.027-3.91 1.183-4.961 3.014-2.117 3.675-.546 9.103 1.519 12.09 1.013 1.454 2.208 3.09 3.792 3.039 1.52-.065 2.09-.987 3.935-.987 1.831 0 2.35.987 3.96.948 1.637-.026 2.676-1.48 3.676-2.948 1.156-1.688 1.636-3.325 1.662-3.415-.039-.013-3.182-1.221-3.22-4.857-.026-3.04 2.48-4.494 2.597-4.559-1.429-2.09-3.623-2.324-4.39-2.376-2-.156-3.675 1.09-4.61 1.09z\"></path></svg><!></button>");
8
+ var __event = (__eventArg, props) => {
9
+ props.onPress?.();
10
+ if (props.onResult) appleAuth.signIn().then((result) => props.onResult?.(result));
11
+ };
12
+ var LABELS = {
13
+ default: "Sign in with Apple",
14
+ signUp: "Sign up with Apple",
15
+ continue: "Continue with Apple"
16
+ };
17
+ var THEMES = {
18
+ black: {
19
+ background: "#000",
20
+ color: "#fff",
21
+ border: "1px solid #000"
22
+ },
23
+ white: {
24
+ background: "#fff",
25
+ color: "#000",
26
+ border: "1px solid #fff"
27
+ },
28
+ whiteOutline: {
29
+ background: "#fff",
30
+ color: "#000",
31
+ border: "1px solid #000"
32
+ }
33
+ };
34
+ var AppleSignInButton = /* @__PURE__ */ __s(function AppleSignInButton(props, __s, __extra) {
35
+ const theme = THEMES[props.theme ?? "black"];
36
+ let _b = __s.slots[0];
37
+ if (_b === void 0) {
38
+ let _m1, _m5, _m6;
39
+ const _root = clone(_t$0);
40
+ _m1 = _root;
41
+ _m5 = evt1e(_root, "$$click", __event, props);
42
+ _m6 = sibling(child(_root), 1);
43
+ _b = bag9(__s, _root, void 0, _m1, void 0, void 0, void 0, _m5, _m6, null, void 0);
44
+ } else evt1u(_b.f, __event, props);
45
+ _b.a = bindSignalAttribute(__s, _b.a, _b.b, "id", props.id, "b:3492bf59", setPlainAttribute);
46
+ _b.c = bindSignalAttribute(__s, _b.c, _b.b, "class", props.className, "b:699cbe0d", "class");
47
+ _b.d = bindSignalAttribute(__s, _b.d, _b.b, "disabled", props.disabled, "b:604f680a", setBooleanAttribute);
48
+ {
49
+ const _v = {
50
+ display: "inline-flex",
51
+ alignItems: "center",
52
+ justifyContent: "center",
53
+ gap: 6,
54
+ minHeight: 40,
55
+ padding: "0 16px",
56
+ borderRadius: 6,
57
+ fontFamily: "-apple-system, 'Helvetica Neue', Helvetica, Arial, sans-serif",
58
+ fontSize: 15,
59
+ cursor: props.disabled ? "default" : "pointer",
60
+ ...theme,
61
+ ...props.style
62
+ };
63
+ if (_b.e !== _v) {
64
+ setStyle(_b.b, _v, _b.e);
65
+ _b.e = _v;
66
+ }
67
+ }
68
+ _b.j = bindSignalChild(__s, _b.j, 1, _b.b, LABELS[props.type ?? "default"], "b:a1fe1cdf", _b.g, true, void 0, void 0, void 0);
69
+ });
70
+ //#endregion
71
+ export { AppleSignInButton };
@@ -0,0 +1,47 @@
1
+ import { renderGoogleButton } from "./google.web.js";
2
+ import { __s, bag5, clone, queueRefAttach, queueRefDetach, setStyle, template } from "octane";
3
+ import { bindSignalAttribute, enableSignalBindings, replaceRef, setPlainAttribute } from "octane/internal/client";
4
+ //#region src/GoogleSignInButton.web.tsrx
5
+ enableSignalBindings(1, true);
6
+ var _t$0 = /* @__PURE__ */ template("<div></div>");
7
+ var _rm$0 = [
8
+ "r",
9
+ "e",
10
+ "b"
11
+ ];
12
+ var GoogleSignInButton = /* @__PURE__ */ __s(function GoogleSignInButton(props, __s, __extra) {
13
+ let _b = __s.slots[0];
14
+ if (_b === void 0) {
15
+ let _m1, _m4;
16
+ const _root = clone(_t$0);
17
+ _m1 = _root;
18
+ queueRefAttach(__s, _m4 = (el) => {
19
+ if (el && !props.disabled) renderGoogleButton(el, {
20
+ theme: props.theme,
21
+ variant: props.variant
22
+ }, (result) => props.onResult?.(result));
23
+ }, _m1);
24
+ (__s.cleanups ??= []).push(() => _b && queueRefDetach(_b.e, _b.b));
25
+ _b = bag5(__s, _root, void 0, _m1, void 0, void 0, _m4);
26
+ __s.refFields = _rm$0;
27
+ } else {
28
+ const _r = (el) => {
29
+ if (el && !props.disabled) renderGoogleButton(el, {
30
+ theme: props.theme,
31
+ variant: props.variant
32
+ }, (result) => props.onResult?.(result));
33
+ };
34
+ if (_r !== _b.e) _b.e = replaceRef(__s, _b.e, _r, _b.b);
35
+ }
36
+ _b.a = bindSignalAttribute(__s, _b.a, _b.b, "id", props.id, "b:2102db66", setPlainAttribute);
37
+ _b.c = bindSignalAttribute(__s, _b.c, _b.b, "class", props.className, "b:e7fd89fa", "class");
38
+ {
39
+ const _v = props.style;
40
+ if (_b.d !== _v) {
41
+ setStyle(_b.b, _v, _b.d);
42
+ _b.d = _v;
43
+ }
44
+ }
45
+ });
46
+ //#endregion
47
+ export { GoogleSignInButton };
@@ -0,0 +1,86 @@
1
+ //#region src/apple.web.ts
2
+ var APPLE_SDK_URL = "https://appleid.cdn.apple.com/appleauth/js/jsapi/AppleID.auth.js";
3
+ var config = {};
4
+ var requestedScopes = [];
5
+ var sdkPromise = null;
6
+ function loadSdk() {
7
+ sdkPromise ??= new Promise((resolve, reject) => {
8
+ const script = document.createElement("script");
9
+ script.src = APPLE_SDK_URL;
10
+ script.async = true;
11
+ script.onload = () => resolve(globalThis.AppleID);
12
+ script.onerror = () => {
13
+ sdkPromise = null;
14
+ reject(/* @__PURE__ */ new Error("failed to load the Sign in with Apple JS SDK"));
15
+ };
16
+ document.head.appendChild(script);
17
+ });
18
+ return sdkPromise;
19
+ }
20
+ function decodeJwt(token) {
21
+ try {
22
+ const part = token.split(".")[1].replace(/-/g, "+").replace(/_/g, "/");
23
+ return JSON.parse(new TextDecoder().decode(Uint8Array.from(atob(part), (c) => c.charCodeAt(0))));
24
+ } catch {
25
+ return {};
26
+ }
27
+ }
28
+ function toCredential(response) {
29
+ const auth = response?.authorization ?? {};
30
+ const claims = auth.id_token ? decodeJwt(auth.id_token) : {};
31
+ const name = [response?.user?.name?.firstName, response?.user?.name?.lastName].filter(Boolean).join(" ") || void 0;
32
+ return {
33
+ provider: "apple",
34
+ idToken: auth.id_token ?? void 0,
35
+ authorizationCode: auth.code ?? void 0,
36
+ scopes: requestedScopes,
37
+ user: {
38
+ id: claims.sub ?? "",
39
+ email: response?.user?.email ?? claims.email ?? void 0,
40
+ name,
41
+ givenName: response?.user?.name?.firstName ?? void 0,
42
+ familyName: response?.user?.name?.lastName ?? void 0
43
+ }
44
+ };
45
+ }
46
+ function isCancel(error) {
47
+ const code = error?.error ?? error?.message ?? error;
48
+ return /popup_closed_by_user|cancel/i.test(String(code));
49
+ }
50
+ var appleAuth = {
51
+ supported: typeof document !== "undefined",
52
+ configure(next) {
53
+ config = { ...next };
54
+ },
55
+ async signIn(options) {
56
+ if (!config.clientId || !config.redirectURI) return {
57
+ status: "error",
58
+ message: "appleAuth.configure({ clientId, redirectURI }) is required on web — the Services ID and a registered return URL"
59
+ };
60
+ try {
61
+ const sdk = await loadSdk();
62
+ requestedScopes = options?.scopes ?? ["name", "email"];
63
+ sdk.auth.init({
64
+ clientId: config.clientId,
65
+ scope: requestedScopes.join(" "),
66
+ redirectURI: config.redirectURI,
67
+ usePopup: config.usePopup !== false,
68
+ nonce: options?.nonce
69
+ });
70
+ return {
71
+ status: "success",
72
+ credential: toCredential(await sdk.auth.signIn())
73
+ };
74
+ } catch (error) {
75
+ return isCancel(error) ? { status: "cancelled" } : {
76
+ status: "error",
77
+ message: String(error?.message ?? error?.error ?? error)
78
+ };
79
+ }
80
+ },
81
+ async getCredentialState() {
82
+ return "unknown";
83
+ }
84
+ };
85
+ //#endregion
86
+ export { appleAuth };
@@ -0,0 +1,130 @@
1
+ //#region src/google.web.ts
2
+ var GIS_URL = "https://accounts.google.com/gsi/client";
3
+ var config = {};
4
+ var sdkPromise = null;
5
+ var credentialResolve = null;
6
+ var configuredNonce;
7
+ function loadSdk() {
8
+ sdkPromise ??= new Promise((resolve, reject) => {
9
+ const script = document.createElement("script");
10
+ script.src = GIS_URL;
11
+ script.async = true;
12
+ script.onload = () => resolve(globalThis.google);
13
+ script.onerror = () => {
14
+ sdkPromise = null;
15
+ reject(/* @__PURE__ */ new Error("failed to load the Google Identity Services SDK"));
16
+ };
17
+ document.head.appendChild(script);
18
+ });
19
+ return sdkPromise;
20
+ }
21
+ function decodeJwt(token) {
22
+ try {
23
+ const part = token.split(".")[1].replace(/-/g, "+").replace(/_/g, "/");
24
+ return JSON.parse(new TextDecoder().decode(Uint8Array.from(atob(part), (c) => c.charCodeAt(0))));
25
+ } catch {
26
+ return {};
27
+ }
28
+ }
29
+ function toCredential(response) {
30
+ const claims = decodeJwt(response?.credential ?? "");
31
+ return {
32
+ provider: "google",
33
+ idToken: response?.credential ?? void 0,
34
+ scopes: claims.scope ? String(claims.scope).split(" ") : config.scopes ?? [],
35
+ user: {
36
+ id: claims.sub ?? "",
37
+ email: claims.email ?? void 0,
38
+ name: claims.name ?? void 0,
39
+ givenName: claims.given_name ?? void 0,
40
+ familyName: claims.family_name ?? void 0,
41
+ photoUrl: claims.picture ?? void 0
42
+ }
43
+ };
44
+ }
45
+ function initialize(google) {
46
+ google.accounts.id.initialize({
47
+ client_id: config.clientId,
48
+ callback: (response) => {
49
+ const resolve = credentialResolve;
50
+ credentialResolve = null;
51
+ resolve?.({
52
+ status: "success",
53
+ credential: toCredential(response)
54
+ });
55
+ },
56
+ nonce: configuredNonce,
57
+ hosted_domain: config.hostedDomain
58
+ });
59
+ }
60
+ /** Internal — the button leaf renders the official GIS button into `host`. */
61
+ async function renderGoogleButton(host, options, onResult) {
62
+ if (!config.clientId) {
63
+ onResult({
64
+ status: "error",
65
+ message: "googleAuth.configure({ clientId }) is required on web — the OAuth web client id"
66
+ });
67
+ return;
68
+ }
69
+ try {
70
+ const google = await loadSdk();
71
+ initialize(google);
72
+ google.accounts.id.renderButton(host, {
73
+ type: options.variant === "icon" ? "icon" : "standard",
74
+ theme: options.theme === "dark" ? "filled_black" : "outline",
75
+ size: "large",
76
+ width: options.width
77
+ });
78
+ credentialResolve = onResult;
79
+ } catch (error) {
80
+ onResult({
81
+ status: "error",
82
+ message: String(error?.message ?? error)
83
+ });
84
+ }
85
+ }
86
+ var googleAuth = {
87
+ supported: typeof document !== "undefined",
88
+ async configure(next) {
89
+ config = { ...next };
90
+ configuredNonce = void 0;
91
+ },
92
+ async signIn(options) {
93
+ if (!config.clientId) return {
94
+ status: "error",
95
+ message: "googleAuth.configure({ clientId }) is required on web — the OAuth web client id"
96
+ };
97
+ if (credentialResolve) return {
98
+ status: "error",
99
+ message: "a Google sign-in flow is already active"
100
+ };
101
+ configuredNonce = options?.nonce;
102
+ try {
103
+ const google = await loadSdk();
104
+ initialize(google);
105
+ return await new Promise((resolve) => {
106
+ credentialResolve = resolve;
107
+ google.accounts.id.prompt((notification) => {
108
+ if (notification.isNotDisplayed?.() || notification.isSkippedMoment?.() || notification.isDismissedMoment?.()) {
109
+ if (credentialResolve === resolve) {
110
+ credentialResolve = null;
111
+ resolve({ status: "cancelled" });
112
+ }
113
+ }
114
+ });
115
+ });
116
+ } catch (error) {
117
+ return {
118
+ status: "error",
119
+ message: String(error?.message ?? error)
120
+ };
121
+ }
122
+ },
123
+ async signOut() {
124
+ try {
125
+ (await loadSdk()).accounts.id.disableAutoSelect();
126
+ } catch {}
127
+ }
128
+ };
129
+ //#endregion
130
+ export { googleAuth, renderGoogleButton };
@@ -0,0 +1,5 @@
1
+ import { appleAuth } from "./apple.web.js";
2
+ import { googleAuth } from "./google.web.js";
3
+ import { AppleSignInButton } from "./AppleSignInButton.web.tsrx.js";
4
+ import { GoogleSignInButton } from "./GoogleSignInButton.web.tsrx.js";
5
+ export { AppleSignInButton, GoogleSignInButton, appleAuth, googleAuth };
@@ -0,0 +1,8 @@
1
+ {
2
+ "version": 1,
3
+ "buildId": "dc0dd9f6-f1fb-4b15-a5c3-95ddbe1709aa",
4
+ "mode": "production",
5
+ "capabilities": {
6
+ "independentHydration": false
7
+ }
8
+ }