Compare commits

...

30 commits

Author SHA1 Message Date
Thomas Hii
06080c879a Updated Changelog 2024-05-21 23:51:17 +08:00
Thomas Hii
2247aae302 Updated 2024-05-21 23:38:44 +08:00
Thomas Hii
a0db187d75 Updated 2024-05-21 23:16:31 +08:00
Thomas
2decae0c3d
Merge pull request #6 from dart-backend/feature/dart3.3-support
Updated to min dart sdk 3.3
2024-05-21 23:09:26 +08:00
Thomas Hii
685419eea6 Updated to min dart sdk 3.3 2024-05-21 23:08:07 +08:00
thomashii@dukefirehawk.com
d466f2e776 Added comments 2023-12-12 10:30:48 +08:00
Thomas
42ca54ec0f
Merge pull request #5 from dart-backend/feature/upgrade_deps
Feature/upgrade deps
2023-12-12 10:24:40 +08:00
thomashii@dukefirehawk.com
8ee0fc607d Merge branch 'main' into feature/upgrade_deps 2023-12-12 10:23:31 +08:00
thomashii@dukefirehawk.com
58f63f0315 Updated to use lints 3.0.0 2023-12-12 10:10:10 +08:00
thomashii@dukefirehawk.com
dfccf23629 Updated pub_sub 2023-12-12 09:30:25 +08:00
thomashii@dukefirehawk.com
b6c1ba243a Updated lints 2023-11-16 23:52:43 +08:00
thomashii@dukefirehawk.com
0aee2f64da Updated lints 2023-11-16 23:44:09 +08:00
thomashii@dukefirehawk.com
f4a7b46cbc Upgraded library 2023-09-23 11:02:18 +08:00
thomashii
08bb59f51f Updated range_header 2023-06-24 13:28:42 +08:00
thomashii
6740e55356 Updated range_header 2023-06-24 13:24:24 +08:00
Thomas Hii
819e030a32
Merge pull request #4 from dart-backend/feature/v8
Updated body_parser
2023-05-26 23:07:40 +08:00
thomashii@dukefirehawk.com
d3946f479a Updated body_parser 2023-05-26 23:05:21 +08:00
Thomas Hii
4e320b1e44
Merge pull request #3 from dart-backend/feature/v8
Feature/v8
2023-05-16 00:05:41 +08:00
thomashii@dukefirehawk.com
ab7c3dc952 Updated to support Dart 3 2023-05-16 00:04:04 +08:00
thomashii@dukefirehawk.com
f482f16ace Upgraded to Melos 3 2023-03-26 10:15:20 +08:00
thomashii@dukefirehawk.com
1dce9a75c3 Migrated to Dart 3 2023-03-26 09:47:42 +08:00
thomashii@dukefirehawk.com
5ad3ab195d Migrated to Dart 3 2023-03-26 09:38:56 +08:00
thomashii@dukefirehawk.com
0010405bda Migrated to Dart 3 2023-03-26 09:34:19 +08:00
thomashii@dukefirehawk.com
f03bd9b3e8 Migrated to Dart 3 2023-03-26 09:28:47 +08:00
thomashii@dukefirehawk.com
5d1a917fac Migrated to Dart 3 2023-03-26 09:24:33 +08:00
thomashii@dukefirehawk.com
0bf0c487bc Migrated to Dart 3 2023-03-26 09:21:14 +08:00
thomashii@dukefirehawk.com
b439c90970 Updated README 2022-08-28 22:33:04 +08:00
thomashii@dukefirehawk.com
2d0082f3b0 Fixed body_parser analysis warnings 2022-08-28 22:11:10 +08:00
thomashii@dukefirehawk.com
ef082cb000 Updated README 2022-07-07 08:03:57 +08:00
Thomas Hii
b8cbfd95ee
Merge pull request #2 from dart-backend/feature/migrate
Updated to SDK 2.17
2022-07-06 23:21:29 +08:00
92 changed files with 750 additions and 345 deletions

1
.gitignore vendored
View file

@ -27,3 +27,4 @@ doc/api/
!.vscode/launch.json
!.vscode/extensions.json
.metals/
.DS_Store

1
.idea/.name Normal file
View file

@ -0,0 +1 @@
belatuk_common_utilities

19
.idea/modules.xml Normal file
View file

@ -0,0 +1,19 @@
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="ProjectModuleManager">
<modules>
<module fileurl="file://$PROJECT_DIR$/packages/body_parser/melos_belatuk_body_parser.iml" filepath="$PROJECT_DIR$/packages/body_parser/melos_belatuk_body_parser.iml" />
<module fileurl="file://$PROJECT_DIR$/packages/code_buffer/melos_belatuk_code_buffer.iml" filepath="$PROJECT_DIR$/packages/code_buffer/melos_belatuk_code_buffer.iml" />
<module fileurl="file://$PROJECT_DIR$/packages/combinator/melos_belatuk_combinator.iml" filepath="$PROJECT_DIR$/packages/combinator/melos_belatuk_combinator.iml" />
<module fileurl="file://$PROJECT_DIR$/packages/html_builder/melos_belatuk_html_builder.iml" filepath="$PROJECT_DIR$/packages/html_builder/melos_belatuk_html_builder.iml" />
<module fileurl="file://$PROJECT_DIR$/packages/json_serializer/melos_belatuk_json_serializer.iml" filepath="$PROJECT_DIR$/packages/json_serializer/melos_belatuk_json_serializer.iml" />
<module fileurl="file://$PROJECT_DIR$/packages/merge_map/melos_belatuk_merge_map.iml" filepath="$PROJECT_DIR$/packages/merge_map/melos_belatuk_merge_map.iml" />
<module fileurl="file://$PROJECT_DIR$/packages/pretty_logging/melos_belatuk_pretty_logging.iml" filepath="$PROJECT_DIR$/packages/pretty_logging/melos_belatuk_pretty_logging.iml" />
<module fileurl="file://$PROJECT_DIR$/packages/pub_sub/melos_belatuk_pub_sub.iml" filepath="$PROJECT_DIR$/packages/pub_sub/melos_belatuk_pub_sub.iml" />
<module fileurl="file://$PROJECT_DIR$/packages/range_header/melos_belatuk_range_header.iml" filepath="$PROJECT_DIR$/packages/range_header/melos_belatuk_range_header.iml" />
<module fileurl="file://$PROJECT_DIR$/packages/symbol_table/melos_belatuk_symbol_table.iml" filepath="$PROJECT_DIR$/packages/symbol_table/melos_belatuk_symbol_table.iml" />
<module fileurl="file://$PROJECT_DIR$/packages/user_agent/melos_user_agent_analyzer.iml" filepath="$PROJECT_DIR$/packages/user_agent/melos_user_agent_analyzer.iml" />
<module fileurl="file://$PROJECT_DIR$/melos_belatuk_common_utilities.iml" filepath="$PROJECT_DIR$/melos_belatuk_common_utilities.iml" />
</modules>
</component>
</project>

View file

@ -0,0 +1,11 @@
<!-- Generated by Melos -->
<component name="ProjectRunConfigurationManager">
<configuration default="false" name="Melos -&gt; Bootstrap Workspace" type="ShConfigurationType">
<option name="INDEPENDENT_SCRIPT_PATH" value="true" />
<option name="SCRIPT_PATH" value="$USER_HOME$/.pub-cache/bin/melos" />
<option name="SCRIPT_OPTIONS" value="bootstrap" />
<option name="INDEPENDENT_SCRIPT_WORKING_DIRECTORY" value="false" />
<option name="SCRIPT_WORKING_DIRECTORY" value="$PROJECT_DIR$" />
<method v="2" />
</configuration>
</component>

View file

@ -0,0 +1,11 @@
<!-- Generated by Melos -->
<component name="ProjectRunConfigurationManager">
<configuration default="false" name="Melos -&gt; Clean Workspace" type="ShConfigurationType">
<option name="INDEPENDENT_SCRIPT_PATH" value="true" />
<option name="SCRIPT_PATH" value="$USER_HOME$/.pub-cache/bin/melos" />
<option name="SCRIPT_OPTIONS" value="clean" />
<option name="INDEPENDENT_SCRIPT_WORKING_DIRECTORY" value="false" />
<option name="SCRIPT_WORKING_DIRECTORY" value="$PROJECT_DIR$" />
<method v="2" />
</configuration>
</component>

View file

@ -18,3 +18,6 @@ This repository contains the common utility packages required for developing dar
* [Symbol Table](https://github.com/dart-backend/belatuk-common-utilities/tree/main/packages/symbol_table)
* [User Agent](https://github.com/dart-backend/belatuk-common-utilities/tree/main/packages/user_agent)
## Donation & Support
If you like this project and interested in supporting its development, you can make a donation via [paypal](https://paypal.me/dukefirehawk?country.x=MY&locale.x=en_US) service.

4
melos.yaml Normal file
View file

@ -0,0 +1,4 @@
name: belatuk_common_utilities
packages:
- packages/*

View file

@ -0,0 +1,12 @@
<?xml version="1.0" encoding="UTF-8"?>
<module type="WEB_MODULE" version="4">
<component name="NewModuleRootManager" inherit-compiler-output="true">
<exclude-output />
<content url="file://$MODULE_DIR$">
<sourceFolder url="file://$MODULE_DIR$" isTestSource="false" />
</content>
<orderEntry type="sourceFolder" forTests="false" />
<orderEntry type="library" name="Dart SDK" level="project" />
<orderEntry type="library" name="Dart Packages" level="project" />
</component>
</module>

View file

@ -1,5 +1,34 @@
# Change Log
## 5.3.0
* Require Dart >= 3.3
* Updated `belatuk_http_server` to 4.4.0
* Updated `lints` to 4.0.0
## 5.2.0
* Updated `lints` to 3.0.0
* Updated `belatuk_http_server` to 4.2.0
## 5.1.0
* Updated `belatuk_http_server` to 4.1.1
* Updated `http` to 1.0.0
## 5.0.0
* Require Dart >= 3.0
## 5.0.0-beta.1
* Require Dart >= 3.0
* Updated `belatuk_http_server` to 4.0.0
## 4.0.1
* Updated `belatuk_http_server` to 3.0.0
## 4.0.0
* Require Dart >= 2.17

View file

@ -21,16 +21,14 @@ This is the request body parser powering the [Angel3 framework](https://pub.dev/
### About
I needed something like Express.js's `body-parser` module, so I made it here. It fully supports JSON requests. x-www-form-urlencoded fully supported, as well as query strings. You can also include arrays in your query, in the same way you would for a PHP application. Full file upload support will also be present by the production 1.0.0 release.
A benefit of this is that primitive types are automatically deserialized correctly. As in, if you have a `hello=1.5` request, then `body['hello']` will equal `1.5` and not `'1.5'`. A very semantic difference, yes, but it relieves stress in my head.
This package is similar to Express.js's `body-parser` module. It fully supports JSON, x-www-form-urlencoded as well as query strings requests. You can also include arrays in your query, in the same way you would for a PHP application. A benefit of this is that primitive types are automatically deserialized correctly. As in, if you have a `hello=1.5` request, then `body['hello']` will equal `1.5` and not `'1.5'`.
### Installation
To install Body Parser for your Dart project, simply add body_parser to your pub dependencies.
dependencies:
belatuk_body_parser: ^4.0.0
belatuk_body_parser: ^5.2.0
### Usage

View file

@ -1,14 +1,14 @@
name: belatuk_body_parser
version: 4.0.0
version: 5.3.0
description: Parse request bodies and query strings in Dart. Supports JSON, URL-encoded, and multi-part bodies.
homepage: https://github.com/dart-backend/belatuk-common-utilities/tree/main/packages/body_parser
environment:
sdk: '>=2.17.0 <3.0.0'
sdk: '>=3.3.0 <4.0.0'
dependencies:
http_parser: ^4.0.0
belatuk_http_server: ^2.0.0
belatuk_http_server: ^4.4.0
mime: ^1.0.0
dev_dependencies:
http: ^0.13.0
test: ^1.17.8
lints: ^2.0.0
http: ^1.0.0
test: ^1.24.0
lints: ^4.0.0

View file

@ -63,9 +63,7 @@ world
print('Response: ${response.body}');
var jsons = json.decode(response.body);
var files = jsons['files'].map((map) {
return map == null
? null
: map.keys.fold<Map<String, dynamic>>(
return map.keys.fold<Map<String, dynamic>>(
<String, dynamic>{}, (out, k) => out..[k.toString()] = map[k]);
});
expect(files.length, equals(0));

View file

@ -6,7 +6,7 @@ import 'package:http/http.dart' as http;
import 'package:http_parser/http_parser.dart';
import 'package:test/test.dart';
const TOKEN =
const token =
'eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJhdWQiOiIxMjcuMC4wLjEiLCJleHAiOi0xLCJpYXQiOiIyMDE2LTEyLTIyVDEyOjQ5OjUwLjM2MTQ0NiIsImlzcyI6ImFuZ2VsX2F1dGgiLCJzdWIiOiIxMDY2OTQ4Mzk2MDIwMjg5ODM2NTYifQ==.PYw7yUb-cFWD7N0sSLztP7eeRvO44nu1J2OgDNyT060=';
String jsonEncodeBody(BodyParseResult result) {
@ -89,12 +89,12 @@ void main() {
});
test('JWT', () async {
var postData = 'token=$TOKEN';
var postData = 'token=$token';
print('Body: $postData');
var response = await client!.get(Uri.parse('$url/?$postData'));
print('Response: ${response.body}');
var query = json.decode(response.body)['query'];
expect(query['token'], equals(TOKEN));
expect(query['token'], equals(token));
});
});
@ -129,11 +129,11 @@ void main() {
});
test('JWT', () async {
var postData = 'token=$TOKEN';
var postData = 'token=$token';
var response =
await client!.post(Uri.parse(url!), headers: headers, body: postData);
var body = json.decode(response.body)['body'];
expect(body['token'], equals(TOKEN));
expect(body['token'], equals(token));
});
});

View file

@ -1,5 +1,22 @@
# Change Log
## 5.2.0
* Require Dart >= 3.3
* Updated `lints` to 4.0.0
## 5.1.0
* Updated `lints` to 3.0.0
## 5.0.0
* Require Dart >= 3.0
## 5.0.0-beta.1
* Require Dart >= 3.0
## 4.0.0
* Require Dart >= 2.17

View file

@ -14,7 +14,7 @@ In your `pubspec.yaml`:
```yaml
dependencies:
belatuk_code_buffer: ^4.0.0
belatuk_code_buffer: ^5.1.0
```
## Usage

View file

@ -1,12 +1,12 @@
name: belatuk_code_buffer
version: 4.0.0
version: 5.2.0
description: An advanced StringBuffer geared toward generating code, and source maps.
homepage: https://github.com/dart-backend/belatuk-common-utilities/tree/main/packages/code_buffer
environment:
sdk: '>=2.17.0 <3.0.0'
sdk: '>=3.3.0 <4.0.0'
dependencies:
charcode: ^1.2.0
source_span: ^1.8.1
dev_dependencies:
test: ^1.17.3
lints: ^2.0.0
test: ^1.24.0
lints: ^4.0.0

View file

@ -1,5 +1,24 @@
# Change Log
## 5.2.0
* Require Dart >= 3.3
* Updated `lints` to 4.0.0
## 5.1.0
* Updated `lints` to 3.0.0
* Fixed lints warnings
## 5.0.0
* Require Dart >= 3.0
## 5.0.0-beta.1
* Require Dart >= 3.0
* Updated `belatuk_code_buffer` to 5.0.0
## 4.0.0
* Require Dart >= 2.17

View file

@ -9,8 +9,7 @@
Packrat parser combinators that support static typing, generics, file spans, memoization, and more.
**RECOMMENDED:**
Check `example/` for examples.
The examples contain examples of using:
Check `example/` for examples. The examples contain examples of using:
* Generic typing
* Reading `FileSpan` from `ParseResult`

View file

@ -1,4 +1,4 @@
part of lex.src.combinator;
part of 'combinator.dart';
class _Advance<T> extends Parser<T> {
final Parser<T> parser;

View file

@ -1,4 +1,4 @@
part of lex.src.combinator;
part of 'combinator.dart';
/// Matches any one of the given [parsers].
///

View file

@ -1,4 +1,4 @@
part of lex.src.combinator;
part of 'combinator.dart';
class _Cache<T> extends Parser<T> {
final Map<int, ParseResult<T>> _cache = {};

View file

@ -1,4 +1,4 @@
part of lex.src.combinator;
part of 'combinator.dart';
class _Cast<T, U extends T> extends Parser<U> {
final Parser<T> parser;

View file

@ -1,4 +1,4 @@
part of lex.src.combinator;
part of 'combinator.dart';
/// Expects to parse a sequence of [parsers].
///

View file

@ -1,4 +1,4 @@
part of lex.src.combinator;
part of 'combinator.dart';
class _Check<T> extends Parser<T> {
final Parser<T> parser;

View file

@ -1,4 +1,4 @@
part of lex.src.combinator;
part of 'combinator.dart';
class _Compare<T> extends ListParser<T> {
final ListParser<T> parser;

View file

@ -1,4 +1,4 @@
part of lex.src.combinator;
part of 'combinator.dart';
class _FoldErrors<T> extends Parser<T> {
final Parser<T> parser;

View file

@ -1,4 +1,4 @@
part of lex.src.combinator;
part of 'combinator.dart';
class _Index<T> extends Parser<T> {
final ListParser<T> parser;

View file

@ -1,4 +1,4 @@
part of lex.src.combinator;
part of 'combinator.dart';
/// Matches any one of the given [parsers].
///

View file

@ -1,4 +1,4 @@
part of lex.src.combinator;
part of 'combinator.dart';
class _Map<T, U> extends Parser<U> {
final Parser<T> parser;

View file

@ -1,4 +1,4 @@
part of lex.src.combinator;
part of 'combinator.dart';
/// Expects to match a given [pattern]. If it is not matched, you can provide a custom [errorMessage].
Parser<T> match<T>(Pattern pattern,

View file

@ -1,4 +1,4 @@
part of lex.src.combinator;
part of 'combinator.dart';
class _MaxDepth<T> extends Parser<T> {
final Parser<T> parser;

View file

@ -1,4 +1,4 @@
part of lex.src.combinator;
part of 'combinator.dart';
class _Negate<T> extends Parser<T> {
final Parser<T> parser;

View file

@ -1,4 +1,4 @@
part of lex.src.combinator;
part of 'combinator.dart';
class _Opt<T> extends Parser<T> {
final Parser<T> parser;

View file

@ -1,4 +1,4 @@
part of lex.src.combinator;
part of 'combinator.dart';
/*
/// Handles left recursion in a grammar using the Pratt algorithm.

View file

@ -1,4 +1,4 @@
part of lex.src.combinator;
part of 'combinator.dart';
class _Reduce<T> extends Parser<T> {
final ListParser<T> parser;

View file

@ -1,4 +1,4 @@
part of lex.src.combinator;
part of 'combinator.dart';
Reference<T> reference<T>() => Reference<T>._();

View file

@ -1,4 +1,4 @@
part of lex.src.combinator;
part of 'combinator.dart';
class _Repeat<T> extends ListParser<T> {
final Parser<T> parser;

View file

@ -1,4 +1,4 @@
part of lex.src.combinator;
part of 'combinator.dart';
class _Safe<T> extends Parser<T> {
final Parser<T> parser;

View file

@ -1,4 +1,4 @@
part of lex.src.combinator;
part of 'combinator.dart';
class _ToList<T> extends ListParser<T> {
final Parser<T> parser;

View file

@ -1,4 +1,4 @@
part of lex.src.combinator;
part of 'combinator.dart';
/// A typed parser that parses a sequence of 2 values of different types.
Parser<Tuple2<A, B>> tuple2<A, B>(Parser<A> a, Parser<B> b) {

View file

@ -1,4 +1,4 @@
part of lex.src.combinator;
part of 'combinator.dart';
class _Value<T> extends Parser<T> {
final Parser<T> parser;

View file

@ -1,15 +1,15 @@
name: belatuk_combinator
version: 4.0.0
version: 5.2.0
description: Packrat parser combinators that support static typing, generics, file spans, memoization, and more.
homepage: https://github.com/dart-backend/belatuk-common-utilities/tree/main/packages/combinator
environment:
sdk: '>=2.17.0 <3.0.0'
sdk: '>=3.3.0 <4.0.0'
dependencies:
belatuk_code_buffer: ^4.0.0
belatuk_code_buffer: ^5.0.0
matcher: ^0.12.10
source_span: ^1.8.1
string_scanner: ^1.1.0
tuple: ^2.0.0
dev_dependencies:
test: ^1.17.4
lints: ^2.0.0
test: ^1.24.0
lints: ^4.0.0

View file

@ -0,0 +1,4 @@
# melos_managed_dependency_overrides: belatuk_code_buffer
#dependency_overrides:
# belatuk_code_buffer:
# path: ../code_buffer

View file

@ -1,5 +1,22 @@
# Change Log
## 5.2.0
* Require Dart >= 3.3
* Updated `lints` to 4.0.0
## 5.1.0
* Updated `lints` to 3.0.0
## 5.0.0
* Require Dart >= 3.0
## 5.0.0-beta.1
* Require Dart >= 3.0
## 4.0.0
* Require Dart >= 2.17

View file

@ -8,17 +8,13 @@
This package builds HTML AST's and renders them to HTML. It can be used as an internal DSL, i.e. for a templating engine.
## Requirements
* Dart SDK: 2.17.x or later
## Installation
In your `pubspec.yaml`:
```yaml
dependencies:
belatuk_html_builder: ^4.0.0
belatuk_html_builder: ^5.1.0
```
## Usage

View file

@ -12,9 +12,9 @@ Node Function(Node) rebuild(NodeBuilder Function(NodeBuilder) transform,
///
/// Use this alongside [rebuild].
Node Function(Node) rebuildRecursive(Node Function(Node) f) {
Node _build(Node node) {
return NodeBuilder.from(f(node)).mapChildren(_build).build();
Node build(Node node) {
return NodeBuilder.from(f(node)).mapChildren(build).build();
}
return _build;
return build;
}

View file

@ -54,7 +54,8 @@ class SelfClosingNode extends Node {
@override
List<Node> get children => List<Node>.unmodifiable([]);
SelfClosingNode(tagName, [Map<String, dynamic> attributes = const {}])
// ignore: use_super_parameters
SelfClosingNode(String tagName, [Map<String, dynamic> attributes = const {}])
: super._selfClosing(tagName, attributes);
}

View file

@ -1,12 +1,12 @@
name: belatuk_html_builder
version: 4.0.0
version: 5.2.0
description: Build HTML AST's and render them to HTML. This can be used as an internal DSL, i.e. for a templating engine.
homepage: https://github.com/dart-backend/belatuk-common-utilities/tree/main/packages/html_builder
environment:
sdk: '>=2.17.0 <3.0.0'
sdk: '>=3.3.0 <4.0.0'
dependencies:
collection: ^1.15.0
collection: ^1.17.0
dev_dependencies:
html: ^0.15.0
test: ^1.17.4
lints: ^2.0.0
test: ^1.24.0
lints: ^4.0.0

View file

@ -1,6 +1,5 @@
import 'package:html/parser.dart' as html5;
import 'package:belatuk_html_builder/elements.dart';
import 'package:belatuk_html_builder/belatuk_html_builder.dart';
import 'package:test/test.dart';
void main() {

View file

@ -1,5 +1,27 @@
# Change Log
## 7.2.0
* Require Dart >= 3.3
* Updated `lints` to 4.0.0
## 7.1.0
* Updated `lints` to 3.0.0
* Fixed lints warnings
## 7.0.0
* Require Dart >= 3.0
## 7.0.0-beta.1
* Require Dart >= 3.0
## 6.0.1
* Updated README
## 6.0.0
* Require Dart >= 2.17

View file

@ -1,6 +1,6 @@
# Belatuk JSON Serializer
![Pub Version (including pre-releases)](https://img.shields.io/pub/v/json_serializer?include_prereleases)
![Pub Version (including pre-releases)](https://img.shields.io/pub/v/belatuk_json_serializer?include_prereleases)
[![Null Safety](https://img.shields.io/badge/null-safety-brightgreen)](https://dart.dev/null-safety)
[![Gitter](https://img.shields.io/gitter/room/angel_dart/discussion)](https://gitter.im/angel_dart/discussion)
[![License](https://img.shields.io/github/license/dart-backend/belatuk-common-utilities)](https://github.com/dart-backend/belatuk-common-utilities/blob/main/packages/json_serializer/LICENSE)
@ -11,8 +11,10 @@ The ***new and improved*** definitive solution for JSON in Dart. It supports syn
## Installation
```yaml
dependencies:
belatuk_json_serializer: ^6.0.0
belatuk_json_serializer: ^7.1.0
```
## Usage

View file

@ -1,4 +1,4 @@
part of belatuk_json_serializer;
part of '../belatuk_json_serializer.dart';
/// Deserializes a JSON string into a Dart datum.
///

View file

@ -1,4 +1,4 @@
part of belatuk_json_serializer;
part of '../belatuk_json_serializer.dart';
/// Serializes any arbitrary Dart datum to JSON. Supports schema validation.
String serialize(value) {

View file

@ -1,4 +1,4 @@
part of belatuk_json_serializer;
part of '../belatuk_json_serializer.dart';
bool _isPrimitive(value) {
return value is num || value is bool || value is String || value == null;

View file

@ -1,4 +1,4 @@
part of belatuk_json_serializer;
part of '../belatuk_json_serializer.dart';
/// Thrown when schema validation fails.
class JsonValidationError implements Exception {

View file

@ -1,12 +1,12 @@
name: belatuk_json_serializer
version: 6.0.0
version: 7.2.0
description: Easy JSON to Object serialization and deserialization in Dart.
homepage: https://github.com/dart-backend/belatuk-common-utilities/tree/main/packages/json_serializer
environment:
sdk: '>=2.17.0 <3.0.0'
sdk: '>=3.3.0 <4.0.0'
dependencies:
logging: ^1.0.1
dev_dependencies:
stack_trace: ^1.10.0
test: ^1.17.4
lints: ^2.0.0
test: ^1.24.0
lints: ^4.0.0

View file

@ -105,11 +105,11 @@ testDeserializationWithSchemaValidation() async {
god.deserialize(babelRcJson, outputType: BabelRc) as BabelRc;
print(deserialized.presets.runtimeType);
expect(deserialized.presets is List, equals(true));
//expect(deserialized.presets is List, equals(true));
expect(deserialized.presets.length, equals(2));
expect(deserialized.presets[0], equals('es2015'));
expect(deserialized.presets[1], equals('stage-0'));
expect(deserialized.plugins is List, equals(true));
//expect(deserialized.plugins is List, equals(true));
expect(deserialized.plugins.length, equals(1));
expect(deserialized.plugins[0], equals('add-module-exports'));
}

View file

@ -11,14 +11,14 @@ void printRecord(LogRecord rec) {
class SampleNestedClass {
String? bar;
SampleNestedClass([String? this.bar]);
SampleNestedClass([this.bar]);
}
class SampleClass {
String? hello;
List<SampleNestedClass> nested = [];
SampleClass([String? this.hello]);
SampleClass([this.hello]);
}
@WithSchemaUrl(
@ -27,25 +27,23 @@ class BabelRc {
List<String> presets;
List<String> plugins;
BabelRc(
{List<String> this.presets: const [],
List<String> this.plugins: const []});
BabelRc({this.presets = const [], this.plugins = const []});
}
@WithSchema(const {
@WithSchema({
r"$schema": "http://json-schema.org/draft-04/schema#",
"title": "Validated Sample Class",
"description": "Sample schema for validation via JSON God",
"type": "object",
"hello": const {"description": "A friendly greeting.", "type": "string"},
"nested": const {
"hello": {"description": "A friendly greeting.", "type": "string"},
"nested": {
"description": "A list of NestedSampleClass items within this instance.",
"type": "array",
"items": const {
"items": {
"type": "object",
"bar": const {"description": "Filler text", "type": "string"}
"bar": {"description": "Filler text", "type": "string"}
}
},
"required": const ["hello", "nested"]
"required": ["hello", "nested"]
})
class ValidatedSampleClass {}

View file

@ -8,7 +8,7 @@ main() {
test('fromJson', () {
var foo = god.deserialize('{"bar":"baz"}', outputType: Foo) as Foo;
expect(foo is Foo, true);
//expect(foo is Foo, true);
expect(foo.text, equals('baz'));
});

View file

@ -1,5 +1,22 @@
# Change Log
## 5.2.0
* Require Dart >= 3.3
* Updated `lints` to 4.0.0
## 5.1.0
* Updated `lints` to 3.0.0
## 5.0.0
* Require Dart >= 3.0
## 5.0.0-beta.1
* Require Dart >= 3.0
## 4.0.0
* Require Dart >= 2.17

View file

@ -7,8 +7,7 @@
**Replacement of `package:merge_map` with breaking changes to support NNBD.**
Combine multiple Maps into one. Equivalent to
[Object.assign](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/assign)
in JS.
[Object.assign](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/assign) in JS.
## Example

View file

@ -1,9 +1,9 @@
name: belatuk_merge_map
version: 4.0.0
version: 5.2.0
description: Combine multiple Maps into one. Equivalent to Object.assign in JS.
homepage: https://github.com/dart-backend/belatuk-common-utilities/tree/main/packages/merge_map
environment:
sdk: '>=2.17.0 <3.0.0'
sdk: '>=3.3.0 <4.0.0'
dev_dependencies:
test: ^1.17.4
lints: ^2.0.0
test: ^1.24.0
lints: ^4.0.0

View file

@ -3,8 +3,7 @@ Primary Authors
* __[Thomas Hii](dukefirehawk.apps@gmail.com)__
Thomas is the current maintainer of the code base. He has refactored and migrated the
code base to support NNBD.
Thomas is the current maintainer of the code base. He has refactored and migrated the code base to support NNBD.
* __[Tobe O](thosakwe@gmail.com)__

View file

@ -1,5 +1,22 @@
# Change Log
## 6.2.0
* Require Dart >= 3.3
* Updated `lints` to 4.0.0
## 6.1.0
* Updated `lints` to 3.0.0
## 6.0.0
* Require Dart >= 3.0
## 6.0.0-beta.1
* Require Dart >= 3.0
## 5.0.0
* Require Dart >= 2.17

View file

@ -15,7 +15,7 @@ In your `pubspec.yaml`:
```yaml
dependencies:
belatuk_pretty_logging: ^5.0.0
belatuk_pretty_logging: ^6.1.0
```
## Usage

View file

@ -1,11 +1,12 @@
name: belatuk_pretty_logging
version: 5.0.0
version: 6.2.0
description: Standalone helper for colorful logging output, using pkg:io AnsiCode.
homepage: https://github.com/dart-backend/belatuk-common-utilities/tree/main/packages/pretty_logging
environment:
sdk: '>=2.17.0 <3.0.0'
sdk: '>=3.3.0 <4.0.0'
dependencies:
io: ^1.0.0
logging: ^1.0.1
dev_dependencies:
lints: ^2.0.0
test: ^1.24.0
lints: ^4.0.0

View file

@ -0,0 +1,8 @@
import 'package:test/test.dart';
void main() {
test('test', () {
var message = "Testing";
expect(message, equals('Testing'));
});
}

View file

@ -1,5 +1,27 @@
# Change Log
## 6.3.0
* Require Dart >= 3.3
* Updated `lints` to 4.0.0
## 6.2.0
* Updated `lints` to 3.0.0
* Refactored encode/decode message handling into `MessageHandler`
## 6.1.0
* Updated `uuid` to 4.0.0
## 6.0.0
* Require Dart >= 3.0
## 6.0.0-beta.1
* Require Dart >= 3.0
## 5.0.0
* Require Dart >= 2.17

View file

@ -14,25 +14,21 @@ Add `belatuk_pub_sub` as a dependency in your `pubspec.yaml` file:
```yaml
dependencies:
belatuk_pub_sub: ^5.0.0
belatuk_pub_sub: ^6.2.0
```
Then, be sure to run `pub get` in your terminal.
Then, be sure to run `dart pub get` in your terminal.
## Usage
`belatuk_pub_sub` is your typical pub/sub API. However, `belatuk_pub_sub` enforces authentication of every
request. It is very possible that `belatuk_pub_sub` will run on both servers and in the browser,
or on a platform belatuk_pub_sublike Flutter. Thus, there are provisions available to limit
access.
request. It is very possible that `belatuk_pub_sub` will run on both server and in the browser,
or on a platform like Flutter.
**Be careful to not leak any `belatuk_pub_sub` client ID's if operating over a network.**
If you do, you risk malicious users injecting events into your application, which
could ultimately spell *disaster*.
If you do, you run the risk of malicious users injecting events into your application.
A `belatuk_pub_sub` server can operate across multiple *adapters*, which take care of interfacing data over different
media. For example, a single server can handle pub/sub between multiple Isolates and TCP Sockets, as well as
WebSockets, simultaneously.
A `belatuk_pub_sub` server can operate across multiple *adapters*, which take care of interfacing data over different media. For example, a single server can handle pub/sub between multiple Isolates and TCP Sockets, as well as WebSockets, simultaneously.
```dart
import 'package:belatuk_pub_sub/belatuk_pub_sub.dart' as pub_sub;
@ -52,13 +48,7 @@ main() async {
### Trusted Clients
You can use `package:belatuk_pub_sub` without explicitly registering
clients, *if and only if* those clients come from trusted sources.
Clients via `Isolate` are always trusted.
Clients via `package:json_rpc_2` must be explicitly marked
as trusted (i.e. using an IP whitelist mechanism):
You can use `package:belatuk_pub_sub` without explicitly registering clients, *if and only if* those clients come from trusted sources. Clients via `Isolate` are always trusted. Clients via `package:json_rpc_2` must be explicitly marked as trusted (i.e. using an IP whitelist mechanism):
```dart
JsonRpc2Adapter(..., isTrusted: false);
@ -70,9 +60,7 @@ pub_sub.IsolateClient(null);
### Access Control
The ID's of all *untrusted* clients who will connect to the server must be known at start-up time.
You may not register new clients after the server has started. This is mostly a security consideration;
if it is impossible to register new clients, then malicious users cannot grant themselves additional
privileges within the system.
You may not register new clients after the server has started. This is mostly a security consideration, to make it impossible to register new clients, thus preventing malicious users from granting themselves additional privileges within the system.
```dart
import 'package:belatuk_pub_sub/belatuk_pub_sub.dart' as pub_sub;
@ -96,10 +84,7 @@ void main() async {
### Isolates
If you are just running multiple instances of a server,
use `package:belatuk_pub_sub/isolate.dart`.
You'll need one isolate to be the master. Typically this is the first isolate you create.
If you are just running multiple instances of a server, use `package:belatuk_pub_sub/isolate.dart`. You'll need one isolate to be the master. Typically this is the first isolate you create.
```dart
import 'dart:io';
@ -157,9 +142,7 @@ Check out `test/json_rpc_2_test.dart` for an example of serving `belatuk_pub_sub
## Protocol
`belatuk_pub_sub` is built upon a simple RPC, and this package includes
an implementation that runs via `SendPort`s and `ReceivePort`s, as
well as one that runs on any `StreamChannel<String>`.
`belatuk_pub_sub` is built upon a simple RPC, and this package includes an implementation that runs via `SendPort`s and `ReceivePort`s, as well as one that runs on any `StreamChannel<String>`.
Data sent over the wire looks like the following:
@ -219,14 +202,11 @@ In the case of Isolate clients/servers, events will be simply sent as Lists:
['<event-name>', value]
```
Clients can send the following (3) methods:
Clients can send with the following 3 methods:
* `subscribe` (`event_name`:string): Subscribe to an event.
* `unsubscribe` (`subscription_id`:string): Unsubscribe from an event you previously subscribed to.
* `publish` (`event_name`:string, `value`:any): Publish an event to all other clients who are subscribed.
The client and server in `package:belatuk_pub_sub/isolate.dart` must make extra
provisions to keep track of client ID's. Since `SendPort`s and `ReceivePort`s
do not have any sort of guaranteed-unique ID's, new clients must send their
`SendPort` to the server before sending any requests. The server then responds
The client and server in `package:belatuk_pub_sub/isolate.dart` must make extra provisions to keep track of client ID's. Since `SendPort`s and `ReceivePort`s do not have any sort of guaranteed-unique ID's, new clients must send their `SendPort` to the server before sending any requests. The server then responds
with an `id` that must be used to identify a `SendPort` to send a response to.

View file

@ -1,19 +1,20 @@
import 'dart:io';
import 'dart:isolate';
import 'package:belatuk_pub_sub/isolate.dart' as pub_sub;
import 'package:belatuk_pub_sub/belatuk_pub_sub.dart' as pub_sub;
import 'package:belatuk_pub_sub/isolate.dart';
import 'package:belatuk_pub_sub/belatuk_pub_sub.dart';
void main() async {
// Easily bring up a server.
var adapter = pub_sub.IsolateAdapter();
var server = pub_sub.Server([adapter]);
var adapter = IsolateAdapter();
var server = Server([adapter]);
// You then need to create a client that will connect to the adapter.
// Every untrusted client in your application should be pre-registered.
//
// In the case of Isolates, however, those are always implicitly trusted.
print("Register Client");
for (var i = 0; i < Platform.numberOfProcessors - 1; i++) {
server.registerClient(pub_sub.ClientInfo('client$i'));
server.registerClient(ClientInfo('client$i'));
}
// Start the server.
@ -22,6 +23,7 @@ void main() async {
// Next, let's start isolates that interact with the server.
//
// Fortunately, we can send SendPorts over Isolates, so this is no hassle.
print("Create Isolate");
for (var i = 0; i < Platform.numberOfProcessors - 1; i++) {
await Isolate.spawn(isolateMain, [i, adapter.receivePort.sendPort]);
}
@ -32,7 +34,7 @@ void main() async {
void isolateMain(List args) {
// Isolates are always trusted, so technically we don't need to pass a client iD.
var client = pub_sub.IsolateClient('client${args[0]}', args[1] as SendPort);
var client = IsolateClient('client${args[0]}', args[1] as SendPort);
// The client will connect automatically. In the meantime, we can start subscribing to events.
client.subscribe('user::logged_in').then((sub) {

View file

@ -2,7 +2,9 @@ import 'dart:async';
import 'dart:collection';
import 'dart:isolate';
import 'package:uuid/uuid.dart';
import '../../belatuk_pub_sub.dart';
import '../protocol/protocol.dart';
import 'shared.dart';
/// A [Client] implementation that communicates via [SendPort]s and [ReceivePort]s.
class IsolateClient extends Client {
@ -29,33 +31,39 @@ class IsolateClient extends Client {
IsolateClient(String? clientId, this.serverSendPort) {
_clientId = clientId;
receivePort.listen((data) {
if (data is Map && data['request_id'] is String) {
var requestId = data['request_id'] as String?;
if (data is Map<String, Object?>) {
var (status, id, requestId, result, errorMessage) =
MessageHandler().decodeResponseMessage(data);
if (requestId != null) {
//var requestId = data['request_id'] as String?;
var c = _requests.remove(requestId);
if (c != null && !c.isCompleted) {
if (data['status'] is! bool) {
c.completeError(
FormatException('The server sent an invalid response.'));
} else if (!(data['status'] as bool)) {
c.completeError(PubSubException(data['error_message']?.toString() ??
//if (data['status'] is! bool) {
// c.completeError(
// FormatException('The server sent an invalid response.'));
//} else if (!(data['status'] as bool)) {
if (!status) {
c.completeError(PubSubException(errorMessage ??
'The server sent a failure response, but did not provide an error message.'));
} else if (data['result'] is! Map) {
} else if (result is! Map) {
c.completeError(FormatException(
'The server sent a success response, but did not include a result.'));
} else {
c.complete(data['result'] as Map?);
c.complete(result);
}
}
} else if (data is Map && data['id'] is String && _id == null) {
_id = data['id'] as String?;
} else if (id != null && _id == null) {
_id = id;
for (var c in _onConnect) {
if (!c.isCompleted) c.complete(_id);
}
_onConnect.clear();
} else if (data is List && data.length == 2 && data[0] is String) {
}
} else if (data is List) {
var eventName = data[0] as String;
var event = data[1];
for (var s in _subscriptions.where((s) => s.eventName == eventName)) {
@ -82,18 +90,13 @@ class IsolateClient extends Client {
var c = Completer<Map>();
var requestId = _uuid.v4();
_requests[requestId] = c;
serverSendPort.send({
'id': _id,
'request_id': requestId,
'method': 'publish',
'params': {
'client_id': clientId,
'event_name': eventName,
'value': value
}
});
serverSendPort.send(MessageHandler().encodePublishRequestMessage(
_id, requestId, clientId, eventName, value));
return c.future.then((result) {
_clientId = result['client_id'] as String?;
var (_, clientId) = MessageHandler()
.decodePublishResponseMessage(result as Map<String, Object?>);
_clientId = clientId;
});
});
}
@ -104,16 +107,14 @@ class IsolateClient extends Client {
var c = Completer<Map>();
var requestId = _uuid.v4();
_requests[requestId] = c;
serverSendPort.send({
'id': _id,
'request_id': requestId,
'method': 'subscribe',
'params': {'client_id': clientId, 'event_name': eventName}
});
serverSendPort.send(MessageHandler().encodeSubscriptionRequestMessage(
_id, requestId, clientId, eventName));
return c.future.then<ClientSubscription>((result) {
_clientId = result['client_id'] as String?;
var s = _IsolateClientSubscription(
eventName, result['subscription_id'] as String?, this);
var (subcriptionId, clientId) = MessageHandler()
.decodeSubscriptionResponseMessage(result as Map<String, Object?>);
_clientId = clientId;
var s = _IsolateClientSubscription(eventName, subcriptionId, this);
_subscriptions.add(s);
return s;
});
@ -171,14 +172,11 @@ class _IsolateClientSubscription extends ClientSubscription {
var c = Completer<Map>();
var requestId = client._uuid.v4();
client._requests[requestId] = c;
client.serverSendPort.send({
'id': client._id,
'request_id': requestId,
'method': 'unsubscribe',
'params': {'client_id': client.clientId, 'subscription_id': id}
});
client.serverSendPort.send(MessageHandler()
.encodeUnsubscriptionRequestMessage(
client._id, requestId, client.clientId, id));
return c.future.then((_) {
return c.future.then((result) {
_close();
});
});

View file

@ -1,7 +1,8 @@
import 'dart:async';
import 'dart:isolate';
import 'package:uuid/uuid.dart';
import '../../belatuk_pub_sub.dart';
import '../protocol/protocol.dart';
import 'shared.dart';
/// A [Adapter] implementation that communicates via [SendPort]s and [ReceivePort]s.
class IsolateAdapter extends Adapter {
@ -42,81 +43,50 @@ class IsolateAdapter extends Adapter {
if (data is SendPort) {
var id = _uuid.v4();
_clients[id] = data;
data.send({'status': true, 'id': id});
} else if (data is Map &&
data['id'] is String &&
data['request_id'] is String &&
data['method'] is String &&
data['params'] is Map) {
var id = data['id'] as String?,
requestId = data['request_id'] as String?,
method = data['method'] as String?;
var params = data['params'] as Map?;
var sp = _clients[id!];
data.send(MessageHandler().encodeSendPortResponseMessage(id));
} else if (data is Map<String, Object?>) {
var (id, method, requestId, params) =
MessageHandler().decodeRequestMessage(data);
var (clientId, eventName, subscriptionId, value) =
MessageHandler().decodeRequestParams(params);
var sp = _clients[id];
if (sp == null) {
// There's nobody to respond to, so don't send anything to anyone. Oops.
} else if (method == 'publish') {
if (_isValidClientId(params!['client_id']) &&
params['event_name'] is String &&
params.containsKey('value')) {
var clientId = params['client_id'] as String?,
eventName = params['event_name'] as String?;
var value = params['value'];
// There's nobody to respond to, so don't send anything to anyone
return;
}
if (method == 'publish') {
if (eventName == null || value == null) {
sp.send(MessageHandler().encodePublishResponseError(requestId));
}
var rq = _IsolatePublishRequestImpl(
requestId, clientId, eventName, value, sp);
_onPublish.add(rq);
} else {
sp.send({
'status': false,
'request_id': requestId,
'error_message': 'Expected client_id, event_name, and value.'
});
}
} else if (method == 'subscribe') {
if (_isValidClientId(params!['client_id']) &&
params['event_name'] is String) {
var clientId = params['client_id'] as String?,
eventName = params['event_name'] as String?;
if (eventName == null) {
sp.send(
MessageHandler().encodeSubscriptionResponseError(requestId));
}
var rq = _IsolateSubscriptionRequestImpl(
clientId, eventName, sp, requestId, _uuid);
_onSubscribe.add(rq);
} else {
sp.send({
'status': false,
'request_id': requestId,
'error_message': 'Expected client_id, and event_name.'
});
}
} else if (method == 'unsubscribe') {
if (_isValidClientId(params!['client_id']) &&
params['subscription_id'] is String) {
var clientId = params['client_id'] as String?,
subscriptionId = params['subscription_id'] as String?;
if (subscriptionId == null) {
sp.send(
MessageHandler().encodeUnsubscriptionResponseError(requestId));
}
var rq = _IsolateUnsubscriptionRequestImpl(
clientId, subscriptionId, sp, requestId);
_onUnsubscribe.add(rq);
} else {
sp.send({
'status': false,
'request_id': requestId,
'error_message': 'Expected client_id, and subscription_id.'
});
}
} else {
sp.send({
'status': false,
'request_id': requestId,
'error_message':
'Unrecognized method "$method". Or, you omitted id, request_id, method, or params.'
});
sp.send(MessageHandler()
.encodeUnknownMethodResponseError(requestId, method));
}
}
});
}
bool _isValidClientId(id) => id == null || id is String;
@override
bool isTrustedPublishRequest(PublishRequest request) {
// Isolate clients are considered trusted, because they are
@ -138,7 +108,7 @@ class _IsolatePublishRequestImpl extends PublishRequest {
final String? eventName;
@override
final dynamic value;
final Object? value;
final SendPort sendPort;
@ -148,24 +118,15 @@ class _IsolatePublishRequestImpl extends PublishRequest {
this.requestId, this.clientId, this.eventName, this.value, this.sendPort);
@override
void accept(PublishResponse response) {
sendPort.send({
'status': true,
'request_id': requestId,
'result': {
'listeners': response.listeners,
'client_id': response.clientId
}
});
void reject(String errorMessage) {
sendPort.send(MessageHandler()
.encodePublishResponseError(requestId, errorMessage: errorMessage));
}
@override
void reject(String errorMessage) {
sendPort.send({
'status': false,
'request_id': requestId,
'error_message': errorMessage
});
void accept(PublishResponse response) {
sendPort.send(MessageHandler().encodePublishResponseMessage2(
requestId, response.listeners, response.clientId));
}
}
@ -187,21 +148,15 @@ class _IsolateSubscriptionRequestImpl extends SubscriptionRequest {
@override
void reject(String errorMessage) {
sendPort.send({
'status': false,
'request_id': requestId,
'error_message': errorMessage
});
sendPort.send(MessageHandler().encodeSubscriptionResponseError(requestId,
errorMessage: errorMessage));
}
@override
FutureOr<Subscription> accept(String? clientId) {
var id = _uuid.v4();
sendPort.send({
'status': true,
'request_id': requestId,
'result': {'subscription_id': id, 'client_id': clientId}
});
sendPort.send(MessageHandler()
.encodeSubscriptionResponseMessage(requestId, id, clientId));
return _IsolateSubscriptionImpl(clientId, id, eventName, sendPort);
}
}
@ -239,15 +194,13 @@ class _IsolateUnsubscriptionRequestImpl extends UnsubscriptionRequest {
@override
void reject(String errorMessage) {
sendPort.send({
'status': false,
'request_id': requestId,
'error_message': errorMessage
});
sendPort.send(MessageHandler().encodeUnsubscriptionResponseError(requestId,
errorMessage: errorMessage));
}
@override
void accept() {
sendPort.send({'status': true, 'request_id': requestId, 'result': {}});
sendPort
.send(MessageHandler().encodeUnsubscriptionResponseMessage(requestId));
}
}

View file

@ -0,0 +1,183 @@
/// A message handler class that handles the encoding/decoding of messages send
/// between isolate [Client] and [Server].
class MessageHandler {
static const _requestId = 'request_id';
static const _method = 'method';
static const _clientId = 'client_id';
static const _eventName = 'event_name';
static const _subscriptionId = 'subscription_id';
static const _errorMessage = 'error_message';
static const _value = 'value';
static const _id = 'id';
static const _params = 'params';
static const _status = 'status';
static const _result = 'result';
static const _listeners = 'listeners';
static const _publishErrorMsg = 'Expected client_id, event_name, and value';
static const _subscribeErrorMsg = 'Expected client_id, and event_name';
static const _unsubscribeErrorMsg = 'Expected client_id, and subscription_id';
const MessageHandler();
Map<String, dynamic> encodePublishResponseError(String? requestId,
{String errorMessage = _publishErrorMsg}) {
return _encodeResponseError(requestId, errorMessage);
}
Map<String, dynamic> encodeSubscriptionResponseError(String? requestId,
{String errorMessage = _subscribeErrorMsg}) {
return _encodeResponseError(requestId, errorMessage);
}
Map<String, dynamic> encodeUnsubscriptionResponseError(String? requestId,
{String errorMessage = _unsubscribeErrorMsg}) {
return _encodeResponseError(requestId, errorMessage);
}
Map<String, dynamic> encodeUnknownMethodResponseError(
String? requestId, String method) {
var unknownMethodErrorMsg =
'Unrecognized method "$method" or you have omitted id, request_id, method, or params';
return _encodeResponseError(requestId, unknownMethodErrorMsg);
}
Map<String, dynamic> _encodeResponseError(String? requestId, String message) {
return {
_status: false,
_requestId: requestId ?? '',
_errorMessage: message
};
}
Map<String, dynamic> encodeEventMessage(String? requestId, Object message) {
return {_status: true, _requestId: requestId ?? '', _result: message};
}
Map<String, dynamic> encodeSubscriptionResponseMessage(
String? requestId, String? subscriptionId, String? clientId) {
return {
_status: true,
_requestId: requestId ?? '',
_result: {_subscriptionId: subscriptionId, _clientId: clientId}
};
}
(String?, String?) decodeSubscriptionResponseMessage(
Map<String, Object?> message) {
var subscriptionId = message[_subscriptionId] as String?;
var clientId = message[_clientId] as String?;
return (subscriptionId, clientId);
}
Map<String, dynamic> encodeUnsubscriptionResponseMessage(String? requestId) {
return {_status: true, _requestId: requestId, _result: {}};
}
(bool, String?, Object?, String?) decodeUnsubscriptionResponseMessage(
Map<String, Object?> message) {
var status = message[_status] as bool? ?? false;
var requestId = message[_requestId] as String?;
var result = message[_result];
var errorMessage = message[_errorMessage] as String?;
return (status, requestId, result, errorMessage);
}
Map<String, Object?> encodePublishResponseMessage2(
String? requestId, int listeners, String? clientId) {
return {
_status: true,
_requestId: requestId,
_result: {_listeners: listeners, _clientId: clientId}
};
}
(int, String?) decodePublishResponseMessage(Map<String, Object?> message) {
var listeners = message[_listeners] as int;
var clientId = message[_clientId] as String?;
return (listeners, clientId);
}
Map<String, Object?> encodePublishResponseMessage(String? id,
String? requestId, String? clientId, String? eventName, Object? value) {
return {
_id: id,
_requestId: requestId,
_method: 'publish',
_params: {_clientId: clientId, _eventName: eventName, _value: value}
};
}
Map<String, dynamic> encodeResponseMessage(
String? requestId, Object message) {
return {_status: true, _requestId: requestId ?? '', _result: message};
}
(bool, String?, String?, Object?, String?) decodeResponseMessage(
Map<String, Object?> message) {
var id = message[_id] as String?;
var status = message[_status] as bool? ?? false;
var requestId = message[_requestId] as String?;
var result = message[_result];
var errorMessage = message[_errorMessage] as String?;
return (status, id, requestId, result, errorMessage);
}
(String, String, String, Map<String, Object?>) decodeRequestMessage(
Map<String, Object?> message) {
var id = message[_id] as String? ?? '';
var method = message[_method] as String? ?? '';
var requestId = message[_requestId] as String? ?? '';
var params = message[_params] as Map<String, Object?>? ?? {};
return (id, method, requestId, params);
}
Map<String, Object?> encodeSubscriptionRequestMessage(
String? id, String? requestId, String? clientId, String? eventName) {
return {
_id: id,
_requestId: requestId,
_method: 'subscribe',
_params: {_clientId: clientId, _eventName: eventName}
};
}
Map<String, Object?> encodeUnsubscriptionRequestMessage(
String? id, String? requestId, String? clientId, String? subscriptionId) {
return {
_id: id,
_requestId: requestId,
_method: 'unsubscribe',
_params: {_clientId: clientId, _subscriptionId: subscriptionId}
};
}
Map<String, Object?> encodePublishRequestMessage(String? id,
String? requestId, String? clientId, String? eventName, Object? value) {
return {
_id: id,
_requestId: requestId,
_method: 'publish',
_params: {_clientId: clientId, _eventName: eventName, _value: value}
};
}
(String?, String?, String?, Object?) decodeRequestParams(
Map<String, Object?> params) {
var clientId = params[_clientId] as String?;
var eventName = params[_eventName] as String?;
var value = params[_value];
var subscriptionId = params[_subscriptionId] as String?;
return (clientId, eventName, subscriptionId, value);
}
Map<String, Object> encodeSendPortResponseMessage(String id) {
return {_status: true, _id: id};
}
}

View file

@ -7,7 +7,7 @@ abstract class PublishRequest {
String? get eventName;
/// The value to be published as an event.
dynamic get value;
Object? get value;
/// Accept the request, with a response.
void accept(PublishResponse response);

View file

@ -1,14 +1,14 @@
name: belatuk_pub_sub
version: 5.0.0
version: 6.3.0
description: Keep application instances in sync with a simple pub/sub API.
homepage: https://github.com/dart-backend/belatuk-common-utilities/tree/main/packages/pub_sub
environment:
sdk: '>=2.17.0 <3.0.0'
sdk: '>=3.3.0 <4.0.0'
dependencies:
json_rpc_2: ^3.0.0
stream_channel: ^2.1.0
uuid: ^3.0.4
collection: ^1.15.0
uuid: ^4.0.0
collection: ^1.17.0
dev_dependencies:
lints: ^2.0.0
test: ^1.17.4
test: ^1.24.0
lints: ^4.0.0

View file

@ -157,7 +157,7 @@ class _SocketStreamChannel extends StreamChannelMixin<List<int>> {
Stream<List<int>> get stream => socket;
}
class _SocketSink extends StreamSink<List<int>> {
class _SocketSink implements StreamSink<List<int>> {
final Socket socket;
_SocketSink(this.socket);

View file

@ -1,5 +1,27 @@
# Change Log
## 6.3.0
* Require Dart >= 3.3
* Updated `lints` to 4.0.0
## 6.2.0
* Updated `lints` to 3.0.0
## 6.1.0
* Updated `file` to 7.0.0
## 6.0.0
* Require Dart >= 3.0
* Updated all dependencies to latest
## 6.0.0-beta.1
* Require Dart >= 3.0
## 5.0.0
* Require Dart >= 2.17

View file

@ -14,7 +14,7 @@ In your `pubspec.yaml`:
```yaml
dependencies:
belatuk_range_header: ^5.0.0
belatuk_range_header: ^6.2.0
```
## Usage

View file

@ -15,7 +15,9 @@ void handleRequest(HttpRequest request) async {
// Get info
header.items;
header.rangeUnit;
header.items.forEach((item) => item.toContentRange(400));
for (var item in header.items) {
item.toContentRange(400);
}
// Serve the file
var transformer =

View file

@ -1,7 +1,9 @@
import 'dart:async';
import 'dart:collection';
import 'dart:convert';
import 'dart:io' show BytesBuilder;
//import 'dart:io' hide BytesBuilder;
import 'dart:typed_data';
import 'dart:math';
import 'package:async/async.dart';
import 'package:charcode/ascii.dart';

View file

@ -1,8 +1,8 @@
class RangeHeaderParseException extends FormatException {
@override
final String message;
//@override
//final String message;
RangeHeaderParseException(this.message);
RangeHeaderParseException(super.message);
@override
String toString() => 'Range header parse exception: $message';

View file

@ -9,7 +9,7 @@ import 'range_header_item.dart';
final RegExp _rgxInt = RegExp(r'[0-9]+');
final RegExp _rgxWs = RegExp(r'[ \n\r\t]');
enum TokenType { RANGE_UNIT, COMMA, INT, DASH, EQUALS }
enum TokenType { rangeUnit, comma, int, dash, equals }
class Token {
final TokenType type;
@ -27,19 +27,19 @@ List<Token> scan(String text, List<String> allowedRangeUnits) {
scanner.scan(_rgxWs);
if (scanner.scanChar($comma)) {
tokens.add(Token(TokenType.COMMA, scanner.lastSpan));
tokens.add(Token(TokenType.comma, scanner.lastSpan));
} else if (scanner.scanChar($dash)) {
tokens.add(Token(TokenType.DASH, scanner.lastSpan));
tokens.add(Token(TokenType.dash, scanner.lastSpan));
} else if (scanner.scan(_rgxInt)) {
tokens.add(Token(TokenType.INT, scanner.lastSpan));
tokens.add(Token(TokenType.int, scanner.lastSpan));
} else if (scanner.scanChar($equal)) {
tokens.add(Token(TokenType.EQUALS, scanner.lastSpan));
tokens.add(Token(TokenType.equals, scanner.lastSpan));
} else {
var matched = false;
for (var unit in allowedRangeUnits) {
if (scanner.scan(unit)) {
tokens.add(Token(TokenType.RANGE_UNIT, scanner.lastSpan));
tokens.add(Token(TokenType.rangeUnit, scanner.lastSpan));
matched = true;
break;
}
@ -98,9 +98,9 @@ class Parser {
}
RangeHeader? parseRangeHeader() {
if (next(TokenType.RANGE_UNIT)) {
if (next(TokenType.rangeUnit)) {
var unit = current!.span!.text;
next(TokenType.EQUALS); // Consume =, if any.
next(TokenType.equals); // Consume =, if any.
var items = <RangeHeaderItem>[];
var item = parseHeaderItem();
@ -108,7 +108,7 @@ class Parser {
while (item != null) {
items.add(item);
// Parse comma
if (next(TokenType.COMMA)) {
if (next(TokenType.comma)) {
item = parseHeaderItem();
} else {
item = null;
@ -126,11 +126,11 @@ class Parser {
}
RangeHeaderItem? parseHeaderItem() {
if (next(TokenType.INT)) {
if (next(TokenType.int)) {
// i.e 500-544, or 600-
var start = int.parse(current!.span!.text);
if (next(TokenType.DASH)) {
if (next(TokenType.INT)) {
if (next(TokenType.dash)) {
if (next(TokenType.int)) {
return RangeHeaderItem(start, int.parse(current!.span!.text));
} else {
return RangeHeaderItem(start);
@ -138,9 +138,9 @@ class Parser {
} else {
throw _expected('"-"');
}
} else if (next(TokenType.DASH)) {
} else if (next(TokenType.dash)) {
// i.e. -599
if (next(TokenType.INT)) {
if (next(TokenType.int)) {
return RangeHeaderItem(-1, int.parse(current!.span!.text));
} else {
throw _expected('integer');

View file

@ -1,18 +1,18 @@
name: belatuk_range_header
version: 5.0.0
version: 6.3.0
description: Range header parser for Dart. Beyond parsing, a stream transformer is included.
homepage: https://github.com/dart-backend/belatuk-common-utilities/tree/main/packages/range_header
environment:
sdk: '>=2.17.0 <3.0.0'
sdk: '>=3.3.0 <4.0.0'
dependencies:
async: ^2.6.0
charcode: ^1.2.0
quiver: ^3.0.1
source_span: ^1.8.1
string_scanner: ^1.1.0
async: ^2.11.0
charcode: ^1.3.0
quiver: ^3.2.0
source_span: ^1.10.0
string_scanner: ^1.2.0
dev_dependencies:
file: ^6.1.0
file: ^7.0.0
http_parser: ^4.0.0
logging: ^1.0.1
test: ^1.17.8
lints: ^2.0.0
test: ^1.24.0
lints: ^4.0.0

View file

@ -1,5 +1,23 @@
# Change Log
## 5.2.0
* Require Dart >= 3.3
* Updated `lints` to 4.0.0
## 5.1.0
* Updated `lints` to 3.0.0
* Fixed lints warnings
## 5.0.0
* Require Dart >= 3.0
## 5.0.0-beta.1
* Require Dart >= 3.0
## 4.0.0
* Require Dart >= 2.17

View file

@ -12,8 +12,7 @@ and utilize basic memoization to speed up repeated lookups.
## Variables
To represent a symbol, use `Variable`. I opted for the name
`Variable` to avoid conflict with the Dart primitive `Symbol`.
To represent a symbol, use `Variable`. I opted for the name `Variable` to avoid conflict with the Dart primitive `Symbol`.
```dart
var foo = Variable<String>('foo');
@ -31,8 +30,7 @@ foo.value = 'baz'; // Also throws a StateError - Once a variable is locked, it c
## Visibility
Variables are *public* by default, but can also be marked as *private* or *protected*. This can be helpful if you are trying
to determine which symbols should be exported from a library or class.
Variables are *public* by default, but can also be marked as *private* or *protected*. This can be helpful if you are trying to determine which symbols should be exported from a library or class.
```dart
myVariable.visibility = Visibility.protected;

View file

@ -1,4 +1,4 @@
part of symbol_table;
part of 'symbol_table.dart';
/// Holds a symbol, the value of which may change or be marked immutable.
class Variable<T> {

View file

@ -1,4 +1,4 @@
part of symbol_table;
part of 'symbol_table.dart';
/// Represents the visibility of a symbol.
///

View file

@ -1,11 +1,11 @@
name: belatuk_symbol_table
version: 4.0.0
version: 5.2.0
description: A generic symbol table implementation in Dart, with support for scopes and constants.
homepage: https://github.com/dart-backend/belatuk-common-utilities/tree/main/packages/symbol_table
environment:
sdk: '>=2.17.0 <3.0.0'
sdk: '>=3.3.0 <4.0.0'
dependencies:
collection: ^1.15.0
collection: ^1.17.0
dev_dependencies:
test: ^1.17.4
lints: ^2.0.0
test: ^1.24.0
lints: ^4.0.0

View file

@ -1,5 +1,22 @@
# Change Log
## 5.2.0
* Require Dart >= 3.3
* Updated `lints` to 4.0.0
## 5.1.0
* Updated `lints` to 3.0.0
## 5.0.0
* Require Dart >= 3.0
## 5.0.0-beta.1
* Require Dart >= 3.0
## 4.0.0
* Require Dart >= 2.17

View file

@ -1,9 +1,9 @@
name: user_agent_analyzer
version: 4.0.0
version: 5.2.0
description: A library to identify the type of devices and web browsers based on User-Agent string.
homepage: https://github.com/dart-backend/belatuk-common-utilities/tree/main/packages/user_agent
environment:
sdk: '>=2.17.0 <3.0.0'
sdk: '>=3.3.0 <4.0.0'
dev_dependencies:
test: ^1.17.8
lints: ^2.0.0
test: ^1.24.0
lints: ^4.0.0

6
pubspec.yaml Normal file
View file

@ -0,0 +1,6 @@
name: belatuk_common_utilities_workspace
environment:
sdk: '>=3.3.0 <4.0.0'
dev_dependencies:
melos: ^6.0.0