Skip to content

PerryTS/google-auth

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

2 Commits
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

@perryts/google-auth

Google Sign In bindings for Perry.

Target Implementation
iOS 16+ Native — Swift bridge over the GoogleSignIn SDK.
macOS 13+ Native — same Swift bridge.
Android 7+ Native — Kotlin bridge over androidx.credentials.CredentialManager with GetGoogleIdOption.
Linux / Windows Stub — every call resolves with {"success":false,"error":"unsupported-platform"}.
tvOS / watchOS / visionOS Stub — no first-party Google Sign In SDK on these platforms.

Closes PerryTS/perry#1138 (follow-up to #674).

Installation

npm install @perryts/google-auth

The package targets perry-ffi ABI v0.5 (perry.nativeLibrary.abiVersion: "0.5" in package.json). Perry validates compatibility at build time.

Configuration

Add a [google_auth] block to your perry.toml:

[google_auth]
ios_client_id     = "1234567890-abcdefghijklmnopqrstuvwxyz.apps.googleusercontent.com"
android_client_id = "1234567890-zyxwvutsrqponmlkjihgfedcba.apps.googleusercontent.com"
server_client_id  = "1234567890-server.apps.googleusercontent.com"
default_scopes    = ["openid", "email", "profile"]

Perry's compile pipeline:

  • iOS / macOS: writes GIDClientID, optional GIDServerClientID, and GIDDefaultScopes into the generated Info.plist, plus a CFBundleURLSchemes entry derived from the reversed client ID (required for the OAuth redirect).
  • Android: writes the server client ID into res/values/strings.xml as google_auth_server_client_id. The Kotlin bridge reads it via R.string.google_auth_server_client_id and passes it to GetGoogleIdOption.Builder().setServerClientId(...). Perry merges the required gradle dependencies (androidx.credentials:credentials, androidx.credentials:credentials-play-services-auth, com.google.android.libraries.identity.googleid:googleid, kotlinx-coroutines-android) into the app's build.gradle.kts.

iOS / macOS GoogleSignIn SDK

The Swift bridge guards every SDK call with #if canImport(GoogleSignIn). Without the SDK on the swiftc framework search path, all three entry points resolve with {"success":false,"error":"framework-not-linked"}. To wire the real SDK:

  1. Install the GoogleSignIn Swift package or CocoaPod.
  2. Set PERRY_GOOGLE_SIGN_IN_FRAMEWORK_DIR=/path/to/Frameworks at build time, where /path/to/Frameworks contains GoogleSignIn.framework and its dependencies (GTMSessionFetcher, GoogleUtilities, AppAuth).
  3. Perry forwards -F $PERRY_GOOGLE_SIGN_IN_FRAMEWORK_DIR to swiftc and adds -framework GoogleSignIn to the link line automatically.

Quick start

import {
  js_google_auth_sign_in,
  js_google_auth_silent_sign_in,
  js_google_auth_sign_out,
  type GoogleSignInResult,
} from "@perryts/google-auth";

// First-launch flow: try the silent path first; fall back to
// interactive on no-cached-session.
async function ensureSignedIn(): Promise<GoogleSignInResult> {
  const silent = JSON.parse(
    await js_google_auth_silent_sign_in(),
  ) as GoogleSignInResult;
  if (silent.success) return silent;

  if (silent.error === "no-cached-session") {
    return JSON.parse(await js_google_auth_sign_in()) as GoogleSignInResult;
  }
  // missing-client-id, framework-not-linked, jvm-unavailable, etc. —
  // surface upstream rather than re-prompting.
  return silent;
}

const result = await ensureSignedIn();
if (result.success) {
  // result.idToken → server-side verification
  // result.email, result.userId, result.name, result.pictureUrl → UI
} else if (result.cancelled) {
  // user dismissed the sheet
} else {
  console.error("sign-in failed:", result.error);
}

Error slugs

Every promise resolves; failures arrive via the { success: false, error } shape. Recognized slugs:

Slug Meaning
cancelled User dismissed the system sign-in sheet (also sets cancelled: true).
missing-client-id [google_auth] ios_client_id / android_client_id not set in perry.toml.
no-cached-session Silent sign-in found no stored credentials.
framework-not-linked Apple build done without the GoogleSignIn SDK on the framework path.
no-presenting-view-controller iOS bridge couldn't locate the key window's root VC.
no-presenting-window macOS bridge couldn't locate keyWindow / mainWindow.
no-user-returned SDK returned without error but no GIDGoogleUser.
sign-in-failed Generic Apple SDK failure (network, server-config, etc.).
android-credential-failed Android CredentialManager surfaced a non-cancel error.
unsupported-platform Linux / Windows / tvOS / watchOS / visionOS stub.
jvm-unavailable Android JNI bridge couldn't reach the JavaVM (host-link misconfigured).
not-installed Android bridge missing application context (host didn't call install).
null-result-from-bridge Internal — Swift bridge returned a null pointer.
non-utf8-result-from-bridge Internal — bridge returned bytes that weren't valid UTF-8.

Migration from the in-tree binding (perry < 0.5.1015)

Prior to v0.5.1015, @perryts/google-auth shipped inside the perry workspace as perry-ext-google-auth and was a not-yet-implemented stub. Replace the implicit binding with an explicit install:

npm install @perryts/google-auth

The import { js_google_auth_sign_in, ... } from "@perryts/google-auth" surface is unchanged.

License

MIT

About

Google Sign In bindings for the Perry TypeScript-to-native compiler. iOS/macOS via the GoogleSignIn SDK; Android via androidx.credentials Credential Manager. Closes PerryTS/perry#1138.

Resources

License

Stars

Watchers

Forks

Packages

 
 
 

Contributors