From 38b100c0c5326680e300b787ec7812bf178a055f Mon Sep 17 00:00:00 2001 From: Kevin Moore Date: Fri, 15 Nov 2024 16:28:23 -0800 Subject: [PATCH] [google_identity_services_web] Migrate all types to JSObject (#8053) And cleanup other legacy JS-interop Also update tests so they pass with WebAssembly --- .../google_identity_services_web/CHANGELOG.md | 4 ++ .../integration_test/js_interop_id_test.dart | 13 ++-- .../js_interop_oauth_test.dart | 14 ++-- .../example/integration_test/utils.dart | 14 ++++ .../src/js_interop/google_accounts_id.dart | 50 +++----------- .../js_interop/google_accounts_oauth2.dart | 67 +++---------------- .../lib/src/js_interop/load_callback.dart | 3 - .../google_identity_services_web/pubspec.yaml | 2 +- 8 files changed, 50 insertions(+), 117 deletions(-) diff --git a/packages/google_identity_services_web/CHANGELOG.md b/packages/google_identity_services_web/CHANGELOG.md index f6d8de6fa0b9..74323f88c30e 100644 --- a/packages/google_identity_services_web/CHANGELOG.md +++ b/packages/google_identity_services_web/CHANGELOG.md @@ -1,3 +1,7 @@ +## 0.3.3 + +* Moves all the JavaScript types to extend `JSObject`. + ## 0.3.2 * Adds the `nonce` parameter to `loadWebSdk`. diff --git a/packages/google_identity_services_web/example/integration_test/js_interop_id_test.dart b/packages/google_identity_services_web/example/integration_test/js_interop_id_test.dart index 1d1c5c29ea81..6c5da4bcd149 100644 --- a/packages/google_identity_services_web/example/integration_test/js_interop_id_test.dart +++ b/packages/google_identity_services_web/example/integration_test/js_interop_id_test.dart @@ -61,25 +61,24 @@ void main() async { utils.createExpectConfigValue(config as JSObject); expectConfigValue('client_id', 'testing_1-2-3'); - expectConfigValue('auto_select', isFalse); + expectConfigValue('auto_select', false); expectConfigValue('callback', utils.isAJs('function')); expectConfigValue('login_uri', 'https://www.example.com/login'); expectConfigValue('native_callback', utils.isAJs('function')); - expectConfigValue('cancel_on_tap_outside', isFalse); - expectConfigValue('allowed_parent_origin', isA>()); + expectConfigValue('cancel_on_tap_outside', false); + expectConfigValue( + 'allowed_parent_origin', ['allowed', 'another']); expectConfigValue('prompt_parent_id', 'some_dom_id'); expectConfigValue('nonce', 's0m3_r4ndOM_vALu3'); expectConfigValue('context', 'signin'); expectConfigValue('state_cookie_domain', 'subdomain.example.com'); expectConfigValue('ux_mode', 'popup'); - expectConfigValue( - 'allowed_parent_origin', ['allowed', 'another']); expectConfigValue( 'intermediate_iframe_close_callback', utils.isAJs('function')); - expectConfigValue('itp_support', isTrue); + expectConfigValue('itp_support', true); expectConfigValue('login_hint', 'login-hint@example.com'); expectConfigValue('hd', 'hd_value'); - expectConfigValue('use_fedcm_for_prompt', isTrue); + expectConfigValue('use_fedcm_for_prompt', true); }); }); diff --git a/packages/google_identity_services_web/example/integration_test/js_interop_oauth_test.dart b/packages/google_identity_services_web/example/integration_test/js_interop_oauth_test.dart index cf243b0859e7..b65b5d8a8e33 100644 --- a/packages/google_identity_services_web/example/integration_test/js_interop_oauth_test.dart +++ b/packages/google_identity_services_web/example/integration_test/js_interop_oauth_test.dart @@ -43,9 +43,9 @@ void main() async { expectConfigValue('client_id', 'testing_1-2-3'); expectConfigValue('callback', utils.isAJs('function')); expectConfigValue('scope', 'one two three'); - expectConfigValue('include_granted_scopes', isTrue); + expectConfigValue('include_granted_scopes', true); expectConfigValue('prompt', 'some-prompt'); - expectConfigValue('enable_granular_consent', isTrue); + expectConfigValue('enable_granular_consent', true); expectConfigValue('login_hint', 'login-hint@example.com'); expectConfigValue('hd', 'hd_value'); expectConfigValue('state', 'some-state'); @@ -66,9 +66,9 @@ void main() async { utils.createExpectConfigValue(config as JSObject); expectConfigValue('scope', 'one two three'); - expectConfigValue('include_granted_scopes', isTrue); + expectConfigValue('include_granted_scopes', true); expectConfigValue('prompt', 'some-prompt'); - expectConfigValue('enable_granular_consent', isTrue); + expectConfigValue('enable_granular_consent', true); expectConfigValue('login_hint', 'login-hint@example.com'); expectConfigValue('state', 'some-state'); }); @@ -93,15 +93,15 @@ void main() async { utils.createExpectConfigValue(config as JSObject); expectConfigValue('scope', 'one two three'); - expectConfigValue('include_granted_scopes', isTrue); + expectConfigValue('include_granted_scopes', true); expectConfigValue('redirect_uri', 'https://www.example.com/login'); expectConfigValue('callback', utils.isAJs('function')); expectConfigValue('state', 'some-state'); - expectConfigValue('enable_granular_consent', isTrue); + expectConfigValue('enable_granular_consent', true); expectConfigValue('login_hint', 'login-hint@example.com'); expectConfigValue('hd', 'hd_value'); expectConfigValue('ux_mode', 'popup'); - expectConfigValue('select_account', isTrue); + expectConfigValue('select_account', true); expectConfigValue('error_callback', utils.isAJs('function')); }); }); diff --git a/packages/google_identity_services_web/example/integration_test/utils.dart b/packages/google_identity_services_web/example/integration_test/utils.dart index 2d5c3f3fab8c..a75d2d9e9ee8 100644 --- a/packages/google_identity_services_web/example/integration_test/utils.dart +++ b/packages/google_identity_services_web/example/integration_test/utils.dart @@ -23,6 +23,20 @@ typedef ExpectConfigValueFn = void Function(String name, Object? matcher); /// Creates a [ExpectConfigValueFn] for the `config` [JSObject]. ExpectConfigValueFn createExpectConfigValue(JSObject config) { return (String name, Object? matcher) { + if (matcher is String) { + matcher = matcher.toJS; + } else if (matcher is bool) { + matcher = matcher.toJS; + } else if (matcher is List) { + final List old = matcher; + matcher = isA().having( + (JSAny? p0) => (p0 as JSArray?) + ?.toDart + .map((JSAny? e) => e.dartify()) + .toList(), + 'Array with matching values', + old); + } expect(config[name], matcher, reason: name); }; } diff --git a/packages/google_identity_services_web/lib/src/js_interop/google_accounts_id.dart b/packages/google_identity_services_web/lib/src/js_interop/google_accounts_id.dart index 99bc70690a4a..7679f8fad1d6 100644 --- a/packages/google_identity_services_web/lib/src/js_interop/google_accounts_id.dart +++ b/packages/google_identity_services_web/lib/src/js_interop/google_accounts_id.dart @@ -20,12 +20,7 @@ import 'shared.dart'; external GoogleAccountsId get id; /// The Dart definition of the `google.accounts.id` global. -@JS() -@staticInterop -abstract class GoogleAccountsId {} - -/// The `google.accounts.id` methods -extension GoogleAccountsIdExtension on GoogleAccountsId { +extension type GoogleAccountsId._(JSObject _) implements JSObject { /// An undocumented method. /// /// Try it with 'debug'. @@ -186,10 +181,7 @@ extension GoogleAccountsIdExtension on GoogleAccountsId { /// /// Data type: IdConfiguration /// https://developers.google.com/identity/gsi/web/reference/js-reference#IdConfiguration -@JS() -@anonymous -@staticInterop -abstract class IdConfiguration { +extension type IdConfiguration._(JSObject _) implements JSObject { /// Constructs a IdConfiguration object in JavaScript. factory IdConfiguration({ /// Your application's client ID, which is found and created in the Google @@ -355,12 +347,7 @@ typedef PromptMomentListenerFn = void Function(PromptMomentNotification moment); /// /// Data type: PromptMomentNotification /// https://developers.google.com/identity/gsi/web/reference/js-reference#PromptMomentNotification -@JS() -@staticInterop -abstract class PromptMomentNotification {} - -/// The methods of the [PromptMomentNotification] data type: -extension PromptMomentNotificationExtension on PromptMomentNotification { +extension type PromptMomentNotification._(JSObject _) implements JSObject { /// Is this notification for a display moment? bool isDisplayMoment() => _isDisplayMoment().toDart; @JS('isDisplayMoment') @@ -415,12 +402,7 @@ extension PromptMomentNotificationExtension on PromptMomentNotification { /// /// Data type: CredentialResponse /// https://developers.google.com/identity/gsi/web/reference/js-reference#CredentialResponse -@JS() -@staticInterop -abstract class CredentialResponse {} - -/// The fields that are contained in the credential response object. -extension CredentialResponseExtension on CredentialResponse { +extension type CredentialResponse._(JSObject _) implements JSObject { /// The ClientID for this Credential. String? get client_id => _client_id?.toDart; @JS('client_id') @@ -469,10 +451,7 @@ typedef CallbackFn = void Function(CredentialResponse credentialResponse); /// /// Data type: GsiButtonConfiguration /// https://developers.google.com/identity/gsi/web/reference/js-reference#GsiButtonConfiguration -@JS() -@anonymous -@staticInterop -abstract class GsiButtonConfiguration { +extension type GsiButtonConfiguration._(JSObject _) implements JSObject { /// Constructs an options object for the [renderButton] method. factory GsiButtonConfiguration({ /// The button type. @@ -535,12 +514,7 @@ abstract class GsiButtonConfiguration { } /// The object passed as an optional parameter to `click_listener` function. -@JS() -@staticInterop -abstract class GsiButtonData {} - -/// The fields that are contained in the button data. -extension GsiButtonDataExtension on GsiButtonData { +extension type GsiButtonData._(JSObject _) implements JSObject { /// Nonce String? get nonce => _nonce?.toDart; @JS('nonce') @@ -565,10 +539,7 @@ typedef GsiButtonClickListenerFn = void Function(GsiButtonData? gsiButtonData); /// /// Data type: Credential /// https://developers.google.com/identity/gsi/web/reference/js-reference#type-Credential -@JS() -@anonymous -@staticInterop -abstract class Credential { +extension type Credential._(JSObject _) implements JSObject { /// factory Credential({ required String id, @@ -620,12 +591,7 @@ typedef RevocationResponseHandlerFn = void Function( /// /// Data type: RevocationResponse /// https://developers.google.com/identity/gsi/web/reference/js-reference#RevocationResponse -@JS() -@staticInterop -abstract class RevocationResponse {} - -/// The fields that are contained in the [RevocationResponse] object. -extension RevocationResponseExtension on RevocationResponse { +extension type RevocationResponse._(JSObject _) implements JSObject { /// This field is a boolean value set to true if the revoke method call /// succeeded or false on failure. bool get successful => _successful.toDart; diff --git a/packages/google_identity_services_web/lib/src/js_interop/google_accounts_oauth2.dart b/packages/google_identity_services_web/lib/src/js_interop/google_accounts_oauth2.dart index 30a843b07e05..64402069004f 100644 --- a/packages/google_identity_services_web/lib/src/js_interop/google_accounts_oauth2.dart +++ b/packages/google_identity_services_web/lib/src/js_interop/google_accounts_oauth2.dart @@ -9,9 +9,6 @@ // * non_constant_identifier_names required to be able to use the same parameter // names as the underlying library. -@JS() -library google_accounts_oauth2; - import 'dart:js_interop'; import 'shared.dart'; @@ -23,12 +20,7 @@ import 'shared.dart'; external GoogleAccountsOauth2 get oauth2; /// The Dart definition of the `google.accounts.oauth2` global. -@JS() -@staticInterop -abstract class GoogleAccountsOauth2 {} - -/// The `google.accounts.oauth2` methods -extension GoogleAccountsOauth2Extension on GoogleAccountsOauth2 { +extension type GoogleAccountsOauth2._(JSObject _) implements JSObject { /// Initializes and returns a code client, with the passed-in [config]. /// /// Method: google.accounts.oauth2.initCodeClient @@ -97,10 +89,7 @@ extension GoogleAccountsOauth2Extension on GoogleAccountsOauth2 { /// /// Data type: CodeClientConfig /// https://developers.google.com/identity/oauth2/web/reference/js-reference#CodeClientConfig -@JS() -@anonymous -@staticInterop -abstract class CodeClientConfig { +extension type CodeClientConfig._(JSObject _) implements JSObject { /// Constructs a CodeClientConfig object in JavaScript. /// /// The [callback] property must be a Dart function and not a JS function. @@ -161,12 +150,7 @@ abstract class CodeClientConfig { /// /// Data type: CodeClient /// https://developers.google.com/identity/oauth2/web/reference/js-reference#CodeClient -@JS() -@staticInterop -abstract class CodeClient {} - -/// The methods available on the [CodeClient]. -extension CodeClientExtension on CodeClient { +extension type CodeClient._(JSObject _) implements JSObject { /// Starts the OAuth 2.0 Code UX flow. external void requestCode(); } @@ -175,12 +159,7 @@ extension CodeClientExtension on CodeClient { /// /// Data type: CodeResponse /// https://developers.google.com/identity/oauth2/web/reference/js-reference#CodeResponse -@JS() -@staticInterop -abstract class CodeResponse {} - -/// The fields that are contained in the code response object. -extension CodeResponseExtension on CodeResponse { +extension type CodeResponse._(JSObject _) implements JSObject { /// The authorization code of a successful token response. String? get code => _code?.toDart; @JS('code') @@ -223,10 +202,7 @@ typedef CodeClientCallbackFn = void Function(CodeResponse response); /// /// Data type: TokenClientConfig /// https://developers.google.com/identity/oauth2/web/reference/js-reference#TokenClientConfig -@JS() -@anonymous -@staticInterop -abstract class TokenClientConfig { +extension type TokenClientConfig._(JSObject _) implements JSObject { /// Constructs a TokenClientConfig object in JavaScript. /// /// The [callback] property must be a Dart function and not a JS function. @@ -281,12 +257,7 @@ abstract class TokenClientConfig { /// /// Data type: TokenClient /// https://developers.google.com/identity/oauth2/web/reference/js-reference#TokenClient -@JS() -@staticInterop -abstract class TokenClient {} - -/// The methods available on the [TokenClient]. -extension TokenClientExtension on TokenClient { +extension type TokenClient._(JSObject _) implements JSObject { /// Starts the OAuth 2.0 Code UX flow. void requestAccessToken([ OverridableTokenClientConfig? overrideConfig, @@ -308,10 +279,7 @@ extension TokenClientExtension on TokenClient { /// /// Data type: OverridableTokenClientConfig /// https://developers.google.com/identity/oauth2/web/reference/js-reference#OverridableTokenClientConfig -@JS() -@anonymous -@staticInterop -abstract class OverridableTokenClientConfig { +extension type OverridableTokenClientConfig._(JSObject _) implements JSObject { /// Constructs an OverridableTokenClientConfig object in JavaScript. factory OverridableTokenClientConfig({ /// A list of scopes that identify the resources that your application could @@ -396,12 +364,7 @@ abstract class OverridableTokenClientConfig { /// /// Data type: TokenResponse /// https://developers.google.com/identity/oauth2/web/reference/js-reference#TokenResponse -@JS() -@staticInterop -abstract class TokenResponse {} - -/// The fields that are contained in the code response object. -extension TokenResponseExtension on TokenResponse { +extension type TokenResponse._(JSObject _) implements JSObject { /// The access token of a successful token response. String? get access_token => _access_token?.toDart; @JS('access_token') @@ -465,12 +428,7 @@ typedef TokenClientCallbackFn = void Function(TokenResponse response); typedef ErrorCallbackFn = void Function(GoogleIdentityServicesError? error); /// An error returned by `initTokenClient` or `initDataClient`. -@JS() -@staticInterop -abstract class GoogleIdentityServicesError {} - -/// Methods of the GoogleIdentityServicesError object. -extension GoogleIdentityServicesErrorExtension on GoogleIdentityServicesError { +extension type GoogleIdentityServicesError._(JSObject _) implements JSObject { /// The type of error GoogleIdentityServicesErrorType get type => GoogleIdentityServicesErrorType.values.byName(_type.toDart); @@ -492,12 +450,7 @@ typedef RevokeTokenDoneFn = void Function(TokenRevocationResponse response); /// /// Data type: RevocationResponse /// https://developers.google.com/identity/oauth2/web/reference/js-reference#TokenResponse -@JS() -@staticInterop -abstract class TokenRevocationResponse {} - -/// The fields that are contained in the [TokenRevocationResponse] object. -extension TokenRevocationResponseExtension on TokenRevocationResponse { +extension type TokenRevocationResponse._(JSObject _) implements JSObject { /// This field is a boolean value set to true if the revoke method call /// succeeded or false on failure. bool get successful => _successful.toDart; diff --git a/packages/google_identity_services_web/lib/src/js_interop/load_callback.dart b/packages/google_identity_services_web/lib/src/js_interop/load_callback.dart index 23b08447b8b6..f48f8aa0203b 100644 --- a/packages/google_identity_services_web/lib/src/js_interop/load_callback.dart +++ b/packages/google_identity_services_web/lib/src/js_interop/load_callback.dart @@ -5,8 +5,6 @@ // Methods here are documented in the Google Identity authentication website, // but they don't really belong to either the authentication nor authorization // libraries. -@JS() -library id_load_callback; import 'dart:js_interop'; @@ -18,7 +16,6 @@ import 'shared.dart'; */ @JS('onGoogleLibraryLoad') -@staticInterop external set _onGoogleLibraryLoad(JSFunction callback); /// Method called after the Sign In With Google JavaScript library is loaded. diff --git a/packages/google_identity_services_web/pubspec.yaml b/packages/google_identity_services_web/pubspec.yaml index 97af6ef049fe..cedb0e5b194b 100644 --- a/packages/google_identity_services_web/pubspec.yaml +++ b/packages/google_identity_services_web/pubspec.yaml @@ -2,7 +2,7 @@ name: google_identity_services_web description: A Dart JS-interop layer for Google Identity Services. Google's new sign-in SDK for Web that supports multiple types of credentials. repository: https://github.com/flutter/packages/tree/main/packages/google_identity_services_web issue_tracker: https://github.com/flutter/flutter/issues?q=is%3Aissue+is%3Aopen+label%3A%22p%3A+google_identiy_services_web%22 -version: 0.3.2 +version: 0.3.3 environment: sdk: ^3.4.0