Skip to content
This repository has been archived by the owner on Oct 28, 2024. It is now read-only.

Commit

Permalink
Merge branch 'master' into Luzzotica/master
Browse files Browse the repository at this point in the history
  • Loading branch information
natebosch committed Feb 13, 2024
2 parents ddfed45 + 639857b commit d704ace
Show file tree
Hide file tree
Showing 17 changed files with 106 additions and 44 deletions.
8 changes: 5 additions & 3 deletions .github/dependabot.yml
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,9 @@
version: 2

updates:
- package-ecosystem: "github-actions"
directory: "/"
- package-ecosystem: github-actions
directory: /
schedule:
interval: "monthly"
interval: monthly
labels:
- autosubmit
37 changes: 37 additions & 0 deletions .github/workflows/no-response.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
# A workflow to close issues where the author hasn't responded to a request for
# more information; see https://github.com/actions/stale.

name: No Response

# Run as a daily cron.
on:
schedule:
# Every day at 8am
- cron: '0 8 * * *'

# All permissions not specified are set to 'none'.
permissions:
issues: write
pull-requests: write

jobs:
no-response:
runs-on: ubuntu-latest
if: ${{ github.repository_owner == 'dart-lang' }}
steps:
- uses: actions/stale@28ca1036281a5e5922ead5184a1bbf96e5fc984e
with:
# Don't automatically mark inactive issues+PRs as stale.
days-before-stale: -1
# Close needs-info issues and PRs after 14 days of inactivity.
days-before-close: 14
stale-issue-label: "needs-info"
close-issue-message: >
Without additional information we're not able to resolve this issue.
Feel free to add more info or respond to any questions above and we
can reopen the case. Thanks for your contribution!
stale-pr-label: "needs-info"
close-pr-message: >
Without additional information we're not able to resolve this PR.
Feel free to add more info or respond to any questions above.
Thanks for your contribution!
10 changes: 5 additions & 5 deletions .github/workflows/test-package.yml
Original file line number Diff line number Diff line change
Expand Up @@ -22,8 +22,8 @@ jobs:
matrix:
sdk: [dev]
steps:
- uses: actions/checkout@ac593985615ec2ede58e132d2e21d2b1cbd6127c
- uses: dart-lang/setup-dart@a57a6c04cf7d4840e88432aad6281d1e125f0d46
- uses: actions/checkout@b4ffde65f46336ab88eb53be808477a3936bae11
- uses: dart-lang/setup-dart@fedb1266e91cf51be2fdb382869461a434b920a3
with:
sdk: ${{ matrix.sdk }}
- id: install
Expand All @@ -47,10 +47,10 @@ jobs:
matrix:
# Add macos-latest and/or windows-latest if relevant for this package.
os: [ubuntu-latest]
sdk: [2.15.0, dev]
sdk: [2.19.0, dev]
steps:
- uses: actions/checkout@ac593985615ec2ede58e132d2e21d2b1cbd6127c
- uses: dart-lang/setup-dart@a57a6c04cf7d4840e88432aad6281d1e125f0d46
- uses: actions/checkout@b4ffde65f46336ab88eb53be808477a3936bae11
- uses: dart-lang/setup-dart@fedb1266e91cf51be2fdb382869461a434b920a3
with:
sdk: ${{ matrix.sdk }}
- id: install
Expand Down
2 changes: 2 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
## 3.0.3-dev

* Require Dart 2.19

## 3.0.2

* Switch to using `package:lints`.
Expand Down
14 changes: 12 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -12,12 +12,20 @@ A JSON-RPC 2.0 server exposes a set of methods that can be called by clients.
These methods can be registered using `Server.registerMethod`:

```dart
import 'dart:io';
import 'package:json_rpc_2/json_rpc_2.dart';
import 'package:web_socket_channel/io.dart';
import 'package:web_socket_channel/web_socket_channel.dart';
void main() {
var socket = WebSocketChannel.connect(Uri.parse('ws://localhost:4321'));
void main() async {
var httpServer = await HttpServer.bind(InternetAddress.loopbackIPv4, 4321);
var connectedChannels =
httpServer.transform(WebSocketTransformer()).map(IOWebSocketChannel.new);
connectedChannels.listen(handleClient);
}
void handleClient(WebSocketChannel socket) {
// The socket is a `StreamChannel<dynamic>` because it might emit binary
// `List<int>`, but JSON RPC 2 only works with Strings so we assert it only
// emits those by casting it.
Expand Down Expand Up @@ -122,6 +130,8 @@ void main() async {
} on RpcException catch (error) {
print('RPC error ${error.code}: ${error.message}');
}
await client.close();
}
```

Expand Down
16 changes: 8 additions & 8 deletions analysis_options.yaml
Original file line number Diff line number Diff line change
@@ -1,15 +1,15 @@
include: package:lints/recommended.yaml
include: package:dart_flutter_team_lints/analysis_options.yaml


analyzer:
language:
strict-casts: false
errors:
avoid_dynamic_calls: ignore

linter:
rules:
- always_declare_return_types
# - avoid_dynamic_calls
- avoid_unused_constructor_parameters
- cancel_subscriptions
- directives_ordering
- omit_local_variable_types
- package_api_docs
- prefer_single_quotes
- test_types_in_equals
- throw_in_finally
- unawaited_futures
2 changes: 2 additions & 0 deletions example/client.dart
Original file line number Diff line number Diff line change
Expand Up @@ -38,4 +38,6 @@ void main() async {
} on RpcException catch (error) {
print('RPC error ${error.code}: ${error.message}');
}

await client.close();
}
12 changes: 10 additions & 2 deletions example/main.dart
Original file line number Diff line number Diff line change
Expand Up @@ -2,12 +2,20 @@
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.

import 'dart:io';

import 'package:json_rpc_2/json_rpc_2.dart';
import 'package:web_socket_channel/io.dart';
import 'package:web_socket_channel/web_socket_channel.dart';

void main() {
var socket = WebSocketChannel.connect(Uri.parse('ws://localhost:4321'));
void main() async {
var httpServer = await HttpServer.bind(InternetAddress.loopbackIPv4, 4321);
var connectedChannels =
httpServer.transform(WebSocketTransformer()).map(IOWebSocketChannel.new);
connectedChannels.listen(handleClient);
}

void handleClient(WebSocketChannel socket) {
// The socket is a `StreamChannel<dynamic>` because it might emit binary
// `List<int>`, but JSON RPC 2 only works with Strings so we assert it only
// emits those by casting it.
Expand Down
12 changes: 6 additions & 6 deletions lib/src/client.dart
Original file line number Diff line number Diff line change
Expand Up @@ -56,7 +56,7 @@ class Client {
/// Creates a [Client] that communicates using decoded messages over
/// [channel].
///
/// Unlike [new Client], this doesn't read or write JSON strings. Instead, it
/// Unlike [Client.new], this doesn't read or write JSON strings. Instead, it
/// reads and writes decoded maps or lists.
///
/// Note that the client won't begin listening to [responses] until
Expand Down Expand Up @@ -113,12 +113,12 @@ class Client {
///
/// Throws a [StateError] if the client is closed while the request is in
/// flight, or if the client is closed when this method is called.
Future sendRequest(String method, [parameters, int? id]) {
var idAct = id ?? _id++;
_send(method, parameters, idAct);
Future sendRequest(String method, [Object? parameters, int? id]) {
id ??= _id++;
_send(method, parameters, id);

var completer = Completer.sync();
_pendingRequests[idAct] = _Request(method, completer, Chain.current());
_pendingRequests[id] = _Request(method, completer, Chain.current());
return completer.future;
}

Expand All @@ -134,7 +134,7 @@ class Client {
/// send a response, it has no return value.
///
/// Throws a [StateError] if the client is closed when this method is called.
void sendNotification(String method, [parameters]) =>
void sendNotification(String method, [Object? parameters]) =>
_send(method, parameters);

/// A helper method for [sendRequest] and [sendNotification].
Expand Down
2 changes: 1 addition & 1 deletion lib/src/exception.dart
Original file line number Diff line number Diff line change
Expand Up @@ -43,7 +43,7 @@ class RpcException implements Exception {

/// Converts this exception into a JSON-serializable object that's a valid
/// JSON-RPC 2.0 error response.
Map<String, dynamic> serialize(request) {
Map<String, dynamic> serialize(Object? request) {
dynamic modifiedData;
if (data is Map && !(data as Map).containsKey('request')) {
modifiedData = Map.from(data as Map);
Expand Down
6 changes: 3 additions & 3 deletions lib/src/parameters.dart
Original file line number Diff line number Diff line change
Expand Up @@ -43,7 +43,7 @@ class Parameters {
/// doesn't exist. On the other hand, if it's accessed through a method with a
/// default value like [Parameter.valueOr] or [Parameter.asNumOr], the default
/// value will be returned.
Parameter operator [](key) {
Parameter operator [](Object? key) {
if (key is int) {
_assertPositional();
if (key < value.length) {
Expand Down Expand Up @@ -156,7 +156,7 @@ class Parameter extends Parameters {
: super(method, value);

/// Returns [value], or [defaultValue] if this parameter wasn't passed.
dynamic valueOr(defaultValue) => value;
dynamic valueOr(Object? defaultValue) => value;

/// Asserts that [value] exists and is a number and returns it.
///
Expand Down Expand Up @@ -320,7 +320,7 @@ class _MissingParameter extends Parameter {
: super._(method, null, parent, key);

@override
dynamic valueOr(defaultValue) => defaultValue;
dynamic valueOr(Object? defaultValue) => defaultValue;

@override
num asNumOr(num defaultValue) => defaultValue;
Expand Down
6 changes: 3 additions & 3 deletions lib/src/peer.dart
Original file line number Diff line number Diff line change
Expand Up @@ -68,7 +68,7 @@ class Peer implements Client, Server {

/// Creates a [Peer] that communicates using decoded messages over [channel].
///
/// Unlike [new Peer], this doesn't read or write JSON strings. Instead, it
/// Unlike [Peer.new], this doesn't read or write JSON strings. Instead, it
/// reads and writes decoded maps or lists.
///
/// Note that the peer won't begin listening to [channel] until
Expand All @@ -94,11 +94,11 @@ class Peer implements Client, Server {
// Client methods.

@override
Future sendRequest(String method, [parameters, int? id]) =>
Future sendRequest(String method, [Object? parameters, int? id]) =>
_client.sendRequest(method, parameters, id);

@override
void sendNotification(String method, [parameters]) =>
void sendNotification(String method, [Object? parameters]) =>
_client.sendNotification(method, parameters);

@override
Expand Down
9 changes: 5 additions & 4 deletions lib/src/server.dart
Original file line number Diff line number Diff line change
Expand Up @@ -91,7 +91,7 @@ class Server {
/// Creates a [Server] that communicates using decoded messages over
/// [channel].
///
/// Unlike [new Server], this doesn't read or write JSON strings. Instead, it
/// Unlike [Server.new], this doesn't read or write JSON strings. Instead, it
/// reads and writes decoded maps or lists.
///
/// Note that the server won't begin listening to [requests] until
Expand Down Expand Up @@ -193,9 +193,10 @@ class Server {
}

/// Handles an individual parsed request.
Future _handleSingleRequest(request) async {
Future _handleSingleRequest(Object? request) async {
try {
_validateRequest(request);
request = request as Map;

var name = request['method'];
var method = _methods[name];
Expand All @@ -220,13 +221,13 @@ class Server {
} catch (error, stackTrace) {
if (error is RpcException) {
if (error.code == error_code.INVALID_REQUEST ||
request.containsKey('id')) {
(request is Map && request.containsKey('id'))) {
return error.serialize(request);
} else {
onUnhandledError?.call(error, stackTrace);
return null;
}
} else if (!request.containsKey('id')) {
} else if (request is Map && !request.containsKey('id')) {
onUnhandledError?.call(error, stackTrace);
return null;
}
Expand Down
2 changes: 1 addition & 1 deletion lib/src/utils.dart
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ final _exceptionPrefix = RegExp(r'^([A-Z][a-zA-Z]*)?(Exception|Error): ');
///
/// Many exceptions include the exception class name at the beginning of their
/// [toString], so we remove that if it exists.
String getErrorMessage(error) =>
String getErrorMessage(Object error) =>
error.toString().replaceFirst(_exceptionPrefix, '');

/// Like `try`/`finally`, run [body] and ensure that [whenComplete] runs
Expand Down
4 changes: 2 additions & 2 deletions pubspec.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -5,13 +5,13 @@ description: >-
repository: https://github.com/dart-lang/json_rpc_2

environment:
sdk: ">=2.12.0 <3.0.0"
sdk: ">=2.19.0 <3.0.0"

dependencies:
stack_trace: ^1.10.0
stream_channel: ^2.1.0

dev_dependencies:
lints: '>=1.0.0 < 3.0.0'
dart_flutter_team_lints: ^1.0.0
test: ^1.16.0
web_socket_channel: ^2.0.0
2 changes: 1 addition & 1 deletion test/client/utils.dart
Original file line number Diff line number Diff line change
Expand Up @@ -45,7 +45,7 @@ class ClientController {
}

/// Sends [response], a decoded response, to [client].
void sendResponse(response) {
void sendResponse(Object? response) {
sendJsonResponse(jsonEncode(response));
}

Expand Down
6 changes: 3 additions & 3 deletions test/server/utils.dart
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,7 @@ class ServerController {

/// Passes [request], a decoded request, to [server] and returns its decoded
/// response.
Future handleRequest(request) =>
Future handleRequest(Object? request) =>
handleJsonRequest(jsonEncode(request)).then(jsonDecode);

/// Passes [request], a JSON-encoded request, to [server] and returns its
Expand All @@ -47,8 +47,8 @@ class ServerController {
/// Expects that [controller]'s server will return an error response to
/// [request] with the given [errorCode], [message], and [data].
void expectErrorResponse(
ServerController controller, request, int errorCode, String message,
{data}) {
ServerController controller, Object? request, int errorCode, String message,
{Object? data}) {
dynamic id;
if (request is Map) id = request['id'];
data ??= {'request': request};
Expand Down

0 comments on commit d704ace

Please sign in to comment.