diff --git a/.github/workflows/on-pr-push-code-check.yml b/.github/workflows/on-pr-push-code-check.yml index 7b4d864..67400e1 100644 --- a/.github/workflows/on-pr-push-code-check.yml +++ b/.github/workflows/on-pr-push-code-check.yml @@ -29,7 +29,7 @@ jobs: uses: dart-lang/setup-dart@v1 with: # https://github.com/invertase/dart_edge/issues/50 - sdk: 3.0.0 + sdk: 3.9.0 - name: Get main dependencies run: dart pub get diff --git a/CHANGELOG.md b/CHANGELOG.md index e006bb5..7707e4b 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,3 +1,8 @@ +## 1.0.0-dev.1 +- Refactored JS Interop layer to modern Dart 3.3+ `extension type` (`dart:js_interop`). +- Updated SDK constraint to `>=3.3.0 <4.0.0` supporting Dart SDK 3.12+ (Flutter 3.44+). +- Removed legacy `@JS()` class annotations and `dart:js_util`. + ## 0.0.4 - Fixed links in docs. - Updated supported platforms. diff --git a/README.md b/README.md index 029624f..77c567c 100644 --- a/README.md +++ b/README.md @@ -58,4 +58,3 @@ The main scenario is Supabase Edge Functions, but it should also work for other 6. You can use the function now. -Note that because of the [bug in dart_edge](https://github.com/invertase/dart_edge/issues/50), SDK versions >= 3.1.0 are not actually supported. diff --git a/analysis_options.yaml b/analysis_options.yaml index 7e89be6..aa6bc53 100644 --- a/analysis_options.yaml +++ b/analysis_options.yaml @@ -1,7 +1,20 @@ include: package:solid_lints/analysis_options.yaml +plugins: + solid_lints: + version: ^1.0.0-dev.1 + diagnostics: + number_of_parameters: false + cyclomatic_complexity: false + avoid_non_null_assertion: false + avoid_duplicate_code: false + linter: rules: - package_api_docs: true prefer_foreach: true prefer_single_quotes: true + +formatter: + trailing_commas: preserve + + diff --git a/bin/add_imports.dart b/bin/add_imports.dart index 1f8f8fe..e154327 100644 --- a/bin/add_imports.dart +++ b/bin/add_imports.dart @@ -32,19 +32,15 @@ void main(List arguments) { } String createNewSource(String sourceString, Config config) { - final classes = RegExp(r'new self.([A-Za-z]+)\(') - .allMatches(sourceString) - .map((e) => e.group(1)) - .whereNotNull() - .toSet() - .intersection(config.classes) + final classesToImport = config.classes .whereNot((e) => sourceString.contains('import { $e }')) .toList(); return [ - ...[config.importStringForClass, (e) => 'self.$e = $e;'] - .map(classes.map) - .flattened, + ...[ + config.importStringForClass, + (e) => 'globalThis.$e = $e;', + ].map(classesToImport.map).flattened, sourceString, ].join('\n'); } diff --git a/example/pubspec.yaml b/example/pubspec.yaml index fc968b5..e102102 100644 --- a/example/pubspec.yaml +++ b/example/pubspec.yaml @@ -4,7 +4,7 @@ version: 1.0.0 publish_to: none environment: - sdk: ^3.0.0 + sdk: ">=3.9.0 <4.0.0" dependencies: deno_postgres_interop: diff --git a/lib/src/client.dart b/lib/src/client.dart index 6e988b2..dfc7968 100644 --- a/lib/src/client.dart +++ b/lib/src/client.dart @@ -1,19 +1,29 @@ import 'dart:js_interop'; -import 'dart:js_util'; +import 'dart:js_interop_unsafe'; import 'package:deno_postgres_interop/src/client_options.dart'; import 'package:deno_postgres_interop/src/query_client.dart'; /// [deno-postgres@v​0.17.0/Client](https://deno.land/x/postgres@v0.17.0/mod.ts?s=Client). -@JS() -class Client extends QueryClient { +@JS('Client') +extension type Client._(JSObject _) implements QueryClient, JSObject { /// [deno-postgres@v​0.17.0/Client/constructor](https://deno.land/x/postgres@v0.17.0/mod.ts?s=Client#ctor_0). - external factory Client(String dbUrl); + factory Client(String dbUrl) => _createClient(dbUrl.toJS); /// [deno-postgres@v​0.17.0/Client/constructor](https://deno.land/x/postgres@v0.17.0/mod.ts?s=Client#ctor_0). - factory Client.config(ClientOptions config) => - callConstructor('Client', [config]); + factory Client.config(ClientOptions config) => _createClient(config); /// [deno-postgres@v​0.17.0/Client/constructor](https://deno.land/x/postgres@v0.17.0/mod.ts?s=Client#ctor_0). - factory Client.empty() => callConstructor('Client', null); + factory Client.empty() => _createClient(); + + static Client _createClient([JSAny? configOrUrl]) { + final constructor = globalContext['Client'] as JSFunction?; + if (constructor == null) { + throw StateError('Client constructor not found in global context.'); + } + + return configOrUrl != null + ? constructor.callAsConstructor(configOrUrl) + : constructor.callAsConstructor(); + } } diff --git a/lib/src/client_common.dart b/lib/src/client_common.dart index c041aee..472bf19 100644 --- a/lib/src/client_common.dart +++ b/lib/src/client_common.dart @@ -1,3 +1,5 @@ +import 'dart:js_interop'; + import 'package:deno_postgres_interop/src/query_array_result.dart'; import 'package:deno_postgres_interop/src/query_object_options.dart'; import 'package:deno_postgres_interop/src/query_object_result.dart'; @@ -7,24 +9,22 @@ import 'package:deno_postgres_interop/src/util.dart'; typedef QueryArguments = Object; /// This class hosts common interops for clients. -class ClientCommon { +abstract final class ClientCommon { /// [deno-postgres@v​0.17.0/Transaction/queryArray](https://deno.land/x/postgres@v0.17.0/mod.ts?s=Transaction#method_queryArray_0). /// [deno-postgres@v​0.17.0/QueryClient/queryArray](https://deno.land/x/postgres@v0.17.0/mod.ts?s=QueryClient#method_queryArray_0). static Future> queryArray>( Object queryable, String query, [ QueryArguments? arguments, - ]) => - _query('queryArray', queryable, query, arguments); + ]) => _query('queryArray', queryable, query, arguments); /// [deno-postgres@v​0.17.0/Transaction/queryArray](https://deno.land/x/postgres@v0.17.0/mod.ts?s=Transaction#method_queryArray_1). /// [deno-postgres@v​0.17.0/QueryClient/queryArray](https://deno.land/x/postgres@v0.17.0/mod.ts?s=QueryClient#method_queryArray_1). static Future> - queryArrayWithOptions>( + queryArrayWithOptions>( Object queryable, QueryObjectOptions config, - ) => - callFutureMethod(queryable, 'queryArray', [config]); + ) => callFutureMethod(queryable as JSObject, 'queryArray', [config]); // This one won't be implemented because it doesn't make much sense for dart, // the query here is of type TemplateStringsArray which is used in @@ -39,21 +39,19 @@ class ClientCommon { // https://deno.land/x/postgres@v0.17.0/mod.ts?s=QueryClient#method_queryArray_2 /// [deno-postgres@v​0.17.0/Transaction/queryObject](https://deno.land/x/postgres@v0.17.0/mod.ts?s=Transaction#method_queryObject_0). - /// [deno-postgres@v​0.17.0/QueryClient/queryObject](https://deno.land/x/postgres@v0.17.0/mod.ts?s=QueryClient#method_queryObject_0). + /// [deno-postgres@v​0.17.0/QueryClient/queryObject](https://deno.land/x/postgres@v0.17.0/mod.ts?s=Transaction#method_queryObject_0). static Future> queryObject( Object queryable, String query, [ QueryArguments? arguments, - ]) => - _query('queryObject', queryable, query, arguments); + ]) => _query('queryObject', queryable, query, arguments); /// [deno-postgres@v​0.17.0/Transaction/queryObject](https://deno.land/x/postgres@v0.17.0/mod.ts?s=Transaction#method_queryObject_1). - /// [deno-postgres@v​0.17.0/QueryClient/queryObject](https://deno.land/x/postgres@v0.17.0/mod.ts?s=QueryClient#method_queryObject_1). + /// [deno-postgres@v​0.17.0/QueryClient/queryObject](https://deno.land/x/postgres@v0.17.0/mod.ts?s=Transaction#method_queryObject_1). static Future> queryObjectWithOptions( Object queryable, QueryObjectOptions config, - ) => - callFutureMethod(queryable, 'queryObject', [config]); + ) => callFutureMethod(queryable as JSObject, 'queryObject', [config]); // This one won't be implemented because it doesn't make much sense for dart, // the query here is of type TemplateStringsArray which is used in @@ -61,7 +59,7 @@ class ClientCommon { // // [related issue](https://github.com/dart-lang/language/issues/1988). // - // [deno-postgres@v​0.17.0/QueryClient/queryObject](https://deno.land/x/postgres@v0.17.0/mod.ts?s=QueryClient#method_queryObject_2). + // [deno-postgres@v0.17.0/QueryClient/queryObject](https://deno.land/x/postgres@v0.17.0/mod.ts?s=QueryClient#method_queryObject_2). // Future> queryObjectWithOptions( // List query, // List args, @@ -77,7 +75,7 @@ class ClientCommon { _assertQueryArgumentsOrNull(arguments); return callFutureMethod( - queryable, + queryable as JSObject, function, [ query, @@ -88,7 +86,8 @@ class ClientCommon { } void _assertQueryArgumentsOrNull(QueryArguments? arguments) { - final isCorrectType = arguments is List || + final isCorrectType = + arguments is List || arguments is Map || arguments == null; diff --git a/lib/src/client_configuration.dart b/lib/src/client_configuration.dart index 9cd638c..5eef68f 100644 --- a/lib/src/client_configuration.dart +++ b/lib/src/client_configuration.dart @@ -1,13 +1,12 @@ import 'dart:js_interop'; -import 'dart:js_util'; import 'package:deno_postgres_interop/src/connection_options.dart'; import 'package:deno_postgres_interop/src/tls_options.dart'; import 'package:deno_postgres_interop/src/transport.dart'; /// [deno-postgres@v​0.17.0/ClientConfiguration](https://deno.land/x/postgres@v0.17.0/connection/connection_params.ts?s=ClientConfiguration). -@JS() -class ClientConfiguration { +@JS('ClientConfiguration') +extension type ClientConfiguration._(JSObject _) implements JSObject { /// [deno-postgres@v​0.17.0/ClientConfiguration/applicationName](https://deno.land/x/postgres@v0.17.0/connection/connection_params.ts?s=ClientConfiguration#prop_applicationName). external String get applicationName; @@ -20,8 +19,18 @@ class ClientConfiguration { /// [deno-postgres@v​0.17.0/ClientConfiguration/hostname](https://deno.land/x/postgres@v0.17.0/connection/connection_params.ts?s=ClientConfiguration#prop_hostname). external String get hostname; + @JS('options') + external JSAny? get _options; + /// [deno-postgres@v​0.17.0/ClientConfiguration/options](https://deno.land/x/postgres@v0.17.0/connection/connection_params.ts?s=ClientConfiguration#prop_options). - external Map get options; + Map get options { + final map = _options?.dartify(); + if (map is Map) { + return map.cast(); + } + + return const {}; + } /// [deno-postgres@v​0.17.0/ClientConfiguration/password](https://deno.land/x/postgres@v0.17.0/connection/connection_params.ts?s=ClientConfiguration#prop_password). external String? get password; @@ -35,6 +44,12 @@ class ClientConfiguration { /// [deno-postgres@v​0.17.0/ClientConfiguration/user](https://deno.land/x/postgres@v0.17.0/connection/connection_params.ts?s=ClientConfiguration#prop_user). external String get user; + @JS('host_type') + external String get _hostType; + + /// [deno-postgres@v​0.17.0/ClientConfiguration/host_type](https://deno.land/x/postgres@v0.17.0/connection/connection_params.ts?s=ClientConfiguration#prop_host_type). + Transport get hostType => Transport.parse(_hostType); + /// [deno-postgres@v​0.17.0/ClientConfiguration](https://deno.land/x/postgres@v0.17.0/connection/connection_params.ts?s=ClientConfiguration). factory ClientConfiguration({ required String applicationName, @@ -47,23 +62,19 @@ class ClientConfiguration { required String user, required Transport hostType, String? password, - }) => - jsify({ - 'applicationName': applicationName, - 'connection': connection, - 'database': database, - 'hostname': hostname, - 'options': options, - if (password != null) 'password': password, - 'port': port, - 'tls': tls, - 'user': user, - 'hostType': hostType.name, - }) as ClientConfiguration; -} - -/// [deno-postgres@v​0.17.0/ClientConfiguration](https://deno.land/x/postgres@v0.17.0/connection/connection_params.ts?s=ClientConfiguration). -extension ClientConfigurationProps on ClientConfiguration { - /// [deno-postgres@v​0.17.0/ClientConfiguration/host_type](https://deno.land/x/postgres@v0.17.0/connection/connection_params.ts?s=ClientConfiguration#prop_host_type). - Transport get hostType => Transport.parse(getProperty(this, 'host_type')); + }) => ClientConfiguration._( + { + 'applicationName': applicationName, + 'connection': connection, + 'database': database, + 'hostname': hostname, + 'options': options, + if (password != null) 'password': password, + 'port': port, + 'tls': tls, + 'user': user, + 'hostType': hostType.name, + }.jsify()! + as JSObject, + ); } diff --git a/lib/src/client_options.dart b/lib/src/client_options.dart index 368e507..83ec83c 100644 --- a/lib/src/client_options.dart +++ b/lib/src/client_options.dart @@ -1,13 +1,12 @@ import 'dart:js_interop'; -import 'dart:js_util'; import 'package:deno_postgres_interop/src/partial/partial_connection_options.dart'; import 'package:deno_postgres_interop/src/partial/partial_tls_options.dart'; import 'package:deno_postgres_interop/src/transport.dart'; /// [deno-postgres@v​0.17.0/ClientOptions](https://deno.land/x/postgres@v0.17.0/mod.ts?s=ClientOptions). -@JS() -class ClientOptions { +@JS('ClientOptions') +extension type ClientOptions._(JSObject _) implements JSObject { /// [deno-postgres@v​0.17.0/ClientOptions/applicationName](https://deno.land/x/postgres@v0.17.0/mod.ts?s=ClientOptions#prop_applicationName). external String? get applicationName; @@ -23,57 +22,20 @@ class ClientOptions { /// [deno-postgres@v​0.17.0/ClientOptions/user](https://deno.land/x/postgres@v0.17.0/mod.ts?s=ClientOptions#prop_applicationName/user). external String? get user; - /// [deno-postgres@v​0.17.0/ClientOptions](https://deno.land/x/postgres@v0.17.0/mod.ts?s=ClientOptions). - factory ClientOptions({ - String? applicationName, - PartialConnectionOptions? connection, - String? database, - String? hostname, - Transport? hostType, - String? optionsString, - Map? optionsMap, - String? password, - String? portString, - int? port, - PartialTLSOptions? tls, - String? user, - }) { - assert(optionsString == null || optionsMap == null); - assert(portString == null || port == null); - - return jsify( - { - if (applicationName != null) 'applicationName': applicationName, - if (connection != null) 'connection': jsify(connection.asMap()), - if (database != null) 'database': database, - if (hostname != null) 'hostname': hostname, - if (hostType != null) 'host_type': hostType.name, - if (optionsString != null) - 'options': optionsString - else if (optionsMap != null) - 'options': jsify(optionsMap), - if (password != null) 'password': password, - if (portString != null) - 'port': portString - else if (port != null) - 'port': port, - if (tls != null) 'tls': jsify(tls.asMap()), - if (user != null) 'user': user, - }, - ) as ClientOptions; - } -} + @JS('host_type') + external String? get _hostType; -/// [deno-postgres@v​0.17.0/ClientOptions](https://deno.land/x/postgres@v0.17.0/mod.ts?s=ClientOptions). -extension ClientOptionsProps on ClientOptions { /// [deno-postgres@v​0.17.0/ClientOptions/host_type](https://deno.land/x/postgres@v0.17.0/mod.ts?s=ClientOptions#prop_host_type). - Transport get hostType => Transport.parse(getProperty(this, 'host_type')); + Transport get hostType => Transport.parse(_hostType ?? ''); + + @JS('options') + external JSAny? get _options; /// [deno-postgres@v​0.17.0/ClientOptions/options](https://deno.land/x/postgres@v0.17.0/mod.ts?s=ClientOptions#prop_options). /// /// Either this or [optionsMap] is null. String? get optionsString { - final prop = getProperty(this, 'options'); + final prop = _options?.dartify(); return prop is String ? prop : null; } @@ -82,16 +44,19 @@ extension ClientOptionsProps on ClientOptions { /// /// Either this or [optionsString] is null. Map? get optionsMap { - final prop = getProperty(this, 'options'); + final prop = _options?.dartify(); - return prop is String ? null : prop as Map; + return prop is Map ? prop.cast() : null; } + @JS('port') + external JSAny? get _port; + /// [deno-postgres@v​0.17.0/ClientOptions/port](https://deno.land/x/postgres@v0.17.0/mod.ts?s=ClientOptions#prop_port). /// /// Either this or [port] is null. String? get portString { - final prop = getProperty(this, 'port'); + final prop = _port?.dartify(); return prop is String ? prop : null; } @@ -100,30 +65,75 @@ extension ClientOptionsProps on ClientOptions { /// /// Either this or [portString] is null. int? get port { - final prop = getProperty(this, 'port'); + final prop = _port?.dartify(); return prop is int ? prop : null; } + @JS('connection') + external JSAny? get _connection; + /// [deno-postgres@v​0.17.0/ClientOptions/connection](https://deno.land/x/postgres@v0.17.0/mod.ts?s=ClientOptions#prop_connection). PartialConnectionOptions? get connection { - final map = - dartify(getProperty(this, 'connection')) as Map?; + final map = _connection?.dartify() as Map?; return map == null ? null : PartialConnectionOptions.fromMap(map); } + @JS('tls') + external JSAny? get _tls; + /// [deno-postgres@v​0.17.0/ClientOptions/tls](https://deno.land/x/postgres@v0.17.0/mod.ts?s=ClientOptions#prop_tls). PartialTLSOptions? get tls { - final map = - dartify(getProperty(this, 'connection')) as Map?; + final map = _tls?.dartify() as Map?; if (map == null) return null; return PartialTLSOptions( - caCertificates: map['caCertificates'] as List?, + caCertificates: (map['caCertificates'] as List?)?.cast(), isEnabled: map['enabled'] as bool?, isEnforced: map['enforced'] as bool?, ); } + + /// [deno-postgres@v​0.17.0/ClientOptions](https://deno.land/x/postgres@v0.17.0/mod.ts?s=ClientOptions). + factory ClientOptions({ + String? applicationName, + PartialConnectionOptions? connection, + String? database, + String? hostname, + Transport? hostType, + String? optionsString, + Map? optionsMap, + String? password, + String? portString, + int? port, + PartialTLSOptions? tls, + String? user, + }) { + assert(optionsString == null || optionsMap == null); + assert(portString == null || port == null); + + return ClientOptions._( + { + if (applicationName != null) 'applicationName': applicationName, + if (connection != null) 'connection': connection.asMap(), + if (database != null) 'database': database, + if (hostname != null) 'hostname': hostname, + if (hostType != null) 'host_type': hostType.name, + if (optionsString != null) + 'options': optionsString + else if (optionsMap != null) + 'options': optionsMap, + if (password != null) 'password': password, + if (portString != null) + 'port': portString + else if (port != null) + 'port': port, + if (tls != null) 'tls': tls.asMap(), + if (user != null) 'user': user, + }.jsify()! + as JSObject, + ); + } } diff --git a/lib/src/column.dart b/lib/src/column.dart index e440866..24d52fa 100644 --- a/lib/src/column.dart +++ b/lib/src/column.dart @@ -1,9 +1,38 @@ import 'dart:js_interop'; -import 'dart:js_util'; /// [deno-postgres@v​0.17.0/Column](https://deno.land/x/postgres@v0.17.0/query/decode.ts?s=Column). -@JS() -class Column { +@JS('Column') +extension type Column._(JSObject _) implements JSObject { + /// [deno-postgres@v​0.17.0/Column](https://deno.land/x/postgres@v0.17.0/query/decode.ts?s=Column#ctor_0). + factory Column({ + required String name, + required int tableOid, + required int index, + required int typeOid, + required int columnLength, + required int typeModifier, + required ColumnFormat format, + }) => Column._internal( + name, + tableOid, + index, + typeOid, + columnLength, + typeModifier, + format.id, + ); + + @JS('Column') + external factory Column._internal( + String name, + int tableOid, + int index, + int typeOid, + int columnLength, + int typeModifier, + int format, + ); + /// [deno-postgres@v​0.17.0/Column](https://deno.land/x/postgres@v0.17.0/query/decode.ts?s=Column). external String get name; @@ -22,32 +51,12 @@ class Column { /// [deno-postgres@v​0.17.0/Column](https://deno.land/x/postgres@v0.17.0/query/decode.ts?s=Column). external int get typeModifier; - /// [deno-postgres@v​0.17.0/Column](https://deno.land/x/postgres@v0.17.0/query/decode.ts?s=Column#ctor_0). - factory Column({ - required String name, - required int tableOid, - required int index, - required int typeOid, - required int columnLength, - required int typeModifier, - required ColumnFormat format, - }) => - callConstructor('Column', [ - name, - tableOid, - index, - typeOid, - columnLength, - typeModifier, - format.id, - ]); -} + @JS('format') + external int get _format; -/// [deno-postgres@v​0.17.0/Column](https://deno.land/x/postgres@v0.17.0/query/decode.ts?s=Column). -extension ColumnProps on Column { /// [deno-postgres@v​0.17.0/Column](https://deno.land/x/postgres@v0.17.0/query/decode.ts?s=Column). - ColumnFormat get format => ColumnFormat.values - .firstWhere((e) => e.id == getProperty(this, 'format')); + ColumnFormat get format => + ColumnFormat.values.firstWhere((e) => e.id == _format); } /// enum Format { diff --git a/lib/src/connection.dart b/lib/src/connection.dart index cd45722..3787f53 100644 --- a/lib/src/connection.dart +++ b/lib/src/connection.dart @@ -1,50 +1,70 @@ import 'dart:js_interop'; -import 'dart:js_util'; import 'package:deno_postgres_interop/src/client_configuration.dart'; import 'package:deno_postgres_interop/src/promise.dart'; import 'package:deno_postgres_interop/src/query.dart'; import 'package:deno_postgres_interop/src/query_result.dart'; import 'package:deno_postgres_interop/src/transport.dart'; -import 'package:deno_postgres_interop/src/util.dart'; /// [deno-postgres@v​0.17.0/Connection](https://deno.land/x/postgres@v0.17.0/connection/connection.ts?s=Connection). -@JS() -class Connection { - /// [deno-postgres@v​0.17.0/Connection/connected](https://deno.land/x/postgres@v0.17.0/connection/connection.ts?s=Connection#accessor_pid). - external int get pid; - +@JS('Connection') +extension type Connection._(JSObject _) implements JSObject { /// [deno-postgres@v​0.17.0/Connection/constructor](https://deno.land/x/postgres@v0.17.0/connection/connection.ts?s=Connection#ctor_0). factory Connection({ required ClientConfiguration connectionParams, required Future Function() disconnectionCallback, - }) => - callConstructor( - 'Connection', - [connectionParams, () => futureToPromise(disconnectionCallback())], - ); -} + }) => Connection._internal( + connectionParams, + (() => futureToPromise(disconnectionCallback())).toJS, + ); + + @JS('Connection') + external factory Connection._internal( + ClientConfiguration connectionParams, + JSFunction disconnectionCallback, + ); + + /// [deno-postgres@v​0.17.0/Connection/connected](https://deno.land/x/postgres@v0.17.0/connection/connection.ts?s=Connection#accessor_pid). + external int get pid; -/// [deno-postgres@v​0.17.0/Connection](https://deno.land/x/postgres@v0.17.0/connection/connection.ts?s=Connection). -extension ConnectionProps on Connection { /// [deno-postgres@v​0.17.0/Connection/connected](https://deno.land/x/postgres@v0.17.0/connection/connection.ts?s=Connection#prop_connected). - bool get isConnected => getProperty(this, 'connected'); + @JS('connected') + external bool get isConnected; /// [deno-postgres@v​0.17.0/Connection/tls](https://deno.land/x/postgres@v0.17.0/connection/connection.ts?s=Connection#accessor_tls). - bool get isCarriedOverTLS => getProperty(this, 'tls'); + @JS('tls') + external bool get isCarriedOverTLS; + + @JS('transport') + external String get _transport; /// [deno-postgres@v​0.17.0/Connection/transport](https://deno.land/x/postgres@v0.17.0/connection/connection.ts?s=Connection#accessor_transport). - Transport get transport => Transport.parse(getProperty(this, 'transport')); + Transport get transport => Transport.parse(_transport); + + @JS('end') + external JSPromise _end(); /// [deno-postgres@v​0.17.0/Connection/end](https://deno.land/x/postgres@v0.17.0/connection/connection.ts?s=Connection#method_end_0). - Future end() => callFutureMethod(this, 'end'); + Future end() async { + await _end().toDart; + } + + @JS('query') + external JSPromise _query(Query query); /// [deno-postgres@v​0.17.0/Connection/query](https://deno.land/x/postgres@v0.17.0/connection/connection.ts?s=Connection#method_query_0). /// [deno-postgres@v​0.17.0/Connection/query](https://deno.land/x/postgres@v0.17.0/connection/connection.ts?s=Connection#method_query_1). - Future queryArray(Query query) => - callFutureMethod(this, 'query', [query]); + Future queryArray(Query query) async { + final res = await _query(query).toDart; + + return res! as T; + } + + @JS('startup') + external JSPromise _startup(bool isReconnection); /// [deno-postgres@v​0.17.0/Connection/startup](https://deno.land/x/postgres@v0.17.0/connection/connection.ts?s=Connection#method_startup_0). - Future startup({required bool isReconnection}) => - callFutureMethod(this, 'startup', [isReconnection]); + Future startup({required bool isReconnection}) async { + await _startup(isReconnection).toDart; + } } diff --git a/lib/src/connection_options.dart b/lib/src/connection_options.dart index c67e83f..d0ffd2c 100644 --- a/lib/src/connection_options.dart +++ b/lib/src/connection_options.dart @@ -1,47 +1,45 @@ import 'dart:js_interop'; -import 'dart:js_util'; import 'package:deno_postgres_interop/src/partial/partial_connection_options.dart'; /// [deno-postgres@v​0.17.0/ConnectionOptions](https://deno.land/x/postgres@v0.17.0/connection/connection_params.ts?s=ConnectionOptions). -@JS() -class ConnectionOptions { +@JS('ConnectionOptions') +extension type ConnectionOptions._(JSObject _) implements JSObject { /// [deno-postgres@v​0.17.0/ConnectionOptions](https://deno.land/x/postgres@v0.17.0/connection/connection_params.ts?s=ConnectionOptions#prop_attempts). external int get attempts; - /// [deno-postgres@v​0.17.0/ConnectionOptions](https://deno.land/x/postgres@v0.17.0/connection/connection_params.ts?s=ConnectionOptions). - factory ConnectionOptions({ - required int attempts, - int Function(int previousInterval)? nextInterval, - int? interval, - }) { - return jsify( - PartialConnectionOptions( - attempts: attempts, - nextInterval: nextInterval, - interval: interval, - ).asMap(), - ) as ConnectionOptions; - } -} + @JS('interval') + external JSAny? get _interval; -/// [deno-postgres@v​0.17.0/ConnectionOptions](https://deno.land/x/postgres@v0.17.0/connection/connection_params.ts?s=ConnectionOptions). -extension ConnectionOptionsProps on ConnectionOptions { /// [deno-postgres@v​0.17.0/ConnectionOptions](https://deno.land/x/postgres@v0.17.0/connection/connection_params.ts?s=ConnectionOptions#prop_interval). /// /// Either this or [interval] is null. int Function(int previousInterval)? get nextInterval { - final prop = getProperty(this, 'interval'); + final prop = _interval?.dartify(); - return prop is int ? null : prop as int Function(int previousInterval); + return prop is int ? null : prop as int Function(int previousInterval)?; } /// [deno-postgres@v​0.17.0/ConnectionOptions](https://deno.land/x/postgres@v0.17.0/connection/connection_params.ts?s=ConnectionOptions#prop_interval). /// /// Either this or [nextInterval] is null. int? get interval { - final prop = getProperty(this, 'interval'); + final prop = _interval?.dartify(); return prop is int ? prop : null; } + + /// [deno-postgres@v​0.17.0/ConnectionOptions](https://deno.land/x/postgres@v0.17.0/connection/connection_params.ts?s=ConnectionOptions). + factory ConnectionOptions({ + required int attempts, + int Function(int previousInterval)? nextInterval, + int? interval, + }) => ConnectionOptions._( + PartialConnectionOptions( + attempts: attempts, + nextInterval: nextInterval, + interval: interval, + ).asMap().jsify()! + as JSObject, + ); } diff --git a/lib/src/encoded_arg.dart b/lib/src/encoded_arg.dart index 69a8a98..a8f0a1d 100644 --- a/lib/src/encoded_arg.dart +++ b/lib/src/encoded_arg.dart @@ -1,2 +1,4 @@ +import 'dart:js_interop'; + /// [deno-postgres@v​0.17.0/EncodedArg](https://deno.land/x/postgres@v0.17.0/query/encode.ts?s=EncodedArg). -typedef EncodedArg = dynamic; +typedef EncodedArg = JSAny?; diff --git a/lib/src/errors/connection_error.dart b/lib/src/errors/connection_error.dart index 92af58b..56295cd 100644 --- a/lib/src/errors/connection_error.dart +++ b/lib/src/errors/connection_error.dart @@ -3,5 +3,5 @@ import 'dart:js_interop'; import 'package:deno_postgres_interop/src/errors/js_error.dart'; /// [deno-postgres@v​0.17.0/ConnectionError](https://deno.land/x/postgres@v0.17.0/client/error.ts?s=ConnectionError). -@JS('Error') -class ConnectionError extends JSError {} +@JS('ConnectionError') +extension type ConnectionError._(JSObject _) implements JSError, JSObject {} diff --git a/lib/src/errors/connection_params_error.dart b/lib/src/errors/connection_params_error.dart index b0179ce..635c75f 100644 --- a/lib/src/errors/connection_params_error.dart +++ b/lib/src/errors/connection_params_error.dart @@ -3,5 +3,6 @@ import 'dart:js_interop'; import 'package:deno_postgres_interop/src/errors/js_error.dart'; /// [deno-postgres@v​0.17.0/ConnectionParamsError](https://deno.land/x/postgres@v0.17.0/client/error.ts?s=ConnectionParamsError). -@JS('Error') -class ConnectionParamsError extends JSError {} +@JS('ConnectionParamsError') +extension type ConnectionParamsError._(JSObject _) + implements JSError, JSObject {} diff --git a/lib/src/errors/js_error.dart b/lib/src/errors/js_error.dart index 3b5474c..2cdfec9 100644 --- a/lib/src/errors/js_error.dart +++ b/lib/src/errors/js_error.dart @@ -2,12 +2,12 @@ import 'dart:js_interop'; /// [js/Error](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Error). @JS('Error') -class JSError { +extension type JSError._(JSObject _) implements JSObject { /// [js/Error/name](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Error/name). external String get name; /// [js/Error/cause](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Error/cause). - external Error? get cause; + external JSError? get cause; /// [js/Error/message](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Error/message). external String get message; diff --git a/lib/src/errors/postgres_error.dart b/lib/src/errors/postgres_error.dart index 191ae48..4297519 100644 --- a/lib/src/errors/postgres_error.dart +++ b/lib/src/errors/postgres_error.dart @@ -4,8 +4,8 @@ import 'package:deno_postgres_interop/src/errors/js_error.dart'; import 'package:deno_postgres_interop/src/notice.dart'; /// [deno-postgres@v​0.17.0/PostgresError](https://deno.land/x/postgres@v0.17.0/client/error.ts?s=TransactionError). -@JS() -class PostgresError extends JSError { +@JS('PostgresError') +extension type PostgresError._(JSObject _) implements JSError, JSObject { /// [deno-postgres@v​0.17.0/PostgresError](https://deno.land/x/postgres@v0.17.0/client/error.ts?s=PostgresError#prop_fields). external Notice get fields; } diff --git a/lib/src/errors/transaction_error.dart b/lib/src/errors/transaction_error.dart index dd75097..cfd07c8 100644 --- a/lib/src/errors/transaction_error.dart +++ b/lib/src/errors/transaction_error.dart @@ -3,8 +3,8 @@ import 'dart:js_interop'; import 'package:deno_postgres_interop/src/errors/postgres_error.dart'; /// [deno-postgres@v​0.17.0/TransactionError](https://deno.land/x/postgres@v0.17.0/client/error.ts?s=TransactionError). -@JS() -class TransactionError { +@JS('TransactionError') +extension type TransactionError._(JSObject _) implements JSObject { /// [js/Error/cause](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Error/cause). /// [deno-postgres@v​0.17.0/TransactionError/constructor](https://deno.land/x/postgres@v0.17.0/client/error.ts?s=TransactionError#ctor_0). external PostgresError get cause; diff --git a/lib/src/notice.dart b/lib/src/notice.dart index 9bbef3b..c4c09bc 100644 --- a/lib/src/notice.dart +++ b/lib/src/notice.dart @@ -1,9 +1,8 @@ import 'dart:js_interop'; -import 'dart:js_util'; /// [deno-postgres@v​0.17.0/Notice](https://deno.land/x/postgres@v0.17.0/connection/message.ts?s=Notice). -@JS() -class Notice { +@JS('Notice') +extension type Notice._(JSObject _) implements JSObject { /// [deno-postgres@v​0.17.0/Notice/severity](https://deno.land/x/postgres@v0.17.0/connection/message.ts?s=Notice#prop_severity). external String get severity; @@ -74,25 +73,26 @@ class Notice { String? file, String? line, String? routine, - }) { - return jsify({ - 'severity': severity, - 'code': code, - 'message': message, - if (detail != null) 'detail': detail, - if (hint != null) 'hint': hint, - if (position != null) 'position': position, - if (internalPosition != null) 'internalPosition': internalPosition, - if (internalQuery != null) 'internalQuery': internalQuery, - if (where != null) 'where': where, - if (schema != null) 'schema': schema, - if (table != null) 'table': table, - if (column != null) 'column': column, - if (dataType != null) 'dataType': dataType, - if (constraint != null) 'constraint': constraint, - if (file != null) 'file': file, - if (line != null) 'line': line, - if (routine != null) 'routine': routine, - }) as Notice; - } + }) => Notice._( + { + 'severity': severity, + 'code': code, + 'message': message, + if (detail != null) 'detail': detail, + if (hint != null) 'hint': hint, + if (position != null) 'position': position, + if (internalPosition != null) 'internalPosition': internalPosition, + if (internalQuery != null) 'internalQuery': internalQuery, + if (where != null) 'where': where, + if (schema != null) 'schema': schema, + if (table != null) 'table': table, + if (column != null) 'column': column, + if (dataType != null) 'dataType': dataType, + if (constraint != null) 'constraint': constraint, + if (file != null) 'file': file, + if (line != null) 'line': line, + if (routine != null) 'routine': routine, + }.jsify()! + as JSObject, + ); } diff --git a/lib/src/partial/partial_tls_options.dart b/lib/src/partial/partial_tls_options.dart index 0b63de6..1dae44f 100644 --- a/lib/src/partial/partial_tls_options.dart +++ b/lib/src/partial/partial_tls_options.dart @@ -18,9 +18,9 @@ class PartialTLSOptions { /// used for interop. PartialTLSOptions.fromMap(Map map) - : caCertificates = map['caCertificates'] as List?, - isEnabled = map['enabled'] as bool?, - isEnforced = map['enforced'] as bool?; + : caCertificates = map['caCertificates'] as List?, + isEnabled = map['enabled'] as bool?, + isEnforced = map['enforced'] as bool?; /// used for jsify. Map asMap() { diff --git a/lib/src/pool.dart b/lib/src/pool.dart index d43c594..fd09767 100644 --- a/lib/src/pool.dart +++ b/lib/src/pool.dart @@ -1,65 +1,91 @@ import 'dart:js_interop'; -import 'dart:js_util'; +import 'dart:js_interop_unsafe'; import 'package:deno_postgres_interop/src/client_options.dart'; import 'package:deno_postgres_interop/src/pool_client.dart'; import 'package:deno_postgres_interop/src/undefined.dart'; -import 'package:deno_postgres_interop/src/util.dart'; /// [deno-postgres@v​0.17.0/Pool](https://deno.land/x/postgres@v0.17.0/mod.ts?s=Pool). -@JS() -class Pool { +@JS('Pool') +extension type Pool._(JSObject _) implements JSObject { /// [deno-postgres@v​0.17.0/Pool/constructor](https://deno.land/x/postgres@v0.17.0/mod.ts?s=Pool#ctor_0). factory Pool({ required int size, bool? lazy, - }) => - callConstructor('Pool', [ - undefined, - size, - if (lazy != null) lazy, - ]); + }) => _createPool( + undefined, + size, + lazy, + ); /// [deno-postgres@v​0.17.0/Pool/constructor](https://deno.land/x/postgres@v0.17.0/mod.ts?s=Pool#ctor_0). factory Pool.withOptions({ required ClientOptions connectionParams, required int size, bool? lazy, - }) => - callConstructor('Pool', [ - connectionParams, - size, - if (lazy != null) lazy, - ]); + }) => _createPool( + connectionParams, + size, + lazy, + ); /// [deno-postgres@v​0.17.0/Pool/constructor](https://deno.land/x/postgres@v0.17.0/mod.ts?s=Pool#ctor_0). factory Pool.withString({ required String connectionString, required int size, bool? lazy, - }) => - callConstructor('Pool', [ - connectionString, - size, - if (lazy != null) lazy, - ]); -} + }) => _createPool( + connectionString.toJS, + size, + lazy, + ); + + static Pool _createPool([ + JSAny? connectionParamsOrString, + int? size, + bool? lazy, + ]) { + final constructor = globalContext['Pool'] as JSFunction?; + if (constructor == null) { + throw StateError('Pool constructor not found in global context.'); + } + + return constructor.callAsConstructor( + connectionParamsOrString, + size?.toJS, + lazy?.toJS, + ); + } -/// [deno-postgres@v​0.17.0/Pool](https://deno.land/x/postgres@v0.17.0/mod.ts?s=Pool). -extension PoolProps on Pool { /// [deno-postgres@v​0.17.0/Pool/size](https://deno.land/x/postgres@v0.17.0/mod.ts?s=Pool#prop_size). - int get connectionsCount => getProperty(this, 'size'); + @JS('size') + external int get connectionsCount; /// [deno-postgres@v​0.17.0/Pool/available](https://deno.land/x/postgres@v0.17.0/mod.ts?s=Pool#prop_available). - int get openConnectionsCount => getProperty(this, 'available'); + @JS('available') + external int get openConnectionsCount; + + @JS('connect') + external JSPromise _connect(); /// [deno-postgres@v​0.17.0/Pool/connect](https://deno.land/x/postgres@v0.17.0/mod.ts?s=Pool#method_connect_0). - Future connect() => callFutureMethod(this, 'connect'); + Future connect() => _connect().toDart; + + @JS('end') + external JSPromise _end(); /// [deno-postgres@v​0.17.0/Pool/end](https://deno.land/x/postgres@v0.17.0/mod.ts?s=Pool#method_end_0). - Future end() => callFutureMethod(this, 'end'); + Future end() async { + await _end().toDart; + } + + @JS('initialized') + external JSPromise _initialized(); /// [deno-postgres@v​0.17.0/Pool/initialized](https://deno.land/x/postgres@v0.17.0/mod.ts?s=Pool#method_initialized_0). - Future initializedConnectionsCount() => - callFutureMethod(this, 'initialized'); + Future initializedConnectionsCount() async { + final res = await _initialized().toDart; + + return res.toDartInt; + } } diff --git a/lib/src/pool_client.dart b/lib/src/pool_client.dart index abaea9d..0adf5db 100644 --- a/lib/src/pool_client.dart +++ b/lib/src/pool_client.dart @@ -4,12 +4,18 @@ import 'package:deno_postgres_interop/src/client_configuration.dart'; import 'package:deno_postgres_interop/src/query_client.dart'; /// [deno-postgres@v​0.17.0/PoolClient](https://deno.land/x/postgres@v0.17.0/mod.ts?s=PoolClient). -@JS() -class PoolClient extends QueryClient { +@JS('PoolClient') +extension type PoolClient._(JSObject _) implements QueryClient, JSObject { /// [deno-postgres@v​0.17.0/PoolClient/constructor](https://deno.land/x/postgres@v0.17.0/mod.ts?s=PoolClient#ctor_0). - external factory PoolClient( + factory PoolClient( ClientConfiguration config, void Function() releaseCallback, + ) => PoolClient._internal(config, releaseCallback.toJS); + + @JS('PoolClient') + external factory PoolClient._internal( + ClientConfiguration config, + JSFunction releaseCallback, ); /// [deno-postgres@v​0.17.0/PoolClient/constructor/release](https://deno.land/x/postgres@v0.17.0/mod.ts?s=PoolClient#method_release_0). diff --git a/lib/src/promise.dart b/lib/src/promise.dart index e8d3998..fc928f1 100644 --- a/lib/src/promise.dart +++ b/lib/src/promise.dart @@ -1,21 +1,9 @@ import 'dart:js_interop'; -import 'dart:js_util'; -typedef _Resolver = void Function(T result); -typedef _Executor = void Function(_Resolver resolve, Function reject); - -/// JS [Promise](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Promise) interop. -@JS() -class Promise { - /// [js/Promise/constructor](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Promise/Promise). - external Promise(_Executor executor); -} +/// JS [Promise](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Promise). +typedef Promise = JSPromise; /// Convert darts [Future] to js' [Promise]. -Promise futureToPromise(Future future) { - return Promise( - allowInterop((resolve, reject) { - future.then(resolve, onError: reject); - }), - ); +JSPromise futureToPromise(Future future) { + return future.then((value) => value?.jsify()).toJS; } diff --git a/lib/src/query.dart b/lib/src/query.dart index ecded0e..5e889c5 100644 --- a/lib/src/query.dart +++ b/lib/src/query.dart @@ -1,5 +1,4 @@ import 'dart:js_interop'; -import 'dart:js_util'; import 'package:deno_postgres_interop/src/client_common.dart'; import 'package:deno_postgres_interop/src/encoded_arg.dart'; @@ -7,25 +6,19 @@ import 'package:deno_postgres_interop/src/query_object_options.dart'; import 'package:deno_postgres_interop/src/result_type.dart'; /// [deno-postgres@v​0.17.0/Query](https://deno.land/x/postgres@v0.17.0/query/query.ts?s=Query). -@JS() -class Query { - /// [deno-postgres@v​0.17.0/Query/args](https://deno.land/x/postgres@v0.17.0/query/query.ts?s=Query#prop_args). - external List args; - - /// [deno-postgres@v​0.17.0/Query/args](https://deno.land/x/postgres@v0.17.0/query/query.ts?s=Query#prop_fields). - external List? get fields; - - /// [deno-postgres@v​0.17.0/Query/args](https://deno.land/x/postgres@v0.17.0/query/query.ts?s=Query#prop_text). - external String get text; - +@JS('Query') +extension type Query._(JSObject _) implements JSObject { /// [deno-postgres@v​0.17.0/Query/constructor](https://deno.land/x/postgres@v0.17.0/query/query.ts?s=Query#ctor_0). /// [deno-postgres@v​0.17.0/Query/constructor](https://deno.land/x/postgres@v0.17.0/query/query.ts?s=Query#ctor_2). factory Query.withConfig({ required QueryObjectOptions config, required ResultType resultType, QueryArguments? args, - }) => - callConstructor('Query', [config, resultType, args]) as Query; + }) => Query._internal( + config, + resultType.index, + args?.jsify(), + ); /// [deno-postgres@v​0.17.0/Query/constructor](https://deno.land/x/postgres@v0.17.0/query/query.ts?s=Query#ctor_1). /// [deno-postgres@v​0.17.0/Query/constructor](https://deno.land/x/postgres@v0.17.0/query/query.ts?s=Query#ctor_2). @@ -33,16 +26,44 @@ class Query { required String text, required ResultType resultType, QueryArguments? args, - }) => - callConstructor('Query', [text, resultType, args]) as Query; -} + }) => Query._internal( + text.toJS, + resultType.index, + args?.jsify(), + ); + + @JS('Query') + external factory Query._internal( + JSAny configOrText, + int resultType, + JSAny? args, + ); + + @JS('args') + external JSArray get _args; + @JS('args') + external set _args(JSArray val); + + /// [deno-postgres@v​0.17.0/Query/args](https://deno.land/x/postgres@v0.17.0/query/query.ts?s=Query#prop_args). + List get args => _args.toDart; + set args(List val) => _args = val.toJS; + + @JS('fields') + external JSArray? get _fields; + + /// [deno-postgres@v​0.17.0/Query/args](https://deno.land/x/postgres@v0.17.0/query/query.ts?s=Query#prop_fields). + List? get fields => _fields?.toDart.map((e) => e.toDart).toList(); + + /// [deno-postgres@v​0.17.0/Query/args](https://deno.land/x/postgres@v0.17.0/query/query.ts?s=Query#prop_text). + external String get text; -/// [deno-postgres@v​0.17.0/Query](https://deno.land/x/postgres@v0.17.0/query/query.ts?s=Query). -extension QueryProps on Query { /// [deno-postgres@v​0.17.0/Query/args](https://deno.land/x/postgres@v0.17.0/query/query.ts?s=Query#prop_camelcase). - bool? get isCamelCase => getProperty(this, 'camelcase'); + @JS('camelcase') + external bool? get isCamelCase; + + @JS('result_type') + external int get _resultType; /// [deno-postgres@v​0.17.0/Query/result_type](https://deno.land/x/postgres@v0.17.0/query/query.ts?s=Query#prop_result_type). - ResultType get resultType => - ResultType.values[getProperty(this, 'result_type')]; + ResultType get resultType => ResultType.values[_resultType]; } diff --git a/lib/src/query_array_result.dart b/lib/src/query_array_result.dart index 93d6803..c319b53 100644 --- a/lib/src/query_array_result.dart +++ b/lib/src/query_array_result.dart @@ -4,11 +4,17 @@ import 'package:deno_postgres_interop/src/query.dart'; import 'package:deno_postgres_interop/src/query_result.dart'; /// [deno-postgres@v​0.17.0/QueryArrayResult](https://deno.land/x/postgres@v0.17.0/query/query.ts?s=QueryArrayResult). -@JS() -class QueryArrayResult> extends QueryResult { - /// [deno-postgres@v​0.17.0/QueryArrayResult/rows](https://deno.land/x/postgres@v0.17.0/query/query.ts?s=QueryArrayResult#prop_rows). - external List get rows; - +@JS('QueryArrayResult') +extension type QueryArrayResult>._(JSObject _) + implements QueryResult, JSObject { /// [deno-postgres@v​0.17.0/QueryResult/constructor](https://deno.land/x/postgres@v0.17.0/query/query.ts?s=QueryResult#ctor_0). external factory QueryArrayResult(Query query); + + @JS('rows') + external JSArray> get _rows; + + /// [deno-postgres@v​0.17.0/QueryArrayResult/rows](https://deno.land/x/postgres@v0.17.0/query/query.ts?s=QueryArrayResult#prop_rows). + List get rows => _rows.toDart + .map((row) => row.toDart.map((e) => e?.dartify()).toList() as T) + .toList(); } diff --git a/lib/src/query_client.dart b/lib/src/query_client.dart index ae6840c..541bb52 100644 --- a/lib/src/query_client.dart +++ b/lib/src/query_client.dart @@ -1,5 +1,4 @@ import 'dart:js_interop'; -import 'dart:js_util'; import 'package:deno_postgres_interop/src/client_common.dart'; import 'package:deno_postgres_interop/src/connection.dart'; @@ -9,49 +8,56 @@ import 'package:deno_postgres_interop/src/query_object_result.dart'; import 'package:deno_postgres_interop/src/session.dart'; import 'package:deno_postgres_interop/src/transaction.dart'; import 'package:deno_postgres_interop/src/transaction_options.dart'; -import 'package:deno_postgres_interop/src/util.dart'; /// [deno-postgres@v​0.17.0/QueryClient](https://deno.land/x/postgres@v0.17.0/mod.ts?s=QueryClient). -@JS() -class QueryClient { - /// [deno-postgres@v​0.17.0/QueryClient/session](https://deno.land/x/postgres@v0.17.0/mod.ts?s=QueryClient#accessor_session). - external Session get session; - +@JS('QueryClient') +extension type QueryClient._(JSObject _) implements JSObject { /// [deno-postgres@v​0.17.0/QueryClient/constructor](https://deno.land/x/postgres@v0.17.0/mod.ts?s=QueryClient#ctor_0). external factory QueryClient(Connection connection); -} -/// [deno-postgres@v​0.17.0/QueryClient](https://deno.land/x/postgres@v0.17.0/mod.ts?s=QueryClient). -extension QueryClientProps on QueryClient { + /// [deno-postgres@v​0.17.0/QueryClient/session](https://deno.land/x/postgres@v0.17.0/mod.ts?s=QueryClient#accessor_session). + external Session get session; + /// [deno-postgres@v​0.17.0/QueryClient/connected](https://deno.land/x/postgres@v0.17.0/mod.ts?s=QueryClient#accessor_connected). - bool get isConnected => getProperty(this, 'connected'); + @JS('connected') + external bool get isConnected; + + @JS('closeConnection') + external JSPromise _closeConnection(); /// [deno-postgres@v​0.17.0/QueryClient/closeConnection](https://deno.land/x/postgres@v0.17.0/mod.ts?s=QueryClient#method_closeConnection_0). - Future closeConnection() => callFutureMethod(this, 'closeConnection'); + Future closeConnection() async { + await _closeConnection().toDart; + } /// [deno-postgres@v​0.17.0/QueryClient/resetSessionMetadata](https://deno.land/x/postgres@v0.17.0/mod.ts?s=QueryClient#method_resetSessionMetadata_0). - void resetSessionMetadata() => callMethod(this, 'resetSessionMetadata', []); + external void resetSessionMetadata(); + + @JS('connect') + external JSPromise _connect(); /// [deno-postgres@v​0.17.0/QueryClient/connect](https://deno.land/x/postgres@v0.17.0/mod.ts?s=QueryClient#method_connect_0). - Future connect() => callFutureMethod(this, 'connect'); + Future connect() async { + await _connect().toDart; + } + + @JS('end') + external JSPromise _end(); /// [deno-postgres@v​0.17.0/QueryClient/end](https://deno.land/x/postgres@v0.17.0/mod.ts?s=QueryClient#method_end_0). - Future end() => callFutureMethod(this, 'end'); + Future end() async { + await _end().toDart; + } /// [deno-postgres@v​0.17.0/QueryClient/createTransaction](https://deno.land/x/postgres@v0.17.0/mod.ts?s=QueryClient#method_createTransaction_0). - Transaction createTransaction(String name, [TransactionOptions? options]) => - callMethod( - this, - 'createTransaction', - [ - name, - if (options != null) options, - ], - ); + external Transaction createTransaction( + String name, [ + TransactionOptions? options, + ]); /// Convinience wrapper for [createTransaction], - /// [TransactionProps.begin], - /// and [TransactionProps.commit]. + /// [Transaction.begin], + /// and [Transaction.commit]. Future transaction( String name, Future Function(Transaction) f, [ @@ -69,25 +75,21 @@ extension QueryClientProps on QueryClient { Future> queryArray>( String query, [ QueryArguments? args, - ]) => - ClientCommon.queryArray(this, query, args); + ]) => ClientCommon.queryArray(this, query, args); /// [deno-postgres@v​0.17.0/QueryClient/queryArray](https://deno.land/x/postgres@v0.17.0/mod.ts?s=QueryClient#method_queryArray_1). Future> queryArrayWithOptions>( QueryObjectOptions config, - ) => - ClientCommon.queryArrayWithOptions(this, config); + ) => ClientCommon.queryArrayWithOptions(this, config); /// [deno-postgres@v​0.17.0/QueryClient/queryObject](https://deno.land/x/postgres@v0.17.0/mod.ts?s=QueryClient#method_queryObject_0). Future> queryObject( String query, [ QueryArguments? arguments, - ]) => - ClientCommon.queryObject(this, query, arguments); + ]) => ClientCommon.queryObject(this, query, arguments); /// [deno-postgres@v​0.17.0/QueryClient/queryObject](https://deno.land/x/postgres@v0.17.0/mod.ts?s=QueryClient#method_queryObject_1). Future> queryObjectWithOptions( QueryObjectOptions config, - ) => - ClientCommon.queryObjectWithOptions(this, config); + ) => ClientCommon.queryObjectWithOptions(this, config); } diff --git a/lib/src/query_object_options.dart b/lib/src/query_object_options.dart index 083e3a3..829addd 100644 --- a/lib/src/query_object_options.dart +++ b/lib/src/query_object_options.dart @@ -1,26 +1,28 @@ import 'dart:js_interop'; -import 'dart:js_util'; import 'package:deno_postgres_interop/src/query_options.dart'; /// [deno-postgres@v​0.17.0/QueryObjectOptions](https://deno.land/x/postgres@v0.17.0/mod.ts?s=QueryObjectOptions). -@JS() -class QueryObjectOptions extends QueryOptions { +@JS('QueryObjectOptions') +extension type QueryObjectOptions._(JSObject _) + implements QueryOptions, JSObject { + @JS('fields') + external JSArray? get _fields; + /// [deno-postgres@v​0.17.0/QueryObjectOptions/fields](https://deno.land/x/postgres@v0.17.0/mod.ts?s=QueryClient#prop_fields). - external List? get fields; + List? get fields => _fields?.toDart.map((e) => e.toDart).toList(); + + /// [deno-postgres@v​0.17.0/QueryObjectOptions/camelcase](https://deno.land/x/postgres@v0.17.0/mod.ts?s=QueryClient#prop_camelcase). + @JS('camelcase') + external bool? get isCamelCase; /// [deno-postgres@v​0.17.0/QueryObjectOptions](https://deno.land/x/postgres@v0.17.0/query/mod.ts?s=QueryObjectOptions). factory QueryObjectOptions({List? fields, bool? isCamelCase}) => - jsify( + QueryObjectOptions._( { - if (isCamelCase != null) 'camelcase': isCamelCase, - if (fields != null) 'fields': fields, - }, - ) as QueryObjectOptions; -} - -/// [deno-postgres@v​0.17.0/QueryObjectOptions](https://deno.land/x/postgres@v0.17.0/mod.ts?s=QueryObjectOptions). -extension QueryObjectOptionsProps on QueryObjectOptions { - /// [deno-postgres@v​0.17.0/QueryObjectOptions/camelcase](https://deno.land/x/postgres@v0.17.0/mod.ts?s=QueryClient#prop_camelcase). - bool? get isCamelCase => getProperty(this, 'camelcase'); + if (isCamelCase != null) 'camelcase': isCamelCase, + if (fields != null) 'fields': fields, + }.jsify()! + as JSObject, + ); } diff --git a/lib/src/query_object_result.dart b/lib/src/query_object_result.dart index bc98b32..f67d9ec 100644 --- a/lib/src/query_object_result.dart +++ b/lib/src/query_object_result.dart @@ -1,26 +1,27 @@ import 'dart:js_interop'; -import 'dart:js_util'; import 'package:deno_postgres_interop/src/query.dart'; import 'package:deno_postgres_interop/src/query_result.dart'; /// [deno-postgres@v​0.17.0/QueryObjectResult](https://deno.land/x/postgres@v0.17.0/query/query.ts?s=QueryObjectResult). -@JS() -class QueryObjectResult extends QueryResult { - /// [deno-postgres@v​0.17.0/QueryObjectResult/columns](https://deno.land/x/postgres@v0.17.0/query/query.ts?s=QueryObjectResult#prop_columns). - external List? get columns; - +@JS('QueryObjectResult') +extension type QueryObjectResult._(JSObject _) + implements QueryResult, JSObject { /// [deno-postgres@v​0.17.0/QueryResult/constructor](https://deno.land/x/postgres@v0.17.0/query/query.ts?s=QueryResult#ctor_0). external factory QueryObjectResult(Query query); -} -/// [deno-postgres@v​0.17.0/QueryObjectResult](https://deno.land/x/postgres@v0.17.0/query/query.ts?s=QueryObjectResult). -extension QueryObjectResultProps on QueryObjectResult { + @JS('columns') + external JSArray? get _columns; + + /// [deno-postgres@v​0.17.0/QueryObjectResult/columns](https://deno.land/x/postgres@v0.17.0/query/query.ts?s=QueryObjectResult#prop_columns). + List? get columns => _columns?.toDart.map((e) => e.toDart).toList(); + + @JS('rows') + external JSArray get _rows; + /// [deno-postgres@v​0.17.0/QueryObjectResult/rows](https://deno.land/x/postgres@v0.17.0/query/query.ts?s=QueryObjectResult#prop_rows). - List> get rows => - // ignore: cast_nullable_to_non_nullable - (dartify(getProperty(this, 'rows')) as List) - .cast>() - .map((e) => e.cast()) - .toList(); + List> get rows => (_rows.dartify()! as List) + .cast>() + .map((e) => e.cast()) + .toList(); } diff --git a/lib/src/query_options.dart b/lib/src/query_options.dart index 52e3e9e..9f43218 100644 --- a/lib/src/query_options.dart +++ b/lib/src/query_options.dart @@ -1,22 +1,32 @@ import 'dart:js_interop'; -import 'dart:js_util'; import 'package:deno_postgres_interop/src/client_common.dart'; import 'package:deno_postgres_interop/src/encoded_arg.dart'; /// [deno-postgres@v​0.17.0/QueryOptions](https://deno.land/x/postgres@v0.17.0/query/query.ts?s=QueryOptions). -@JS() -class QueryOptions { +@JS('QueryOptions') +extension type QueryOptions._(JSObject _) implements JSObject { + @JS('args') + external JSAny? get _args; + /// [deno-postgres@v​0.17.0/QueryOptions/args](https://deno.land/x/postgres@v0.17.0/query/query.ts?s=QueryOptions#prop_args). - external QueryArguments? get args; + QueryArguments? get args => _args?.dartify(); + + @JS('encoder') + external JSFunction? get _encoder; /// [deno-postgres@v​0.17.0/QueryOptions/encoder](https://deno.land/x/postgres@v0.17.0/query/query.ts?s=QueryOptions#prop_encoder). - external EncodedArg Function(dynamic arg)? get encoder; + EncodedArg Function(dynamic arg)? get encoder { + final fn = _encoder; + if (fn == null) return null; + + return (Object? arg) => fn.callAsFunction(null, arg?.jsify()); + } /// [deno-postgres@v​0.17.0/QueryOptions/name](https://deno.land/x/postgres@v0.17.0/query/query.ts?s=QueryOptions#prop_name). external String? get name; - /// [deno-postgres@v​0.17.0/QueryOptions/text](https://deno.land/x/postgres@v0.17.0/query/query.ts?s=QueryOptions#prop_text. + /// [deno-postgres@v​0.17.0/QueryOptions/text](https://deno.land/x/postgres@v0.17.0/query/query.ts?s=QueryOptions#prop_text). external String get text; /// [deno-postgres@v​0.17.0/QueryOptions](https://deno.land/x/postgres@v0.17.0/query/query.ts?s=QueryOptions). @@ -25,11 +35,14 @@ class QueryOptions { QueryArguments? args, EncodedArg Function(dynamic arg)? encoder, String? name, - }) => - jsify({ - if (args != null) 'args': args, - if (encoder != null) 'encoder': encoder, - if (name != null) 'name': name, - 'text': text, - }) as QueryOptions; + }) => QueryOptions._( + { + if (args != null) 'args': args, + if (encoder != null) + 'encoder': ((JSAny? arg) => encoder(arg?.dartify())).toJS, + if (name != null) 'name': name, + 'text': text, + }.jsify()! + as JSObject, + ); } diff --git a/lib/src/query_result.dart b/lib/src/query_result.dart index d518d15..400eeb0 100644 --- a/lib/src/query_result.dart +++ b/lib/src/query_result.dart @@ -1,5 +1,4 @@ import 'dart:js_interop'; -import 'dart:js_util'; import 'package:deno_postgres_interop/src/command_type.dart'; import 'package:deno_postgres_interop/src/notice.dart'; @@ -7,13 +6,19 @@ import 'package:deno_postgres_interop/src/query.dart'; import 'package:deno_postgres_interop/src/row_description.dart'; /// [deno-postgres@v​0.17.0/QueryResult](https://deno.land/x/postgres@v0.17.0/query/query.ts?s=QueryResult). -@JS() -class QueryResult { +@JS('QueryResult') +extension type QueryResult._(JSObject _) implements JSObject { + /// [deno-postgres@v​0.17.0/QueryResult/constructor](https://deno.land/x/postgres@v0.17.0/query/query.ts?s=QueryResult#ctor_0). + external factory QueryResult(Query query); + /// [deno-postgres@v​0.17.0/QueryResult/rowCount](https://deno.land/x/postgres@v0.17.0/query/query.ts?s=QueryResult#prop_rowCount). external int? get rowCount; + @JS('warnings') + external JSArray get _warnings; + /// [deno-postgres@v​0.17.0/QueryResult/warnings](https://deno.land/x/postgres@v0.17.0/query/query.ts?s=QueryResult#prop_warnings). - external List get warnings; + List get warnings => _warnings.toDart; /// [deno-postgres@v​0.17.0/QueryResult/constructor](https://deno.land/x/postgres@v0.17.0/query/query.ts?s=QueryResult#ctor_0). external Query get query; @@ -21,23 +26,23 @@ class QueryResult { /// [deno-postgres@v​0.17.0/QueryResult/rowDescription](https://deno.land/x/postgres@v0.17.0/query/query.ts?s=QueryResult#accessor_rowDescription). external RowDescription? get rowDescription; - /// [deno-postgres@v​0.17.0/QueryResult/constructor](https://deno.land/x/postgres@v0.17.0/query/query.ts?s=QueryResult#ctor_0). - external factory QueryResult(Query query); - /// [deno-postgres@v​0.17.0/QueryResult/handleCommandComplete](https://deno.land/x/postgres@v0.17.0/query/query.ts?s=QueryResult#method_handleCommandComplete_0). external void handleCommandComplete(String commandTag); /// [deno-postgres@v​0.17.0/QueryResult/loadColumnDescriptions](https://deno.land/x/postgres@v0.17.0/query/query.ts?s=QueryResult#method_loadColumnDescriptions_0). external void loadColumnDescriptions(RowDescription description); -} -/// [deno-postgres@v​0.17.0/QueryResult](https://deno.land/x/postgres@v0.17.0/query/query.ts?s=QueryResult). -extension QueryResultProps on QueryResult { + @JS('insertRow') + external void _insertRow(JSArray> row); + /// [deno-postgres@v​0.17.0/QueryResult/insertRow](https://deno.land/x/postgres@v0.17.0/query/query.ts?s=QueryResult#method_insertRow_0). - void insertRow(List> row) => callMethod(this, 'insertRow', [row]); + void insertRow(List> row) => _insertRow( + row.map((inner) => inner.map((e) => e.toJS).toList().toJS).toList().toJS, + ); + + @JS('command') + external String? get _command; /// [deno-postgres@v​0.17.0/QueryResult/command](https://deno.land/x/postgres@v0.17.0/query/query.ts?s=QueryResult#prop_command). - CommandType get command => CommandType.parse( - getProperty(this, 'command'), - ); + CommandType get command => CommandType.parse(_command ?? ''); } diff --git a/lib/src/result_type.dart b/lib/src/result_type.dart index a1e518d..fc9611c 100644 --- a/lib/src/result_type.dart +++ b/lib/src/result_type.dart @@ -4,5 +4,5 @@ enum ResultType { array, /// object. - object; + object, } diff --git a/lib/src/row_description.dart b/lib/src/row_description.dart index 735956a..f05b990 100644 --- a/lib/src/row_description.dart +++ b/lib/src/row_description.dart @@ -3,14 +3,24 @@ import 'dart:js_interop'; import 'package:deno_postgres_interop/src/column.dart'; /// [deno-postgres@v​0.17.0/RowDescription](https://deno.land/x/postgres@v0.17.0/query/query.ts?s=RowDescription). -@JS() -class RowDescription { +@JS('RowDescription') +extension type RowDescription._(JSObject _) implements JSObject { /// https://deno.land/x/postgres@v0.17.0/query/query.ts?s=RowDescription#ctor_0 - external int get columnCount; + factory RowDescription(int columnCount, List columns) => + RowDescription._internal(columnCount, columns.toJS); + + @JS('RowDescription') + external factory RowDescription._internal( + int columnCount, + JSArray columns, + ); /// https://deno.land/x/postgres@v0.17.0/query/query.ts?s=RowDescription#ctor_0 - external List get columns; + external int get columnCount; + + @JS('columns') + external JSArray get _columns; /// https://deno.land/x/postgres@v0.17.0/query/query.ts?s=RowDescription#ctor_0 - external factory RowDescription(int columnCount, List columns); + List get columns => _columns.toDart; } diff --git a/lib/src/savepoint.dart b/lib/src/savepoint.dart index b872af5..24d4750 100644 --- a/lib/src/savepoint.dart +++ b/lib/src/savepoint.dart @@ -1,33 +1,45 @@ import 'dart:js_interop'; -import 'dart:js_util'; import 'package:deno_postgres_interop/src/promise.dart'; -import 'package:deno_postgres_interop/src/util.dart'; /// [deno-postgres@v​0.17.0/Savepoint](https://deno.land/x/postgres@v0.17.0/mod.ts?s=Savepoint). -@JS() -class Savepoint { +@JS('Savepoint') +extension type Savepoint._(JSObject _) implements JSObject { /// [deno-postgres@v​0.17.0/Savepoint/constructor](https://deno.land/x/postgres@v0.17.0/mod.ts?s=Savepoint#ctor_0). factory Savepoint( String name, Future Function(String name) updateCallback, Future Function(String name) releaseCallback, - ) => - callConstructor('Savepoint', [ - name, - (String name) => futureToPromise(updateCallback(name)), - (String name) => futureToPromise(releaseCallback(name)), - ]); -} + ) => Savepoint._internal( + name, + ((JSString name) => futureToPromise(updateCallback(name.toDart))).toJS, + ((JSString name) => futureToPromise(releaseCallback(name.toDart))).toJS, + ); + + @JS('Savepoint') + external factory Savepoint._internal( + String name, + JSFunction updateCallback, + JSFunction releaseCallback, + ); -/// [deno-postgres@v​0.17.0/Savepoint](https://deno.land/x/postgres@v0.17.0/mod.ts?s=Savepoint). -extension SavepointProps on Savepoint { /// [deno-postgres@v​0.17.0/Savepoint/instances](https://deno.land/x/postgres@v0.17.0/mod.ts?s=Savepoint#accessor_instances). - int get instancesCount => getProperty(this, 'instances'); + @JS('instances') + external int get instancesCount; + + @JS('release') + external JSPromise _release(); /// [deno-postgres@v​0.17.0/Savepoint/instances](https://deno.land/x/postgres@v0.17.0/mod.ts?s=Savepoint#method_release_0). - Future release() => callFutureMethod(this, 'release'); + Future release() async { + await _release().toDart; + } + + @JS('update') + external JSPromise _update(); /// [deno-postgres@v​0.17.0/Savepoint/instances](https://deno.land/x/postgres@v0.17.0/mod.ts?s=Savepoint#method_update_0). - Future update() => callFutureMethod(this, 'update'); + Future update() async { + await _update().toDart; + } } diff --git a/lib/src/session.dart b/lib/src/session.dart index 3b2d40c..9474232 100644 --- a/lib/src/session.dart +++ b/lib/src/session.dart @@ -1,26 +1,26 @@ import 'dart:js_interop'; -import 'dart:js_util'; import 'package:deno_postgres_interop/src/transport.dart'; /// [deno-postgres@v​0.17.0/Session](https://deno.land/x/postgres@v0.17.0/mod.ts?s=Session). -@JS() -class Session { +@JS('Session') +extension type Session._(JSObject _) implements JSObject { /// [deno-postgres@v​0.17.0/Session/pid](https://deno.land/x/postgres@v0.17.0/mod.ts?s=Session#prop_pid) external int? get pid; /// [deno-postgres@v​0.17.0/Session/tls](https://deno.land/x/postgres@v0.17.0/mod.ts?s=Session#prop_tls) external bool? get tls; -} -/// [deno-postgres@v​0.17.0/Session](https://deno.land/x/postgres@v0.17.0/mod.ts?s=Session). -extension SessionProps on Session { /// [deno-postgres@v​0.17.0/Session/current_transaction](https://deno.land/x/postgres@v0.17.0/mod.ts?s=Session#prop_current_transaction) - String? get currentTransacton => getProperty(this, 'current_transaction'); + @JS('current_transaction') + external String? get currentTransacton; + + @JS('transport') + external String? get _transport; /// [deno-postgres@v​0.17.0/Session/transport](https://deno.land/x/postgres@v0.17.0/mod.ts?s=Session#prop_transport) Transport? get transport { - final string = getProperty(this, 'transport'); + final string = _transport; return string == null ? null : Transport.parse(string); } diff --git a/lib/src/tls_options.dart b/lib/src/tls_options.dart index 7b3f3c4..fa26391 100644 --- a/lib/src/tls_options.dart +++ b/lib/src/tls_options.dart @@ -1,30 +1,34 @@ import 'dart:js_interop'; -import 'dart:js_util'; /// [deno-postgres@v​0.17.0/TLSOptions](https://deno.land/x/postgres@v0.17.0/mod.ts?s=TLSOptions). -@JS() -class TLSOptions { +@JS('TLSOptions') +extension type TLSOptions._(JSObject _) implements JSObject { + @JS('caCertificates') + external JSArray get _caCertificates; + /// [deno-postgres@v​0.17.0/TLSOptions/caCertificates](https://deno.land/x/postgres@v0.17.0/mod.ts?s=TLSOptions#prop_caCertificates). - external List get caCertificates; + List get caCertificates => + _caCertificates.toDart.map((e) => e.toDart).toList(); + + /// [deno-postgres@v​0.17.0/TLSOptions/enabled](https://deno.land/x/postgres@v0.17.0/mod.ts?s=TLSOptions#prop_enabled). + @JS('enabled') + external bool get isEnabled; + + /// [deno-postgres@v​0.17.0/TLSOptions/enforce](https://deno.land/x/postgres@v0.17.0/mod.ts?s=TLSOptions#prop_enforce). + @JS('enforce') + external bool get isEnforced; /// [deno-postgres@v​0.17.0/TLSOptions](https://deno.land/x/postgres@v0.17.0/mod.ts?s=TLSOptions). factory TLSOptions({ required List caCertificates, required bool isEnabled, required bool isEnforced, - }) => - jsify({ - 'caCertificates': caCertificates, - 'enabled': isEnabled, - 'enforce': isEnforced, - }) as TLSOptions; -} - -/// [deno-postgres@v​0.17.0/TLSOptions](https://deno.land/x/postgres@v0.17.0/mod.ts?s=TLSOptions). -extension TLSOptionsProps on TLSOptions { - /// [deno-postgres@v​0.17.0/TLSOptions/enabled](https://deno.land/x/postgres@v0.17.0/mod.ts?s=TLSOptions#prop_enabled). - bool get isEnabled => getProperty(this, 'isEnabled'); - - /// [deno-postgres@v​0.17.0/TLSOptions/enforce](https://deno.land/x/postgres@v0.17.0/mod.ts?s=TLSOptions#prop_enforce). - bool get isEnforced => getProperty(this, 'enforce'); + }) => TLSOptions._( + { + 'caCertificates': caCertificates, + 'enabled': isEnabled, + 'enforce': isEnforced, + }.jsify()! + as JSObject, + ); } diff --git a/lib/src/transaction.dart b/lib/src/transaction.dart index 7c112e1..45de8d6 100644 --- a/lib/src/transaction.dart +++ b/lib/src/transaction.dart @@ -1,5 +1,5 @@ import 'dart:js_interop'; -import 'dart:js_util'; +import 'dart:js_interop_unsafe'; import 'package:deno_postgres_interop/src/client_common.dart'; import 'package:deno_postgres_interop/src/isolation_level.dart'; @@ -12,15 +12,10 @@ import 'package:deno_postgres_interop/src/query_object_result.dart'; import 'package:deno_postgres_interop/src/query_result.dart'; import 'package:deno_postgres_interop/src/savepoint.dart'; import 'package:deno_postgres_interop/src/transaction_options.dart'; -import 'package:deno_postgres_interop/src/undefined.dart'; -import 'package:deno_postgres_interop/src/util.dart'; /// [deno-postgres@v​0.17.0/Transaction](https://deno.land/x/postgres@v0.17.0/mod.ts?s=Transaction). -@JS() -class Transaction { - /// [deno-postgres@v​0.17.0/Transaction/savepoints](https://deno.land/x/postgres@v0.17.0/mod.ts?s=Transaction#accessor_savepoints). - external List get savepoints; - +@JS('Transaction') +extension type Transaction._(JSObject _) implements JSObject { /// [deno-postgres@v​0.17.0/Transaction/construtor](https://deno.land/x/postgres@v0.17.0/mod.ts?s=Transaction#ctor_0). factory Transaction({ required String name, @@ -28,98 +23,128 @@ class Transaction { required Future Function(Query query) executeQueryCallback, required void Function(String? name) updateClientLockCallback, TransactionOptions? options, - }) => - callConstructor( - 'Transaction', - [ - name, - if (options != null) options else undefined, - client, - (Query query) => futureToPromise(executeQueryCallback(query)), - updateClientLockCallback, - ], - ); + }) => _createTransaction( + name.toJS, + options, + client, + ((Query query) => futureToPromise(executeQueryCallback(query))).toJS, + ((JSString? name) => updateClientLockCallback(name?.toDart)).toJS, + ); + + static Transaction _createTransaction( + JSString name, + TransactionOptions? options, + QueryClient client, + JSFunction executeQueryCallback, + JSFunction updateClientLockCallback, + ) { + final constructor = globalContext['Transaction'] as JSFunction?; + if (constructor == null) { + throw StateError('Transaction constructor not found in global context.'); + } + + return constructor.callAsConstructorVarArgs([ + name, + options, + client, + executeQueryCallback, + updateClientLockCallback, + ]); + } + + @JS('savepoints') + external JSArray get _savepoints; + + /// [deno-postgres@v​0.17.0/Transaction/savepoints](https://deno.land/x/postgres@v0.17.0/mod.ts?s=Transaction#accessor_savepoints). + List get savepoints => _savepoints.toDart; /// [deno-postgres@v​0.17.0/Transaction/getSavepoint](https://deno.land/x/postgres@v0.17.0/mod.ts?s=Transaction#method_getSavepoint_0). external Savepoint? getSavepoint(String name); -} -/// [deno-postgres@v​0.17.0/Transaction](https://deno.land/x/postgres@v0.17.0/mod.ts?s=Transaction). -extension TransactionProps on Transaction { + @JS('isolation_name') + external String get _isolationName; + /// [deno-postgres@v​0.17.0/Transaction/isolation_level](https://deno.land/x/postgres@v0.17.0/mod.ts?s=Transaction#accessor_isolation_level). - IsolationLevel get isolationLevel => - IsolationLevel.parse(getProperty(this, 'isolation_name')); + IsolationLevel get isolationLevel => IsolationLevel.parse(_isolationName); + + @JS('begin') + external JSPromise _begin(); /// [deno-postgres@v​0.17.0/Transaction/begin](https://deno.land/x/postgres@v0.17.0/mod.ts?s=Transaction#method_begin_0). - Future begin() => callFutureMethod(this, 'begin'); + Future begin() async { + await _begin().toDart; + } + + @JS('commit') + external JSPromise _commit([JSObject? options]); /// [deno-postgres@v​0.17.0/Transaction/commit](https://deno.land/x/postgres@v0.17.0/mod.ts?s=Transaction#method_commit_0). - Future commit({bool? chain}) => callFutureMethod( - this, - 'commit', - [ - if (chain != null) {'chain': chain}, - ], - ); + Future commit({bool? chain}) async { + await _commit( + chain != null ? {'chain': chain}.jsify()! as JSObject : null, + ).toDart; + } + + @JS('getSavepoints') + external JSArray _getSavepoints(); /// [deno-postgres@v​0.17.0/Transaction/getSavepoints](https://deno.land/x/postgres@v0.17.0/mod.ts?s=Transaction#method_getSavepoints_0). List getActiveSavepointsNames() => - callMethod(this, 'getSavepoints', []); + _getSavepoints().toDart.map((e) => e.toDart).toList(); + + @JS('getSnapshot') + external JSPromise _getSnapshot(); /// [deno-postgres@v​0.17.0/Transaction/getSnapshot](https://deno.land/x/postgres@v0.17.0/mod.ts?s=Transaction#method_getSnapshot_0). - Future get snapshot => callFutureMethod(this, 'getSnapshot'); + Future get snapshot async { + final res = await _getSnapshot().toDart; + + return res.toDart; + } /// [deno-postgres@v​0.17.0/Transaction/queryArray](https://deno.land/x/postgres@v0.17.0/mod.ts?s=Transaction#method_queryArray_0). Future> queryArray>( String query, [ QueryArguments? args, - ]) => - ClientCommon.queryArray(this, query, args); + ]) => ClientCommon.queryArray(this, query, args); /// [deno-postgres@v​0.17.0/Transaction/queryArray](https://deno.land/x/postgres@v0.17.0/mod.ts?s=Transaction#method_queryArray_1). Future> queryArrayWithOptions>( QueryObjectOptions config, - ) => - ClientCommon.queryArrayWithOptions(this, config); + ) => ClientCommon.queryArrayWithOptions(this, config); - /// [deno-postgres@v​0.17.0/Transaction/rollback](https://deno.land/x/postgres@v0.17.0/mod.ts?s=Transaction#method_rollback_0). - Future rollback([Savepoint? savepoint]) => callFutureMethod( - this, - 'rollback', - [if (savepoint != null) savepoint], - ); + @JS('rollback') + external JSPromise _rollback([JSAny? savepointOrOptions]); - // [deno-postgres@v​0.17.0/Transaction/rollback](https://deno.land/x/postgres@v0.17.0/mod.ts?s=Transaction#method_rollback_1). - // this has the same functionality as [rollback] and [rollbackByName] - // so it won't be implemented. + /// [deno-postgres@v​0.17.0/Transaction/rollback](https://deno.land/x/postgres@v0.17.0/mod.ts?s=Transaction#method_rollback_0). + Future rollback([Savepoint? savepoint]) async { + await _rollback(savepoint).toDart; + } /// [deno-postgres@v​0.17.0/Transaction/rollback](https://deno.land/x/postgres@v0.17.0/mod.ts?s=Transaction#method_rollback_2). - Future rollbackWithChain() => callFutureMethod( - this, - 'rollback', - [ - jsify({'chain': true}), - ], - ); + Future rollbackWithChain() async { + await _rollback({'chain': true}.jsify()).toDart; + } /// [deno-postgres@v​0.17.0/Transaction/rollback](https://deno.land/x/postgres@v0.17.0/mod.ts?s=Transaction#method_rollback_0). - Future rollbackByName(String savepoint) => - callFutureMethod(this, 'rollback', [savepoint]); + Future rollbackByName(String savepoint) async { + await _rollback(savepoint.toJS).toDart; + } + + @JS('savepoint') + external JSPromise _savepoint(String name); /// [deno-postgres@v​0.17.0/Transaction/savepoint](https://deno.land/x/postgres@v0.17.0/mod.ts?s=Transaction#method_savepoint_0). - Future createSavepoint(String name) => - callFutureMethod(this, 'savepoint', [name]); + Future createSavepoint(String name) => _savepoint(name).toDart; /// [deno-postgres@v​0.17.0/Transaction/queryObject](https://deno.land/x/postgres@v0.17.0/mod.ts?s=Transaction#method_queryObject_0). Future> queryObject( String query, [ QueryArguments? arguments, - ]) => - ClientCommon.queryObject(this, query, arguments); + ]) => ClientCommon.queryObject(this, query, arguments); /// [deno-postgres@v​0.17.0/Transaction/queryObject](https://deno.land/x/postgres@v0.17.0/mod.ts?s=Transaction#method_queryObject_1). Future> queryObjectWithOptions( QueryObjectOptions config, - ) => - ClientCommon.queryObjectWithOptions(this, config); + ) => ClientCommon.queryObjectWithOptions(this, config); } diff --git a/lib/src/transaction_options.dart b/lib/src/transaction_options.dart index fa23292..dfc8075 100644 --- a/lib/src/transaction_options.dart +++ b/lib/src/transaction_options.dart @@ -1,36 +1,38 @@ import 'dart:js_interop'; -import 'dart:js_util'; import 'package:deno_postgres_interop/src/isolation_level.dart'; /// [deno-postgres@v​0.17.0/TransactionOptions](https://deno.land/x/postgres@v0.17.0/mod.ts?s=TransactionOptions). -@JS() -class TransactionOptions { +@JS('TransactionOptions') +extension type TransactionOptions._(JSObject _) implements JSObject { /// [deno-postgres@v​0.17.0/TransactionOptions/snapshot](https://deno.land/x/postgres@v0.17.0/mod.ts?s=TransactionOptions). external String? get snapshot; - /// [deno-postgres@v​0.17.0/TransactionOptions/constructor](https://deno.land/x/postgres@v0.17.0/mod.ts?s=TransactionOptions). - factory TransactionOptions({ - IsolationLevel? isolationLevel, - bool? isReadOnly, - String? snapshot, - }) => - jsify({ - if (isolationLevel != null) 'isolation_level': isolationLevel.name, - if (isReadOnly != null) 'read_only': isReadOnly, - if (snapshot != null) 'snapshot': snapshot, - }) as TransactionOptions; -} + @JS('isolation_level') + external String? get _isolationLevel; -/// [deno-postgres@v​0.17.0/TransactionOptions](https://deno.land/x/postgres@v0.17.0/mod.ts?s=TransactionOptions). -extension TransactionOptionsProps on TransactionOptions { /// [deno-postgres@v​0.17.0/TransactionOptions/isolation_level](https://deno.land/x/postgres@v0.17.0/mod.ts?s=TransactionOptions). IsolationLevel? get isolationLevel { - final jsProperty = getProperty(this, 'isolation_level'); + final jsProperty = _isolationLevel; return jsProperty == null ? null : IsolationLevel.parse(jsProperty); } /// [deno-postgres@v​0.17.0/TransactionOptions/read_only](https://deno.land/x/postgres@v0.17.0/mod.ts?s=TransactionOptions). - bool? get isReadOnly => getProperty(this, 'read_only'); + @JS('read_only') + external bool? get isReadOnly; + + /// [deno-postgres@v​0.17.0/TransactionOptions/constructor](https://deno.land/x/postgres@v0.17.0/mod.ts?s=TransactionOptions). + factory TransactionOptions({ + IsolationLevel? isolationLevel, + bool? isReadOnly, + String? snapshot, + }) => TransactionOptions._( + { + if (isolationLevel != null) 'isolation_level': isolationLevel.name, + if (isReadOnly != null) 'read_only': isReadOnly, + if (snapshot != null) 'snapshot': snapshot, + }.jsify()! + as JSObject, + ); } diff --git a/lib/src/undefined.dart b/lib/src/undefined.dart index 4615e4c..9dd3457 100644 --- a/lib/src/undefined.dart +++ b/lib/src/undefined.dart @@ -2,4 +2,4 @@ import 'dart:js_interop'; /// The js' undefined. @JS() -external dynamic get undefined; +external JSAny? get undefined; diff --git a/lib/src/util.dart b/lib/src/util.dart index 8b09a01..d84d5e0 100644 --- a/lib/src/util.dart +++ b/lib/src/util.dart @@ -1,15 +1,18 @@ -import 'dart:js_util'; +import 'dart:js_interop'; +import 'dart:js_interop_unsafe'; -/// Convinience wrapper for [promiseToFuture] and [callMethod]. +/// Convenience wrapper for promise to future call. Future callFutureMethod( - Object o, - Object method, [ + JSObject o, + String method, [ List args = const [], -]) => - promiseToFuture( - callMethod( - o, - method, - args, - ), - ); +]) async { + final jsArgs = args.map((e) => e?.jsify()).toList(); + final promise = o.callMethodVarArgs>( + method.toJS, + jsArgs, + ); + final result = await promise.toDart; + + return result?.dartify() as T; +} diff --git a/pubspec.yaml b/pubspec.yaml index 18d3298..33bc3b2 100644 --- a/pubspec.yaml +++ b/pubspec.yaml @@ -2,11 +2,11 @@ name: deno_postgres_interop description: An interop for js package deno-postgres - PostgreSQL driver that can be used in deno-deploy (supabase edge functions). -version: 0.0.4 +version: 1.0.0-dev.1 repository: https://github.com/solid-software/deno_postgres_interop environment: - sdk: ^3.0.0 + sdk: ">=3.9.0 <4.0.0" dependencies: args: ^2.4.2 @@ -14,7 +14,7 @@ dependencies: yaml: ^3.1.2 dev_dependencies: - solid_lints: ^0.0.19 + solid_lints: ^1.0.0-dev.1 platforms: web: