From fea1cb458341990ad7103b7f4bb5465915f5af0a Mon Sep 17 00:00:00 2001 From: Vojtech Novak Date: Sat, 8 Feb 2025 14:04:00 +0100 Subject: [PATCH] docs: rename Modern to Universal --- docs/_oneTapModuleTable.mdx | 2 +- docs/_sponsorBanner.mdx | 4 + docs/api/index.mdx | 12 +- docs/buttons/{web.md => web.mdx} | 8 +- docs/errors.md | 8 +- docs/install.mdx | 53 ++--- docs/license.md | 2 +- docs/migrating.md | 2 +- docs/one-tap.mdx | 60 ++---- docs/screenshots.mdx | 28 +++ docs/screenshots/_createAccount.mdx | 8 + docs/screenshots/_presentExplicitSignIn.mdx | 8 + docs/screenshots/_requestAuthorization.mdx | 7 + docs/screenshots/_signIn.mdx | 7 + docs/security.mdx | 8 +- docs/setting-up/_category_.json | 2 +- docs/setting-up/expo.md | 2 +- docs/setting-up/web.mdx | 6 +- docusaurus.config.ts | 2 +- package.json | 6 +- src/components/HomepageFeatures/index.tsx | 4 +- src/css/custom.css | 2 +- yarn.lock | 208 +++++++------------- 23 files changed, 212 insertions(+), 237 deletions(-) create mode 100644 docs/_sponsorBanner.mdx rename docs/buttons/{web.md => web.mdx} (90%) create mode 100644 docs/screenshots.mdx create mode 100644 docs/screenshots/_createAccount.mdx create mode 100644 docs/screenshots/_presentExplicitSignIn.mdx create mode 100644 docs/screenshots/_requestAuthorization.mdx create mode 100644 docs/screenshots/_signIn.mdx diff --git a/docs/_oneTapModuleTable.mdx b/docs/_oneTapModuleTable.mdx index cca29fe..c43cb06 100644 --- a/docs/_oneTapModuleTable.mdx +++ b/docs/_oneTapModuleTable.mdx @@ -1,6 +1,6 @@ > `const` **GoogleOneTapSignIn**: complex type, see below -The entry point of the Modern Sign In API, exposed as `GoogleOneTapSignIn`. +The entry point of the Universal sign in API, exposed as `GoogleOneTapSignIn`. On the web, the signatures of `signIn`, `presentExplicitSignIn`, and `createAccount` are callback-based and on native they are Promise-based. Read more in the [guide](/docs/one-tap#web-support). diff --git a/docs/_sponsorBanner.mdx b/docs/_sponsorBanner.mdx new file mode 100644 index 0000000..f344216 --- /dev/null +++ b/docs/_sponsorBanner.mdx @@ -0,0 +1,4 @@ +:::tip +The functionality covered in this page is available in the licensed +version. [You can get a license here](https://rngs-package.com/#pricing) ⭐️. +::: diff --git a/docs/api/index.mdx b/docs/api/index.mdx index f0a6453..a9d61e2 100644 --- a/docs/api/index.mdx +++ b/docs/api/index.mdx @@ -1,6 +1,6 @@ # API reference -## Modern sign in module +## Universal sign in module ### AuthorizationResponse @@ -61,7 +61,7 @@ Parameters for enabling [App Check](/docs/security#appcheck). Provide `debugProv | `openIdRealm`? | `string` | iOS only. The OpenID2 realm of the home web server. This allows Google to include the user's OpenID Identifier in the OpenID Connect ID token. | | `profileImageSize`? | `number` | iOS only. The desired height and width of the profile image. **Default** `120px` | | `scopes`? | `string`[] | iOS only. The Google API scopes to request access to. Use `requestAuthorization` to request additional scopes on Android. **Default** `["email", "profile"]` | -| `webClientId` | `WebClientId` | The web client ID obtained from Google Cloud console. In the Modern module only, pass `autoDetect` to automatically determine the value from Firebase config file. | +| `webClientId` | `WebClientId` | The web client ID obtained from Google Cloud console. In the Universal module only, pass `autoDetect` to automatically determine the value from Firebase config file. | --- @@ -194,7 +194,7 @@ Learn more in the [guide](/docs/one-tap#requestauthorization). > `const` **GoogleOneTapSignIn**: complex type, see below -The entry point of the Modern Sign In API, exposed as `GoogleOneTapSignIn`. +The entry point of the Universal sign in API, exposed as `GoogleOneTapSignIn`. On the web, the signatures of `signIn`, `presentExplicitSignIn`, and `createAccount` are callback-based and on native they are Promise-based. Read more in the [guide](/docs/one-tap#web-support). @@ -278,7 +278,7 @@ On the web, the signatures of `signIn`, `presentExplicitSignIn`, and `createAcco | Name | Type | Description | | ------------ | -------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ | | `loginHint`? | `string` | iOS only. The user's ID, or email address, to be prefilled in the authentication UI if possible. [See docs here](https://developers.google.com/identity/sign-in/ios/reference/Classes/GIDSignIn#-signinwithpresentingviewcontroller:hint:completion:). | -| `nonce`? | `string` | iOS only. A cryptographically random value used to mitigate replay attacks. Only available in the paid version. For support across all platforms, use the Modern sign in module. | +| `nonce`? | `string` | iOS only. A cryptographically random value used to mitigate replay attacks. Only available in the paid version. For support across all platforms, use the Universal sign in module. | --- @@ -592,13 +592,13 @@ The response to calling One Tap's `signIn` and Original Google Sign In's `signIn | `data` | `null` | | `type` | `"noSavedCredentialFound"` | -## Web Modern sign in module +## Web Universal sign in module ### WebOneTapSignInCallbacks > **WebOneTapSignInCallbacks**: \{`momentListener`: `MomentListener`;`onError`: (`error`: `NativeModuleError`) => `void` \| `Promise`\<`void`\>;`onResponse`: (`userInfo`: [`OneTapExplicitSignInResponse`](index.mdx#onetapexplicitsigninresponse)) => `void` \| `Promise`\<`void`\>; \} -When using Modern sign in on the web, the sign in result is delivered via a callback, not via a promise. +When using Universal sign in on the web, the sign in result is delivered via a callback, not via a promise. The shape of data delivered to the callback is the same as the shape of the data in the promise, enabling code reuse. Read more in the [guide](/docs/one-tap#web-support). diff --git a/docs/buttons/web.md b/docs/buttons/web.mdx similarity index 90% rename from docs/buttons/web.md rename to docs/buttons/web.mdx index e7e7edc..d89fae0 100644 --- a/docs/buttons/web.md +++ b/docs/buttons/web.mdx @@ -3,15 +3,15 @@ This is the sign-in button that you can use in web apps. It renders `null` when used in native apps. It has a slightly different API than the native `GoogleSigninButton` component which is why it exists as a separate component. -:::tip -Web support is only available in the paid version. [It takes just a few clicks to get access](/docs/install.mdx#obtaining-access) ❤️. -::: +import Banner from '../_sponsorBanner.mdx'; + + The button will _not render_ before the [Google Client API has been loaded](../setting-up/web). You can use the `onError` prop to detect this case. ### How to use this -As the Modern Sign In Guide explains, there are two ways to sign in on the web: using the One-tap UI or using the Google Sign-In button. +As the Universal sign in Guide explains, there are two ways to sign in on the web: using the One-tap UI or using the Google Sign-In button. One-tap UI may not always be available: This happens if user has [opted out](https://developers.google.com/identity/gsi/web/guides/features#globally_opt_out) or when they close the dialog several times in a row, entering the [cooldown period](https://developers.google.com/identity/gsi/web/guides/features#exponential_cooldown). diff --git a/docs/errors.md b/docs/errors.md index 431199d..0e1e106 100644 --- a/docs/errors.md +++ b/docs/errors.md @@ -45,10 +45,10 @@ See [example usage](original#signin). | `IN_PROGRESS` | Trying to invoke another operation (e.g. `signInSilently`) when previous one has not yet finished. If you call e.g. `signInSilently` twice, two calls to `signInSilently` in the native module will be done. The promise from the first call to `signInSilently` will be rejected with this error, and the second will resolve / reject with the result of the native call. | | `PLAY_SERVICES_NOT_AVAILABLE` | Play services are not available or outdated. This happens on Android, or on the web when you're calling the exposed APIs [before the Client library is loaded](setting-up/web). | -### Status codes specific to Modern sign in {#modern-status-codes} +### Status codes specific to Universal sign in {#universal-status-codes} -| Name | Description | -| ---------------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | -| `ONE_TAP_START_FAILED` | Thrown only on Android when the Modern sign in UI cannot be presented. This happens during the [cooldown period](https://developers.google.com/identity/gsi/web/guides/features#exponential_cooldown). You can still call `presentExplicitSignIn` in that case. | +| Name | Description | +| ---------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ | +| `ONE_TAP_START_FAILED` | Thrown only on Android when the Universal sign in UI cannot be presented. This happens during the [cooldown period](https://developers.google.com/identity/gsi/web/guides/features#exponential_cooldown). You can still call `presentExplicitSignIn` in that case. | See [example usage](one-tap#signin). diff --git a/docs/install.mdx b/docs/install.mdx index f8c6e4e..771e6aa 100644 --- a/docs/install.mdx +++ b/docs/install.mdx @@ -8,47 +8,52 @@ There are two ways to consume the package: [//]: # '🌟' -### Modern version {#sponsor-only-version} +### Universal Sign In {#sponsor-only-version} -Available through purchasing a license, and to Expo customers, this version includes: +⭐️ **Key Features**: -⚡️[**Modern Sign In**](/docs/one-tap) implemented with: +- **Cross-Platform**: Unified API which works on **Android**, **iOS**, **Web**, and **macOS**. -- Android: latest [Credential Manager library](https://developers.google.com/identity/android-credential-manager) -- Web: [Sign In with Google for Web](https://developers.google.com/identity/gsi/web/guides/features) -- iOS & macOS: [Google Sign-In SDK](https://developers.google.com/identity/sign-in/ios/start) + - Android: Built with [Credential Manager library](https://developers.google.com/identity/android-credential-manager) + - Web: Uses [Sign In with Google for Web](https://developers.google.com/identity/gsi/web/guides/features) + - iOS & macOS: Powered by the [Google Sign-In SDK](https://developers.google.com/identity/sign-in/ios/start) + +- **Licensed:** see [pricing](https://rngs-package.com/#pricing) and [license](https://rngs-package.com/license). +- **Trusted**: Over 130k npm package downloads. +- **See the UI**: [screenshots](screenshots) of the features. +- **Faster Sign-Ups**: Reduce sign-up and sign-in times on Android by up to 50%, according to [Google](https://developer.android.com/identity/sign-in/legacy-gsi-migration#authentication). 🛡️ **Advanced [security features](/docs/security)** -🔧 **Easier configuration** - [some parameters can be detected automatically](one-tap#automatic-config) +🔧 **Easier setup** - Automatic detection of [configuration parameters](one-tap#automatic-config) for faster integration. -🖥️ **Full platform support** - Deploy everywhere with a unified api: Android, iOS, Web, and macOS +[//]: # '🖥️ **Unified API** - Write code once, deploy everywhere.' -✅ **An example app** - to showcase all **Modern Sign In** features +📱 **An example app** - to showcase all Universal sign in features -Your support helps improve the module and upstream SDKs (such as [1](https://github.com/openid/AppAuth-iOS/pull/788), [2](https://github.com/google/GoogleSignIn-iOS/pull/402)). +Your purchase enables improvements in the module and upstream SDKs (such as [1](https://github.com/openid/AppAuth-iOS/pull/788), [2](https://github.com/google/GoogleSignIn-iOS/pull/402)). ### Public version Available on the public npm registry, this version: - Has platform support limited to Android and iOS. -- Uses functional, but deprecated [Legacy Android Google Sign-In](https://web.archive.org/web/20240308064911/https://developers.google.com/identity/sign-in/android/start-integrating). +- Uses functional, but deprecated [legacy Android Google Sign-In](https://web.archive.org/web/20240308064911/https://developers.google.com/identity/sign-in/android/start-integrating). - Contains none of the extra features listed above. -## Obtaining access to the Modern version {#obtaining-access} +## Obtaining Universal Sign In {#obtaining-access} -[Upon purchasing a license](https://rngs-package.com/), you will be able to configure your (or your colleagues') access to the private npm package and to the private repo with the sources and examples. Alternatively, as an Expo customer, obtain access through [this form](https://forms.gle/tpP7TfUGW1CwgaEZ8). +Universal sign in requires [purchasing a license](https://rngs-package.com/#pricing), after which you will be able to configure your (or your colleagues') access to the private npm package and to the private repo with the sources and examples. Alternatively, as an Expo customer, obtain access through this [form](https://forms.gle/tpP7TfUGW1CwgaEZ8). [//]: # 'Note that this version is distributed under a [custom license](license).' -Three steps are needed to access the private package, which is hosted on [GitHub npm packages registry](https://docs.github.com/en/packages/working-with-a-github-packages-registry/working-with-the-npm-registry). +## Accessing the private npm package {#package-manager-setup} -1. [Purchase a license](https://rngs-package.com/) to immediately set up access. Alternatively, [complete the form](https://forms.gle/tpP7TfUGW1CwgaEZ8). +The private npm package is like any other, but it's hosted on the [GitHub npm packages registry](https://docs.github.com/en/packages/working-with-a-github-packages-registry/working-with-the-npm-registry), not the public npm registry. Therefore, a small bit of setup is needed: -2. [Obtain here](https://github.com/settings/tokens/new?description=react-native-google-sign-in&scopes=read:packages) a Personal Access Token with `packages:read` permission. +1. [Obtain here](https://github.com/settings/tokens/new?description=react-native-google-sign-in&scopes=read:packages) a Personal Access Token with `packages:read` permission. -3. Set up your package manager so that it fetches the package from the GH packages registry instead of the public registry. In this example, we're using an `NPM_TOKEN_GOOGLE_SIGN_IN` environment variable. +2. Set up your package manager so that it fetches the package from the GH packages registry instead of the public registry. In this example, we're using an `NPM_TOKEN_GOOGLE_SIGN_IN` environment variable. import Tabs from '@theme/Tabs'; import TabItem from '@theme/TabItem'; @@ -82,12 +87,6 @@ import TabItem from '@theme/TabItem'; If you use another package manager ([such as Bun](https://bun.sh/docs/install/registries)), refer to its documentation on how to set up a custom registry. -## Requirements - -The packages support last 3 stable releases of React Native. Unofficially, they may work with older versions too. - -If you're using the [New Architecture](https://reactnative.dev/docs/new-architecture-intro), it's strongly recommended to use the latest React Native version available. - ## Installing @@ -107,10 +106,16 @@ If you're using the [New Architecture](https://reactnative.dev/docs/new-architec -If you're using the Modern version, open the lockfile (`yarn.lock` / `package-lock.json`...) and verify that the package is fetched from the GitHub registry (the entry must point to `npm.pkg.github.com`, not `registry.npmjs.org`). If it does not, it means that your package manager is not configured correctly - try uninstalling and reinstalling the package. +If you're using the Universal version, open the lockfile (`yarn.lock` / `package-lock.json`...) and verify that the package is fetched from the GitHub registry (the entry must point to `npm.pkg.github.com`, not `registry.npmjs.org`). If it does not, it means that your package manager is not configured correctly - try uninstalling and reinstalling the package. There are several guides to follow now: - [Expo guide](setting-up/expo) for native mobile apps built with Expo - [Web guide](setting-up/web) if you want to use the package on web - If you're not using Expo but plain React Native, follow [Android guide](setting-up/android) and [iOS guide](setting-up/ios) + +## Requirements + +The packages support last 3 stable releases of React Native. Unofficially, they may work with older versions too. + +If you're using the [New Architecture](https://reactnative.dev/docs/new-architecture-intro), it's strongly recommended to use the latest React Native version available. diff --git a/docs/license.md b/docs/license.md index f77411e..b1de825 100644 --- a/docs/license.md +++ b/docs/license.md @@ -3,6 +3,6 @@ sidebar_position: 80 sidebar_label: License --- -The original module is licensed as MIT, the Modern Sign In module has [this license](https://rngs-package.com/license). +The original module is licensed as MIT, the Universal sign in module has [this license](https://rngs-package.com/license). Please do get in touch if you have any questions or concerns about the license! diff --git a/docs/migrating.md b/docs/migrating.md index e4f84be..59df001 100644 --- a/docs/migrating.md +++ b/docs/migrating.md @@ -7,7 +7,7 @@ sidebar_label: Migrating Version 13 introduced a new JS API, which changes some method response signatures and makes minor changes to error handling (details [here](https://github.com/react-native-google-signin/google-signin/pull/1326)). If you're upgrading from version 12 or earlier, you'll need to make some minor adjustments. -## Modern sign in module +## Universal Sign In 1. Add the [`configure`](one-tap#configure) method to your code. This method is required to be called to configure the module. diff --git a/docs/one-tap.mdx b/docs/one-tap.mdx index 5be2d19..4a3ad6c 100644 --- a/docs/one-tap.mdx +++ b/docs/one-tap.mdx @@ -1,20 +1,16 @@ --- sidebar_position: 30 -sidebar_label: Modern Google sign in +sidebar_label: Universal Google sign in sidebar_class_name: sponsor-heart --- -import Image from '@theme/IdealImage'; - -# Modern Google sign in +# Universal Google sign in This is Google's recommended way to implement Google Sign In. This API is available on Android, iOS, macOS and web (with a little extra work [described below](#web-support)). It is a replacement for the [Original Google sign in](original). The module APIs are named `GoogleOneTapSignIn` for historical reasons. -:::tip -The functionality covered in this page is only available in the paid version. [It takes just a few clicks to get access](install#obtaining-access) ❤️. +import Banner from './_sponsorBanner.mdx'; -This module is being actively developed, and new features are added regularly. -::: + - On Android, it is built on top of the new [Credential Manager](https://developers.google.com/identity/android-credential-manager) APIs. @@ -22,7 +18,7 @@ This module is being actively developed, and new features are added regularly. - On the web, it covers both the [One-tap](https://developers.google.com/identity/gsi/web/guides/offerings#one_tap) flow and the [Google Sign-In button](https://developers.google.com/identity/gsi/web/guides/offerings#sign_in_with_google_button). -Note that on Apple and Android, you can combine the Modern Sign In methods with those one from the [Original Google Sign In](original). To do that, use the Modern sign in to sign in the user. Then call `signInSilently()` and then (for example) `getCurrentUser()` to get the current user's information. However, this shouldn't be necessary because this module should cover all your needs. Please open an issue if that's not the case. +Note that on Apple and Android, you can combine the Universal sign in methods with those one from the [Original Google Sign In](original). To do that, use the Universal sign in to sign in the user. Then call `signInSilently()` and then (for example) `getCurrentUser()` to get the current user's information. However, this shouldn't be necessary because this module should cover all your needs. Please open an issue if that's not the case. ```ts title="example of importing the module" import { @@ -105,13 +101,9 @@ Returns a `Promise` that resolves with [`OneTapResponse`](api#onetapresponse) or If there is no user that was previously signed in, the promise resolves with [`NoSavedCredentialFound`](api#nosavedcredentialfound) object. In that case, you can call [`createAccount`](one-tap#createaccount) to start a flow to create a new account. You don't need to call `signIn` as a response to a user action - you can call it when your app starts or when suitable. -
- UI screenshots -| Android | iOS | Web | -| :-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------: | :--------------------------: | :----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------: | -| No UI, no user interaction the first time. If user has signed up previously, they will see this:
| (no UI, no user interaction) | The prompt presented the first time:
If user has signed in previously, they will see this: | +import SignInScreenshots from './screenshots/_signIn.mdx'; -
+ #### Example code snippet @@ -184,14 +176,9 @@ Use `createAccount` if `signIn` resolved with [`NoSavedCredentialFound` result]( Returns a `Promise` that resolves with [`OneTapResponse`](api#onetapresponse) or rejects in case of error. -
- UI screenshots +import CreateAccount from './screenshots/_createAccount.mdx'; -| Android | iOS | Web | -| :------------------------------------------------------------------------: | :--------------------------------------------------------------------: | :--------------------------------------------------------------------: | -| | | | - -
+ ```ts await GoogleOneTapSignIn.createAccount({ @@ -207,22 +194,17 @@ await GoogleOneTapSignIn.createAccount({ signature: (`params`?: [`OneTapExplicitSignInParams`](api#onetapexplicitsigninparams)) => `Promise`\<[`OneTapExplicitSignInResponse`](api#onetapexplicitsigninresponse)\> -| Platform | Behavior | -| -------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | -| Android | Presents the sign in dialog explicitly. This is useful when the user has hit rate limiting ([`ONE_TAP_START_FAILED`](errors#modern-status-codes)) and the one-tap flow is thus not available, or if both `signIn` and `createAccount` resolve with [`NoSavedCredentialFound`](api#nosavedcredentialfound) object - which happens (in the unlikely case) when no Google account is present on the device. This will prompt the user to add a Google account. | -| Apple | Starts an interactive sign-in flow. Same as `createAccount`. | -| Web | Presents a one-tap prompt. Same as `createAccount`. | +| Platform | Behavior | +| -------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | +| Android | Presents the sign in dialog explicitly. This is useful when the user has hit rate limiting ([`ONE_TAP_START_FAILED`](errors#universal-status-codes)) and the one-tap flow is thus not available, or if both `signIn` and `createAccount` resolve with [`NoSavedCredentialFound`](api#nosavedcredentialfound) object - which happens (in the unlikely case) when no Google account is present on the device. This will prompt the user to add a Google account. | +| Apple | Starts an interactive sign-in flow. Same as `createAccount`. | +| Web | Presents a one-tap prompt. Same as `createAccount`. | Preferably, call this method only as a reaction to when user taps a "sign in with Google" button. -
- UI screenshots - -| Android | iOS | Web | -| :----------------------------------------------------------------------: | :--------------------------------------------------------------------: | :--------------------------------------------------------------------: | -| | | | +import PresentExplicitSignIn from './screenshots/_presentExplicitSignIn.mdx'; -
+ ```ts await GoogleOneTapSignIn.presentExplicitSignIn({ @@ -264,13 +246,9 @@ This method is used to request extra authorization from the user. Use this on An > There are minor differences between the Android and Apple implementations stemming from the underlying Google SDKs. For example, Apple returns all granted scopes, while Android may only return the scopes that were requested. -
- UI screenshots - | Android | iOS | - | :-----------------------------------------------------------------------: | :--------------------------------------------------------------------: | - | | | +import RequestAuthorization from './screenshots/_requestAuthorization.mdx'; -
+ ## Automatic `webClientId` & `iosClientId` detection {#automatic-config} @@ -357,7 +335,7 @@ useEffect(() => { Optionally, you can provide a `momentListener` callback function. The callback is called when important events take place. [See reference.](https://developers.google.com/identity/gsi/web/reference/js-reference#PromptMomentNotification) -2. Render the [`WebGoogleSigninButton`](buttons/web.md) component +2. Render the [`WebGoogleSigninButton`](buttons/web) component One-tap UI may not always be available: This happens if you disable it (`skipPrompt`), when user has [opted out](https://developers.google.com/identity/gsi/web/guides/features#globally_opt_out) or when they cancel the prompt several times in a row, entering the [cooldown period](https://developers.google.com/identity/gsi/web/guides/features#exponential_cooldown). diff --git a/docs/screenshots.mdx b/docs/screenshots.mdx new file mode 100644 index 0000000..1844395 --- /dev/null +++ b/docs/screenshots.mdx @@ -0,0 +1,28 @@ +--- +sidebar_position: 78 +sidebar_label: Screenshots +--- + +# Universal Sign In Screenshots + +:::tip +Universal Sign In is only available in the licensed version. [You can get a license here](https://rngs-package.com/#pricing) ⭐️. +::: + +### `signIn` + +import SignInScreenshots from './screenshots/_signIn.mdx'; + + + +### `createAccount` + +import CreateAccount from './screenshots/_createAccount.mdx'; + + + +### `requestAuthorization` + +import RequestAuthorization from './screenshots/_requestAuthorization.mdx'; + + diff --git a/docs/screenshots/_createAccount.mdx b/docs/screenshots/_createAccount.mdx new file mode 100644 index 0000000..23954dd --- /dev/null +++ b/docs/screenshots/_createAccount.mdx @@ -0,0 +1,8 @@ +
+ UI screenshots + +| Android | iOS | Web | +| :------------------------------------------------------------------------: | :--------------------------------------------------------------------: | :--------------------------------------------------------------------: | +| | | | + +
diff --git a/docs/screenshots/_presentExplicitSignIn.mdx b/docs/screenshots/_presentExplicitSignIn.mdx new file mode 100644 index 0000000..b7e1792 --- /dev/null +++ b/docs/screenshots/_presentExplicitSignIn.mdx @@ -0,0 +1,8 @@ +
+ UI screenshots + +| Android | iOS | Web | +| :----------------------------------------------------------------------: | :--------------------------------------------------------------------: | :--------------------------------------------------------------------: | +| | | | + +
diff --git a/docs/screenshots/_requestAuthorization.mdx b/docs/screenshots/_requestAuthorization.mdx new file mode 100644 index 0000000..73aaea9 --- /dev/null +++ b/docs/screenshots/_requestAuthorization.mdx @@ -0,0 +1,7 @@ +
+ UI screenshots + | Android | iOS | + | :-----------------------------------------------------------------------: | :--------------------------------------------------------------------: | + | | | + +
diff --git a/docs/screenshots/_signIn.mdx b/docs/screenshots/_signIn.mdx new file mode 100644 index 0000000..680970e --- /dev/null +++ b/docs/screenshots/_signIn.mdx @@ -0,0 +1,7 @@ +
+ UI screenshots + | Android | iOS | Web | + | :-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------: | :--------------------------: | :----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------: | + | No UI, no user interaction the first time. If user has signed up previously, they will see this:
| (no UI, no user interaction) | The prompt presented the first time:
If user has signed in previously, they will see this: | + +
diff --git a/docs/security.mdx b/docs/security.mdx index 81a23f2..96927e1 100644 --- a/docs/security.mdx +++ b/docs/security.mdx @@ -4,9 +4,9 @@ sidebar_label: Advanced security sidebar_class_name: sponsor-heart --- -:::tip -The functionality covered in this page is only available in the paid version. [It takes just a few clicks to get access](install#obtaining-access) ❤️. -::: +import Banner from './_sponsorBanner.mdx'; + + # Advanced security @@ -21,7 +21,7 @@ There are 2 security-related features available: [Nonce](https://en.wikipedia.org/wiki/Cryptographic_nonce) (number used once) is a security measure used to mitigate replay attacks and to associate a Client session with an ID Token. -The authorization APIs in [Modern Google Sign-In](/docs/one-tap) for Apple, Android and web allow you to specify a nonce. +The authorization APIs in [Universal Google Sign-In](/docs/one-tap) for Apple, Android and web allow you to specify a nonce. Example usage: diff --git a/docs/setting-up/_category_.json b/docs/setting-up/_category_.json index b091bd6..db441c2 100644 --- a/docs/setting-up/_category_.json +++ b/docs/setting-up/_category_.json @@ -4,6 +4,6 @@ "collapsed": true, "link": { "type": "generated-index", - "description": "Learn how to install and configure the package for different platforms. (Note that the Obtaining Configuration Information section is required for all platforms.)" + "description": "Learn how to install and configure the package for different platforms. Obtaining Configuration Information section is required for all platforms." } } diff --git a/docs/setting-up/expo.md b/docs/setting-up/expo.md index f6eb627..372eb47 100644 --- a/docs/setting-up/expo.md +++ b/docs/setting-up/expo.md @@ -8,7 +8,7 @@ sidebar_position: 1 :::note -This package cannot be used in [Expo Go](https://docs.expo.dev/workflow/overview/#expo-go-an-optional-tool-for-learning) because it requires custom native code. This applies to both the [original](../original) and [modern](../one-tap) (one-tap) sign in methods. +This package cannot be used in [Expo Go](https://docs.expo.dev/workflow/overview/#expo-go-an-optional-tool-for-learning) because it requires custom native code. This applies to both the [Original](../original) and [Universal](../one-tap) (one-tap) sign in methods. However, you can add custom native code to an Expo app by using a [development build](https://docs.expo.dev/workflow/overview/#development-builds). Using a development build is the recommended approach for production apps, and is documented in this guide. diff --git a/docs/setting-up/web.mdx b/docs/setting-up/web.mdx index a0abfb4..efd31e7 100644 --- a/docs/setting-up/web.mdx +++ b/docs/setting-up/web.mdx @@ -7,9 +7,9 @@ sidebar_class_name: sponsor-heart On the web, there is one extra step necessary to use the library: you need to load the Google Client Library and make it available in the browser **before** calling any of the APIs exposed by this package. -:::tip -Web support is only available in the paid version. [It takes just a few clicks to get access](/docs/install.mdx#obtaining-access) ❤️. -::: +import Banner from '../_sponsorBanner.mdx'; + + There are different ways to load the client script. Some of them are: diff --git a/docusaurus.config.ts b/docusaurus.config.ts index 9ba76af..420b0ba 100644 --- a/docusaurus.config.ts +++ b/docusaurus.config.ts @@ -108,7 +108,7 @@ const config: Config = { // categoryOrder: ['Top-level api', 'Type aliases', '*'], // categories are not good groupOrder: [ - 'Modern sign in module', + 'Universal sign in module', 'Original Google sign in', '*', ], diff --git a/package.json b/package.json index 9b6dbdb..2bfc402 100644 --- a/package.json +++ b/package.json @@ -22,7 +22,7 @@ "@docusaurus/preset-classic": "^3.6.3", "@mdx-js/react": "^3.1.0", "clsx": "^2.1.1", - "docusaurus-lunr-search": "^3.5.0", + "docusaurus-lunr-search": "^3.6.1", "prism-react-renderer": "^2.4.0", "react": "^18.3.1", "react-dom": "^18.3.1" @@ -33,8 +33,8 @@ "@docusaurus/types": "^3.6.3", "docusaurus-plugin-typedoc": "^1.0.5", "prettier": "^3.3.3", - "typedoc": "^0.26.11", - "typedoc-plugin-markdown": "^4.2.10", + "typedoc": "^0.27.6", + "typedoc-plugin-markdown": "^4.4.1", "typescript": "~5.6.3" }, "browserslist": { diff --git a/src/components/HomepageFeatures/index.tsx b/src/components/HomepageFeatures/index.tsx index 098cdfc..443c34d 100644 --- a/src/components/HomepageFeatures/index.tsx +++ b/src/components/HomepageFeatures/index.tsx @@ -24,8 +24,8 @@ const FeatureList: FeatureItem[] = [ Svg: require('@site/static/img/undraw_docusaurus_tree.svg').default, description: ( <> - Thanks to the paid version, the module receives updates regularly, and - comes with this detailed documentation site. + Thanks to the licensed version, the module is maintained, and comes with + this detailed documentation site. ), }, diff --git a/src/css/custom.css b/src/css/custom.css index 251f455..b3bf78e 100644 --- a/src/css/custom.css +++ b/src/css/custom.css @@ -35,7 +35,7 @@ } .sponsor-heart a:after { - content: '❤️'; + content: '⭐️'; margin-left: auto; /* Pushes the content to the right */ } diff --git a/yarn.lock b/yarn.lock index b05a033..c4216ef 100644 --- a/yarn.lock +++ b/yarn.lock @@ -4191,6 +4191,17 @@ __metadata: languageName: node linkType: hard +"@gerrit0/mini-shiki@npm:^1.24.0": + version: 1.27.2 + resolution: "@gerrit0/mini-shiki@npm:1.27.2" + dependencies: + "@shikijs/engine-oniguruma": "npm:^1.27.2" + "@shikijs/types": "npm:^1.27.2" + "@shikijs/vscode-textmate": "npm:^10.0.1" + checksum: 10c0/aee681637d123e0e8c9ec154b117ce166dd8b4b9896341e617fef16d0b21ef91a17f6f90cc874137e33ca85b5898817b59bb8aea178cdb2fa6e75b0fff3640c2 + languageName: node + linkType: hard + "@hapi/hoek@npm:^9.0.0": version: 9.3.0 resolution: "@hapi/hoek@npm:9.3.0" @@ -4476,55 +4487,30 @@ __metadata: languageName: node linkType: hard -"@shikijs/core@npm:1.22.0": - version: 1.22.0 - resolution: "@shikijs/core@npm:1.22.0" - dependencies: - "@shikijs/engine-javascript": "npm:1.22.0" - "@shikijs/engine-oniguruma": "npm:1.22.0" - "@shikijs/types": "npm:1.22.0" - "@shikijs/vscode-textmate": "npm:^9.3.0" - "@types/hast": "npm:^3.0.4" - hast-util-to-html: "npm:^9.0.3" - checksum: 10c0/d663fee39180680ccb9ea8dd5abb397e953375989a4fd52fb65a2616388db21d1d0a715a68afae93c4b48f0e037bd0c3a600cd52fb8560461ba87e2102e00cd1 - languageName: node - linkType: hard - -"@shikijs/engine-javascript@npm:1.22.0": - version: 1.22.0 - resolution: "@shikijs/engine-javascript@npm:1.22.0" - dependencies: - "@shikijs/types": "npm:1.22.0" - "@shikijs/vscode-textmate": "npm:^9.3.0" - oniguruma-to-js: "npm:0.4.3" - checksum: 10c0/f1a2c3c6ad5db549229dafe11a57bef2b0896e5c1b33dec15bd323e4e785dc469a277b088a89f774a66b30c8c62e9e5b76d3d485f46096dc290329aab33d92eb - languageName: node - linkType: hard - -"@shikijs/engine-oniguruma@npm:1.22.0": - version: 1.22.0 - resolution: "@shikijs/engine-oniguruma@npm:1.22.0" +"@shikijs/engine-oniguruma@npm:^1.27.2": + version: 1.29.2 + resolution: "@shikijs/engine-oniguruma@npm:1.29.2" dependencies: - "@shikijs/types": "npm:1.22.0" - "@shikijs/vscode-textmate": "npm:^9.3.0" - checksum: 10c0/a57f2352dc35e6f3705348488c0ec2b91a99380489917bddc1d1444b775ba529fc99491ac0c16d0add6d2552ca9fd197e88bd47b0166d163bfc6a80345294452 + "@shikijs/types": "npm:1.29.2" + "@shikijs/vscode-textmate": "npm:^10.0.1" + checksum: 10c0/87d77e05af7fe862df40899a7034cbbd48d3635e27706873025e5035be578584d012f850208e97ca484d5e876bf802d4e23d0394d25026adb678eeb1d1f340ff languageName: node linkType: hard -"@shikijs/types@npm:1.22.0": - version: 1.22.0 - resolution: "@shikijs/types@npm:1.22.0" +"@shikijs/types@npm:1.29.2, @shikijs/types@npm:^1.27.2": + version: 1.29.2 + resolution: "@shikijs/types@npm:1.29.2" dependencies: - "@shikijs/vscode-textmate": "npm:^9.3.0" + "@shikijs/vscode-textmate": "npm:^10.0.1" "@types/hast": "npm:^3.0.4" - checksum: 10c0/220ba56b046dd07cb5e12c02f061e926129d5295fba60c4910a45d65312cdcbcc120329ec550195fdb85ab60ae9e3af31430bffce3ceba80b30d21e32467c013 + checksum: 10c0/37b4ac315effc03e7185aca1da0c2631ac55bdf613897476bd1d879105c41f86ccce6ebd0b78779513d88cc2ee371039f7efd95d604f77f21f180791978822b3 languageName: node linkType: hard -"@shikijs/vscode-textmate@npm:^9.3.0": - version: 9.3.0 - resolution: "@shikijs/vscode-textmate@npm:9.3.0" - checksum: 10c0/6aa80798b7d7f8be8029bb397ce1b9b75c0d0963d6aa444b9ae165595ceee931cf3767ca1681ba71a6e27484eeccab584bd38db3420da477f1a8d745040b1b1f +"@shikijs/vscode-textmate@npm:^10.0.1": + version: 10.0.1 + resolution: "@shikijs/vscode-textmate@npm:10.0.1" + checksum: 10c0/acdbcf1b00d2503620ab50c2a23c7876444850ae0610c8e8b85a29587a333be40c9b98406ff17b9f87cbc64674dac6a2ada680374bde3e51a890e16cf1407490 languageName: node linkType: hard @@ -5890,7 +5876,7 @@ __metadata: languageName: node linkType: hard -"autocomplete.js@npm:^0.37.0": +"autocomplete.js@npm:^0.37.1": version: 0.37.1 resolution: "autocomplete.js@npm:0.37.1" dependencies: @@ -6584,13 +6570,6 @@ __metadata: languageName: node linkType: hard -"clsx@npm:^1.2.1": - version: 1.2.1 - resolution: "clsx@npm:1.2.1" - checksum: 10c0/34dead8bee24f5e96f6e7937d711978380647e936a22e76380290e35486afd8634966ce300fc4b74a32f3762c7d4c0303f442c3e259f4ce02374eb0c82834f27 - languageName: node - linkType: hard - "clsx@npm:^2.0.0": version: 2.0.0 resolution: "clsx@npm:2.0.0" @@ -7500,41 +7479,41 @@ __metadata: "@docusaurus/types": "npm:^3.6.3" "@mdx-js/react": "npm:^3.1.0" clsx: "npm:^2.1.1" - docusaurus-lunr-search: "npm:^3.5.0" + docusaurus-lunr-search: "npm:^3.6.1" docusaurus-plugin-typedoc: "npm:^1.0.5" prettier: "npm:^3.3.3" prism-react-renderer: "npm:^2.4.0" react: "npm:^18.3.1" react-dom: "npm:^18.3.1" - typedoc: "npm:^0.26.11" - typedoc-plugin-markdown: "npm:^4.2.10" + typedoc: "npm:^0.27.6" + typedoc-plugin-markdown: "npm:^4.4.1" typescript: "npm:~5.6.3" languageName: unknown linkType: soft -"docusaurus-lunr-search@npm:^3.5.0": - version: 3.5.0 - resolution: "docusaurus-lunr-search@npm:3.5.0" +"docusaurus-lunr-search@npm:^3.6.1": + version: 3.6.1 + resolution: "docusaurus-lunr-search@npm:3.6.1" dependencies: - autocomplete.js: "npm:^0.37.0" - clsx: "npm:^1.2.1" - gauge: "npm:^3.0.0" - hast-util-select: "npm:^4.0.0" - hast-util-to-text: "npm:^2.0.0" + autocomplete.js: "npm:^0.37.1" + clsx: "npm:^2.1.1" + gauge: "npm:^3.0.2" + hast-util-select: "npm:^4.0.2" + hast-util-to-text: "npm:^2.0.1" hogan.js: "npm:^3.0.2" - lunr: "npm:^2.3.8" + lunr: "npm:^2.3.9" lunr-languages: "npm:^1.4.0" mark.js: "npm:^8.11.1" - minimatch: "npm:^3.0.4" + minimatch: "npm:^3.1.2" rehype-parse: "npm:^7.0.1" to-vfile: "npm:^6.1.0" - unified: "npm:^9.0.0" - unist-util-is: "npm:^4.0.2" + unified: "npm:^9.2.2" + unist-util-is: "npm:^4.1.0" peerDependencies: "@docusaurus/core": ^2.0.0-alpha.60 || ^2.0.0 || ^3.0.0 - react: ^16.8.4 || ^17 || ^18 - react-dom: ^16.8.4 || ^17 || ^18 - checksum: 10c0/b3ed4f5bb90d1c1bd76e633ef7a83e8158cb71935268587ff7fb2063444422bcea1cea555305a5e79de818fc02982bdf33279d2c161367c228248f7f56959da9 + react: ^16.8.4 || ^17 || ^18 || ^19 + react-dom: ^16.8.4 || ^17 || ^18 || ^19 + checksum: 10c0/89962e2a8004bac0fa0999cd189c05ee0b34a4268c038f10db62d5ec41de89d9b672375832a21d93776d277c4a14bc022a717dffdc7a85048255969cc0eeb583 languageName: node linkType: hard @@ -8463,7 +8442,7 @@ __metadata: languageName: node linkType: hard -"gauge@npm:^3.0.0": +"gauge@npm:^3.0.2": version: 3.0.2 resolution: "gauge@npm:3.0.2" dependencies: @@ -8855,7 +8834,7 @@ __metadata: languageName: node linkType: hard -"hast-util-select@npm:^4.0.0": +"hast-util-select@npm:^4.0.2": version: 4.0.2 resolution: "hast-util-select@npm:4.0.2" dependencies: @@ -8901,25 +8880,6 @@ __metadata: languageName: node linkType: hard -"hast-util-to-html@npm:^9.0.3": - version: 9.0.3 - resolution: "hast-util-to-html@npm:9.0.3" - dependencies: - "@types/hast": "npm:^3.0.0" - "@types/unist": "npm:^3.0.0" - ccount: "npm:^2.0.0" - comma-separated-tokens: "npm:^2.0.0" - hast-util-whitespace: "npm:^3.0.0" - html-void-elements: "npm:^3.0.0" - mdast-util-to-hast: "npm:^13.0.0" - property-information: "npm:^6.0.0" - space-separated-tokens: "npm:^2.0.0" - stringify-entities: "npm:^4.0.0" - zwitch: "npm:^2.0.4" - checksum: 10c0/af938a03034727f6c944d3855732d72f71a3bcd920d36b9ba3e083df2217faf81713740934db64673aca69d76b60abe80052e47c0702323fd0bd5dce03b67b8d - languageName: node - linkType: hard - "hast-util-to-jsx-runtime@npm:^2.0.0": version: 2.2.0 resolution: "hast-util-to-jsx-runtime@npm:2.2.0" @@ -8959,7 +8919,7 @@ __metadata: languageName: node linkType: hard -"hast-util-to-text@npm:^2.0.0": +"hast-util-to-text@npm:^2.0.1": version: 2.0.1 resolution: "hast-util-to-text@npm:2.0.1" dependencies: @@ -10178,7 +10138,7 @@ __metadata: languageName: node linkType: hard -"lunr@npm:^2.3.8, lunr@npm:^2.3.9": +"lunr@npm:^2.3.9": version: 2.3.9 resolution: "lunr@npm:2.3.9" checksum: 10c0/77d7dbb4fbd602aac161e2b50887d8eda28c0fa3b799159cee380fbb311f1e614219126ecbbd2c3a9c685f1720a8109b3c1ca85cc893c39b6c9cc6a62a1d8a8b @@ -11156,7 +11116,7 @@ __metadata: languageName: node linkType: hard -"minimatch@npm:3.1.2, minimatch@npm:^3.0.4, minimatch@npm:^3.0.5, minimatch@npm:^3.1.1": +"minimatch@npm:3.1.2, minimatch@npm:^3.0.4, minimatch@npm:^3.0.5, minimatch@npm:^3.1.1, minimatch@npm:^3.1.2": version: 3.1.2 resolution: "minimatch@npm:3.1.2" dependencies: @@ -11616,15 +11576,6 @@ __metadata: languageName: node linkType: hard -"oniguruma-to-js@npm:0.4.3": - version: 0.4.3 - resolution: "oniguruma-to-js@npm:0.4.3" - dependencies: - regex: "npm:^4.3.2" - checksum: 10c0/47d8a4089b1fd0ae4b9781907a92222ae549756ddb72a177a85fdc3bda8e59ce2840710dd03e448b80c9878aa8f4e14519fccc3652da71fc3e8bc048d5cb6acb - languageName: node - linkType: hard - "open@npm:^8.0.9, open@npm:^8.4.0": version: 8.4.2 resolution: "open@npm:8.4.2" @@ -13388,13 +13339,6 @@ __metadata: languageName: node linkType: hard -"regex@npm:^4.3.2": - version: 4.3.3 - resolution: "regex@npm:4.3.3" - checksum: 10c0/543caebc029af8e6205513accf1b32bcafd71a6c48d39af63ce667d043d11d3c81f5c3fa6d9729175c23257180c5588de9e7ae9fe8a1c1d8924699265764dea2 - languageName: node - linkType: hard - "regexpu-core@npm:^5.3.1": version: 5.3.2 resolution: "regexpu-core@npm:5.3.2" @@ -14048,20 +13992,6 @@ __metadata: languageName: node linkType: hard -"shiki@npm:^1.16.2": - version: 1.22.0 - resolution: "shiki@npm:1.22.0" - dependencies: - "@shikijs/core": "npm:1.22.0" - "@shikijs/engine-javascript": "npm:1.22.0" - "@shikijs/engine-oniguruma": "npm:1.22.0" - "@shikijs/types": "npm:1.22.0" - "@shikijs/vscode-textmate": "npm:^9.3.0" - "@types/hast": "npm:^3.0.4" - checksum: 10c0/750ee1751340ad65368921a4a4f29249b9632c8b547a0c4052eb8a467be0da8b3af7a5e8751482a9e387f67053f8c8a7e5f50bf1be6fcf6f91ed3952bd20965e - languageName: node - linkType: hard - "side-channel@npm:^1.0.4": version: 1.0.4 resolution: "side-channel@npm:1.0.4" @@ -14853,29 +14783,29 @@ __metadata: languageName: node linkType: hard -"typedoc-plugin-markdown@npm:^4.2.10": - version: 4.2.10 - resolution: "typedoc-plugin-markdown@npm:4.2.10" +"typedoc-plugin-markdown@npm:^4.4.1": + version: 4.4.1 + resolution: "typedoc-plugin-markdown@npm:4.4.1" peerDependencies: - typedoc: 0.26.x - checksum: 10c0/5771602a2d673824e1a01841f81eb0fe45fe2d6b61070c278903e2c14e5aab4eafd7c37831b7297aaef27185b4eb2b638111add22fc2a0e26b6165b3c54d0bd1 + typedoc: 0.27.x + checksum: 10c0/54c9a25aed64d07258033c4d060acac15a618ee0494cbb2bc70fd10d03c82b3434715b6db01fbeb09d672cff736340666d70da1be83188e3a994048a0a0c6b65 languageName: node linkType: hard -"typedoc@npm:^0.26.11": - version: 0.26.11 - resolution: "typedoc@npm:0.26.11" +"typedoc@npm:^0.27.6": + version: 0.27.6 + resolution: "typedoc@npm:0.27.6" dependencies: + "@gerrit0/mini-shiki": "npm:^1.24.0" lunr: "npm:^2.3.9" markdown-it: "npm:^14.1.0" minimatch: "npm:^9.0.5" - shiki: "npm:^1.16.2" - yaml: "npm:^2.5.1" + yaml: "npm:^2.6.1" peerDependencies: - typescript: 4.6.x || 4.7.x || 4.8.x || 4.9.x || 5.0.x || 5.1.x || 5.2.x || 5.3.x || 5.4.x || 5.5.x || 5.6.x + typescript: 5.0.x || 5.1.x || 5.2.x || 5.3.x || 5.4.x || 5.5.x || 5.6.x || 5.7.x bin: typedoc: bin/typedoc - checksum: 10c0/441104f1215af8d7589375691afc993bea1fab7c9b7b91ead22781e994f9f21a7a779a283dc42d72260171164185fad7dbcf61166b0442107d9c7decb84b2aee + checksum: 10c0/74af856fc2b9ca151567db8e08737a6ab8b29efb611414510eb833f80723245bc6ade00f2be7a410e335833cfd5e3deb1ae1ecfdb4da3a13c65faedd1f1805b0 languageName: node linkType: hard @@ -14966,7 +14896,7 @@ __metadata: languageName: node linkType: hard -"unified@npm:^9.0.0": +"unified@npm:^9.2.2": version: 9.2.2 resolution: "unified@npm:9.2.2" dependencies: @@ -15016,7 +14946,7 @@ __metadata: languageName: node linkType: hard -"unist-util-is@npm:^4.0.0, unist-util-is@npm:^4.0.2": +"unist-util-is@npm:^4.0.0, unist-util-is@npm:^4.1.0": version: 4.1.0 resolution: "unist-util-is@npm:4.1.0" checksum: 10c0/21ca3d7bacc88853b880b19cb1b133a056c501617d7f9b8cce969cd8b430ed7e1bc416a3a11b02540d5de6fb86807e169d00596108a459d034cf5faec97c055e @@ -15761,12 +15691,12 @@ __metadata: languageName: node linkType: hard -"yaml@npm:^2.5.1": - version: 2.5.1 - resolution: "yaml@npm:2.5.1" +"yaml@npm:^2.6.1": + version: 2.7.0 + resolution: "yaml@npm:2.7.0" bin: yaml: bin.mjs - checksum: 10c0/40fba5682898dbeeb3319e358a968fe886509fab6f58725732a15f8dda3abac509f91e76817c708c9959a15f786f38ff863c1b88062d7c1162c5334a7d09cb4a + checksum: 10c0/886a7d2abbd70704b79f1d2d05fe9fb0aa63aefb86e1cb9991837dced65193d300f5554747a872b4b10ae9a12bc5d5327e4d04205f70336e863e35e89d8f4ea9 languageName: node linkType: hard @@ -15791,7 +15721,7 @@ __metadata: languageName: node linkType: hard -"zwitch@npm:^2.0.0, zwitch@npm:^2.0.4": +"zwitch@npm:^2.0.0": version: 2.0.4 resolution: "zwitch@npm:2.0.4" checksum: 10c0/3c7830cdd3378667e058ffdb4cf2bb78ac5711214e2725900873accb23f3dfe5f9e7e5a06dcdc5f29605da976fc45c26d9a13ca334d6eea2245a15e77b8fc06e