Repository: dukefirehawk/angel Branch: master Commit: 2224e8985da6 Files: 552 Total size: 1.8 MB Directory structure: gitextract_l8l0_3lv/ ├── .devcontainer/ │ └── devcontainer.json ├── .github/ │ ├── FUNDING.yml │ └── workflows/ │ └── dart.yml ├── .gitignore ├── .pubignore ├── .vscode/ │ └── settings.json ├── AI_CONTEXT.md ├── AUTHORS.md ├── CHANGELOG.md ├── CONTRIBUTING.md ├── LICENSE ├── README.md ├── TODO.md ├── archived/ │ └── tool/ │ └── archived/ │ ├── move_repos │ └── pull_subproject ├── belatuk.session.sql ├── doc/ │ └── deployment/ │ ├── docker/ │ │ ├── README.md │ │ ├── docker-compose-mariadb.yml │ │ ├── docker-compose-mongo.yml │ │ ├── docker-compose-mysql.yml │ │ ├── docker-compose-pg.yml │ │ ├── docker-compose-redis.yml │ │ └── docker-compose-rethinkdb.yml │ ├── helm_chart/ │ │ └── README.md │ ├── podman/ │ │ ├── README.md │ │ ├── podman-compose-mariadb.yml │ │ ├── podman-compose-mongo.yml │ │ ├── podman-compose-mysql.yml │ │ ├── podman-compose-pg.yml │ │ ├── podman-compose-redis.yml │ │ └── podman-compose-rethinkdb.yml │ └── rancher/ │ ├── README.md │ ├── rancher-compose-mariadb.yml │ ├── rancher-compose-mongo.yml │ ├── rancher-compose-mysql.yml │ ├── rancher-compose-pg.yml │ ├── rancher-compose-redis.yml │ └── rancher-compose-rethinkdb.yml ├── melos.yaml ├── melos_angel3.iml ├── packages/ │ ├── cache/ │ │ ├── .gitignore │ │ ├── AUTHORS.md │ │ ├── CHANGELOG.md │ │ ├── LICENSE │ │ ├── README.md │ │ ├── analysis_options.yaml │ │ ├── example/ │ │ │ ├── cache_service.dart │ │ │ └── main.dart │ │ ├── lib/ │ │ │ ├── angel3_cache.dart │ │ │ └── src/ │ │ │ ├── cache.dart │ │ │ ├── cache_service.dart │ │ │ └── serializer.dart │ │ ├── melos_angel3_cache.iml │ │ ├── pubspec.yaml │ │ └── test/ │ │ ├── cache_test.dart │ │ └── files/ │ │ └── date.txt │ ├── container/ │ │ └── angel_container_generator/ │ │ ├── .gitignore │ │ ├── CHANGELOG.md │ │ ├── LICENSE │ │ ├── README.md │ │ ├── analysis_options.yaml │ │ ├── example/ │ │ │ ├── main.dart │ │ │ └── main.reflectable.dart │ │ ├── lib/ │ │ │ └── angel3_container_generator.dart │ │ ├── melos_angel3_container_generator.iml │ │ ├── pubspec.yaml │ │ └── test/ │ │ ├── reflector_test.dart │ │ └── reflector_test.reflectable.dart │ ├── file_service/ │ │ ├── .gitignore │ │ ├── AUTHORS.md │ │ ├── CHANGELOG.md │ │ ├── LICENSE │ │ ├── README.md │ │ ├── analysis_options.yaml │ │ ├── example/ │ │ │ └── main.dart │ │ ├── lib/ │ │ │ └── angel3_file_service.dart │ │ ├── melos_angel3_file_service.iml │ │ ├── pubspec.yaml │ │ └── test/ │ │ └── all_test.dart │ ├── framework/ │ │ ├── AUTHORS.md │ │ ├── CHANGELOG.md │ │ ├── LICENSE │ │ ├── README.md │ │ ├── analysis_options.yaml │ │ ├── dev.key │ │ ├── dev.pem │ │ ├── example/ │ │ │ ├── controller.dart │ │ │ ├── handle_error.dart │ │ │ ├── hostname.dart │ │ │ ├── http2/ │ │ │ │ ├── body_parsing.dart │ │ │ │ ├── common.dart │ │ │ │ ├── dev.key │ │ │ │ ├── dev.pem │ │ │ │ ├── main.dart │ │ │ │ ├── public/ │ │ │ │ │ ├── app.js │ │ │ │ │ ├── body_parsing.html │ │ │ │ │ ├── index.html │ │ │ │ │ └── style.css │ │ │ │ └── server_push.dart │ │ │ ├── json.dart │ │ │ ├── main.dart │ │ │ ├── map_service.dart │ │ │ ├── status.dart │ │ │ ├── view.dart │ │ │ └── views/ │ │ │ └── index.jl │ │ ├── lib/ │ │ │ ├── angel3_framework.dart │ │ │ ├── http.dart │ │ │ ├── http2.dart │ │ │ └── src/ │ │ │ ├── core/ │ │ │ │ ├── anonymous_service.dart │ │ │ │ ├── controller.dart │ │ │ │ ├── core.dart │ │ │ │ ├── driver.dart │ │ │ │ ├── env.dart │ │ │ │ ├── hooked_service.dart │ │ │ │ ├── hostname_parser.dart │ │ │ │ ├── hostname_router.dart │ │ │ │ ├── injection.dart │ │ │ │ ├── map_service.dart │ │ │ │ ├── metadata.dart │ │ │ │ ├── request_context.dart │ │ │ │ ├── response_context.dart │ │ │ │ ├── routable.dart │ │ │ │ ├── server.dart │ │ │ │ └── service.dart │ │ │ ├── fast_name_from_symbol.dart │ │ │ ├── http/ │ │ │ │ ├── angel_http.dart │ │ │ │ ├── http.dart │ │ │ │ ├── http_request_context.dart │ │ │ │ └── http_response_context.dart │ │ │ ├── http2/ │ │ │ │ ├── angel_http2.dart │ │ │ │ ├── http2_request_context.dart │ │ │ │ └── http2_response_context.dart │ │ │ ├── safe_stream_controller.dart │ │ │ └── util.dart │ │ ├── melos_angel3_framework.iml │ │ ├── performance/ │ │ │ └── hello/ │ │ │ ├── angel.md │ │ │ ├── main.dart │ │ │ ├── raw.dart │ │ │ └── raw.md │ │ ├── pubspec.yaml │ │ └── test/ │ │ ├── accepts_test.dart │ │ ├── all.dart │ │ ├── anonymous_service_test.dart │ │ ├── body_test.dart │ │ ├── common.dart │ │ ├── controller_test.dart │ │ ├── detach_test.dart │ │ ├── di_test.dart │ │ ├── encoders_buffer_test.dart │ │ ├── env_test.dart │ │ ├── exception_test.dart │ │ ├── extension_test.dart │ │ ├── find_one_test.dart │ │ ├── general_test.dart │ │ ├── hm.dart │ │ ├── hooked_test.dart │ │ ├── http2/ │ │ │ ├── adapter_test.dart │ │ │ └── http2_client.dart │ │ ├── http_404_hole_test.dart │ │ ├── jsonp_test.dart │ │ ├── parameter_meta_test.dart │ │ ├── parse_id_test.dart │ │ ├── precontained_test.dart │ │ ├── pretty_log.dart │ │ ├── primitives_test.dart │ │ ├── repeat_request_test.dart │ │ ├── req_shutdown_test.dart │ │ ├── response_header_test.dart │ │ ├── routing_test.dart │ │ ├── serialize_test.dart │ │ ├── server_test.dart │ │ ├── service_map_test.dart │ │ ├── services_test.dart │ │ ├── streaming_test.dart │ │ └── view_generator_test.dart │ ├── html/ │ │ ├── AUTHORS.md │ │ ├── CHANGELOG.md │ │ ├── LICENSE │ │ ├── README.md │ │ ├── analysis_options.yaml │ │ ├── example/ │ │ │ └── main.dart │ │ ├── lib/ │ │ │ └── angel3_html.dart │ │ ├── melos_angel3_html.iml │ │ ├── pubspec.yaml │ │ └── test/ │ │ └── all_test.dart │ ├── jael/ │ │ ├── LICENSE │ │ ├── README.md │ │ ├── angel_jael/ │ │ │ ├── AUTHORS.md │ │ │ ├── CHANGELOG.md │ │ │ ├── LICENSE │ │ │ ├── README.md │ │ │ ├── analysis_options.yaml │ │ │ ├── example/ │ │ │ │ ├── main.dart │ │ │ │ └── views/ │ │ │ │ ├── index.jael │ │ │ │ └── layout.jael │ │ │ ├── lib/ │ │ │ │ └── angel3_jael.dart │ │ │ ├── melos_angel3_jael.iml │ │ │ ├── pubspec.yaml │ │ │ └── test/ │ │ │ ├── all_test.dart │ │ │ └── minified_test.dart │ │ ├── jael/ │ │ │ ├── AUTHORS.md │ │ │ ├── CHANGELOG.md │ │ │ ├── LICENSE │ │ │ ├── README.md │ │ │ ├── analysis_options.yaml │ │ │ ├── bin/ │ │ │ │ └── jaelfmt.dart │ │ │ ├── example/ │ │ │ │ └── main.dart │ │ │ ├── lib/ │ │ │ │ ├── jael3.dart │ │ │ │ └── src/ │ │ │ │ ├── ast/ │ │ │ │ │ ├── array.dart │ │ │ │ │ ├── ast.dart │ │ │ │ │ ├── ast_node.dart │ │ │ │ │ ├── attribute.dart │ │ │ │ │ ├── binary.dart │ │ │ │ │ ├── call.dart │ │ │ │ │ ├── conditional.dart │ │ │ │ │ ├── document.dart │ │ │ │ │ ├── element.dart │ │ │ │ │ ├── error.dart │ │ │ │ │ ├── expression.dart │ │ │ │ │ ├── identifier.dart │ │ │ │ │ ├── interpolation.dart │ │ │ │ │ ├── map.dart │ │ │ │ │ ├── member.dart │ │ │ │ │ ├── new.dart │ │ │ │ │ ├── number.dart │ │ │ │ │ ├── string.dart │ │ │ │ │ └── token.dart │ │ │ │ ├── formatter.dart │ │ │ │ ├── renderer.dart │ │ │ │ └── text/ │ │ │ │ ├── parselet/ │ │ │ │ │ ├── infix.dart │ │ │ │ │ ├── parselet.dart │ │ │ │ │ └── prefix.dart │ │ │ │ ├── parser.dart │ │ │ │ └── scanner.dart │ │ │ ├── melos_jael3.iml │ │ │ ├── pubspec.yaml │ │ │ └── test/ │ │ │ ├── render/ │ │ │ │ ├── custom_element_test.dart │ │ │ │ ├── dsx_test.dart │ │ │ │ └── render_test.dart │ │ │ └── text/ │ │ │ ├── common.dart │ │ │ └── scan_test.dart │ │ ├── jael.iml │ │ ├── jael_language_server/ │ │ │ ├── LICENSE │ │ │ ├── analysis_options.yaml │ │ │ ├── bin/ │ │ │ │ └── jael3_language_server.dart │ │ │ ├── lib/ │ │ │ │ ├── jael3_language_server.dart │ │ │ │ └── src/ │ │ │ │ ├── analyzer.dart │ │ │ │ ├── object.dart │ │ │ │ ├── protocol/ │ │ │ │ │ └── language_server/ │ │ │ │ │ ├── interface.dart │ │ │ │ │ ├── messages.dart │ │ │ │ │ ├── messages.yaml │ │ │ │ │ ├── server.dart │ │ │ │ │ └── wireformat.dart │ │ │ │ └── server.dart │ │ │ ├── melos_jael3_language_server.iml │ │ │ └── pubspec.yaml │ │ ├── jael_preprocessor/ │ │ │ ├── AUTHORS.md │ │ │ ├── CHANGELOG.md │ │ │ ├── LICENSE │ │ │ ├── README.md │ │ │ ├── analysis_options.yaml │ │ │ ├── example/ │ │ │ │ └── main.dart │ │ │ ├── lib/ │ │ │ │ └── jael3_preprocessor.dart │ │ │ ├── melos_jael3_preprocessor.iml │ │ │ ├── pubspec.yaml │ │ │ └── test/ │ │ │ ├── block_test.dart │ │ │ └── include_test.dart │ │ └── jael_web/ │ │ ├── CHANGELOG.md │ │ ├── LICENSE │ │ ├── README.md │ │ ├── analysis_options.yaml │ │ ├── build.yaml │ │ ├── example/ │ │ │ ├── main.dart │ │ │ ├── main.g.dart │ │ │ ├── stateful.dart │ │ │ ├── stateful.g.dart │ │ │ ├── using_components.dart │ │ │ └── using_components.g.dart │ │ ├── lib/ │ │ │ ├── builder.dart │ │ │ ├── elements.dart │ │ │ ├── jael3_web.dart │ │ │ └── src/ │ │ │ ├── builder/ │ │ │ │ ├── builder.dart │ │ │ │ └── util.dart │ │ │ ├── builder_node.dart │ │ │ ├── component.dart │ │ │ ├── dom_builder.dart │ │ │ ├── dom_node.dart │ │ │ ├── elements.dart │ │ │ ├── fn.dart │ │ │ └── jael_component.dart │ │ ├── melos_jael3_web.iml │ │ └── pubspec.yaml │ ├── jinja/ │ │ ├── .gitignore │ │ ├── AUTHORS.md │ │ ├── CHANGELOG.md │ │ ├── LICENSE │ │ ├── README.md │ │ ├── analysis_options.yaml │ │ ├── example/ │ │ │ ├── main.dart │ │ │ └── views/ │ │ │ ├── hello.html │ │ │ ├── index.html │ │ │ └── layout.html │ │ ├── lib/ │ │ │ └── angel3_jinja.dart │ │ ├── melos_angel3_jinja.iml │ │ └── pubspec.yaml │ ├── markdown/ │ │ ├── .gitignore │ │ ├── AUTHORS.md │ │ ├── CHANGELOG.md │ │ ├── LICENSE │ │ ├── README.md │ │ ├── analysis_options.yaml │ │ ├── example/ │ │ │ ├── main.dart │ │ │ └── views/ │ │ │ └── hello.md │ │ ├── lib/ │ │ │ └── angel3_markdown.dart │ │ ├── melos_angel3_markdown.iml │ │ └── pubspec.yaml │ ├── oauth2/ │ │ ├── .gitignore │ │ ├── AUTHORS.md │ │ ├── CHANGELOG.md │ │ ├── LICENSE │ │ ├── README.md │ │ ├── analysis_options.yaml │ │ ├── example/ │ │ │ ├── example1.dart │ │ │ └── main.dart │ │ ├── lib/ │ │ │ ├── angel3_oauth2.dart │ │ │ └── src/ │ │ │ ├── exception.dart │ │ │ ├── pkce.dart │ │ │ ├── response.dart │ │ │ ├── server.dart │ │ │ └── token_type.dart │ │ ├── melos_angel3_oauth2.iml │ │ ├── pubspec.yaml │ │ └── test/ │ │ ├── auth_code_test.dart │ │ ├── client_credentials_test.dart │ │ ├── common.dart │ │ ├── device_code_test.dart │ │ ├── implicit_grant_test.dart │ │ ├── password_test.dart │ │ └── pkce_test.dart │ ├── orm/ │ │ ├── LICENSE │ │ ├── README.md │ │ ├── angel_orm_mysql/ │ │ │ ├── AUTHORS.md │ │ │ ├── CHANGELOG.md │ │ │ ├── LICENSE │ │ │ ├── README.md │ │ │ ├── analysis_options.yaml │ │ │ ├── example/ │ │ │ │ ├── example2.dart │ │ │ │ ├── main.dart │ │ │ │ └── main.g.dart │ │ │ ├── lib/ │ │ │ │ ├── angel3_orm_mysql.dart │ │ │ │ └── src/ │ │ │ │ ├── orm_mariadb.dart │ │ │ │ └── orm_mysql.dart │ │ │ ├── melos_angel3_orm_mysql.iml │ │ │ ├── pubspec.yaml │ │ │ └── test/ │ │ │ ├── belongs_to_test.dart │ │ │ ├── common.dart │ │ │ ├── custom_expr_test.dart │ │ │ ├── edge_case_test.dart │ │ │ ├── enum_and_nested_test.dart │ │ │ ├── enum_test.dart │ │ │ ├── has_many_test.dart │ │ │ ├── has_map_test.dart │ │ │ ├── has_one_test.dart │ │ │ ├── join_test.dart │ │ │ ├── many_to_many_test.dart │ │ │ ├── models/ │ │ │ │ ├── asset.dart │ │ │ │ ├── asset.g.dart │ │ │ │ ├── bike.dart │ │ │ │ ├── bike.g.dart │ │ │ │ ├── boat.d.ts │ │ │ │ ├── boat.dart │ │ │ │ ├── boat.g.dart │ │ │ │ ├── book.dart │ │ │ │ ├── book.g.dart │ │ │ │ ├── car.dart │ │ │ │ ├── car.g.dart │ │ │ │ ├── custom_expr.dart │ │ │ │ ├── custom_expr.g.dart │ │ │ │ ├── email_indexed.dart │ │ │ │ ├── email_indexed.g.dart │ │ │ │ ├── fortune.dart │ │ │ │ ├── fortune.g.dart │ │ │ │ ├── has_car.dart │ │ │ │ ├── has_car.g.dart │ │ │ │ ├── has_map.dart │ │ │ │ ├── has_map.g.dart │ │ │ │ ├── leg.dart │ │ │ │ ├── leg.g.dart │ │ │ │ ├── order.dart │ │ │ │ ├── order.g.dart │ │ │ │ ├── person.dart │ │ │ │ ├── person.g.dart │ │ │ │ ├── person_order.dart │ │ │ │ ├── person_order.g.dart │ │ │ │ ├── quotation.dart │ │ │ │ ├── quotation.g.dart │ │ │ │ ├── todo.dart │ │ │ │ ├── todo.g.dart │ │ │ │ ├── tree.dart │ │ │ │ ├── tree.g.dart │ │ │ │ ├── unorthodox.dart │ │ │ │ ├── unorthodox.g.dart │ │ │ │ ├── user.dart │ │ │ │ ├── user.g.dart │ │ │ │ ├── world.dart │ │ │ │ └── world.g.dart │ │ │ ├── performance_test.dart │ │ │ ├── standalone_test.dart │ │ │ └── util.dart │ │ ├── angel_orm_service/ │ │ │ ├── AUTHORS.md │ │ │ ├── CHANGELOG.md │ │ │ ├── LICENSE │ │ │ ├── README.md │ │ │ ├── analysis_options.yaml │ │ │ ├── example/ │ │ │ │ ├── connect.dart │ │ │ │ ├── main.dart │ │ │ │ ├── migrate.dart │ │ │ │ ├── todo.dart │ │ │ │ └── todo.g.dart │ │ │ ├── lib/ │ │ │ │ └── angel3_orm_service.dart │ │ │ ├── melos_angel3_orm_service.iml │ │ │ ├── pubspec.yaml │ │ │ └── test/ │ │ │ ├── all_test.dart │ │ │ ├── pokemon.dart │ │ │ └── pokemon.g.dart │ │ └── angel_orm_test/ │ │ └── README.md │ ├── paginate/ │ │ ├── .analysis-options │ │ ├── .gitignore │ │ ├── AUTHORS.md │ │ ├── CHANGELOG.md │ │ ├── LICENSE │ │ ├── README.md │ │ ├── analysis_options.yaml │ │ ├── example/ │ │ │ └── main.dart │ │ ├── lib/ │ │ │ └── angel3_paginate.dart │ │ ├── melos_angel3_paginate.iml │ │ ├── pubspec.yaml │ │ └── test/ │ │ ├── all_test.dart │ │ ├── bounds_test.dart │ │ └── paginate_test.dart │ ├── production/ │ │ ├── .pubignore │ │ ├── AUTHORS.md │ │ ├── CHANGELOG.md │ │ ├── LICENSE │ │ ├── README.md │ │ ├── analysis_options.yaml │ │ ├── example/ │ │ │ └── main.dart │ │ ├── lib/ │ │ │ ├── angel3_production.dart │ │ │ └── src/ │ │ │ ├── instance_info.dart │ │ │ ├── options.dart │ │ │ └── runner.dart │ │ ├── melos_angel3_production.iml │ │ └── pubspec.yaml │ ├── redis/ │ │ ├── .gitignore │ │ ├── AUTHORS.md │ │ ├── CHANGELOG.md │ │ ├── LICENSE │ │ ├── README.md │ │ ├── analysis_options.yaml │ │ ├── example/ │ │ │ └── main.dart │ │ ├── lib/ │ │ │ ├── angel3_redis.dart │ │ │ └── src/ │ │ │ └── redis_service.dart │ │ ├── melos_angel3_redis.iml │ │ ├── pubspec.yaml │ │ └── test/ │ │ └── all_test.dart │ ├── sembast/ │ │ ├── .gitignore │ │ ├── AUTHORS.md │ │ ├── CHANGELOG.md │ │ ├── LICENSE │ │ ├── README.md │ │ ├── analysis_options.yaml │ │ ├── example/ │ │ │ └── main.dart │ │ ├── lib/ │ │ │ └── angel3_sembast.dart │ │ ├── melos_angel3_sembast.iml │ │ ├── pubspec.yaml │ │ └── test/ │ │ └── all_test.dart │ ├── seo/ │ │ ├── .gitignore │ │ ├── AUTHORS.md │ │ ├── CHANGELOG.md │ │ ├── LICENSE │ │ ├── README.md │ │ ├── analysis_options.yaml │ │ ├── example/ │ │ │ ├── main.dart │ │ │ └── web/ │ │ │ ├── index.html │ │ │ ├── not-inlined.css │ │ │ ├── not-inlined.js │ │ │ ├── site.css │ │ │ └── site.js │ │ ├── lib/ │ │ │ ├── angel3_seo.dart │ │ │ └── src/ │ │ │ └── inline_assets.dart │ │ ├── melos_angel3_seo.iml │ │ ├── pubspec.yaml │ │ └── test/ │ │ └── inline_assets_test.dart │ ├── shelf/ │ │ ├── AUTHORS.md │ │ ├── CHANGELOG.md │ │ ├── LICENSE │ │ ├── README.md │ │ ├── analysis_options.yaml │ │ ├── example/ │ │ │ ├── angel_in_shelf.dart │ │ │ └── main.dart │ │ ├── lib/ │ │ │ ├── angel3_shelf.dart │ │ │ └── src/ │ │ │ ├── convert.dart │ │ │ ├── embed_shelf.dart │ │ │ ├── shelf_driver.dart │ │ │ ├── shelf_request.dart │ │ │ └── shelf_response.dart │ │ ├── melos_angel3_shelf.iml │ │ ├── pubspec.yaml │ │ └── test/ │ │ ├── all.dart │ │ └── embed_shelf_test.dart │ ├── static/ │ │ ├── AUTHORS.md │ │ ├── CHANGELOG.md │ │ ├── LICENSE │ │ ├── README.md │ │ ├── analysis_options.yaml │ │ ├── example/ │ │ │ └── main.dart │ │ ├── lib/ │ │ │ ├── angel3_static.dart │ │ │ └── src/ │ │ │ ├── cache.dart │ │ │ └── virtual_directory.dart │ │ ├── melos_angel3_static.iml │ │ ├── pubspec.yaml │ │ └── test/ │ │ ├── HELLO.md │ │ ├── all_test.dart │ │ ├── cache_sample.dart │ │ ├── cache_test.dart │ │ ├── foo.mustache │ │ ├── index.txt │ │ ├── issue41_test.dart │ │ ├── nested/ │ │ │ └── index.txt │ │ ├── push_state_test.dart │ │ ├── sample.txt │ │ └── web/ │ │ └── index.html │ ├── sync/ │ │ ├── AUTHORS.md │ │ ├── CHANGELOG.md │ │ ├── LICENSE │ │ ├── README.md │ │ ├── analysis_options.yaml │ │ ├── example/ │ │ │ └── main.dart │ │ ├── lib/ │ │ │ └── angel3_sync.dart │ │ ├── melos_angel3_sync.iml │ │ ├── pubspec.yaml │ │ └── test/ │ │ └── all_test.dart │ └── user_agent/ │ └── angel_user_agent/ │ ├── AUTHORS.md │ ├── CHANGELOG.md │ ├── LICENSE │ ├── README.md │ ├── analysis_options.yaml │ ├── example/ │ │ └── example.dart │ ├── lib/ │ │ └── angel3_user_agent.dart │ ├── melos_angel3_user_agent.iml │ └── pubspec.yaml └── pubspec.yaml ================================================ FILE CONTENTS ================================================ ================================================ FILE: .devcontainer/devcontainer.json ================================================ { "image": "dart:3.4", "forwardPorts": [3000,5000], "features": { } } ================================================ FILE: .github/FUNDING.yml ================================================ # These are supported funding model platforms github: [dukefirehawk] custom: ["https://paypal.me/dukefirehawk?country.x=MY&locale.x=en_US"] ================================================ FILE: .github/workflows/dart.yml ================================================ # This workflow uses actions that are not certified by GitHub. # They are provided by a third-party and are governed by # separate terms of service, privacy policy, and support # documentation. name: Angel3 CI on: push: branches: [ master ] pull_request: branches: [ master ] jobs: job_001: name: Validate framework package runs-on: ubuntu-latest steps: - uses: actions/checkout@v2 - uses: dart-lang/setup-dart@v1 with: sdk: "3.11.0" - id: angel3_container_upgrade name: angel3_container; Upgrade depedencies working-directory: packages/container/angel_container run: dart pub upgrade - name: angel3_container; Verify formatting working-directory: packages/container/angel_container run: dart format --output=none --set-exit-if-changed . # Consider passing '--fatal-infos' for slightly stricter analysis. - name: angel3_container; Analyze source code working-directory: packages/container/angel_container run: dart analyze - name: angel3_container; Run tests working-directory: packages/container/angel_container run: dart test - id: angel3_framework_upgrade name: angel3_framework; Upgrade depedencies working-directory: packages/framework run: dart pub upgrade - name: angel3_framework; Verify formatting working-directory: packages/framework run: dart format --output=none --set-exit-if-changed . # Consider passing '--fatal-infos' for slightly stricter analysis. - name: angel3_framework; Analyze source code working-directory: packages/framework run: dart analyze - name: angel3_framework; Run tests working-directory: packages/framework run: dart test job_002: name: Validate ORM packages runs-on: ubuntu-latest # Service containers to run with `runner-job` services: # Label used to access the service container postgres: # Docker Hub image image: postgres # Provide the password for postgres env: POSTGRES_PASSWORD: postgres # Set health checks to wait until postgres has started options: >- --health-cmd pg_isready --health-interval 10s --health-timeout 5s --health-retries 5 ports: # Maps tcp port 5432 on service container to the host - 5432:5432 steps: - uses: actions/checkout@v2 - uses: dart-lang/setup-dart@v1 with: sdk: "3.11.0" # Angel3 ORM - id: angel3_orm_upgrade name: angel3_orm; Upgrade depedencies working-directory: packages/orm/angel_orm run: dart pub upgrade - name: angel3_orm; Verify formatting working-directory: packages/orm/angel_orm run: dart format --output=none --set-exit-if-changed . # Consider passing '--fatal-infos' for slightly stricter analysis. - name: angel3_orm; Analyze source code working-directory: packages/orm/angel_orm run: dart analyze # Angel3 ORM Generator - id: angel3_orm_generator_upgrade name: angel3_orm_generator; Upgrade depedencies working-directory: packages/orm/angel_orm_generator run: dart pub upgrade - name: angel3_orm_generator; Verify formatting working-directory: packages/orm/angel_orm_generator run: dart format --output=none --set-exit-if-changed . # Consider passing '--fatal-infos' for slightly stricter analysis. - name: angel3_orm_generator; Analyze source code working-directory: packages/orm/angel_orm_generator run: dart analyze # Angel3 ORM Test #- id: angel3_orm_test_upgrade # name: angel3_orm_test; Upgrade depedencies # working-directory: packages/orm/angel_orm_test # run: dart pub upgrade #- name: angel3_orm_test; Run orm code generator # working-directory: packages/orm/angel_orm_test # run: dart run build_runner build --delete-conflicting-outputs #- name: angel3_orm_test; Verify formatting # working-directory: packages/orm/angel_orm_test # run: dart format --output=none --set-exit-if-changed . # Consider passing '--fatal-infos' for slightly stricter analysis. #- name: angel3_orm_test; Analyze source code # working-directory: packages/orm/angel_orm_test # run: dart analyze # Angel3 ORM PostgreSQL - id: angel3_orm_postgres_upgrade name: angel3_orm_postgres; Upgrade depedencies working-directory: packages/orm/angel_orm_postgres run: dart pub upgrade - name: angel3_orm_postgres; Verify formatting working-directory: packages/orm/angel_orm_postgres run: dart format --output=none --set-exit-if-changed . # Consider passing '--fatal-infos' for slightly stricter analysis. - name: angel3_orm_postgres; Analyze source code working-directory: packages/orm/angel_orm_postgres run: dart analyze - name: angel3_orm_postgres; Run tests working-directory: packages/orm/angel_orm_postgres run: dart test env: # The hostname used to communicate with the PostgreSQL service container POSTGRES_HOST: localhost # The default PostgreSQL port POSTGRES_PORT: 5432 POSTGRES_PASSWORD: postgres POSTGRES_USERNAME: postgres POSTGRES_DB: postgres ================================================ FILE: .gitignore ================================================ # Created by .ignore support plugin (hsz.mobi) ### Dart template # See https://www.dartlang.org/tools/private-files.html # source_gen .dart_tool # Files and directories created by pub .buildlog .packages .project .pub/ .scripts-bin/ .metals/ build/ #**/packages/ # Files created by dart2js # (Most Dart developers will use pub build to compile Dart, use/modify these # rules if you intend to use dart2js directly # Convention is to use extension '.dart.js' for Dart compiled to Javascript to # differentiate from explicit Javascript files) *.dart.js *.part.js *.js.deps *.js.map *.info.json # Directory created by dartdoc doc/api/ # Don't commit pubspec lock file # (Library packages only! Remove pattern if developing an application package) pubspec.lock ### JetBrains template # Covers JetBrains IDEs: IntelliJ, RubyMine, PhpStorm, AppCode, PyCharm, CLion, Android Studio and Webstorm # Reference: https://intellij-support.jetbrains.com/hc/en-us/articles/206544839 # User-specific stuff: ## VsCode .vscode/ !.vscode/settings.json !.vscode/tasks.json !.vscode/launch.json !.vscode/extensions.json # IntelliJ .idea/ /out/ .idea_modules/ # Gradle: .idea/gradle.xml .idea/libraries ## File-based project format: *.iws ## Plugin-specific files: # JIRA plugin atlassian-ide-plugin.xml # Crashlytics plugin (for Android Studio and IntelliJ) com_crashlytics_export_strings.xml crashlytics.properties crashlytics-build.properties fabric.properties # Others logs/ .DS_Store server_log.txt backup/ ================================================ FILE: .pubignore ================================================ .DS_Store tasks.json ================================================ FILE: .vscode/settings.json ================================================ { "files.watcherExclude": { "**/target": true }, "[javascript]": { "editor.defaultFormatter": "esbenp.prettier-vscode", "editor.formatOnSave": true }, "beautify.language": { "html": ["html"], "css": [], "js": [] }, "editor.codeActionsOnSave": { "source.fixAll.markdownlint": "explicit" }, "cmake.configureOnOpen": false } ================================================ FILE: AI_CONTEXT.md ================================================ # AI Context for Angel3 ## Project Overview **Angel3** is a production-ready, full-stack backend framework in Dart. It originated as a fork of the original Angel framework to support Dart SDK null-safety and later versions. It aims to streamline development by providing many common backend features out-of-the-box and enables developers to build both frontends and backends in Dart. It is highly modular, designed as a collection of plugins. ## Repository Structure This repository is a **monorepo** managed using [Melos](https://pub.dev/packages/melos). - **Packages**: Located in the `packages/` directory. Each sub-directory represents an individual plugin or module that can be published to `pub.dev` under the `angel3_` prefix. ## Core Architecture and Packages The framework is divided into several categories of packages: 1. **Core Framework & Request Handling**: - `framework`: Base HTTP server, contexts, DI container, and middleware pipelines. - `route`: URL matching and route parameters. - `container`: Dependency Injection (DI) system. - `configuration`: Utilities for loading config files (YAML, JSON, .env). 2. **Data Modeling & Persistence (ORM)**: - `model`: Base model abstractions for data entities. - `serialize`: JSON serialization and deserialization using code generation. - `orm`: Main ORM library, code generator, and SQL dialects (MySQL, PostgreSQL) - `mongo`, `rethinkdb`, `sembast`: Specialized NoSQL database drivers. 3. **Authentication & Security**: - `auth`: Core authentication abstractions and strategies. - `auth_oauth2`, `oauth2`: OAuth2 authentication flows. - `security`: Security middleware (rate limiting, standard headers). - `cors`: Cross-Origin Resource Sharing handling. 4. **Frontend & Template Rendering**: - `jael`: Jael template engine built specifically for Angel. - `mustache`, `jinja`, `markdown`: Template integrations. - `html`, `seo`: Utilities for HTML responses and search engine optimization. 5. **Utilities**: - `websocket`: Real-time bidirectional communication. - `client`: Client-side library to interface directly with Angel3 backends. - `cache`, `redis`: Caching interfaces. - `hot`, `production`: Hot-reloading tooling and production load management. - `test`, `mock_request`: Testing utilities. ## Technology Stack & Requirements - **Language**: Dart - **Minimum SDK Version**: `>=3.11.0 <4.0.0` - **Monorepo Management**: `melos` (`^7.3.0`) ## Development Workflow - **Master Branch**: Stable production branch. Use this branch for all standard PR submissions. - **feature/v9 Branch**: Early development for major refactoring targeting the `9.0.0` release. Contains breaking changes (e.g., restructure and rename packages). - **Tooling**: Uses `melos` for managing dependencies and executing tasks across the monorepo (e.g., `melos exec "dart pub upgrade"`). ## Key Technical Debt and Future Roadmap - Removal of dependency on the `dart:mirrors` library. - Performance optimizations to address long-overdue issues. - Integration of OpenAPI 3 support. - Expanding ORM support for SQLite, multi-tenant architectures, and SQL schema reverse engineering. - Out-of-the-box OIDC and SAML2 support. ================================================ FILE: AUTHORS.md ================================================ 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. * __[Tobe O](thosakwe@gmail.com)__ Tobe has written much of the original code prior to NNBD migration. He has moved on and is no longer involved with the project. ================================================ FILE: CHANGELOG.md ================================================ # Change Log All notable changes to this project will be documented in this file. See [Conventional Commits](https://conventionalcommits.org) for commit guidelines. ## 8.7.0 - Require Dart >= 3.11.0 ## 8.6.0 - Require Dart >= 3.8.0 - Updated `lints` to 6.0.0 - Updated dependencies to the latest release ## 8.5.0 - Require Dart >= 3.6 - Updated `lints` to 5.0.0 - Updated dependencies to the latest release ## 8.0.0 - Require Dart >= 3.0 - Updated: angel3_http_exception - Updated: angel3_route - Updated: angel3_model - Updated: angel3_container - Updated: angel3_container_generator - Updated: angel3_mock_request - Updated: angel3_framework - Updated: angel3_auth - Updated: angel3_configuration - Updated: angel3_validate - Updated: angel3_client - Updated: angel3_websocket - Updated: angel3_test - Updated: jael3 - Updated: jael3_preprocessor - Updated: jael3_language_server - Updated: angel3_jael - Updated: jael3_web - Updated: angel3_production - Updated: angel3_hot - Updated: angel3_static - Updated: angel3_serialize - Updated: angel3_serialize_generator - Updated: angel3_orm - Updated: angel3_orm_generator - Updated: angel3_migration - Updated: angel3_migration_runner - Updated: angel3_orm_postgresql - Updated: angel3_orm_mysql - Updated: angel3_orm_service - Updated: angel3_orm_test - Updated: angel3_cache - Updated: angel3_cors - Updated: angel3_mustache - Updated: angel3_proxy - Updated: angel3_redis - Updated: angel3_jinja - Updated: angel3_security - Updated: angel3_user_agent - Updated: angel3_seo - Updated: angel3_sync - Updated: angel3_sembast - Updated: angel3_markdown - Updated: angel3_auth_oauth2 - Updated: angel3_oauth2 (5 failed test cases) - Updated: angel3_auth_twitter (issue: oauth1 don't support http 1.0.0) - Updated: angel3_mongo (issue: mongo_dart don't support http 1.0.0) - Updated: angel3_shelf (2 failed test cases) ## 7.0.0 - Require Dart >= 2.17 ## 6.0.0 - Require Dart >= 2.16 - Added ORM MySQL ## 5.0.0 - Skipped version ## 4.1.x - Refactored the framework internal to use [Belatuk Common Utilities]() - Updated to use `lints` linter - Updated [website]() - Updated [examples]() - Fixed ORM code generator - Fixed Serializer code generator - Fixed graphQL code generator - Fixed CLI - Fixed failed test cases ## 4.0.0 (NNBD) - Published all packages with `angel3_` prefix - Changed Dart SDK requirements for all packages to ">=2.12.0 <3.0.0" to support NNBD. - Migrated pretty_logging to 3.0.0 (0/0 tests passed) - Migrated angel_http_exception to 3.0.0 (0/0 tests passed) - Moved angel_cli to [CLI Repository]() (Not migrated yet) - Added code_buffer and migrated to 2.0.0 (16/16 tests passed) - Added combinator and migrated to 2.0.0 (16/16 tests passed) - Migrated angel_route to 5.0.0 (35/35 tests passed) - Migrated angel_model to 3.0.0 (0/0 tests passed) - Migrated angel_container to 3.0.0 (55/55 tests passed) - Added merge_map and migrated to 2.0.0 (6/6 tests passed) - Added mock_request and migrated to 2.0.0 (5/5 tests) - Migrated angel_framework to 4.0.0 (149/150 tests passed) - Migrated angel_auth to 4.0.0 (31/31 tests passed) - Migrated angel_configuration to 4.0.0 (8/8 testspassed) - Migrated angel_validate to 4.0.0 (7/7 tests passed) - Migrated json_god to 4.0.0 (13/13 tests passed) - Migrated angel_client to 4.0.0 (13/13 tests passed) - Migrated angel_websocket to 4.0.0 (3/3 tests passed) - Migrated angel_test to 4.0.0 (1/1 test passed) - Added symbol_table and migrated to 2.0.0 (16/16 tests passed) - Migrated jael to 4.0.0 (20/20 tests passed) - Migrated jael_preprocessor to 3.0.0 (5/5 tests passed) - Migrated angel_jael to 4.0.0 (1/1 test passed) - Migrated pub_sub to 4.0.0 (16/16 tests passed) - Migrated production to 3.0.0 (0/0 tests passed) - Added html_builder and migrated to 2.0.0 (1/1 tests passed) - Migrated hot to 4.0.0 (0/0 tests passed) - Added range_header and migrated to 3.0.0 (12/12 tests passed) - Migrated angel_static to 4.0.0 (12/12 test passed) - Created basic-sdk-2.12.x_nnbd template (1/1 test passed) <= Milestone 1 - Migrated angel_serialize to 4.0.0 (0/0 test passed) - Migrated angel_serialize_generator to 4.0.0 (33/33 tests passed) - Migrated angel_orm to 3.0.0 (0/0 tests passed) - Migrated angel_migration to 3.0.0 (0/0 tests passed) - Added inflection2 and migrated to 1.0.0 (28/32 tests passed) - Migrated angel_orm_generator to 4.0.0 (0/0 tests passed) - Migrated angel_migration_runner to 3.0.0 (0/0 tests passed) - Migrated angel_orm_test to 3.0.0 (0/0 tests passed) - Migrated angel_orm_postgres to 3.0.0 (51/54 tests passed) - Create orm-sdk-2.12.x boilerplate (in progress) <= Milestone 2 - Migrated angel_auth_oauth2 to 4.0.0 (0/0 tests passed) - Migrated angel_auth_cache to 4.0.0 (7/7 tests passed) - Migrated angel_auth_cors to 4.0.0 (15/15 tests passed) - Migrated angel_oauth2 to 4.0.0 (17/25 tests passed) - Migrated angel_proxy to 4.0.0 (6/7 tests passed) - Migrated angel_file_service to 4.0.0 (6/6 tests passed) - Migrated graphql_parser to 2.0.0 (55/55 tests passed) - Migrated graphql_schema to 2.0.0 (34/35 tests passed) - Migrated graphql_server to 2.0.0 (9/10 tests passed) - Migrated graphql_generator to 2.0.0 (0/0 tests passed) - Migrated data_loader to 2.0.0 (7/7 tests passed) - Migrated angel_graphql to 2.0.0 (0/0 tests passed) - Migrated angel_mongo to 3.0.0 (0/0 tests passed) - Migrated angel_orm_mysql to 2.0.0 (0/0 tests passed) - Migrated angel_orm_service to 2.0.0 (0/0 tests passed) - Migrated body_parser to 2.0.0 (11/11 tests passed) - Migrated angel_markdown to 3.0.0 (0/0 tests passed) - Migrated angel_jinja to 2.0.0 (0/0 tests passed) - Migrated angel_html to 3.0.0 (1/3 tests passed) - Migrated angel_mustache to 2.0.0 (3/3 tests passed) - Migrated angel_paginate to 3.0.0 (18/18 tests passed) - Migrated angel_poll to 2.0.0 (0/5 tests passed) - Migrated angel_redis to 2.0.0 (0/8 tests passed) - Migrated angel_seeder to 2.0.0 (0/0 tests passed) - Migrated angel_relations to 2.0.0 (0/0 tests passed) - Migrated angel_rethink to 2.0.0 (0/0 tests passed) - Migrated angel_security to 2.0.0 (0/1 tests passed) - Migrated angel_sembast to 2.0.0 (10/10 tests passed) - Migrated angel_sync to 3.0.0 (0/1 tests passed) - Migrated angel_typed_service to 3.0.0 (4/4 tests passed) - Migrated angel_shelf to 2.0.0 (0/1 tests passed) - Migrated user_agent to 2.0.0 (0/0 tests passed) - Migrated angel_user_agent to 2.0.0 (0/0 tests passed) ## 3.0.0 (Non NNBD) - Changed Dart SDK requirements for all packages to ">=2.10.0 <3.0.0" - Updated pretty_logging to 2.0.0 (0/0 tests passed) - Updated angel_http_exception to 2.0.0 (0/0 tests passed) - Updated angel_cli to 3.0.0. (Rename not working) - Updated angel_route to 4.0.0 (35/35 tests passed) - Updated angel_model to 2.0.0 (0/0 tests passed) - Updated angel_container to 2.0.0 (55/55 tests passed) - Updated angel_framework to 3.0.0 (150/151 tests passed) - Updated angel_auth to 3.0.0 (28/32 tests passed) - Updated angel_configuration to 3.0.0 (6/8 tests passed) - Updated angel_validate to 3.0.0 (7/7 tests passed) - Added and updated json_god to 3.0.0 (7/7 tests passed) - Updated angel_client to 3.0.0 (10/13 tests passed) - Updated angel_websocket to 3.0.0 (3/3 tests passed) - Updated jael to 3.0.0 (20/20 tests passed) - Updated jael_preprocessor to 3.0.0 (5/5 tests passed) - Updated test to 3.0.0 (1/1 tests passed) - Updated angel_jael to 3.0.0 (1/1 tests passed, Issue with 2 dependencies) - Added pub_sub and updated to 3.0.0 (16/16 tests passed) - Updated production to 2.0.0 (0/0 tests passed) - Updated hot to 3.0.0 (0/0 tests passed) - Updated static to 3.0.0 (12/12 tests passed) - Update basic-sdk-2.12.x boilerplate (1/1 tests passed) - Updated angel_serialize to 3.0.0 (0/0 tests passed) - Updated angel_serialize_generator to 3.0.0 (33/33 tests passed) - Updated angel_orm to 3.0.0 (0/0 tests passed) - Updated angel_migration to 3.0.0 (0/0 tests passed) - Updated angel_orm_generator to 3.0.0 (0/0 tests passed, use a fork of postgres) - Updated angel_migration_runner to 3.0.0 (0/0 tests passed) - Updated angel_orm_test to 1.0.0 (0/0 tests passed) - Updated angel_orm_postgres to 2.0.0 (52/54 tests passed) - Update orm-sdk-2.12.x boilerplate - Updated angel_auth_oauth2 to 3.0.0 (0/0 tests passed) - Updated angel_auth_cache to 3.0.0 (0/7 tests passed) - Updated angel_auth_cors to 3.0.0 (15/15 tests passed) - Updated angel_oauth2 to 3.0.0 (17/25 tests passed) - Updated angel_container_generator to 2.0.0 - Updated angel_file_service to 3.0.0 - Updated angel_eventsource to 2.0.0 (use a fork of eventsource) - Updated angel_auth_twitter to 3.0.0 (use a fork of twitter and oauth) ## 2.2.0 - Changed Dart SDK requirements for all packages to ">=2.10.0 <2.12.0" - Upgraded 3rd party libraries to the latest version prior to dart 2.12 - Fixed broken code due to 3rd party libraries update - Revert packages/validate from version 3.0 to version 2.2 ## 2.1.x and below - Refer to the orginal repo before the fork ================================================ FILE: CONTRIBUTING.md ================================================ # Contribution Any help from the open-source community is always welcome and needed: 1. Found an issue? - Please [fill a bug report][tracker] with error message and steps to reproduce it. 2. Wish a feature? - Open a feature request with use cases. 3. Are you using and liking the project? - Create an article about your use case - Do a post on your likes and dislikes - Make a donation. 4. Are you a developer? - Fix a bug and send a [pull request][pull_request] - Implement a new feature - Improve the Unit Tests - Improve the [User Guide][doc] and send a [document pull request][doc_repo] 5. Have you already helped in any way? - **Many thanks to the contributors and everybody that uses this project!** [tracker]: https://github.com/dart-backend/angel/issues [pull_request]: https://github.com/dart-backend/angel/pulls [doc]: https://angel3-docs.dukefirehawk.com [doc_repo]: https://github.com/dart-backend/angel3-guide/pulls ================================================ FILE: LICENSE ================================================ BSD 3-Clause License Copyright (c) 2024, dukefirehawk.com All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: 1. Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. 2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. 3. Neither the name of the copyright holder nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. ================================================ FILE: README.md ================================================ # Angel3 Framework [![Angel3 Framework](angel3_logo.png)](https://github.com/dart-backend/angel) ![Pub Version (including pre-releases)](https://img.shields.io/pub/v/angel3_framework?include_prereleases) [![Null Safety](https://img.shields.io/badge/null-safety-brightgreen)](https://dart.dev/null-safety) [![Discord](https://img.shields.io/discord/1060322353214660698)](https://discord.gg/3X6bxTUdCM) [![License](https://img.shields.io/github/license/dart-backend/angel)](https://github.com/dart-backend/angel/LICENSE) [![melos](https://img.shields.io/badge/maintained%20with-melos-f700ff.svg?style=flat-square)](https://github.com/invertase/melos) **A production-ready dart backend framework.** ----- ## About Angel3 originated from a fork of the archived Angel framework in support of Dart SDK 2.12.x or later. It is a full-stack backend framework in Dart that aims to streamline development by providing many common features out-of-the-box in a consistent manner. The codebase has been completely migrated and refactored to support null safety. One of the main goal is to enable developers to build both frontend and backend in dart language. Angel3 is designed as a collection of plugins that enable developers to pick and choose the parts needed for their projects. A series of starter templates are also provided for quick start and trial run with Angel3. Visit our [website]() to learn more. The available features in Angel3 includes: * OAuth2 Authentication * WebSocket * HTTP/2 * HTTP Streaming * GraphQL * Markdown, Mustache, Jinja and JAEL as Server-Side HTML Rendering * ORM support for PostgreSQL and MySQL * MongoDB, Sembast and RethinkDB as storage * Redis as cache ## The Core Framework The `packages` directory contains specialized sub-packages that act as individual plugins or modules. Depending on the needs of a project, a developer can plug in specific packages. They can broadly be categorized as follows: 1. Core Framework & Request Handling * framework: The foundational package (angel3_framework). It provides the base HTTP server, request/response contexts, dependency injection container, and middleware pipelines. * route: The routing engine handling URL matching and route parameters. * container: Dependency Injection (DI) system for resolving services. * configuration: Utilities for loading configuration files (YAML, JSON, .env). 2. Data Modeling & Persistence (ORM) The framework provides an extensive ORM (angel3_orm) ecosystem with generators and database drivers: * orm: Houses the main ORM library, code generator (angel_orm_generator), and SQL dialects for MySQL and PostgreSQL. * model: Base model abstractions for data entities. * serialize: Libraries to serialize/deserialize data to and from JSON using code generation (angel_serialize_generator). * mongo, rethinkdb, sembast: Specialized drivers for interacting with MongoDB, RethinkDB, and Sembast (a NoSQL local database). 3. Authentication & Security * auth: Core authentication abstractions and strategies (local, token-based). * auth_oauth2 & oauth2: Out-of-the-box support for OAuth2 authentication flows. * security: Security middleware (rate limiting, standard headers, etc.). * cors: Middleware to handle Cross-Origin Resource Sharing effortlessly. 4. Frontend & Template Rendering Support for processing and returning HTML views to the client: * jael: The Jael template engine specifically built for Angel, capable of HTML manipulation. It is split into language servers, preprocessors, and web renderers. * mustache, jinja, markdown: Wrappers/integrations for rendering Mustache templates, Jinja templates, or parsing Markdown into HTML. * html & seo: Utilities for building out HTML responses and optimizing for search engines. 5. Additional Utilities and APIs * websocket: Integration for real-time bidirectional communication. * client: A client-side library designed to interface seamlessly with Angel3 backends directly from Dart/Flutter. * cache & redis: Caching interfaces with Redis integration to improve response times. * hot & production: Tooling for hot-reloading the server during development, and managing clustering/multi-threading under production loads. * test & mock_request: Testing utilities for mocking HTTP requests without spinning up a real server. * file_service & static: For serving static assets (images, CSS, JS) efficiently. ## Important Notes Angel3 packages are published under `angel3_` prefix on pub.dev. These packages have passed all of their respective test suites before going live. The development work are currently focused on: * Keeping the packages with `angel3_` prefix in sync with Dart SDK releases * Remove and replace deprecated classes and methods while keeping it backward compatible * Refactor the code to use new language features * Fix and resolve reported issues * Performance optimization * Improve on existing features, unit test, user guide and examples * Add new features ## Status ### Latest Release Notes (Version: 8.6.0) * Updated `angel3_` packages to require dart >= 3.11.0 * Updated to `melos:7.3` * Updated code generator to use `analyzer` 8.4.x * Removed `angel3_orm_test` ### Latest development work Branch: `feature/v9` * Dart version : 3.11.0 or later. * Status : Early Development * Notes : Major refactoring on going with breaking changes targeting `9.0.0` release * Restructre and rename packages * Removal of dependency on `Mirror` * Fix long overdued performance issues Branch: `master` * Dart version : 3.11.0 or later. * Publish : Refer to all packages with`angel3_` prefix on [pub.dev](https://pub.dev/publishers/dukefirehawk.com/packages). * Status : Production * Notes : Use this branch for all PR submission ### Archieved releases Starting with release 8.5.0. All subsequence releases published to `pub.dev` will be available on a release branch. The branch name will adopt the following naming conventions, `release/`. For example: `release/8.5` branch is for release version 8.5 on `pub.dev`. ### What is in the pipeline? * Remove the use of Mirror * Performance optimsation * Out of the box OIDC and SAML2 support * Integrated Open API 3 support * Expand ORM to support * SQLite * Multi tenant * Reverse Engineering ## Installation and Setup ### (Option 1) Create a new project by cloning from boilerplate templates 1. Download and install [Dart](https://dart.dev/get-dart). Minimum 3.11.0. 2. Clone one of the following starter projects: * [Angel3 Basic Template](https://github.com/dukefirehawk/boilerplates/tree/angel3-basic) * [Angel3 ORM Template](https://github.com/dukefirehawk/boilerplates/tree/angel3-orm) * [Angel3 ORM MySQL Template](https://github.com/dukefirehawk/boilerplates/tree/angel3-orm-mysql) * [Angel3 Graphql Template](https://github.com/dukefirehawk/boilerplates/tree/angel3-graphql) 3. Run the project in development mode (*hot-reloaded* is enabled on file changes). ```bash dart --observe bin/dev.dart ``` 4. Run the project in production mode (*hot-reloaded* is disabled). ```bash dart bin/prod.dart ``` 5. Run as docker. Edit and build the image with the provided `Dockerfile` file. 6. Next, refer to the [developer guide](https://angel3-docs.dukefirehawk.com/) to learn more about Angel3 framework. ### (Option 2) Create a new project with Angel3 CLI 1. Download and install [Dart](https://dart.dev/get-dart) 2. Install the [Angel3 CLI](https://pub.dev/packages/angel3_cli): ```bash dart pub global activate angel3_cli ``` 3. On terminal, create a new project: ```bash angel3 init hello ``` 4. Run the project in development mode (*hot-reloaded* is enabled on file changes). ```bash dart --observe bin/dev.dart ``` 5. Run the project in production mode (*hot-reloaded* is disabled). ```bash dart bin/prod.dart ``` 6. Run as docker. Edit and build the image with the provided `Dockerfile` file. 7. Next, refer to the [User Guide](https://angel3-docs.dukefirehawk.com/) to learn more about Angel3 framework. ## Performance Testing Refer to [Angel3 Performance Test Suite](https://github.com/dart-backend/angel3-perf-test) for more information. It is still in early stage, but eventually will contain test cases for running load testing with [Locust](https://locust.io/) on various key features of Angel3 framework. These test cases can serve as a foundation for building performance tests for any applications developed with Angel3 framework. ## Performance Benchmark An offical performance benchmark can be found at [TechEmpower Framework Benchmarks](https://www.techempower.com/benchmarks/#section=data-r23) The test cases are build using standard `Angel3 ORM` template for PostgreSQL and MySQL databases. The result are used for improving Angel3 framework with respect to other frameworks. The following test cases will be added in the subsequent update to this benchmark. 1. Cache with Redis 2. Angel3 with MongoDB ## Documentation Refer to [User Guide](https://angel3-docs.dukefirehawk.com/) for more detailed information on the available features of Angel3 framework. ## Examples Take various applications at [Examples](https://github.com/dart-backend/angel3-examples) for a spin to get a feel of what Angel3 framework can do. ## Community Join us on [Discord](https://discord.gg/3X6bxTUdCM). ## Contributing If you are interested in contributing to Angel3 framework please check out the [Contribution Guide](CONTRIBUTING.md). ### Development Setup 1. Fork [angel](https://github.com/dart-backend/angel) repository 2. Clone the project to local and create a new branch ```bash git clone https://github.com//angel.git git checkout -b feature/ ``` 3. Download and install [Dart 3](https://dart.dev/get-dart) 4. Install `melos:7.3` ```bash dart pub global activate melos ``` 5. Run `melos exec "dart pub upgrade"` to update all the packages 6. Contribute changes to the desired packages ## Donation & Support If you like this project and interested in supporting its development work, you are welcome to make a donation via the following links. * [![GitHub Sponsor](https://img.shields.io/static/v1?label=Sponsor&message=%E2%9D%A4&logo=GitHub&color=%23fe8e86)](https://github.com/sponsors/dukefirehawk) * [Paypal Donation](https://paypal.me/dukefirehawk?country.x=MY&locale.x=en_US) ### Paid Support We offer professional paid support for teams and developers using `Angel3` framework. Our support services are designed to help you build faster, deploy with confidence, and scale reliably, whether you’re just getting started or running the framework in production. The fund collected will go into continued improvements of the framework. #### What we can help with * Architecture and best-practice guidance * Framework setup, configuration, and upgrades * Debugging runtime, performance, or build issues * Production readiness (scaling, monitoring, deployment) * Code reviews and design feedback * Custom feature guidance and extensions #### Who this is for * Teams using or planning to use `Angel3` in production * Developers who want expert guidance from people who maintain the framework * Migration from other dart or none dart framework #### Support options We offer flexible plans depending on your needs: * Hourly support for one-off issues * Monthly retainers for ongoing help * Consulting sessions for architecture and planning Support is available via email, chat, and scheduled calls. #### Why paid support? Paid support ensures you get reliable, professional assistance when it matters most. #### Get in touch If you’re interested in paid support, contact us at [dukefirehawk.apps@gmail.com] with your contact and use cases. We will get back within 24 hours. ================================================ FILE: TODO.md ================================================ # TODO * `angel3_container_generator` upgrade blocked by `reflectable` not supporting `analyzer` > 7.7.0 * Improve HTTP and ORM performance * Add cache support in ORM (using Redis) * Upgrade and release angel3_oauth2 8.0.0 (5 failed test cases) * Upgrade and release angel3_auth_twitter 8.0.0 (Migrate to OAuth2) * Upgrade and release angel3_shelf 8.0.0 (2 failed test cases) * [ORM] custom column name is not working. i.e @Column(name: "randomNumber") ================================================ FILE: archived/tool/archived/move_repos ================================================ #!/usr/bin/env python from __future__ import print_function import os from github import Github github_token = os.getenv("GITHUB_TOKEN") packages_dir = "./packages" if not github_token: print("$GITHUB_TOKEN environment variable missing.") quit() gh = Github(github_token) for basename in os.listdir(packages_dir): path = os.path.join(packages_dir, basename) if os.path.isdir(path): print("===Entering repo `" + basename + "`") repo = gh.get_repo("angel-dart/" + basename) if repo.owner.login != "angel-dart-archive": # Manually do the transfer... params = {"new_owner": "angel-dart-archive"} repo._requester.requestJsonAndCheck( "POST", repo.url + "/transfer", input=params, ) print("======Transferred `" + basename + "` to angel-dart-archive") if repo.archived: print("======SKIPPED ARCHIVED REPO") continue new_desc = "moved to angel-dart/angel/packages/" + basename new_homepage = "https://github.com/angel-dart/angel/tree/master/packages/" + basename if (repo.description != new_desc) or (repo.homepage != new_homepage): repo.edit(description=new_desc, homepage=new_homepage) print("======Changed description+homepage") open_issues = repo.get_issues(state="open") for issue in open_issues: label_name = "package:" + basename label_found = False for label in issue.labels: if label.name == label_name: label_found = True break if not label_found: issue.edit(labels=[label_name]) print("======Labeled issue \"" + issue.title + "\"") # Duplicate the issue in angel-dart/angel... angel = gh.get_repo("angel-dart/angel") body = "*This issue was originally created by @" + issue.user.login body += " here, before being automatically moved: " body += "\n" + issue.html_url body += "*\n\n---\n" + issue.body new_issue = angel.create_issue(title=issue.title, labels=[label_name], body=body) for comment in issue.get_comments(): comment_body = "@" + comment.user.login + " commented:\n\n" + comment.body new_issue.create_comment(comment_body) new_body = "*This issue was automatically moved to: " + new_issue.html_url + "." issue.edit(state='closed', body=new_body) print("======Moved issue \"" + issue.title + "\"") open_pulls = repo.get_pulls(state="open") for pull in open_pulls: msg = "Hi, @" + pull.user.login + "! Thanks again for this PR." msg += "\n\nAll Angel subprojects have been consolidated into a single monorepo: " msg += "https://github.com/angel-dart/angel." msg += "\n\nPlease fork the monorepo, and open a new PR there instead." pull.create_issue_comment(msg) pull.edit(state='closed') print("======Commented on + closed PR \"" + pull.title + "\"") # Archive the repository! repo.edit(archived=True) print("======Archived `" + basename + "`. Rest in Peace!") ================================================ FILE: archived/tool/archived/pull_subproject ================================================ #!/usr/bin/env bash # # Simple tool script that pulls an angel-dart/ project into ./packages/. if [ "$#" == "0" ]; then echo "usage: pull_subproject " exit 1 fi set -ex for project in $*; do git subtree add --prefix="packages/$project" "https://github.com/angel-dart/$project.git" master done ================================================ FILE: belatuk.session.sql ================================================ ================================================ FILE: doc/deployment/docker/README.md ================================================ # Running as Container Services using Docker The required applications by the framework can be run using the Docker compose files provided in this folder. ## Installation ### PostreSQL * Starting the PostreSQL container ```bash docker compose -f docker-compose-pg.yml -p pg up -d ``` * Stopping the PostreSQL container ```bash docker compose -f docker-compose-pg.yml -p pg stop docker compose -f docker-compose-pg.yml -p pg down ``` * Checking the PostreSQL container log ```bash docker logs docker-pg-1 -f ``` * Running psql ```bash docker exec -it /bin/bash psql --username postgres ``` * Create PostgreSQL database, user and grant access ```sql create database orm_test; create user test with encrypted password 'test123'; grant all privileges on database orm_test to test; ``` ### MariaDB * Starting the MariaDB container ```bash docker compose -f docker-compose-mariadb.yml -p maria up -d ``` * Stopping the MariaDB container ```bash docker compose -f docker-compose-mariadb.yml -p maria stop docker compose -f docker-compose-mariadb.yml -p maria down ``` * Checking the MariaDB container log ```bash docker logs maria-mariadb-1 -f ``` * Create MariaDB database, user and grant access ```sql create database orm_test; -- Granting localhost access only create user 'test'@'localhost' identified by 'test123'; grant all privileges on orm_test.* to 'test'@'localhost'; -- Granting localhost and remote access create user 'test'@'%' identified by 'test123'; grant all privileges on orm_test.* to 'test'@'%'; ``` ### MySQL * Starting the MySQL container ```bash docker compose -f docker-compose-mysql.yml -p mysql up -d ``` * Stopping the MySQL container ```bash docker compose -f docker-compose-mysql.yml -p mysql stop docker compose -f docker-compose-mysql.yml -p mysql down ``` * Checking the MySQL container log ```bash docker logs mysql-mysql-1 -f ``` * Create MySQL database, user and grant access ```sql create database orm_test; -- Granting localhost access only create user 'test'@'localhost' identified by 'test123'; grant all privileges on orm_test.* to 'test'@'localhost'; -- Granting localhost and remote access create user 'test'@'%' identified by 'test123'; grant all privileges on orm_test.* to 'test'@'%'; ``` ### MongoDB * Starting the MongoDB container ```bash docker compose -f docker-compose-mongo.yml -p mongo up -d ``` * Stopping the MongoDB container ```bash docker compose -f docker-compose-mongo.yml -p mongo stop docker compose -f docker-compose-mongo.yml -p mongo down ``` * Checking the MongoDB container log ```bash docker logs mongo-mongo-1 -f ``` ### rethinkDB * Starting the rethinkDB container ```bash docker compose -f docker-compose-rethinkdb.yml -p rethink up -d ``` * Stopping the rethinkDB container ```bash docker compose -f docker-compose-rethinkdb.yml -p rethink stop docker compose -f docker-compose-rethinkdb.yml -p rethink down ``` * Checking the rethinkDB container log ```bash docker logs rethink-rethinkdb-1 -f ``` ### Redis * Starting the Redis container ```bash docker compose -f docker-compose-redis.yml -p redis up -d ``` * Stopping the Redis container ```bash docker compose -f docker-compose-redis.yml -p redis stop docker compose -f docker-compose-redis.yml -p redis down ``` * Checking the Redis container log ```bash docker logs redis-redis-1 -f ``` ================================================ FILE: doc/deployment/docker/docker-compose-mariadb.yml ================================================ services: mariadb: image: mariadb:latest restart: "no" ports: - "3306:3306" environment: - MARIADB_ROOT_PASSWORD=Qwerty - MARIADB_DATABASE=orm_test - MARIADB_USER=test - MARIADB_PASSWORD=Test123 networks: - appnet adminer: image: adminer:latest restart: "no" ports: - 8080:8080 networks: - appnet networks: appnet: ================================================ FILE: doc/deployment/docker/docker-compose-mongo.yml ================================================ services: mongo: image: mongo:latest restart: no ports: - 27017:27017 environment: MONGO_INITDB_ROOT_USERNAME: root MONGO_INITDB_ROOT_PASSWORD: Qwerty MONGO_INITDB_DATABASE: local networks: - appnet mongo-express: image: mongo-express:latest restart: no depends_on: - mongo ports: - 8081:8081 environment: ME_CONFIG_MONGODB_ADMINUSERNAME: root ME_CONFIG_MONGODB_ADMINPASSWORD: Qwerty ME_CONFIG_MONGODB_URL: mongodb://root:Qwerty@mongo:27017/ ME_CONFIG_BASICAUTH: false networks: - appnet networks: appnet: ================================================ FILE: doc/deployment/docker/docker-compose-mysql.yml ================================================ services: mysql: image: mysql:latest restart: "no" ports: - "3306:3306" environment: - MYSQL_ROOT_PASSWORD=Qwerty - MYSQL_DATABASE=orm_test - MYSQL_USER=test - MYSQL_PASSWORD=Test123 # volumes: # - C://storage/mysql:/var/lib/mysql:ro networks: - appnet #volumes: # mysql-data-external: # driver: local networks: appnet: ================================================ FILE: doc/deployment/docker/docker-compose-pg.yml ================================================ services: pgdb: image: postgres:latest restart: "no" ports: - "5432:5432" environment: - POSTGRES_USER=postgres - POSTGRES_PASSWORD=postgres networks: - appnet pgadmin4: image: dpage/pgadmin4:latest restart: "no" ports: - "5050:80" environment: - PGADMIN_DEFAULT_EMAIL=admin@mydomain.com - PGADMIN_DEFAULT_PASSWORD=Qwerty networks: - appnet networks: appnet: ================================================ FILE: doc/deployment/docker/docker-compose-redis.yml ================================================ services: redis: image: redis:latest restart: "no" ports: - "5432:5432" environment: - POSTGRES_USER=postgres - POSTGRES_PASSWORD=postgres networks: - appnet networks: appnet: ================================================ FILE: doc/deployment/docker/docker-compose-rethinkdb.yml ================================================ services: rethinkdb: image: rethinkdb:latest restart: "no" ports: - "8080:8080" - "28015:28015" - "29015:29015" networks: - appnet networks: appnet: ================================================ FILE: doc/deployment/helm_chart/README.md ================================================ # Running as Container Services using Helm Chart To be available soon ================================================ FILE: doc/deployment/podman/README.md ================================================ # Running as Container Services using Podman The required applications by the framework can be run using the Docker compose files provided in this folder. ## Installation ### PostreSQL * Starting the PostreSQL container ```bash podman-compose -f podman-compose-pg.yml -p pg up -d ``` * Stopping the PostreSQL container ```bash podman-compose -f podman-compose-pg.yml -p pg stop podman-compose -f podman-compose-pg.yml -p pg down ``` * Checking the PostreSQL container log ```bash podman logs -f podman-pg-1 ``` * Running psql ```bash podman exec -it /bin/bash psql --username postgres ``` * Create PostgreSQL database, user and grant access ```sql create database orm_test; create user test with encrypted password 'test123'; grant all privileges on database orm_test to test; ``` ### MariaDB * Starting the MariaDB container ```bash podman-compose -f podman-compose-mariadb.yml -p maria up -d ``` * Stopping the MariaDB container ```bash podman-compose -f podman-compose-mariadb.yml -p maria stop podman-compose -f podman-compose-mariadb.yml -p maria down ``` * Checking the MariaDB container log ```bash podman logs -f maria-mariadb-1 ``` * Create MariaDB database, user and grant access ```sql create database orm_test; -- Granting localhost access only create user 'test'@'localhost' identified by 'test123'; grant all privileges on orm_test.* to 'test'@'localhost'; -- Granting localhost and remote access create user 'test'@'%' identified by 'test123'; grant all privileges on orm_test.* to 'test'@'%'; ``` ### MySQL * Starting the MySQL container ```bash podman-compose -f podman-compose-mysql.yml -p mysql up -d ``` * Stopping the MySQL container ```bash podman-compose -f podman-compose-mysql.yml -p mysql stop podman-compose -f podman-compose-mysql.yml -p mysql down ``` * Checking the MySQL container log ```bash podman logs -f mysql-mysql-1 ``` * Create MySQL database, user and grant access ```sql create database orm_test; -- Granting localhost access only create user 'test'@'localhost' identified by 'test123'; grant all privileges on orm_test.* to 'test'@'localhost'; -- Granting localhost and remote access create user 'test'@'%' identified by 'test123'; grant all privileges on orm_test.* to 'test'@'%'; ``` ### MongoDB * Starting the MongoDB container ```bash podman-compose -f podman-compose-mongo.yml -p mongo up -d ``` * Stopping the MongoDB container ```bash podman-compose -f podman-compose-mongo.yml -p mongo stop podman-compose -f podman-compose-mongo.yml -p mongo down ``` * Checking the MongoDB container log ```bash podman logs -f mongo-mongo-1 ``` ### rethinkDB * Starting the rethinkDB container ```bash podman-compose -f podman-compose-rethinkdb.yml -p rethink up -d ``` * Stopping the rethinkDB container ```bash podman-compose -f podman-compose-rethinkdb.yml -p rethink stop podman-compose -f podman-compose-rethinkdb.yml -p rethink down ``` * Checking the rethinkDB container log ```bash podman logs -f rethink-rethinkdb-1 ``` ### Redis * Starting the Redis container ```bash podman-compose -f podman-compose-redis.yml -p redis up -d ``` * Stopping the Redis container ```bash podman-compose -f podman-compose-redis.yml -p redis stop podman-compose -f podman-compose-redis.yml -p redis down ``` * Checking the Redis container log ```bash podman logs -f redis-redis-1 ``` ================================================ FILE: doc/deployment/podman/podman-compose-mariadb.yml ================================================ services: mariadb: image: docker.io/mariadb:latest restart: "no" ports: - "3306:3306" environment: - MARIADB_ROOT_PASSWORD=Qwerty - MARIADB_DATABASE=orm_test - MARIADB_USER=test - MARIADB_PASSWORD=Test123 networks: - appnet adminer: image: docker.io/adminer:latest restart: "no" ports: - 8080:8080 networks: - appnet networks: appnet: ================================================ FILE: doc/deployment/podman/podman-compose-mongo.yml ================================================ services: mongo: image: docker.io/mongo:latest restart: no ports: - 27017:27017 environment: MONGO_INITDB_ROOT_USERNAME: root MONGO_INITDB_ROOT_PASSWORD: Qwerty MONGO_INITDB_DATABASE: local networks: - appnet mongo-express: image: docker.io/mongo-express:latest restart: no depends_on: - mongo ports: - 8081:8081 environment: ME_CONFIG_MONGODB_ADMINUSERNAME: root ME_CONFIG_MONGODB_ADMINPASSWORD: Qwerty ME_CONFIG_MONGODB_URL: mongodb://root:Qwerty@mongo:27017/ ME_CONFIG_BASICAUTH: false networks: - appnet networks: appnet: ================================================ FILE: doc/deployment/podman/podman-compose-mysql.yml ================================================ services: mysql: image: docker.io/mysql:latest restart: "no" ports: - "3306:3306" environment: - MYSQL_ROOT_PASSWORD=Qwerty - MYSQL_DATABASE=orm_test - MYSQL_USER=test - MYSQL_PASSWORD=Test123 # volumes: # - C://storage/mysql:/var/lib/mysql:ro networks: - appnet #volumes: # mysql-data-external: # driver: local networks: appnet: ================================================ FILE: doc/deployment/podman/podman-compose-pg.yml ================================================ services: pgdb: image: docker.io/postgres:latest restart: "no" ports: - "5432:5432" environment: - POSTGRES_USER=postgres - POSTGRES_PASSWORD=postgres networks: - appnet pgadmin4: image: docker.io/dpage/pgadmin4:latest restart: "no" ports: - "5050:80" environment: - PGADMIN_DEFAULT_EMAIL=admin@mydomain.com - PGADMIN_DEFAULT_PASSWORD=Qwerty networks: - appnet networks: appnet: ================================================ FILE: doc/deployment/podman/podman-compose-redis.yml ================================================ services: redis: image: docker.io/redis:latest restart: "no" ports: - "5432:5432" environment: - POSTGRES_USER=postgres - POSTGRES_PASSWORD=postgres networks: - appnet networks: appnet: ================================================ FILE: doc/deployment/podman/podman-compose-rethinkdb.yml ================================================ services: rethinkdb: image: docker.io/rethinkdb:latest restart: "no" ports: - "8080:8080" - "28015:28015" - "29015:29015" networks: - appnet networks: appnet: ================================================ FILE: doc/deployment/rancher/README.md ================================================ # Running as Container Services using Rancher The required applications by the framework can be run using the Docker compose files provided in this folder. ## Installation ### PostreSQL * Starting the PostreSQL container ```bash nerdctl compose -f rancher-compose-pg.yml -p pg up -d ``` * Stopping the PostreSQL container ```bash nerdctl compose -f rancher-compose-pg.yml -p pg stop nerdctl compose -f rancher-compose-pg.yml -p pg down ``` * Checking the PostreSQL container log ```bash nerdctl logs rancher-pg-1 -f ``` * Running psql ```bash nerdctl exec -it /bin/bash psql --username postgres ``` * Create PostgreSQL database, user and grant access ```sql create database orm_test; create user test with encrypted password 'test123'; grant all privileges on database orm_test to test; ``` ### MariaDB * Starting the MariaDB container ```bash nerdctl compose -f rancher-compose-mariadb.yml -p maria up -d ``` * Stopping the MariaDB container ```bash nerdctl compose -f rancher-compose-mariadb.yml -p maria stop nerdctl compose -f rancher-compose-mariadb.yml -p maria down ``` * Checking the MariaDB container log ```bash nerdctl logs maria-mariadb-1 -f ``` * Create MariaDB database, user and grant access ```sql create database orm_test; -- Granting localhost access only create user 'test'@'localhost' identified by 'test123'; grant all privileges on orm_test.* to 'test'@'localhost'; -- Granting localhost and remote access create user 'test'@'%' identified by 'test123'; grant all privileges on orm_test.* to 'test'@'%'; ``` ### MySQL * Starting the MySQL container ```bash nerdctl compose -f rancher-compose-mysql.yml -p mysql up -d ``` * Stopping the MySQL container ```bash nerdctl compose -f rancher-compose-mysql.yml -p mysql stop nerdctl compose -f rancher-compose-mysql.yml -p mysql down ``` * Checking the MySQL container log ```bash nerdctl logs mysql-mysql-1 -f ``` * Create MySQL database, user and grant access ```sql create database orm_test; -- Granting localhost access only create user 'test'@'localhost' identified by 'test123'; grant all privileges on orm_test.* to 'test'@'localhost'; -- Granting localhost and remote access create user 'test'@'%' identified by 'test123'; grant all privileges on orm_test.* to 'test'@'%'; ``` ### MongoDB * Starting the MongoDB container ```bash nerdctl compose -f rancher-compose-mongo.yml -p mongo up -d ``` * Stopping the MongoDB container ```bash nerdctl compose -f rancher-compose-mongo.yml -p mongo stop nerdctl compose -f rancher-compose-mongo.yml -p mongo down ``` * Checking the MongoDB container log ```bash nerdctl logs mongo-mongo-1 -f ``` ### rethinkDB * Starting the rethinkDB container ```bash nerdctl compose -f rancher-compose-rethinkdb.yml -p rethink up -d ``` * Stopping the rethinkDB container ```bash nerdctl compose -f rancher-compose-rethinkdb.yml -p rethink stop nerdctl compose -f rancher-compose-rethinkdb.yml -p rethink down ``` * Checking the rethinkDB container log ```bash nerdctl logs rethink-rethinkdb-1 -f ``` ### Redis * Starting the Redis container ```bash nerdctl compose -f rancher-compose-redis.yml -p redis up -d ``` * Stopping the Redis container ```bash nerdctl compose -f rancher-compose-redis.yml -p redis stop nerdctl compose -f rancher-compose-redis.yml -p redis down ``` * Checking the Redis container log ```bash nerdctl logs redis-redis-1 -f ``` ================================================ FILE: doc/deployment/rancher/rancher-compose-mariadb.yml ================================================ services: mariadb: image: mariadb:latest restart: "no" ports: - "3306:3306" environment: - MARIADB_ROOT_PASSWORD=Qwerty - MARIADB_DATABASE=orm_test - MARIADB_USER=test - MARIADB_PASSWORD=Test123 networks: - appnet adminer: image: adminer:latest restart: "no" ports: - 8080:8080 networks: - appnet networks: appnet: ================================================ FILE: doc/deployment/rancher/rancher-compose-mongo.yml ================================================ services: mongo: image: mongo:latest restart: no ports: - 27017:27017 environment: MONGO_INITDB_ROOT_USERNAME: root MONGO_INITDB_ROOT_PASSWORD: Qwerty MONGO_INITDB_DATABASE: local networks: - appnet mongo-express: image: mongo-express:latest restart: no depends_on: - mongo ports: - 8081:8081 environment: ME_CONFIG_MONGODB_ADMINUSERNAME: root ME_CONFIG_MONGODB_ADMINPASSWORD: Qwerty ME_CONFIG_MONGODB_URL: mongodb://root:Qwerty@mongo:27017/ ME_CONFIG_BASICAUTH: false networks: - appnet networks: appnet: ================================================ FILE: doc/deployment/rancher/rancher-compose-mysql.yml ================================================ services: mysql: image: mysql:latest restart: "no" ports: - "3306:3306" environment: - MYSQL_ROOT_PASSWORD=Qwerty - MYSQL_DATABASE=orm_test - MYSQL_USER=test - MYSQL_PASSWORD=Test123 # volumes: # - C://storage/mysql:/var/lib/mysql:ro networks: - appnet #volumes: # mysql-data-external: # driver: local networks: appnet: ================================================ FILE: doc/deployment/rancher/rancher-compose-pg.yml ================================================ services: pgdb: image: postgres:latest restart: "no" ports: - "5432:5432" environment: - POSTGRES_USER=postgres - POSTGRES_PASSWORD=postgres networks: - appnet pgadmin4: image: dpage/pgadmin4:latest restart: "no" ports: - "5050:80" environment: - PGADMIN_DEFAULT_EMAIL=admin@mydomain.com - PGADMIN_DEFAULT_PASSWORD=Qwerty networks: - appnet networks: appnet: ================================================ FILE: doc/deployment/rancher/rancher-compose-redis.yml ================================================ services: redis: image: redis:latest restart: "no" ports: - "5432:5432" environment: - POSTGRES_USER=postgres - POSTGRES_PASSWORD=postgres networks: - appnet networks: appnet: ================================================ FILE: doc/deployment/rancher/rancher-compose-rethinkdb.yml ================================================ services: rethinkdb: image: rethinkdb:latest restart: "no" ports: - "8080:8080" - "28015:28015" - "29015:29015" networks: - appnet networks: appnet: ================================================ FILE: melos.yaml ================================================ name: angel3 packages: - packages/http_exception - packages/route - packages/model - packages/serialize/angel_serialize - packages/serialize/angel_serialize_generator - packages/container/angel_container - packages/container/angel_container_generator - packages/mock_request - packages/framework - packages/user_agent/angel_user_agent - packages/validate - packages/redis - packages/cache - packages/configuration - packages/cors - packages/auth - packages/auth_oauth2 # - packages/auth_twitter - packages/file_service - packages/html - packages/client - packages/websocket - packages/hot - packages/production - packages/test - packages/sync - packages/oauth2 - packages/security - packages/proxy - packages/paginate - packages/static - packages/jael/jael - packages/jael/jael_preprocessor - packages/jael/angel_jael - packages/jael/jael_language_server - packages/jael/jael_web - packages/jinja - packages/markdown - packages/mustache - packages/seo - packages/mongo - packages/rethinkdb - packages/sembast - packages/orm/angel_migration - packages/orm/angel_migration_runner - packages/orm/angel_orm - packages/orm/angel_orm_generator - packages/orm/angel_orm_postgres - packages/orm/angel_orm_mysql - packages/orm/angel_orm_service - packages/shelf #scripts: # analyze: melos exec -- "dart analyze ." ================================================ FILE: melos_angel3.iml ================================================ ================================================ FILE: packages/cache/.gitignore ================================================ # See https://www.dartlang.org/tools/private-files.html # Files and directories created by pub .packages .pub/ build/ # If you're building an application, you may want to check-in your pubspec.lock pubspec.lock # Directory created by dartdoc # If you don't generate documentation locally you can remove this line. doc/api/ ### JetBrains template # Covers JetBrains IDEs: IntelliJ, RubyMine, PhpStorm, AppCode, PyCharm, CLion, Android Studio and Webstorm # Reference: https://intellij-support.jetbrains.com/hc/en-us/articles/206544839 # User-specific stuff: .idea/**/workspace.xml .idea/**/tasks.xml .idea/dictionaries # Sensitive or high-churn files: .idea/**/dataSources/ .idea/**/dataSources.ids .idea/**/dataSources.xml .idea/**/dataSources.local.xml .idea/**/sqlDataSources.xml .idea/**/dynamic.xml .idea/**/uiDesigner.xml # Gradle: .idea/**/gradle.xml .idea/**/libraries # CMake cmake-build-debug/ # Mongo Explorer plugin: .idea/**/mongoSettings.xml ## File-based project format: *.iws ## Plugin-specific files: # IntelliJ out/ # mpeltonen/sbt-idea plugin .idea_modules/ # JIRA plugin atlassian-ide-plugin.xml # Cursive Clojure plugin .idea/replstate.xml # Crashlytics plugin (for Android Studio and IntelliJ) com_crashlytics_export_strings.xml crashlytics.properties crashlytics-build.properties fabric.properties .dart_tool ================================================ FILE: packages/cache/AUTHORS.md ================================================ 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. * __[Tobe O](thosakwe@gmail.com)__ Tobe has written much of the original code prior to NNBD migration. He has moved on and is no longer involved with the project. ================================================ FILE: packages/cache/CHANGELOG.md ================================================ # Change Log ## 8.5.0 * Require Dart >= 3.11 ## 8.4.0 * Require Dart >= 3.8 * Updated `lints` to 6.0.0 * Updated dependencies to the latest release ## 8.3.0 * Require Dart >= 3.6 * Updated `lints` to 5.0.0 * Updated dependencies to the latest release ## 8.2.0 * Require Dart >= 3.3 * Updated `lints` to 4.0.0 ## 8.1.1 * Updated repository link ## 8.1.0 * Updated `lints` to 3.0.0 * Fixed linter warnings ## 8.0.0 * Require Dart >= 3.0 ## 7.0.0 * Require Dart >= 2.17 ## 6.0.0 * Require Dart >= 2.16 ## 5.0.0 * Skipped release ## 4.0.3 * Updated linter to `package:lints` ## 4.0.2 * Updated README * Added home page link * All 7 unit tests passed ## 4.0.1 * Updated pubspec description * Fixed: Return `200` with cached data instead of `403` * Updated broken unit tests ## 4.0.0 * Migrated to support Dart >= 2.12 NNBD ## 3.0.0 * Migrated to work with Dart >= 2.12 Non NNBD ## 2.0.1 * Add `ignoreQueryAndFragment` to `ResponseCache`. * Rename `CacheService.ignoreQuery` to `ignoreParams`. ## 1.0.0 * First version ================================================ FILE: packages/cache/LICENSE ================================================ BSD 3-Clause License Copyright (c) 2021, dukefirehawk.com All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: 1. Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. 2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. 3. Neither the name of the copyright holder nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. ================================================ FILE: packages/cache/README.md ================================================ # Angel3 HTTP Cache ![Pub Version (including pre-releases)](https://img.shields.io/pub/v/angel3_cache?include_prereleases) [![Null Safety](https://img.shields.io/badge/null-safety-brightgreen)](https://dart.dev/null-safety) [![Discord](https://img.shields.io/discord/1060322353214660698)](https://discord.gg/3X6bxTUdCM) [![License](https://img.shields.io/github/license/dart-backend/angel)](https://github.com/dart-backend/angel/tree/master/packages/cache/LICENSE) A service that provides HTTP caching to the response data for [Angel3 framework](https://pub.dev/packages/angel3). ## `CacheService` A `Service` class that caches data from one service, storing it in another. An imaginable use case is storing results from MongoDB or another database in Memcache/Redis. ## `cacheSerializationResults` A middleware that enables the caching of response serialization. This can improve the performance of sending objects that are complex to serialize. You can pass a [shouldCache] callback to determine which values should be cached. ```dart void main() async { var app = Angel()..lazyParseBodies = true; app.use( '/api/todos', CacheService( database: AnonymousService( index: ([params]) { print('Fetched directly from the underlying service at ${DateTime.now()}!'); return ['foo', 'bar', 'baz']; }, read: (id, [params]) { return {id: '$id at ${DateTime.now()}'}; } ), ), ); } ``` ## `ResponseCache` A flexible response cache for Angel3. Use this to improve real and perceived response of Web applications, as well as to memorize expensive responses. Supports the `If-Modified-Since` header, as well as storing the contents of response buffers in memory. To initialize a simple cache: ```dart Future configureServer(Angel app) async { // Simple instance. var cache = ResponseCache(); // You can also pass an invalidation timeout. var cache = ResponseCache(timeout: const Duration(days: 2)); // Close the cache when the application closes. app.shutdownHooks.add((_) => cache.close()); // Use `patterns` to specify which resources should be cached. cache.patterns.addAll([ 'robots.txt', RegExp(r'\.(png|jpg|gif|txt)$'), Glob('public/**/*'), ]); // REQUIRED: The middleware that serves cached responses app.use(cache.handleRequest); // REQUIRED: The response finalizer that saves responses to the cache app.responseFinalizers.add(cache.responseFinalizer); } ``` ### Purging the Cache Call `invalidate` to remove a resource from a `ResponseCache`. Some servers expect a reverse proxy or caching layer to support `PURGE` requests. If this is your case, make sure to include some sort of validation (maybe IP-based) to ensure no arbitrary attacker can hack your cache: ```dart Future configureServer(Angel app) async { app.addRoute('PURGE', '*', (req, res) { if (req.ip != '127.0.0.1') throw AngelHttpException.forbidden(); return cache.purge(req.uri.path); }); } ``` ================================================ FILE: packages/cache/analysis_options.yaml ================================================ include: package:lints/recommended.yaml ================================================ FILE: packages/cache/example/cache_service.dart ================================================ import 'package:angel3_cache/angel3_cache.dart'; import 'package:angel3_framework/angel3_framework.dart'; import 'package:angel3_framework/http.dart'; void main() async { var app = Angel(); app.use( '/api/todos', CacheService( cache: MapService(), database: AnonymousService( index: ([params]) { print( 'Fetched directly from the underlying service at ${DateTime.now()}!', ); return ['foo', 'bar', 'baz']; }, read: (dynamic id, [params]) { return {id: '$id at ${DateTime.now()}'}; }, ), ), ); var http = AngelHttp(app); var server = await http.startServer('127.0.0.1', 3000); print('Listening at http://${server.address.address}:${server.port}'); } ================================================ FILE: packages/cache/example/main.dart ================================================ import 'package:angel3_cache/angel3_cache.dart'; import 'package:angel3_framework/angel3_framework.dart'; import 'package:angel3_framework/http.dart'; void main() async { var app = Angel(); // Cache a glob var cache = ResponseCache()..patterns.addAll([RegExp('^/?\\w+\\.txt')]); // Handle `if-modified-since` header, and also send cached content app.fallback(cache.handleRequest); // A simple handler that returns a different result every time. app.get( '/date.txt', (req, res) => res.write(DateTime.now().toIso8601String()), ); // Support purging the cache. app.addRoute('PURGE', '*', (req, res) { if (req.ip != '127.0.0.1') { throw AngelHttpException.forbidden(); } cache.purge(req.uri!.path); print('Purged ${req.uri!.path}'); }); // The response finalizer that actually saves the content app.responseFinalizers.add(cache.responseFinalizer); var http = AngelHttp(app); var server = await http.startServer('127.0.0.1', 3000); print('Listening at http://${server.address.address}:${server.port}'); } ================================================ FILE: packages/cache/lib/angel3_cache.dart ================================================ export 'src/cache.dart'; export 'src/cache_service.dart'; export 'src/serializer.dart'; ================================================ FILE: packages/cache/lib/src/cache.dart ================================================ import 'dart:async'; import 'dart:io' show HttpDate; import 'package:angel3_framework/angel3_framework.dart'; import 'package:pool/pool.dart'; import 'package:logging/logging.dart'; /// A flexible response cache for Angel. /// /// Use this to improve real and perceived response of Web applications, /// as well as to memorize expensive responses. class ResponseCache { /// A set of [Patterns] for which responses will be cached. /// /// For example, you can pass a `Glob` matching `**/*.png` files to catch all PNG images. final List patterns = []; /// An optional timeout, after which a given response will be removed from the cache, and the contents refreshed. final Duration timeout; final Map _cache = {}; final Map _writeLocks = {}; /// If `true` (default: `false`), then caching of results will discard URI query parameters and fragments. final bool ignoreQueryAndFragment; final log = Logger('ResponseCache'); ResponseCache({ this.timeout = const Duration(minutes: 10), this.ignoreQueryAndFragment = false, }); /// Closes all internal write-locks, and closes the cache. Future close() async { _writeLocks.forEach((_, p) => p.close()); } /// Removes an entry from the response cache. void purge(String path) => _cache.remove(path); /// A middleware that handles requests with an `If-Modified-Since` header. /// /// This prevents the server from even having to access the cache, and plays very well with static assets. Future ifModifiedSince(RequestContext req, ResponseContext res) async { if (req.method != 'GET' && req.method != 'HEAD') { return true; } var modifiedSince = req.headers?.ifModifiedSince; if (modifiedSince != null) { // Check if there is a cache entry. for (var pattern in patterns) { var reqPath = _getEffectivePath(req); if (pattern.allMatches(reqPath).isNotEmpty && _cache.containsKey(reqPath)) { var response = _cache[reqPath]; //log.info('timestamp ${response?.timestamp} vs since $modifiedSince'); if (response != null && response.timestamp.compareTo(modifiedSince) <= 0) { // If the cache timeout has been met, don't send the cached response. var timeDiff = DateTime.now().toUtc().difference( response.timestamp, ); //log.info( // 'Time Diff: ${timeDiff.inMilliseconds} >= ${timeout.inMilliseconds}'); if (timeDiff.inMilliseconds >= timeout.inMilliseconds) { return true; } // Old code: res.statusCode = 304; // Return the response stored in the cache _setCachedHeaders(response.timestamp, req, res); res ..headers.addAll(response.headers) ..add(response.body); await res.close(); return false; } } } } return true; } String _getEffectivePath(RequestContext req) { if (req.uri == null) { log.severe('Request URI is null'); throw ArgumentError('Request URI is null'); } return ignoreQueryAndFragment == true ? req.uri!.path : req.uri.toString(); } /// Serves content from the cache, if applicable. Future handleRequest(RequestContext req, ResponseContext res) async { if (!await ifModifiedSince(req, res)) return false; if (req.method != 'GET' && req.method != 'HEAD') return true; if (!res.isOpen) return true; // Check if there is a cache entry. // // If `if-modified-since` is present, this check has already been performed. if (req.headers?.ifModifiedSince == null) { for (var pattern in patterns) { if (pattern.allMatches(_getEffectivePath(req)).isNotEmpty) { var now = DateTime.now().toUtc(); if (_cache.containsKey(_getEffectivePath(req))) { var response = _cache[_getEffectivePath(req)]; if (response == null || now.difference(response.timestamp) >= timeout) { return true; } _setCachedHeaders(response.timestamp, req, res); res ..headers.addAll(response.headers) ..add(response.body); await res.close(); return false; } else { _setCachedHeaders(now, req, res); } } } } return true; } /// A response finalizer that saves responses to the cache. Future responseFinalizer( RequestContext req, ResponseContext res, ) async { if (res.statusCode == 304) { return true; } if (req.method != 'GET' && req.method != 'HEAD') { return true; } // Check if there is a cache entry. for (var pattern in patterns) { var reqPath = _getEffectivePath(req); if (pattern.allMatches(reqPath).isNotEmpty) { var now = DateTime.now().toUtc(); // Invalidate the response, if need be. if (_cache.containsKey(reqPath)) { // If there is no timeout, don't invalidate. //if (timeout == null) return true; // Otherwise, don't invalidate unless the timeout has been exceeded. var response = _cache[reqPath]; if (response == null || now.difference(response.timestamp) < timeout) { return true; } // If the cache entry should be invalidated, then invalidate it. purge(reqPath); } // Save the response. var writeLock = _writeLocks.putIfAbsent(reqPath, () => Pool(1)); await writeLock.withResource(() { if (res.buffer != null) { _cache[reqPath] = _CachedResponse( Map.from(res.headers), res.buffer!.toBytes(), now, ); } }); _setCachedHeaders(now, req, res); } } return true; } void _setCachedHeaders( DateTime modified, RequestContext req, ResponseContext res, ) { var privacy = 'public'; res.headers ..['cache-control'] = '$privacy, max-age=${timeout.inSeconds}' ..['last-modified'] = HttpDate.format(modified); var expiry = DateTime.now().add(timeout); res.headers['expires'] = HttpDate.format(expiry); } } class _CachedResponse { final Map headers; final List body; final DateTime timestamp; _CachedResponse(this.headers, this.body, this.timestamp); } ================================================ FILE: packages/cache/lib/src/cache_service.dart ================================================ import 'dart:async'; import 'package:collection/collection.dart'; import 'package:angel3_framework/angel3_framework.dart'; /// An Angel [Service] that caches data from another service. /// /// This is useful for applications of scale, where network latency /// can have real implications on application performance. class CacheService extends Service { /// The underlying [Service] that represents the original data store. final Service database; /// The [Service] used to interface with a caching layer. /// /// If not provided, this defaults to a [MapService]. final Service cache; /// If `true` (default: `false`), then result caching will discard parameters passed to service methods. /// /// If you want to return a cached result more-often-than-not, you may want to enable this. final bool ignoreParams; final Duration timeout; final Map> _cache = {}; _CachedItem>? _indexed; CacheService({ required this.database, required this.cache, this.timeout = const Duration(minutes: 10), this.ignoreParams = false, }); Future _getCached( Map params, _CachedItem? Function() get, FutureOr Function() getFresh, FutureOr Function() getCached, FutureOr Function(T data, DateTime now) save, ) async { var cached = get(); var now = DateTime.now().toUtc(); if (cached != null) { // If the entry has expired, don't send from the cache var expired = now.difference(cached.timestamp) >= timeout; if (!expired) { // Read from the cache if necessary var queryEqual = ignoreParams == true || (cached.params != null && const MapEquality().equals( params['query'] as Map, cached.params['query'] as Map, )); if (queryEqual) { return await getCached(); } } } // If we haven't fetched from the cache by this point, // let's fetch from the database. var data = await getFresh(); await save(data, now); return data; } @override Future> index([Map? params]) { return _getCached( params ?? {}, () => _indexed, () => database.index(params), () => _indexed?.data ?? [], (data, now) async { _indexed = _CachedItem(params, now, data); return data; }, ); } @override Future read(Id id, [Map? params]) async { return _getCached( params ?? {}, () => _cache[id], () => database.read(id, params), () => cache.read(id), (data, now) async { _cache[id] = _CachedItem(params, now, data); return await cache.modify(id, data); }, ); } @override Future create(data, [Map? params]) { _indexed = null; return database.create(data, params); } @override Future modify(Id id, Data data, [Map? params]) { _indexed = null; _cache.remove(id); return database.modify(id, data, params); } @override Future update(Id id, Data data, [Map? params]) { _indexed = null; _cache.remove(id); return database.modify(id, data, params); } @override Future remove(Id id, [Map? params]) { _indexed = null; _cache.remove(id); return database.remove(id, params); } } class _CachedItem { final dynamic params; final DateTime timestamp; final Data? data; _CachedItem(this.params, this.timestamp, [this.data]); @override String toString() { return '$timestamp:$params:$data'; } } ================================================ FILE: packages/cache/lib/src/serializer.dart ================================================ import 'dart:async'; import 'package:angel3_framework/angel3_framework.dart'; /// A middleware that enables the caching of response serialization. /// /// This can improve the performance of sending objects that are complex to serialize. /// /// You can pass a [shouldCache] callback to determine which values should be cached. RequestHandler cacheSerializationResults({ Duration? timeout, FutureOr Function(RequestContext, ResponseContext, Object)? shouldCache, }) { return (RequestContext req, ResponseContext res) async { var oldSerializer = res.serializer; // TODO: Commented out as it is not doing anything useful var cache = {}; res.serializer = (value) { if (shouldCache == null) { return cache.putIfAbsent(value, () => oldSerializer(value) as String); } return oldSerializer(value); }; return true; }; } ================================================ FILE: packages/cache/melos_angel3_cache.iml ================================================ ================================================ FILE: packages/cache/pubspec.yaml ================================================ name: angel3_cache version: 8.5.0 description: A service that provides HTTP caching to the response data for Angel3 homepage: https://angel3-framework.web.app/ repository: https://github.com/dart-backend/angel/tree/master/packages/cache resolution: workspace environment: sdk: '>=3.11.0 <4.0.0' dependencies: angel3_framework: ^8.4.0 collection: ^1.17.0 meta: ^1.9.0 pool: ^1.5.0 logging: ^1.2.0 dev_dependencies: angel3_test: ^8.2.0 glob: ^2.0.1 http: ^1.0.0 test: ^1.24.0 lints: ^6.0.0 ================================================ FILE: packages/cache/test/cache_test.dart ================================================ import 'dart:async'; import 'dart:io'; import 'package:angel3_cache/angel3_cache.dart'; import 'package:angel3_framework/angel3_framework.dart'; import 'package:angel3_test/angel3_test.dart'; import 'package:http/http.dart' as http; //import 'package:glob/glob.dart'; import 'package:test/test.dart'; import 'package:logging/logging.dart'; Future main() async { Logger.root.level = Level.ALL; Logger.root.onRecord.listen((record) { print( '${record.time}: ${record.level.name}: ${record.loggerName}: ${record.message}', ); }); group('no timeout', () { late TestClient client; DateTime? lastModified; late http.Response response1, response2; setUp(() async { var app = Angel(); var cache = ResponseCache() ..patterns.addAll([ //Glob('/*.txt'), // Requires to create folders and files for testing RegExp('^/?\\w+\\.txt'), ]); app.fallback(cache.handleRequest); app.get('/date.txt', (req, res) { var data = DateTime.now().toIso8601String(); print('Res data: $data'); res ..useBuffer() ..write(data); print('Generate results...'); }); app.addRoute('PURGE', '*', (req, res) { if (req.uri != null) { cache.purge(req.uri!.path); print('Purged ${req.uri!.path}'); } else { print('req.uri is null'); } }); app.responseFinalizers.add(cache.responseFinalizer); var oldHandler = app.errorHandler; app.errorHandler = (e, req, res) { if (e.error == null) { oldHandler(e, req, res); } return Zone.current.handleUncaughtError( e.error as Object, e.stackTrace!, ); }; client = await connectTo(app); response1 = await client.get(Uri.parse('/date.txt')); print('Response 1 status: ${response1.statusCode}'); print('Response 1 headers: ${response1.headers}'); print('Response 1 body: ${response1.body}'); response2 = await client.get(Uri.parse('/date.txt')); print('Response 2 status: ${response2.statusCode}'); print('Response 2 headers: ${response2.headers}'); print('Response 2 body: ${response2.body}'); if (response2.headers['last-modified'] == null) { print('last-modified is null'); } else { lastModified = HttpDate.parse(response2.headers['last-modified']!); } }); tearDown(() => client.close()); test('saves content', () async { expect(response2.body, response1.body); }); test('saves headers', () async { response1.headers.forEach((k, v) { expect(response2.headers, containsPair(k, v)); }); }); test('first response is normal', () { expect(response1.statusCode, 200); }); test('sends last-modified', () { expect(response2.headers.keys, contains('last-modified')); }); test('invalidate', () async { await client.sendUnstreamed('PURGE', '/date.txt', {}); var response = await client.get(Uri.parse('/date.txt')); print('Response after invalidation: ${response.body}'); expect(response.body, isNot(response1.body)); }); test('sends 304 on if-modified-since', () async { lastModified ??= DateTime.now(); var headers = { 'if-modified-since': HttpDate.format( lastModified!.add(const Duration(days: 1)), ), }; var response = await client.get(Uri.parse('/date.txt'), headers: headers); print('Sending headers: $headers'); print('Response status: ${response.statusCode})'); print('Response headers: ${response.headers}'); print('Response body: ${response.body}'); //expect(response.statusCode, 304); expect(response.statusCode, 200); }); test('last-modified in the past', () async { lastModified ??= DateTime.now(); var response = await client.get( Uri.parse('/date.txt'), headers: { 'if-modified-since': HttpDate.format( lastModified!.subtract(const Duration(days: 10)), ), }, ); print('Response: ${response.body}'); expect(response.statusCode, 200); expect(response.body, isNot(response1.body)); }); }); group('with timeout', () {}); } ================================================ FILE: packages/cache/test/files/date.txt ================================================ ================================================ FILE: packages/container/angel_container_generator/.gitignore ================================================ # See https://www.dartlang.org/guides/libraries/private-files # Files and directories created by pub .dart_tool/ .packages .pub/ build/ # If you're building an application, you may want to check-in your pubspec.lock pubspec.lock # Directory created by dartdoc # If you don't generate documentation locally you can remove this line. doc/api/ ================================================ FILE: packages/container/angel_container_generator/CHANGELOG.md ================================================ # Change Log ## 8.5.0 * Require Dart >= 3.11 ## 8.4.0 * Require Dart >= 3.9 * Updated `lints` to 6.0.0 * Updated dependencies to the latest release ## 8.3.0 * Require Dart >= 3.6 * Updated `lints` to 5.0.0 * Updated dependencies to the latest release ## 8.2.0 * Require Dart >= 3.3 * Updated `lints` to 4.0.0 ## 8.1.1 * Updated repository link ## 8.1.0 * Updated `lints` to 3.0.0 * Fixed analyser warnings ## 8.0.0 * Require Dart >= 3.0 ## 7.1.0-beta.1 * Require Dart >= 2.19 * Upgraded `relectable` to 4.x.x ## 7.0.0 * Require Dart >= 2.17 ## 6.0.0 * Require Dart >= 2.16 ## 5.0.0 * Skipped release ## 4.0.0 * Skipped release ## 3.0.1 * Updated `package:angel3_container` ## 3.0.0 * Fixed NNBD issues * All 9 test cases passed ## 3.0.0-beta.1 * Migrated to support Dart >= 2.12 NNBD * Updated linter to `package:lints` * Updated to use `angel3_` packages ## 2.0.0 * Migrated to work with Dart >= 2.12 Non NNBD ## 1.0.1 * Update for `pkg:angel_container@1.0.3`. ================================================ FILE: packages/container/angel_container_generator/LICENSE ================================================ BSD 3-Clause License Copyright (c) 2021, dukefirehawk.com All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: 1. Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. 2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. 3. Neither the name of the copyright holder nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. ================================================ FILE: packages/container/angel_container_generator/README.md ================================================ # Angel3 Container Generator ![Pub Version (including pre-releases)](https://img.shields.io/pub/v/angel3_container_generator?include_prereleases) [![Null Safety](https://img.shields.io/badge/null-safety-brightgreen)](https://dart.dev/null-safety) [![Discord](https://img.shields.io/discord/1060322353214660698)](https://discord.gg/3X6bxTUdCM) [![License](https://img.shields.io/github/license/dart-backend/angel)](https://github.com/dart-backend/angel/tree/master/packages/container/angel3_container_generator/LICENSE) An alternative container for Angel3 that uses `reflectable` package instead of `dart:mirrors` for reflection. However, `reflectable` has more limited relfection capabilities when compared to `dart:mirrors`. ## Usage * Annotable the class with `@contained`. * Run `dart run build_runner build ` * Alternatively create a `build.xml` file with the following content ```yaml targets: $default: builders: reflectable: generate_for: - bin/**_controller.dart options: formatted: true ``` ## Known limitation * Reflection on functions/closures is not supported * Reflection on private declarations is not supported * Reflection on generic type is not supported ================================================ FILE: packages/container/angel_container_generator/analysis_options.yaml ================================================ include: package:lints/recommended.yaml ================================================ FILE: packages/container/angel_container_generator/example/main.dart ================================================ import 'dart:async'; import 'package:angel3_container/angel3_container.dart'; import 'package:angel3_container_generator/angel3_container_generator.dart'; Future main() async { // Create a container instance. Container container = Container(GeneratedReflector()); // Register a singleton. container.registerSingleton(Engine(40)); // You can also omit the type annotation, in which the object's runtime type will be used. // If you're injecting an abstract class, prefer the type annotation. // // container.registerSingleton(Engine(40)); // Register a factory that creates a truck. container.registerFactory((container) { return _TruckImpl(container.make()); }); // Use `make` to create an instance. var truck = container.make(); // You can also resolve injections asynchronously. container.registerFactory>((_) async => 24); print(await container.makeAsync()); // Asynchronous resolution also works for plain objects. await container.makeAsync().then((t) => t.drive()); // Register a named singleton. container.registerNamedSingleton('the_truck', truck); // Should print: 'Vroom! I have 40 horsepower in my engine.' truck.drive(); // Should print the same. container.findByName('the_truck').drive(); // We can make a child container with its own factory. var childContainer = container.createChild(); childContainer.registerFactory((container) { return _TruckImpl(Engine(5666)); }); // Make a truck with 5666 HP. childContainer.make().drive(); // However, calling `make` will return the Engine singleton we created above. print(childContainer.make().horsePower); } abstract class Truck { void drive(); } class Engine { final int horsePower; Engine(this.horsePower); } class _TruckImpl implements Truck { final Engine engine; _TruckImpl(this.engine); @override void drive() { print('Vroom! I have ${engine.horsePower} horsepower in my engine.'); } } ================================================ FILE: packages/container/angel_container_generator/example/main.reflectable.dart ================================================ // This file has been generated by the reflectable package. // https://github.com/dart-lang/reflectable. import 'dart:core'; import 'dart:math' as prefix6; import 'package:angel3_container_generator/angel3_container_generator.dart' as prefix0; import 'package:reflectable/capability.dart' as prefix5; import 'package:reflectable/mirrors.dart' as prefix4; import 'package:reflectable/reflectable.dart' as prefix1; import 'package:reflectable/src/reflectable_base.dart' as prefix3; import 'package:reflectable/src/reflectable_builder_based.dart' as prefix2; // ignore_for_file: camel_case_types // ignore_for_file: implementation_imports // ignore_for_file: prefer_adjacent_string_concatenation // ignore_for_file: prefer_collection_literals // ignore_for_file: unnecessary_const // ignore:unused_import import 'package:reflectable/mirrors.dart' as m; // ignore:unused_import import 'package:reflectable/src/reflectable_builder_based.dart' as r; // ignore:unused_import import 'package:reflectable/reflectable.dart' as r show Reflectable; final _data = { const prefix0.ContainedReflectable(): r.ReflectorData( [ r.NonGenericClassMirrorImpl( r'ContainedReflectable', r'.ContainedReflectable', 134217735, 0, const prefix0.ContainedReflectable(), const [67], const [68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, 79, 80], const [], 1, {}, {}, { r'': (bool b) => () => b ? prefix0.ContainedReflectable() : null, }, 0, 0, const [], const [prefix0.contained], null, ), r.NonGenericClassMirrorImpl( r'Reflectable', r'reflectable.reflectable.Reflectable', 134218247, 1, const prefix0.ContainedReflectable(), const [27, 28, 81, 84, 85], const [68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, 79, 80], const [81, 82, 83], 2, { r'getInstance': () => prefix1.Reflectable.getInstance, r'thisClassName': () => prefix1.Reflectable.thisClassName, r'thisClassId': () => prefix1.Reflectable.thisClassId, }, {}, {}, 1, 1, const [], const [], null, ), r.NonGenericClassMirrorImpl( r'ReflectableImpl', r'reflectable.src.reflectable_builder_based.ReflectableImpl', 134218247, 2, const prefix0.ContainedReflectable(), const [74, 75, 76, 77, 78, 79, 80, 86, 87], const [68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, 79, 80], const [], 3, {}, {}, {}, 2, 2, const [], const [], null, ), r.NonGenericClassMirrorImpl( r'ReflectableBase', r'reflectable.src.reflectable_base.ReflectableBase', 134217735, 3, const prefix0.ContainedReflectable(), const [73, 88, 89], const [68, 69, 70, 71, 72, 73], const [], 4, {}, {}, { r'': (bool b) => ([ _cap0, _cap1, _cap2, _cap3, _cap4, _cap5, _cap6, _cap7, _cap8, _cap9, ]) => b ? prefix3.ReflectableBase( _cap0, _cap1, _cap2, _cap3, _cap4, _cap5, _cap6, _cap7, _cap8, _cap9, ) : null, r'fromList': (bool b) => (_capabilities) => b ? prefix3.ReflectableBase.fromList(_capabilities) : null, }, 3, 3, const [], const [], null, ), r.NonGenericClassMirrorImpl( r'Object', r'dart.core.Object', 134217735, 4, const prefix0.ContainedReflectable(), const [68, 69, 70, 90, 91, 92, 71, 72, 93], const [68, 69, 70, 71, 72], const [90, 91, 92], null, { r'hash': () => Object.hash, r'hashAll': () => Object.hashAll, r'hashAllUnordered': () => Object.hashAllUnordered, }, {}, { r'': (bool b) => () => b ? Object() : null, }, 4, 4, const [], const [], null, ), r.NonGenericClassMirrorImpl( r'Invocation', r'dart.core.Invocation', 134218247, 5, const prefix0.ContainedReflectable(), const [94, 95, 96, 97, 98, 99, 100, 101, 102, 103, 104, 105, 106], const [68, 69, 70, 71, 72, 95, 101], const [], 4, {}, {}, { r'method': (bool b) => (memberName, positionalArguments, [namedArguments]) => b ? Invocation.method( memberName, positionalArguments, namedArguments, ) : null, r'genericMethod': (bool b) => ( memberName, typeArguments, positionalArguments, [ namedArguments, ]) => b ? Invocation.genericMethod( memberName, typeArguments, positionalArguments, namedArguments, ) : null, r'getter': (bool b) => (name) => b ? Invocation.getter(name) : null, r'setter': (bool b) => (memberName, argument) => b ? Invocation.setter(memberName, argument) : null, }, 4, 5, const [], const [], null, ), r.NonGenericClassMirrorImpl( r'Type', r'dart.core.Type', 134218247, 6, const prefix0.ContainedReflectable(), const [107, 108, 109, 110], const [68, 69, 70, 71, 72], const [], 4, {}, {}, {}, 4, 6, const [], const [], null, ), r.NonGenericClassMirrorImpl( r'String', r'dart.core.String', 134218247, 7, const prefix0.ContainedReflectable(), const [ 111, 112, 113, 114, 115, 116, 117, 118, 119, 120, 121, 122, 123, 124, 125, 126, 127, 128, 129, 130, 131, 132, 133, 134, 135, 136, 137, 138, 139, 140, 141, 142, 143, 144, 145, ], const [68, 69, 70, 71, 72], const [], 4, {}, {}, { r'fromCharCodes': (bool b) => (charCodes, [start, end]) => b ? String.fromCharCodes(charCodes, start, end) : null, r'fromCharCode': (bool b) => (charCode) => b ? String.fromCharCode(charCode) : null, r'fromEnvironment': (bool b) => (name, {defaultValue}) => b ? String.fromEnvironment(name, defaultValue: defaultValue) : null, }, 4, 7, const [], const [], null, ), r.NonGenericClassMirrorImpl( r'bool', r'dart.core.bool', 134217735, 8, const prefix0.ContainedReflectable(), const [146, 147, 148, 149, 150, 151, 152, 153, 154], const [68, 151, 70, 152, 72, 148, 149, 150], const [146, 147], 4, {r'parse': () => bool.parse, r'tryParse': () => bool.tryParse}, {}, { r'fromEnvironment': (bool b) => (name, {defaultValue}) => b ? bool.fromEnvironment(name, defaultValue: defaultValue) : null, r'hasEnvironment': (bool b) => (name) => b ? bool.hasEnvironment(name) : null, }, 4, 8, const [], const [], null, ), r.NonGenericClassMirrorImpl( r'int', r'dart.core.int', 134218247, 9, const prefix0.ContainedReflectable(), const [ 155, 156, 157, 158, 159, 160, 161, 162, 163, 164, 165, 166, 167, 168, 169, 170, 171, 172, 173, 174, 175, 176, 177, 178, 179, 180, 181, 182, 183, 184, 185, ], const [68, 69, 70, 71, 72], const [179, 180], -1, {r'parse': () => int.parse, r'tryParse': () => int.tryParse}, {}, { r'fromEnvironment': (bool b) => (name, {defaultValue}) => b ? int.fromEnvironment(name, defaultValue: defaultValue) : null, }, 4, 9, const [], const [], null, ), r.GenericClassMirrorImpl( r'List', r'dart.core.List', 134218247, 10, const prefix0.ContainedReflectable(), const [ 186, 187, 188, 189, 190, 191, 192, 193, 194, 195, 196, 197, 198, 199, 200, 201, 202, 203, 204, 205, 206, 207, 208, 209, 210, 211, 212, 213, 214, 215, 216, 217, 218, 219, 220, 221, 222, 223, 224, 225, 226, 227, 228, ], const [68, 69, 70, 71, 72], const [186, 187, 188], 4, { r'castFrom': () => List.castFrom, r'copyRange': () => List.copyRange, r'writeIterable': () => List.writeIterable, }, {}, { r'filled': (bool b) => (length, fill, {growable}) => b ? List.filled(length, fill, growable: growable) : null, r'empty': (bool b) => ({growable}) => b ? List.empty(growable: growable) : null, r'from': (bool b) => (elements, {growable}) => b ? List.from(elements, growable: growable) : null, r'of': (bool b) => (elements, {growable}) => b ? List.of(elements, growable: growable) : null, r'generate': (bool b) => (length, generator, {growable}) => b ? List.generate(length, generator, growable: growable) : null, r'unmodifiable': (bool b) => (elements) => b ? List.unmodifiable(elements) : null, }, 4, 10, const [15], const [], null, (o) => false, const [17], 10, ), r.NonGenericClassMirrorImpl( r'InstanceMirror', r'reflectable.mirrors.InstanceMirror', 134218247, 11, const prefix0.ContainedReflectable(), const [229, 230, 231, 232, 233, 234, 235], const [68, 69, 70, 71, 72], const [], 4, {}, {}, {}, 5, 11, const [], const [], null, ), r.NonGenericClassMirrorImpl( r'TypeMirror', r'reflectable.mirrors.TypeMirror', 134218247, 12, const prefix0.ContainedReflectable(), const [ 236, 237, 238, 239, 240, 241, 242, 243, 244, 245, 246, 247, 248, 249, ], const [68, 69, 70, 71, 72], const [], 4, {}, {}, {}, 5, 12, const [], const [], null, ), r.NonGenericClassMirrorImpl( r'LibraryMirror', r'reflectable.mirrors.LibraryMirror', 134218247, 13, const prefix0.ContainedReflectable(), const [250, 251, 252, 253, 254, 255, 256], const [68, 69, 70, 71, 72], const [], 4, {}, {}, {}, 5, 13, const [], const [], null, ), r.GenericClassMirrorImpl( r'Map', r'dart.core.Map', 134218247, 14, const prefix0.ContainedReflectable(), const [ 257, 258, 259, 260, 261, 262, 263, 264, 265, 266, 267, 268, 269, 270, 271, 272, 273, 274, 275, 276, 277, 278, 279, 280, 281, 282, 283, 284, 285, 286, ], const [68, 69, 70, 71, 72], const [257], 4, {r'castFrom': () => Map.castFrom}, {}, { r'': (bool b) => () => b ? Map() : null, r'from': (bool b) => (other) => b ? Map.from(other) : null, r'of': (bool b) => (other) => b ? Map.of(other) : null, r'unmodifiable': (bool b) => (other) => b ? Map.unmodifiable(other) : null, r'identity': (bool b) => () => b ? Map.identity() : null, r'fromIterable': (bool b) => (iterable, {key, value}) => b ? Map.fromIterable(iterable, key: key, value: value) : null, r'fromIterables': (bool b) => (keys, values) => b ? Map.fromIterables(keys, values) : null, r'fromEntries': (bool b) => (entries) => b ? Map.fromEntries(entries) : null, }, 4, 14, const [], const [], null, (o) => false, const [18, 19], 14, ), r.GenericClassMirrorImpl( r'Iterable', r'dart.core.Iterable', 134218247, 15, const prefix0.ContainedReflectable(), const [ 287, 288, 289, 290, 291, 292, 293, 294, 295, 296, 297, 298, 299, 300, 301, 302, 303, 304, 305, 306, 307, 308, 309, 310, 311, 312, 313, 314, 315, 316, 317, 318, 319, 320, 321, 322, 323, ], const [ 68, 311, 70, 71, 72, 288, 289, 290, 291, 292, 293, 294, 295, 296, 297, 298, 299, 300, 301, 302, 303, 304, 305, 306, 307, 308, 309, 310, 315, 316, 317, 318, 319, 320, ], const [287, 312, 313], 4, { r'castFrom': () => Iterable.castFrom, r'iterableToShortString': () => Iterable.iterableToShortString, r'iterableToFullString': () => Iterable.iterableToFullString, }, {}, { r'generate': (bool b) => (count, [generator]) => b ? Iterable.generate(count, generator) : null, r'empty': (bool b) => () => b ? Iterable.empty() : null, }, 4, 15, const [], const [], null, (o) => false, const [20], 15, ), r.NonGenericClassMirrorImpl( r'ReflectCapability', r'reflectable.capability.ReflectCapability', 134218247, 16, const prefix0.ContainedReflectable(), const [324], const [68, 69, 70, 71, 72], const [], 4, {}, {}, {}, 6, 16, const [], const [], null, ), r.TypeVariableMirrorImpl( r'E', r'dart.core.List.E', const prefix0.ContainedReflectable(), 4, 10, [], ), r.TypeVariableMirrorImpl( r'K', r'dart.core.Map.K', const prefix0.ContainedReflectable(), 4, 14, [], ), r.TypeVariableMirrorImpl( r'V', r'dart.core.Map.V', const prefix0.ContainedReflectable(), 4, 14, [], ), r.TypeVariableMirrorImpl( r'E', r'dart.core.Iterable.E', const prefix0.ContainedReflectable(), 4, 15, [], ), ], [ r.VariableMirrorImpl( r'contained', 142738581, 0, const prefix0.ContainedReflectable(), 1, 1, 1, const [], const [], ), r.VariableMirrorImpl( r'pleaseInitializeMessage', 142738581, -1, const prefix0.ContainedReflectable(), 7, 7, 7, const [], const [], ), r.VariableMirrorImpl( r'data', 142737429, -1, const prefix0.ContainedReflectable(), 14, 17, 14, const [1, 18], const [], ), r.VariableMirrorImpl( r'memberSymbolMap', 75628565, -1, const prefix0.ContainedReflectable(), 14, 19, 14, const [20, 7], const [], ), r.VariableMirrorImpl( r'deprecated', 142738581, -1, const prefix0.ContainedReflectable(), -1, 21, 21, const [], const [], ), r.VariableMirrorImpl( r'override', 142738581, -1, const prefix0.ContainedReflectable(), 4, 4, 4, const [], const [], ), r.VariableMirrorImpl( r'instanceInvokeCapability', 142738581, -1, const prefix0.ContainedReflectable(), -1, 22, 22, const [], const [], ), r.VariableMirrorImpl( r'staticInvokeCapability', 142738581, -1, const prefix0.ContainedReflectable(), -1, 23, 23, const [], const [], ), r.VariableMirrorImpl( r'topLevelInvokeCapability', 142738581, -1, const prefix0.ContainedReflectable(), -1, 24, 24, const [], const [], ), r.VariableMirrorImpl( r'newInstanceCapability', 142738581, -1, const prefix0.ContainedReflectable(), -1, 25, 25, const [], const [], ), r.VariableMirrorImpl( r'metadataCapability', 142738581, -1, const prefix0.ContainedReflectable(), -1, 26, 26, const [], const [], ), r.VariableMirrorImpl( r'typeCapability', 142738581, -1, const prefix0.ContainedReflectable(), -1, 27, 27, const [], const [], ), r.VariableMirrorImpl( r'typeRelationsCapability', 142738581, -1, const prefix0.ContainedReflectable(), -1, 28, 28, const [], const [], ), r.VariableMirrorImpl( r'reflectedTypeCapability', 142738581, -1, const prefix0.ContainedReflectable(), -1, 29, 29, const [], const [], ), r.VariableMirrorImpl( r'libraryCapability', 142738581, -1, const prefix0.ContainedReflectable(), -1, 30, 30, const [], const [], ), r.VariableMirrorImpl( r'declarationsCapability', 142738581, -1, const prefix0.ContainedReflectable(), -1, 31, 31, const [], const [], ), r.VariableMirrorImpl( r'uriCapability', 142738581, -1, const prefix0.ContainedReflectable(), -1, 32, 32, const [], const [], ), r.VariableMirrorImpl( r'libraryDependenciesCapability', 142738581, -1, const prefix0.ContainedReflectable(), -1, 33, 33, const [], const [], ), r.VariableMirrorImpl( r'invokingCapability', 142738581, -1, const prefix0.ContainedReflectable(), -1, 34, 34, const [], const [], ), r.VariableMirrorImpl( r'typingCapability', 142738581, -1, const prefix0.ContainedReflectable(), -1, 35, 35, const [], const [], ), r.VariableMirrorImpl( r'delegateCapability', 142738581, -1, const prefix0.ContainedReflectable(), -1, 36, 36, const [], const [], ), r.VariableMirrorImpl( r'subtypeQuantifyCapability', 142738581, -1, const prefix0.ContainedReflectable(), -1, 37, 37, const [], const [], ), r.VariableMirrorImpl( r'superclassQuantifyCapability', 142738581, -1, const prefix0.ContainedReflectable(), -1, 38, 38, const [], const [], ), r.VariableMirrorImpl( r'typeAnnotationQuantifyCapability', 142738581, -1, const prefix0.ContainedReflectable(), -1, 39, 39, const [], const [], ), r.VariableMirrorImpl( r'typeAnnotationDeepQuantifyCapability', 142738581, -1, const prefix0.ContainedReflectable(), -1, 39, 39, const [], const [], ), r.VariableMirrorImpl( r'correspondingSetterQuantifyCapability', 142738581, -1, const prefix0.ContainedReflectable(), -1, 40, 40, const [], const [], ), r.VariableMirrorImpl( r'admitSubtypeCapability', 142738581, -1, const prefix0.ContainedReflectable(), -1, 41, 41, const [], const [], ), r.VariableMirrorImpl( r'thisClassName', 134349973, 1, const prefix0.ContainedReflectable(), 7, 7, 7, const [], const [], ), r.VariableMirrorImpl( r'thisClassId', 134349973, 1, const prefix0.ContainedReflectable(), 7, 7, 7, const [], const [], ), r.ImplicitGetterMirrorImpl(const prefix0.ContainedReflectable(), 0, 2), r.ImplicitGetterMirrorImpl(const prefix0.ContainedReflectable(), 1, 3), r.ImplicitGetterMirrorImpl(const prefix0.ContainedReflectable(), 2, 4), r.ImplicitSetterMirrorImpl(const prefix0.ContainedReflectable(), 2, 5), r.ImplicitGetterMirrorImpl(const prefix0.ContainedReflectable(), 3, 6), r.ImplicitSetterMirrorImpl(const prefix0.ContainedReflectable(), 3, 7), r.MethodMirrorImpl( r'reflectors', 44040211, -1, -1, 42, 43, const [1], const [], const prefix0.ContainedReflectable(), const [], ), r.MethodMirrorImpl( r'identical', 10485784, -1, 8, 8, 8, const [], const [2, 3], const prefix0.ContainedReflectable(), const [], ), r.MethodMirrorImpl( r'identityHashCode', 10485784, -1, 9, 9, 9, const [], const [4], const prefix0.ContainedReflectable(), const [], ), r.MethodMirrorImpl( r'print', 9699352, -1, -1, -1, -1, const [], const [5], const prefix0.ContainedReflectable(), const [], ), r.ImplicitGetterMirrorImpl(const prefix0.ContainedReflectable(), 4, 12), r.ImplicitGetterMirrorImpl(const prefix0.ContainedReflectable(), 5, 13), r.MethodMirrorImpl( r'reflectableNoSuchInvokableError', 8912920, -1, -1, -1, -1, const [], const [6, 7, 8, 9, 10], const prefix0.ContainedReflectable(), const [], ), r.MethodMirrorImpl( r'reflectableNoSuchMethodError', 8912920, -1, -1, -1, -1, const [], const [11, 12, 13, 14], const prefix0.ContainedReflectable(), const [], ), r.MethodMirrorImpl( r'reflectableNoSuchGetterError', 8912920, -1, -1, -1, -1, const [], const [15, 16, 17, 18], const prefix0.ContainedReflectable(), const [], ), r.MethodMirrorImpl( r'reflectableNoSuchSetterError', 8912920, -1, -1, -1, -1, const [], const [19, 20, 21, 22], const prefix0.ContainedReflectable(), const [], ), r.MethodMirrorImpl( r'reflectableNoSuchConstructorError', 8912920, -1, -1, -1, -1, const [], const [23, 24, 25, 26], const prefix0.ContainedReflectable(), const [], ), r.ImplicitGetterMirrorImpl(const prefix0.ContainedReflectable(), 6, 19), r.ImplicitGetterMirrorImpl(const prefix0.ContainedReflectable(), 7, 20), r.ImplicitGetterMirrorImpl(const prefix0.ContainedReflectable(), 8, 21), r.ImplicitGetterMirrorImpl(const prefix0.ContainedReflectable(), 9, 22), r.ImplicitGetterMirrorImpl(const prefix0.ContainedReflectable(), 10, 23), r.ImplicitGetterMirrorImpl(const prefix0.ContainedReflectable(), 11, 24), r.ImplicitGetterMirrorImpl(const prefix0.ContainedReflectable(), 12, 25), r.ImplicitGetterMirrorImpl(const prefix0.ContainedReflectable(), 13, 26), r.ImplicitGetterMirrorImpl(const prefix0.ContainedReflectable(), 14, 27), r.ImplicitGetterMirrorImpl(const prefix0.ContainedReflectable(), 15, 28), r.ImplicitGetterMirrorImpl(const prefix0.ContainedReflectable(), 16, 29), r.ImplicitGetterMirrorImpl(const prefix0.ContainedReflectable(), 17, 30), r.ImplicitGetterMirrorImpl(const prefix0.ContainedReflectable(), 18, 31), r.ImplicitGetterMirrorImpl(const prefix0.ContainedReflectable(), 19, 32), r.ImplicitGetterMirrorImpl(const prefix0.ContainedReflectable(), 20, 33), r.ImplicitGetterMirrorImpl(const prefix0.ContainedReflectable(), 21, 34), r.ImplicitGetterMirrorImpl(const prefix0.ContainedReflectable(), 22, 35), r.ImplicitGetterMirrorImpl(const prefix0.ContainedReflectable(), 23, 36), r.ImplicitGetterMirrorImpl(const prefix0.ContainedReflectable(), 24, 37), r.ImplicitGetterMirrorImpl(const prefix0.ContainedReflectable(), 25, 38), r.ImplicitGetterMirrorImpl(const prefix0.ContainedReflectable(), 26, 39), r.MethodMirrorImpl( r'', 128, 0, -1, 0, 0, const [], const [], const prefix0.ContainedReflectable(), const [], ), r.MethodMirrorImpl( r'==', 2097154, 4, 8, 8, 8, const [], const [27], const prefix0.ContainedReflectable(), const [], ), r.MethodMirrorImpl( r'toString', 2097154, 4, 7, 7, 7, const [], const [], const prefix0.ContainedReflectable(), const [], ), r.MethodMirrorImpl( r'noSuchMethod', 524290, 4, -1, -1, -1, const [], const [28], const prefix0.ContainedReflectable(), const [], ), r.MethodMirrorImpl( r'hashCode', 2097155, 4, 9, 9, 9, const [], const [], const prefix0.ContainedReflectable(), const [], ), r.MethodMirrorImpl( r'runtimeType', 2097155, 4, 6, 6, 6, const [], const [], const prefix0.ContainedReflectable(), const [], ), r.MethodMirrorImpl( r'capabilities', 35651587, 3, 10, 44, 10, const [16], const [], const prefix0.ContainedReflectable(), const [], ), r.MethodMirrorImpl( r'canReflect', 2097154, 2, 8, 8, 8, const [], const [29], const prefix0.ContainedReflectable(), const [override], ), r.MethodMirrorImpl( r'reflect', 2097154, 2, 11, 11, 11, const [], const [30], const prefix0.ContainedReflectable(), const [override], ), r.MethodMirrorImpl( r'canReflectType', 2097154, 2, 8, 8, 8, const [], const [31], const prefix0.ContainedReflectable(), const [override], ), r.MethodMirrorImpl( r'reflectType', 2097154, 2, 12, 12, 12, const [], const [32], const prefix0.ContainedReflectable(), const [override], ), r.MethodMirrorImpl( r'findLibrary', 2097154, 2, 13, 13, 13, const [], const [33], const prefix0.ContainedReflectable(), const [override], ), r.MethodMirrorImpl( r'libraries', 35651587, 2, 14, 46, 14, const [45, 13], const [], const prefix0.ContainedReflectable(), const [override], ), r.MethodMirrorImpl( r'annotatedClasses', 35651587, 2, 15, 48, 15, const [47], const [], const prefix0.ContainedReflectable(), const [override], ), r.MethodMirrorImpl( r'getInstance', 2097170, 1, 1, 1, 1, const [], const [34], const prefix0.ContainedReflectable(), const [], ), r.ImplicitGetterMirrorImpl(const prefix0.ContainedReflectable(), 0, 55), r.ImplicitGetterMirrorImpl(const prefix0.ContainedReflectable(), 1, 56), r.MethodMirrorImpl( r'', 128, 1, -1, 1, 1, const [], const [35, 36, 37, 38, 39, 40, 41, 42, 43, 44], const prefix0.ContainedReflectable(), const [], ), r.MethodMirrorImpl( r'fromList', 128, 1, -1, 1, 1, const [], const [45], const prefix0.ContainedReflectable(), const [], ), r.MethodMirrorImpl( r'', 128, 2, -1, 2, 2, const [], const [46, 47, 48, 49, 50, 51, 52, 53, 54, 55], const prefix0.ContainedReflectable(), const [], ), r.MethodMirrorImpl( r'fromList', 128, 2, -1, 2, 2, const [], const [56], const prefix0.ContainedReflectable(), const [], ), r.MethodMirrorImpl( r'', 128, 3, -1, 3, 3, const [], const [57, 58, 59, 60, 61, 62, 63, 64, 65, 66], const prefix0.ContainedReflectable(), const [], ), r.MethodMirrorImpl( r'fromList', 128, 3, -1, 3, 3, const [], const [67], const prefix0.ContainedReflectable(), const [], ), r.MethodMirrorImpl( r'hash', 2097170, 4, 9, 9, 9, const [], const [ 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, 79, 80, 81, 82, 83, 84, 85, 86, 87, ], const prefix0.ContainedReflectable(), const [], ), r.MethodMirrorImpl( r'hashAll', 2097170, 4, 9, 9, 9, const [], const [88], const prefix0.ContainedReflectable(), const [], ), r.MethodMirrorImpl( r'hashAllUnordered', 2097170, 4, 9, 9, 9, const [], const [89], const prefix0.ContainedReflectable(), const [], ), r.MethodMirrorImpl( r'', 128, 4, -1, 4, 4, const [], const [], const prefix0.ContainedReflectable(), const [], ), r.MethodMirrorImpl( r'memberName', 2097667, 5, -1, 20, 20, const [], const [], const prefix0.ContainedReflectable(), const [], ), r.MethodMirrorImpl( r'typeArguments', 35651587, 5, 10, 49, 10, const [6], const [], const prefix0.ContainedReflectable(), const [], ), r.MethodMirrorImpl( r'positionalArguments', 35652099, 5, 10, 50, 10, null, const [], const prefix0.ContainedReflectable(), const [], ), r.MethodMirrorImpl( r'namedArguments', 35652099, 5, 14, 51, 14, null, const [], const prefix0.ContainedReflectable(), const [], ), r.MethodMirrorImpl( r'isMethod', 2097667, 5, 8, 8, 8, const [], const [], const prefix0.ContainedReflectable(), const [], ), r.MethodMirrorImpl( r'isGetter', 2097667, 5, 8, 8, 8, const [], const [], const prefix0.ContainedReflectable(), const [], ), r.MethodMirrorImpl( r'isSetter', 2097667, 5, 8, 8, 8, const [], const [], const prefix0.ContainedReflectable(), const [], ), r.MethodMirrorImpl( r'isAccessor', 2097155, 5, 8, 8, 8, const [], const [], const prefix0.ContainedReflectable(), const [], ), r.MethodMirrorImpl( r'', 0, 5, -1, 5, 5, const [], const [], const prefix0.ContainedReflectable(), const [], ), r.MethodMirrorImpl( r'method', 1, 5, -1, 5, 5, const [], const [90, 91, 92], const prefix0.ContainedReflectable(), const [], ), r.MethodMirrorImpl( r'genericMethod', 1, 5, -1, 5, 5, const [], const [93, 94, 95, 96], const prefix0.ContainedReflectable(), const [], ), r.MethodMirrorImpl( r'getter', 257, 5, -1, 5, 5, const [], const [97], const prefix0.ContainedReflectable(), const [], ), r.MethodMirrorImpl( r'setter', 257, 5, -1, 5, 5, const [], const [98, 99], const prefix0.ContainedReflectable(), const [], ), r.MethodMirrorImpl( r'==', 2097666, 6, 8, 8, 8, const [], const [100], const prefix0.ContainedReflectable(), const [], ), r.MethodMirrorImpl( r'toString', 2097666, 6, 7, 7, 7, const [], const [], const prefix0.ContainedReflectable(), const [], ), r.MethodMirrorImpl( r'hashCode', 2097667, 6, 9, 9, 9, const [], const [], const prefix0.ContainedReflectable(), const [], ), r.MethodMirrorImpl( r'', 64, 6, -1, 6, 6, const [], const [], const prefix0.ContainedReflectable(), const [], ), r.MethodMirrorImpl( r'[]', 2097666, 7, 7, 7, 7, const [], const [101], const prefix0.ContainedReflectable(), const [], ), r.MethodMirrorImpl( r'codeUnitAt', 2097666, 7, 9, 9, 9, const [], const [102], const prefix0.ContainedReflectable(), const [], ), r.MethodMirrorImpl( r'==', 2097666, 7, 8, 8, 8, const [], const [103], const prefix0.ContainedReflectable(), const [], ), r.MethodMirrorImpl( r'compareTo', 2097666, 7, 9, 9, 9, const [], const [104], const prefix0.ContainedReflectable(), const [], ), r.MethodMirrorImpl( r'endsWith', 2097666, 7, 8, 8, 8, const [], const [105], const prefix0.ContainedReflectable(), const [], ), r.MethodMirrorImpl( r'startsWith', 2097666, 7, 8, 8, 8, const [], const [106, 107], const prefix0.ContainedReflectable(), const [], ), r.MethodMirrorImpl( r'indexOf', 2097666, 7, 9, 9, 9, const [], const [108, 109], const prefix0.ContainedReflectable(), const [], ), r.MethodMirrorImpl( r'lastIndexOf', 2097666, 7, 9, 9, 9, const [], const [110, 111], const prefix0.ContainedReflectable(), const [], ), r.MethodMirrorImpl( r'+', 2097666, 7, 7, 7, 7, const [], const [112], const prefix0.ContainedReflectable(), const [], ), r.MethodMirrorImpl( r'substring', 2097666, 7, 7, 7, 7, const [], const [113, 114], const prefix0.ContainedReflectable(), const [], ), r.MethodMirrorImpl( r'trim', 2097666, 7, 7, 7, 7, const [], const [], const prefix0.ContainedReflectable(), const [], ), r.MethodMirrorImpl( r'trimLeft', 2097666, 7, 7, 7, 7, const [], const [], const prefix0.ContainedReflectable(), const [], ), r.MethodMirrorImpl( r'trimRight', 2097666, 7, 7, 7, 7, const [], const [], const prefix0.ContainedReflectable(), const [], ), r.MethodMirrorImpl( r'*', 2097666, 7, 7, 7, 7, const [], const [115], const prefix0.ContainedReflectable(), const [], ), r.MethodMirrorImpl( r'padLeft', 2097666, 7, 7, 7, 7, const [], const [116, 117], const prefix0.ContainedReflectable(), const [], ), r.MethodMirrorImpl( r'padRight', 2097666, 7, 7, 7, 7, const [], const [118, 119], const prefix0.ContainedReflectable(), const [], ), r.MethodMirrorImpl( r'contains', 2097666, 7, 8, 8, 8, const [], const [120, 121], const prefix0.ContainedReflectable(), const [], ), r.MethodMirrorImpl( r'replaceFirst', 2097666, 7, 7, 7, 7, const [], const [122, 123, 124], const prefix0.ContainedReflectable(), const [], ), r.MethodMirrorImpl( r'replaceFirstMapped', 2097666, 7, 7, 7, 7, const [], const [125, 126, 127], const prefix0.ContainedReflectable(), const [], ), r.MethodMirrorImpl( r'replaceAll', 2097666, 7, 7, 7, 7, const [], const [128, 129], const prefix0.ContainedReflectable(), const [], ), r.MethodMirrorImpl( r'replaceAllMapped', 2097666, 7, 7, 7, 7, const [], const [130, 131], const prefix0.ContainedReflectable(), const [], ), r.MethodMirrorImpl( r'replaceRange', 2097666, 7, 7, 7, 7, const [], const [132, 133, 134], const prefix0.ContainedReflectable(), const [], ), r.MethodMirrorImpl( r'split', 35652098, 7, 10, 52, 10, const [7], const [135], const prefix0.ContainedReflectable(), const [], ), r.MethodMirrorImpl( r'splitMapJoin', 2097666, 7, 7, 7, 7, const [], const [136, 137, 138], const prefix0.ContainedReflectable(), const [], ), r.MethodMirrorImpl( r'toLowerCase', 2097666, 7, 7, 7, 7, const [], const [], const prefix0.ContainedReflectable(), const [], ), r.MethodMirrorImpl( r'toUpperCase', 2097666, 7, 7, 7, 7, const [], const [], const prefix0.ContainedReflectable(), const [], ), r.MethodMirrorImpl( r'length', 2097667, 7, 9, 9, 9, const [], const [], const prefix0.ContainedReflectable(), const [], ), r.MethodMirrorImpl( r'hashCode', 2097667, 7, 9, 9, 9, const [], const [], const prefix0.ContainedReflectable(), const [], ), r.MethodMirrorImpl( r'isEmpty', 2097667, 7, 8, 8, 8, const [], const [], const prefix0.ContainedReflectable(), const [], ), r.MethodMirrorImpl( r'isNotEmpty', 2097667, 7, 8, 8, 8, const [], const [], const prefix0.ContainedReflectable(), const [], ), r.MethodMirrorImpl( r'codeUnits', 35652099, 7, 10, 53, 10, const [9], const [], const prefix0.ContainedReflectable(), const [], ), r.MethodMirrorImpl( r'runes', 2097667, 7, -1, 54, 54, const [], const [], const prefix0.ContainedReflectable(), const [], ), r.MethodMirrorImpl( r'fromCharCodes', 1, 7, -1, 7, 7, const [], const [139, 140, 141], const prefix0.ContainedReflectable(), const [], ), r.MethodMirrorImpl( r'fromCharCode', 1, 7, -1, 7, 7, const [], const [142], const prefix0.ContainedReflectable(), const [], ), r.MethodMirrorImpl( r'fromEnvironment', 129, 7, -1, 7, 7, const [], const [143, 144], const prefix0.ContainedReflectable(), const [], ), r.MethodMirrorImpl( r'parse', 2097170, 8, 8, 8, 8, const [], const [145, 146], const prefix0.ContainedReflectable(), const [], ), r.MethodMirrorImpl( r'tryParse', 2097170, 8, 8, 8, 8, const [], const [147, 148], const prefix0.ContainedReflectable(), const [], ), r.MethodMirrorImpl( r'&', 2097154, 8, 8, 8, 8, const [], const [149], const prefix0.ContainedReflectable(), const [], ), r.MethodMirrorImpl( r'|', 2097154, 8, 8, 8, 8, const [], const [150], const prefix0.ContainedReflectable(), const [], ), r.MethodMirrorImpl( r'^', 2097154, 8, 8, 8, 8, const [], const [151], const prefix0.ContainedReflectable(), const [], ), r.MethodMirrorImpl( r'toString', 2097154, 8, 7, 7, 7, const [], const [], const prefix0.ContainedReflectable(), const [], ), r.MethodMirrorImpl( r'hashCode', 2097155, 8, 9, 9, 9, const [], const [], const prefix0.ContainedReflectable(), const [], ), r.MethodMirrorImpl( r'fromEnvironment', 129, 8, -1, 8, 8, const [], const [152, 153], const prefix0.ContainedReflectable(), const [], ), r.MethodMirrorImpl( r'hasEnvironment', 129, 8, -1, 8, 8, const [], const [154], const prefix0.ContainedReflectable(), const [], ), r.MethodMirrorImpl( r'&', 2097666, 9, 9, 9, 9, const [], const [155], const prefix0.ContainedReflectable(), const [], ), r.MethodMirrorImpl( r'|', 2097666, 9, 9, 9, 9, const [], const [156], const prefix0.ContainedReflectable(), const [], ), r.MethodMirrorImpl( r'^', 2097666, 9, 9, 9, 9, const [], const [157], const prefix0.ContainedReflectable(), const [], ), r.MethodMirrorImpl( r'~', 2097666, 9, 9, 9, 9, const [], const [], const prefix0.ContainedReflectable(), const [], ), r.MethodMirrorImpl( r'<<', 2097666, 9, 9, 9, 9, const [], const [158], const prefix0.ContainedReflectable(), const [], ), r.MethodMirrorImpl( r'>>', 2097666, 9, 9, 9, 9, const [], const [159], const prefix0.ContainedReflectable(), const [], ), r.MethodMirrorImpl( r'>>>', 2097666, 9, 9, 9, 9, const [], const [160], const prefix0.ContainedReflectable(), const [], ), r.MethodMirrorImpl( r'modPow', 2097666, 9, 9, 9, 9, const [], const [161, 162], const prefix0.ContainedReflectable(), const [], ), r.MethodMirrorImpl( r'modInverse', 2097666, 9, 9, 9, 9, const [], const [163], const prefix0.ContainedReflectable(), const [], ), r.MethodMirrorImpl( r'gcd', 2097666, 9, 9, 9, 9, const [], const [164], const prefix0.ContainedReflectable(), const [], ), r.MethodMirrorImpl( r'toUnsigned', 2097666, 9, 9, 9, 9, const [], const [165], const prefix0.ContainedReflectable(), const [], ), r.MethodMirrorImpl( r'toSigned', 2097666, 9, 9, 9, 9, const [], const [166], const prefix0.ContainedReflectable(), const [], ), r.MethodMirrorImpl( r'unary-', 2097666, 9, 9, 9, 9, const [], const [], const prefix0.ContainedReflectable(), const [], ), r.MethodMirrorImpl( r'abs', 2097666, 9, 9, 9, 9, const [], const [], const prefix0.ContainedReflectable(), const [], ), r.MethodMirrorImpl( r'round', 2097666, 9, 9, 9, 9, const [], const [], const prefix0.ContainedReflectable(), const [], ), r.MethodMirrorImpl( r'floor', 2097666, 9, 9, 9, 9, const [], const [], const prefix0.ContainedReflectable(), const [], ), r.MethodMirrorImpl( r'ceil', 2097666, 9, 9, 9, 9, const [], const [], const prefix0.ContainedReflectable(), const [], ), r.MethodMirrorImpl( r'truncate', 2097666, 9, 9, 9, 9, const [], const [], const prefix0.ContainedReflectable(), const [], ), r.MethodMirrorImpl( r'roundToDouble', 2097666, 9, -1, 55, 55, const [], const [], const prefix0.ContainedReflectable(), const [], ), r.MethodMirrorImpl( r'floorToDouble', 2097666, 9, -1, 55, 55, const [], const [], const prefix0.ContainedReflectable(), const [], ), r.MethodMirrorImpl( r'ceilToDouble', 2097666, 9, -1, 55, 55, const [], const [], const prefix0.ContainedReflectable(), const [], ), r.MethodMirrorImpl( r'truncateToDouble', 2097666, 9, -1, 55, 55, const [], const [], const prefix0.ContainedReflectable(), const [], ), r.MethodMirrorImpl( r'toString', 2097666, 9, 7, 7, 7, const [], const [], const prefix0.ContainedReflectable(), const [], ), r.MethodMirrorImpl( r'toRadixString', 2097666, 9, 7, 7, 7, const [], const [167], const prefix0.ContainedReflectable(), const [], ), r.MethodMirrorImpl( r'parse', 2097170, 9, 9, 9, 9, const [], const [168, 169], const prefix0.ContainedReflectable(), const [], ), r.MethodMirrorImpl( r'tryParse', 2097170, 9, 9, 9, 9, const [], const [170, 171], const prefix0.ContainedReflectable(), const [], ), r.MethodMirrorImpl( r'isEven', 2097667, 9, 8, 8, 8, const [], const [], const prefix0.ContainedReflectable(), const [], ), r.MethodMirrorImpl( r'isOdd', 2097667, 9, 8, 8, 8, const [], const [], const prefix0.ContainedReflectable(), const [], ), r.MethodMirrorImpl( r'bitLength', 2097667, 9, 9, 9, 9, const [], const [], const prefix0.ContainedReflectable(), const [], ), r.MethodMirrorImpl( r'sign', 2097667, 9, 9, 9, 9, const [], const [], const prefix0.ContainedReflectable(), const [], ), r.MethodMirrorImpl( r'fromEnvironment', 129, 9, -1, 9, 9, const [], const [172, 173], const prefix0.ContainedReflectable(), const [], ), r.MethodMirrorImpl( r'castFrom', 35651602, 10, 10, 56, 10, null, const [174], const prefix0.ContainedReflectable(), const [], ), r.MethodMirrorImpl( r'copyRange', 1310738, 10, -1, -1, -1, const [], const [175, 176, 177, 178, 179], const prefix0.ContainedReflectable(), const [], ), r.MethodMirrorImpl( r'writeIterable', 1310738, 10, -1, -1, -1, const [], const [180, 181, 182], const prefix0.ContainedReflectable(), const [], ), r.MethodMirrorImpl( r'cast', 35652098, 10, 10, 57, 10, null, const [], const prefix0.ContainedReflectable(), const [], ), r.MethodMirrorImpl( r'[]', 514, 10, -1, -1, -1, const [], const [183], const prefix0.ContainedReflectable(), const [], ), r.MethodMirrorImpl( r'[]=', 1311234, 10, -1, -1, -1, const [], const [184, 185], const prefix0.ContainedReflectable(), const [], ), r.MethodMirrorImpl( r'add', 1311234, 10, -1, -1, -1, const [], const [186], const prefix0.ContainedReflectable(), const [], ), r.MethodMirrorImpl( r'addAll', 1311234, 10, -1, -1, -1, const [], const [187], const prefix0.ContainedReflectable(), const [], ), r.MethodMirrorImpl( r'sort', 1311234, 10, -1, -1, -1, const [], const [188], const prefix0.ContainedReflectable(), const [], ), r.MethodMirrorImpl( r'shuffle', 1311234, 10, -1, -1, -1, const [], const [189], const prefix0.ContainedReflectable(), const [], ), r.MethodMirrorImpl( r'indexOf', 2097666, 10, 9, 9, 9, const [], const [190, 191], const prefix0.ContainedReflectable(), const [], ), r.MethodMirrorImpl( r'indexWhere', 2097666, 10, 9, 9, 9, const [], const [192, 193], const prefix0.ContainedReflectable(), const [], ), r.MethodMirrorImpl( r'lastIndexWhere', 2097666, 10, 9, 9, 9, const [], const [194, 195], const prefix0.ContainedReflectable(), const [], ), r.MethodMirrorImpl( r'lastIndexOf', 2097666, 10, 9, 9, 9, const [], const [196, 197], const prefix0.ContainedReflectable(), const [], ), r.MethodMirrorImpl( r'clear', 1311234, 10, -1, -1, -1, const [], const [], const prefix0.ContainedReflectable(), const [], ), r.MethodMirrorImpl( r'insert', 1311234, 10, -1, -1, -1, const [], const [198, 199], const prefix0.ContainedReflectable(), const [], ), r.MethodMirrorImpl( r'insertAll', 1311234, 10, -1, -1, -1, const [], const [200, 201], const prefix0.ContainedReflectable(), const [], ), r.MethodMirrorImpl( r'setAll', 1311234, 10, -1, -1, -1, const [], const [202, 203], const prefix0.ContainedReflectable(), const [], ), r.MethodMirrorImpl( r'remove', 2097666, 10, 8, 8, 8, const [], const [204], const prefix0.ContainedReflectable(), const [], ), r.MethodMirrorImpl( r'removeAt', 514, 10, -1, -1, -1, const [], const [205], const prefix0.ContainedReflectable(), const [], ), r.MethodMirrorImpl( r'removeLast', 514, 10, -1, -1, -1, const [], const [], const prefix0.ContainedReflectable(), const [], ), r.MethodMirrorImpl( r'removeWhere', 1311234, 10, -1, -1, -1, const [], const [206], const prefix0.ContainedReflectable(), const [], ), r.MethodMirrorImpl( r'retainWhere', 1311234, 10, -1, -1, -1, const [], const [207], const prefix0.ContainedReflectable(), const [], ), r.MethodMirrorImpl( r'+', 35652098, 10, 10, 58, 10, null, const [208], const prefix0.ContainedReflectable(), const [], ), r.MethodMirrorImpl( r'sublist', 35652098, 10, 10, 58, 10, null, const [209, 210], const prefix0.ContainedReflectable(), const [], ), r.MethodMirrorImpl( r'getRange', 35652098, 10, 15, 59, 15, null, const [211, 212], const prefix0.ContainedReflectable(), const [], ), r.MethodMirrorImpl( r'setRange', 1311234, 10, -1, -1, -1, const [], const [213, 214, 215, 216], const prefix0.ContainedReflectable(), const [], ), r.MethodMirrorImpl( r'removeRange', 1311234, 10, -1, -1, -1, const [], const [217, 218], const prefix0.ContainedReflectable(), const [], ), r.MethodMirrorImpl( r'fillRange', 1311234, 10, -1, -1, -1, const [], const [219, 220, 221], const prefix0.ContainedReflectable(), const [], ), r.MethodMirrorImpl( r'replaceRange', 1311234, 10, -1, -1, -1, const [], const [222, 223, 224], const prefix0.ContainedReflectable(), const [], ), r.MethodMirrorImpl( r'asMap', 35652098, 10, 14, 60, 14, null, const [], const prefix0.ContainedReflectable(), const [], ), r.MethodMirrorImpl( r'==', 2097666, 10, 8, 8, 8, const [], const [225], const prefix0.ContainedReflectable(), const [], ), r.MethodMirrorImpl( r'first=', 1311236, 10, -1, -1, -1, const [], const [238], const prefix0.ContainedReflectable(), const [], ), r.MethodMirrorImpl( r'last=', 1311236, 10, -1, -1, -1, const [], const [239], const prefix0.ContainedReflectable(), const [], ), r.MethodMirrorImpl( r'length', 2097667, 10, 9, 9, 9, const [], const [], const prefix0.ContainedReflectable(), const [], ), r.MethodMirrorImpl( r'length=', 1311236, 10, -1, -1, -1, const [], const [240], const prefix0.ContainedReflectable(), const [], ), r.MethodMirrorImpl( r'reversed', 35652099, 10, 15, 59, 15, null, const [], const prefix0.ContainedReflectable(), const [], ), r.MethodMirrorImpl( r'filled', 1, 10, -1, 58, 10, null, const [226, 227, 228], const prefix0.ContainedReflectable(), const [], ), r.MethodMirrorImpl( r'empty', 1, 10, -1, 58, 10, null, const [229], const prefix0.ContainedReflectable(), const [], ), r.MethodMirrorImpl( r'from', 1, 10, -1, 58, 10, null, const [230, 231], const prefix0.ContainedReflectable(), const [], ), r.MethodMirrorImpl( r'of', 1, 10, -1, 58, 10, null, const [232, 233], const prefix0.ContainedReflectable(), const [], ), r.MethodMirrorImpl( r'generate', 1, 10, -1, 58, 10, null, const [234, 235, 236], const prefix0.ContainedReflectable(), const [], ), r.MethodMirrorImpl( r'unmodifiable', 1, 10, -1, 58, 10, null, const [237], const prefix0.ContainedReflectable(), const [], ), r.MethodMirrorImpl( r'==', 2097666, 11, 8, 8, 8, const [], const [241], const prefix0.ContainedReflectable(), const [override], ), r.MethodMirrorImpl( r'delegate', 2097666, 11, 4, 4, 4, const [], const [242], const prefix0.ContainedReflectable(), const [], ), r.MethodMirrorImpl( r'type', 2097667, 11, -1, 47, 47, const [], const [], const prefix0.ContainedReflectable(), const [], ), r.MethodMirrorImpl( r'hasReflectee', 2097667, 11, 8, 8, 8, const [], const [], const prefix0.ContainedReflectable(), const [], ), r.MethodMirrorImpl( r'reflectee', 2097667, 11, 4, 4, 4, const [], const [], const prefix0.ContainedReflectable(), const [], ), r.MethodMirrorImpl( r'hashCode', 2097667, 11, 9, 9, 9, const [], const [], const prefix0.ContainedReflectable(), const [override], ), r.MethodMirrorImpl( r'', 64, 11, -1, 11, 11, const [], const [], const prefix0.ContainedReflectable(), const [], ), r.MethodMirrorImpl( r'isSubtypeOf', 2097666, 12, 8, 8, 8, const [], const [243], const prefix0.ContainedReflectable(), const [], ), r.MethodMirrorImpl( r'isAssignableTo', 2097666, 12, 8, 8, 8, const [], const [244], const prefix0.ContainedReflectable(), const [], ), r.MethodMirrorImpl( r'hasReflectedType', 2097667, 12, 8, 8, 8, const [], const [], const prefix0.ContainedReflectable(), const [], ), r.MethodMirrorImpl( r'reflectedType', 2097667, 12, 6, 6, 6, const [], const [], const prefix0.ContainedReflectable(), const [], ), r.MethodMirrorImpl( r'typeVariables', 35652099, 12, 10, 62, 10, const [61], const [], const prefix0.ContainedReflectable(), const [], ), r.MethodMirrorImpl( r'typeArguments', 35652099, 12, 10, 63, 10, const [12], const [], const prefix0.ContainedReflectable(), const [], ), r.MethodMirrorImpl( r'reflectedTypeArguments', 35652099, 12, 10, 49, 10, const [6], const [], const prefix0.ContainedReflectable(), const [], ), r.MethodMirrorImpl( r'isOriginalDeclaration', 2097667, 12, 8, 8, 8, const [], const [], const prefix0.ContainedReflectable(), const [], ), r.MethodMirrorImpl( r'originalDeclaration', 2097667, 12, 12, 12, 12, const [], const [], const prefix0.ContainedReflectable(), const [], ), r.MethodMirrorImpl( r'isNullable', 2097667, 12, 8, 8, 8, const [], const [], const prefix0.ContainedReflectable(), const [], ), r.MethodMirrorImpl( r'isNonNullable', 2097667, 12, 8, 8, 8, const [], const [], const prefix0.ContainedReflectable(), const [], ), r.MethodMirrorImpl( r'isPotentiallyNullable', 2097667, 12, 8, 8, 8, const [], const [], const prefix0.ContainedReflectable(), const [], ), r.MethodMirrorImpl( r'isPotentiallyNonNullable', 2097667, 12, 8, 8, 8, const [], const [], const prefix0.ContainedReflectable(), const [], ), r.MethodMirrorImpl( r'', 64, 12, -1, 12, 12, const [], const [], const prefix0.ContainedReflectable(), const [], ), r.MethodMirrorImpl( r'==', 2097666, 13, 8, 8, 8, const [], const [245], const prefix0.ContainedReflectable(), const [override], ), r.MethodMirrorImpl( r'uri', 2097667, 13, -1, 45, 45, const [], const [], const prefix0.ContainedReflectable(), const [], ), r.MethodMirrorImpl( r'declarations', 35652099, 13, 14, 65, 14, const [7, 64], const [], const prefix0.ContainedReflectable(), const [], ), r.MethodMirrorImpl( r'hashCode', 2097667, 13, 9, 9, 9, const [], const [], const prefix0.ContainedReflectable(), const [override], ), r.MethodMirrorImpl( r'libraryDependencies', 35652099, 13, 10, 67, 10, const [66], const [], const prefix0.ContainedReflectable(), const [], ), r.MethodMirrorImpl( r'owner', 2097667, 13, -1, 68, 68, const [], const [], const prefix0.ContainedReflectable(), const [override], ), r.MethodMirrorImpl( r'', 64, 13, -1, 13, 13, const [], const [], const prefix0.ContainedReflectable(), const [], ), r.MethodMirrorImpl( r'castFrom', 35651602, 14, 14, 69, 14, null, const [246], const prefix0.ContainedReflectable(), const [], ), r.MethodMirrorImpl( r'cast', 35652098, 14, 14, 70, 14, null, const [], const prefix0.ContainedReflectable(), const [], ), r.MethodMirrorImpl( r'containsValue', 2097666, 14, 8, 8, 8, const [], const [247], const prefix0.ContainedReflectable(), const [], ), r.MethodMirrorImpl( r'containsKey', 2097666, 14, 8, 8, 8, const [], const [248], const prefix0.ContainedReflectable(), const [], ), r.MethodMirrorImpl( r'[]', 514, 14, -1, -1, -1, const [], const [249], const prefix0.ContainedReflectable(), const [], ), r.MethodMirrorImpl( r'[]=', 1311234, 14, -1, -1, -1, const [], const [250, 251], const prefix0.ContainedReflectable(), const [], ), r.MethodMirrorImpl( r'map', 35652098, 14, 14, 71, 14, null, const [252], const prefix0.ContainedReflectable(), const [], ), r.MethodMirrorImpl( r'addEntries', 1311234, 14, -1, -1, -1, const [], const [253], const prefix0.ContainedReflectable(), const [], ), r.MethodMirrorImpl( r'update', 514, 14, -1, -1, -1, const [], const [254, 255, 256], const prefix0.ContainedReflectable(), const [], ), r.MethodMirrorImpl( r'updateAll', 1311234, 14, -1, -1, -1, const [], const [257], const prefix0.ContainedReflectable(), const [], ), r.MethodMirrorImpl( r'removeWhere', 1311234, 14, -1, -1, -1, const [], const [258], const prefix0.ContainedReflectable(), const [], ), r.MethodMirrorImpl( r'putIfAbsent', 514, 14, -1, -1, -1, const [], const [259, 260], const prefix0.ContainedReflectable(), const [], ), r.MethodMirrorImpl( r'addAll', 1311234, 14, -1, -1, -1, const [], const [261], const prefix0.ContainedReflectable(), const [], ), r.MethodMirrorImpl( r'remove', 514, 14, -1, -1, -1, const [], const [262], const prefix0.ContainedReflectable(), const [], ), r.MethodMirrorImpl( r'clear', 1311234, 14, -1, -1, -1, const [], const [], const prefix0.ContainedReflectable(), const [], ), r.MethodMirrorImpl( r'forEach', 1311234, 14, -1, -1, -1, const [], const [263], const prefix0.ContainedReflectable(), const [], ), r.MethodMirrorImpl( r'entries', 35652099, 14, 15, 72, 15, null, const [], const prefix0.ContainedReflectable(), const [], ), r.MethodMirrorImpl( r'keys', 35652099, 14, 15, 73, 15, null, const [], const prefix0.ContainedReflectable(), const [], ), r.MethodMirrorImpl( r'values', 35652099, 14, 15, 74, 15, null, const [], const prefix0.ContainedReflectable(), const [], ), r.MethodMirrorImpl( r'length', 2097667, 14, 9, 9, 9, const [], const [], const prefix0.ContainedReflectable(), const [], ), r.MethodMirrorImpl( r'isEmpty', 2097667, 14, 8, 8, 8, const [], const [], const prefix0.ContainedReflectable(), const [], ), r.MethodMirrorImpl( r'isNotEmpty', 2097667, 14, 8, 8, 8, const [], const [], const prefix0.ContainedReflectable(), const [], ), r.MethodMirrorImpl( r'', 1, 14, -1, 75, 14, null, const [], const prefix0.ContainedReflectable(), const [], ), r.MethodMirrorImpl( r'from', 257, 14, -1, 75, 14, null, const [264], const prefix0.ContainedReflectable(), const [], ), r.MethodMirrorImpl( r'of', 257, 14, -1, 75, 14, null, const [265], const prefix0.ContainedReflectable(), const [], ), r.MethodMirrorImpl( r'unmodifiable', 1, 14, -1, 75, 14, null, const [266], const prefix0.ContainedReflectable(), const [], ), r.MethodMirrorImpl( r'identity', 257, 14, -1, 75, 14, null, const [], const prefix0.ContainedReflectable(), const [], ), r.MethodMirrorImpl( r'fromIterable', 257, 14, -1, 75, 14, null, const [267, 268, 269], const prefix0.ContainedReflectable(), const [], ), r.MethodMirrorImpl( r'fromIterables', 257, 14, -1, 75, 14, null, const [270, 271], const prefix0.ContainedReflectable(), const [], ), r.MethodMirrorImpl( r'fromEntries', 1, 14, -1, 75, 14, null, const [272], const prefix0.ContainedReflectable(), const [], ), r.MethodMirrorImpl( r'castFrom', 35651602, 15, 15, 76, 15, null, const [273], const prefix0.ContainedReflectable(), const [], ), r.MethodMirrorImpl( r'cast', 35651586, 15, 15, 77, 15, null, const [], const prefix0.ContainedReflectable(), const [], ), r.MethodMirrorImpl( r'followedBy', 35651586, 15, 15, 78, 15, null, const [274], const prefix0.ContainedReflectable(), const [], ), r.MethodMirrorImpl( r'map', 35651586, 15, 15, 79, 15, null, const [275], const prefix0.ContainedReflectable(), const [], ), r.MethodMirrorImpl( r'where', 35651586, 15, 15, 78, 15, null, const [276], const prefix0.ContainedReflectable(), const [], ), r.MethodMirrorImpl( r'whereType', 35651586, 15, 15, 80, 15, null, const [], const prefix0.ContainedReflectable(), const [], ), r.MethodMirrorImpl( r'expand', 35651586, 15, 15, 81, 15, null, const [277], const prefix0.ContainedReflectable(), const [], ), r.MethodMirrorImpl( r'contains', 2097154, 15, 8, 8, 8, const [], const [278], const prefix0.ContainedReflectable(), const [], ), r.MethodMirrorImpl( r'forEach', 1310722, 15, -1, -1, -1, const [], const [279], const prefix0.ContainedReflectable(), const [], ), r.MethodMirrorImpl( r'reduce', 2, 15, -1, -1, -1, const [], const [280], const prefix0.ContainedReflectable(), const [], ), r.MethodMirrorImpl( r'fold', 2, 15, -1, -1, -1, const [], const [281, 282], const prefix0.ContainedReflectable(), const [], ), r.MethodMirrorImpl( r'every', 2097154, 15, 8, 8, 8, const [], const [283], const prefix0.ContainedReflectable(), const [], ), r.MethodMirrorImpl( r'join', 2097154, 15, 7, 7, 7, const [], const [284], const prefix0.ContainedReflectable(), const [], ), r.MethodMirrorImpl( r'any', 2097154, 15, 8, 8, 8, const [], const [285], const prefix0.ContainedReflectable(), const [], ), r.MethodMirrorImpl( r'toList', 35651586, 15, 10, 82, 10, null, const [286], const prefix0.ContainedReflectable(), const [], ), r.MethodMirrorImpl( r'toSet', 35651586, 15, -1, 83, 84, null, const [], const prefix0.ContainedReflectable(), const [], ), r.MethodMirrorImpl( r'take', 35651586, 15, 15, 78, 15, null, const [287], const prefix0.ContainedReflectable(), const [], ), r.MethodMirrorImpl( r'takeWhile', 35651586, 15, 15, 78, 15, null, const [288], const prefix0.ContainedReflectable(), const [], ), r.MethodMirrorImpl( r'skip', 35651586, 15, 15, 78, 15, null, const [289], const prefix0.ContainedReflectable(), const [], ), r.MethodMirrorImpl( r'skipWhile', 35651586, 15, 15, 78, 15, null, const [290], const prefix0.ContainedReflectable(), const [], ), r.MethodMirrorImpl( r'firstWhere', 2, 15, -1, -1, -1, const [], const [291, 292], const prefix0.ContainedReflectable(), const [], ), r.MethodMirrorImpl( r'lastWhere', 2, 15, -1, -1, -1, const [], const [293, 294], const prefix0.ContainedReflectable(), const [], ), r.MethodMirrorImpl( r'singleWhere', 2, 15, -1, -1, -1, const [], const [295, 296], const prefix0.ContainedReflectable(), const [], ), r.MethodMirrorImpl( r'elementAt', 2, 15, -1, -1, -1, const [], const [297], const prefix0.ContainedReflectable(), const [], ), r.MethodMirrorImpl( r'toString', 2097154, 15, 7, 7, 7, const [], const [], const prefix0.ContainedReflectable(), const [], ), r.MethodMirrorImpl( r'iterableToShortString', 2097170, 15, 7, 7, 7, const [], const [298, 299, 300], const prefix0.ContainedReflectable(), const [], ), r.MethodMirrorImpl( r'iterableToFullString', 2097170, 15, 7, 7, 7, const [], const [301, 302, 303], const prefix0.ContainedReflectable(), const [], ), r.MethodMirrorImpl( r'iterator', 35652099, 15, -1, 85, 86, null, const [], const prefix0.ContainedReflectable(), const [], ), r.MethodMirrorImpl( r'length', 2097155, 15, 9, 9, 9, const [], const [], const prefix0.ContainedReflectable(), const [], ), r.MethodMirrorImpl( r'isEmpty', 2097155, 15, 8, 8, 8, const [], const [], const prefix0.ContainedReflectable(), const [], ), r.MethodMirrorImpl( r'isNotEmpty', 2097155, 15, 8, 8, 8, const [], const [], const prefix0.ContainedReflectable(), const [], ), r.MethodMirrorImpl( r'first', 3, 15, -1, -1, -1, const [], const [], const prefix0.ContainedReflectable(), const [], ), r.MethodMirrorImpl( r'last', 3, 15, -1, -1, -1, const [], const [], const prefix0.ContainedReflectable(), const [], ), r.MethodMirrorImpl( r'single', 3, 15, -1, -1, -1, const [], const [], const prefix0.ContainedReflectable(), const [], ), r.MethodMirrorImpl( r'', 128, 15, -1, 78, 15, null, const [], const prefix0.ContainedReflectable(), const [], ), r.MethodMirrorImpl( r'generate', 1, 15, -1, 78, 15, null, const [304, 305], const prefix0.ContainedReflectable(), const [], ), r.MethodMirrorImpl( r'empty', 385, 15, -1, 78, 15, null, const [], const prefix0.ContainedReflectable(), const [], ), r.MethodMirrorImpl( r'', 128, 16, -1, 16, 16, const [], const [], const prefix0.ContainedReflectable(), const [], ), ], [ r.ParameterMirrorImpl( r'_data', 151126118, 5, const prefix0.ContainedReflectable(), 14, 17, 14, const [1, 18], const [], null, null, ), r.ParameterMirrorImpl( r'_memberSymbolMap', 84017254, 7, const prefix0.ContainedReflectable(), 14, 19, 14, const [20, 7], const [], null, null, ), r.ParameterMirrorImpl( r'a', 67239942, 9, const prefix0.ContainedReflectable(), 4, 4, 4, const [], const [], null, null, ), r.ParameterMirrorImpl( r'b', 67239942, 9, const prefix0.ContainedReflectable(), 4, 4, 4, const [], const [], null, null, ), r.ParameterMirrorImpl( r'object', 67239942, 10, const prefix0.ContainedReflectable(), 4, 4, 4, const [], const [], null, null, ), r.ParameterMirrorImpl( r'object', 67239942, 11, const prefix0.ContainedReflectable(), 4, 4, 4, const [], const [], null, null, ), r.ParameterMirrorImpl( r'receiver', 67239942, 14, const prefix0.ContainedReflectable(), 4, 4, 4, const [], const [], null, null, ), r.ParameterMirrorImpl( r'memberName', 134348806, 14, const prefix0.ContainedReflectable(), 7, 7, 7, const [], const [], null, null, ), r.ParameterMirrorImpl( r'positionalArguments', 151126022, 14, const prefix0.ContainedReflectable(), 10, 50, 10, null, const [], null, null, ), r.ParameterMirrorImpl( r'namedArguments', 84017158, 14, const prefix0.ContainedReflectable(), 14, 87, 14, null, const [], null, null, ), r.ParameterMirrorImpl( r'kind', 134348806, 14, const prefix0.ContainedReflectable(), -1, 88, 88, const [], const [], null, null, ), r.ParameterMirrorImpl( r'receiver', 67239942, 15, const prefix0.ContainedReflectable(), 4, 4, 4, const [], const [], null, null, ), r.ParameterMirrorImpl( r'memberName', 134348806, 15, const prefix0.ContainedReflectable(), 7, 7, 7, const [], const [], null, null, ), r.ParameterMirrorImpl( r'positionalArguments', 151126022, 15, const prefix0.ContainedReflectable(), 10, 50, 10, null, const [], null, null, ), r.ParameterMirrorImpl( r'namedArguments', 84017158, 15, const prefix0.ContainedReflectable(), 14, 87, 14, null, const [], null, null, ), r.ParameterMirrorImpl( r'receiver', 67239942, 16, const prefix0.ContainedReflectable(), 4, 4, 4, const [], const [], null, null, ), r.ParameterMirrorImpl( r'memberName', 134348806, 16, const prefix0.ContainedReflectable(), 7, 7, 7, const [], const [], null, null, ), r.ParameterMirrorImpl( r'positionalArguments', 151126022, 16, const prefix0.ContainedReflectable(), 10, 50, 10, null, const [], null, null, ), r.ParameterMirrorImpl( r'namedArguments', 84017158, 16, const prefix0.ContainedReflectable(), 14, 87, 14, null, const [], null, null, ), r.ParameterMirrorImpl( r'receiver', 67239942, 17, const prefix0.ContainedReflectable(), 4, 4, 4, const [], const [], null, null, ), r.ParameterMirrorImpl( r'memberName', 134348806, 17, const prefix0.ContainedReflectable(), 7, 7, 7, const [], const [], null, null, ), r.ParameterMirrorImpl( r'positionalArguments', 151126022, 17, const prefix0.ContainedReflectable(), 10, 50, 10, null, const [], null, null, ), r.ParameterMirrorImpl( r'namedArguments', 84017158, 17, const prefix0.ContainedReflectable(), 14, 87, 14, null, const [], null, null, ), r.ParameterMirrorImpl( r'receiver', 67239942, 18, const prefix0.ContainedReflectable(), 4, 4, 4, const [], const [], null, null, ), r.ParameterMirrorImpl( r'constructorName', 134348806, 18, const prefix0.ContainedReflectable(), 7, 7, 7, const [], const [], null, null, ), r.ParameterMirrorImpl( r'positionalArguments', 151126022, 18, const prefix0.ContainedReflectable(), 10, 50, 10, null, const [], null, null, ), r.ParameterMirrorImpl( r'namedArguments', 84017158, 18, const prefix0.ContainedReflectable(), 14, 87, 14, null, const [], null, null, ), r.ParameterMirrorImpl( r'other', 134348806, 41, const prefix0.ContainedReflectable(), 4, 4, 4, const [], const [], null, null, ), r.ParameterMirrorImpl( r'invocation', 134348806, 43, const prefix0.ContainedReflectable(), 5, 5, 5, const [], const [], null, null, ), r.ParameterMirrorImpl( r'reflectee', 134348806, 47, const prefix0.ContainedReflectable(), 4, 4, 4, const [], const [], null, null, ), r.ParameterMirrorImpl( r'reflectee', 134348806, 48, const prefix0.ContainedReflectable(), 4, 4, 4, const [], const [], null, null, ), r.ParameterMirrorImpl( r'type', 134348806, 49, const prefix0.ContainedReflectable(), 6, 6, 6, const [], const [], null, null, ), r.ParameterMirrorImpl( r'type', 134348806, 50, const prefix0.ContainedReflectable(), 6, 6, 6, const [], const [], null, null, ), r.ParameterMirrorImpl( r'libraryName', 134348806, 51, const prefix0.ContainedReflectable(), 7, 7, 7, const [], const [], null, null, ), r.ParameterMirrorImpl( r'type', 134348806, 54, const prefix0.ContainedReflectable(), 6, 6, 6, const [], const [], null, null, ), r.ParameterMirrorImpl( r'cap0', 67244038, 57, const prefix0.ContainedReflectable(), 16, 16, 16, const [], const [], null, null, ), r.ParameterMirrorImpl( r'cap1', 67244038, 57, const prefix0.ContainedReflectable(), 16, 16, 16, const [], const [], null, null, ), r.ParameterMirrorImpl( r'cap2', 67244038, 57, const prefix0.ContainedReflectable(), 16, 16, 16, const [], const [], null, null, ), r.ParameterMirrorImpl( r'cap3', 67244038, 57, const prefix0.ContainedReflectable(), 16, 16, 16, const [], const [], null, null, ), r.ParameterMirrorImpl( r'cap4', 67244038, 57, const prefix0.ContainedReflectable(), 16, 16, 16, const [], const [], null, null, ), r.ParameterMirrorImpl( r'cap5', 67244038, 57, const prefix0.ContainedReflectable(), 16, 16, 16, const [], const [], null, null, ), r.ParameterMirrorImpl( r'cap6', 67244038, 57, const prefix0.ContainedReflectable(), 16, 16, 16, const [], const [], null, null, ), r.ParameterMirrorImpl( r'cap7', 67244038, 57, const prefix0.ContainedReflectable(), 16, 16, 16, const [], const [], null, null, ), r.ParameterMirrorImpl( r'cap8', 67244038, 57, const prefix0.ContainedReflectable(), 16, 16, 16, const [], const [], null, null, ), r.ParameterMirrorImpl( r'cap9', 67244038, 57, const prefix0.ContainedReflectable(), 16, 16, 16, const [], const [], null, null, ), r.ParameterMirrorImpl( r'capabilities', 151126022, 58, const prefix0.ContainedReflectable(), 10, 44, 10, const [16], const [], null, null, ), r.ParameterMirrorImpl( r'cap0', 67244038, 59, const prefix0.ContainedReflectable(), 16, 16, 16, const [], const [], null, null, ), r.ParameterMirrorImpl( r'cap1', 67244038, 59, const prefix0.ContainedReflectable(), 16, 16, 16, const [], const [], null, null, ), r.ParameterMirrorImpl( r'cap2', 67244038, 59, const prefix0.ContainedReflectable(), 16, 16, 16, const [], const [], null, null, ), r.ParameterMirrorImpl( r'cap3', 67244038, 59, const prefix0.ContainedReflectable(), 16, 16, 16, const [], const [], null, null, ), r.ParameterMirrorImpl( r'cap4', 67244038, 59, const prefix0.ContainedReflectable(), 16, 16, 16, const [], const [], null, null, ), r.ParameterMirrorImpl( r'cap5', 67244038, 59, const prefix0.ContainedReflectable(), 16, 16, 16, const [], const [], null, null, ), r.ParameterMirrorImpl( r'cap6', 67244038, 59, const prefix0.ContainedReflectable(), 16, 16, 16, const [], const [], null, null, ), r.ParameterMirrorImpl( r'cap7', 67244038, 59, const prefix0.ContainedReflectable(), 16, 16, 16, const [], const [], null, null, ), r.ParameterMirrorImpl( r'cap8', 67244038, 59, const prefix0.ContainedReflectable(), 16, 16, 16, const [], const [], null, null, ), r.ParameterMirrorImpl( r'cap9', 67244038, 59, const prefix0.ContainedReflectable(), 16, 16, 16, const [], const [], null, null, ), r.ParameterMirrorImpl( r'capabilities', 151126022, 60, const prefix0.ContainedReflectable(), 10, 44, 10, const [16], const [], null, null, ), r.ParameterMirrorImpl( r'_cap0', 67245094, 61, const prefix0.ContainedReflectable(), 16, 16, 16, const [], const [], null, null, ), r.ParameterMirrorImpl( r'_cap1', 67245094, 61, const prefix0.ContainedReflectable(), 16, 16, 16, const [], const [], null, null, ), r.ParameterMirrorImpl( r'_cap2', 67245094, 61, const prefix0.ContainedReflectable(), 16, 16, 16, const [], const [], null, null, ), r.ParameterMirrorImpl( r'_cap3', 67245094, 61, const prefix0.ContainedReflectable(), 16, 16, 16, const [], const [], null, null, ), r.ParameterMirrorImpl( r'_cap4', 67245094, 61, const prefix0.ContainedReflectable(), 16, 16, 16, const [], const [], null, null, ), r.ParameterMirrorImpl( r'_cap5', 67245094, 61, const prefix0.ContainedReflectable(), 16, 16, 16, const [], const [], null, null, ), r.ParameterMirrorImpl( r'_cap6', 67245094, 61, const prefix0.ContainedReflectable(), 16, 16, 16, const [], const [], null, null, ), r.ParameterMirrorImpl( r'_cap7', 67245094, 61, const prefix0.ContainedReflectable(), 16, 16, 16, const [], const [], null, null, ), r.ParameterMirrorImpl( r'_cap8', 67245094, 61, const prefix0.ContainedReflectable(), 16, 16, 16, const [], const [], null, null, ), r.ParameterMirrorImpl( r'_cap9', 67245094, 61, const prefix0.ContainedReflectable(), 16, 16, 16, const [], const [], null, null, ), r.ParameterMirrorImpl( r'_capabilities', 84018214, 62, const prefix0.ContainedReflectable(), 10, 89, 10, const [16], const [], null, null, ), r.ParameterMirrorImpl( r'object1', 67239942, 63, const prefix0.ContainedReflectable(), 4, 4, 4, const [], const [], null, null, ), r.ParameterMirrorImpl( r'object2', 67239942, 63, const prefix0.ContainedReflectable(), 4, 4, 4, const [], const [], null, null, ), r.ParameterMirrorImpl( r'object3', 67246086, 63, const prefix0.ContainedReflectable(), 4, 4, 4, const [], const [], null, null, ), r.ParameterMirrorImpl( r'object4', 67246086, 63, const prefix0.ContainedReflectable(), 4, 4, 4, const [], const [], null, null, ), r.ParameterMirrorImpl( r'object5', 67246086, 63, const prefix0.ContainedReflectable(), 4, 4, 4, const [], const [], null, null, ), r.ParameterMirrorImpl( r'object6', 67246086, 63, const prefix0.ContainedReflectable(), 4, 4, 4, const [], const [], null, null, ), r.ParameterMirrorImpl( r'object7', 67246086, 63, const prefix0.ContainedReflectable(), 4, 4, 4, const [], const [], null, null, ), r.ParameterMirrorImpl( r'object8', 67246086, 63, const prefix0.ContainedReflectable(), 4, 4, 4, const [], const [], null, null, ), r.ParameterMirrorImpl( r'object9', 67246086, 63, const prefix0.ContainedReflectable(), 4, 4, 4, const [], const [], null, null, ), r.ParameterMirrorImpl( r'object10', 67246086, 63, const prefix0.ContainedReflectable(), 4, 4, 4, const [], const [], null, null, ), r.ParameterMirrorImpl( r'object11', 67246086, 63, const prefix0.ContainedReflectable(), 4, 4, 4, const [], const [], null, null, ), r.ParameterMirrorImpl( r'object12', 67246086, 63, const prefix0.ContainedReflectable(), 4, 4, 4, const [], const [], null, null, ), r.ParameterMirrorImpl( r'object13', 67246086, 63, const prefix0.ContainedReflectable(), 4, 4, 4, const [], const [], null, null, ), r.ParameterMirrorImpl( r'object14', 67246086, 63, const prefix0.ContainedReflectable(), 4, 4, 4, const [], const [], null, null, ), r.ParameterMirrorImpl( r'object15', 67246086, 63, const prefix0.ContainedReflectable(), 4, 4, 4, const [], const [], null, null, ), r.ParameterMirrorImpl( r'object16', 67246086, 63, const prefix0.ContainedReflectable(), 4, 4, 4, const [], const [], null, null, ), r.ParameterMirrorImpl( r'object17', 67246086, 63, const prefix0.ContainedReflectable(), 4, 4, 4, const [], const [], null, null, ), r.ParameterMirrorImpl( r'object18', 67246086, 63, const prefix0.ContainedReflectable(), 4, 4, 4, const [], const [], null, null, ), r.ParameterMirrorImpl( r'object19', 67246086, 63, const prefix0.ContainedReflectable(), 4, 4, 4, const [], const [], null, null, ), r.ParameterMirrorImpl( r'object20', 67246086, 63, const prefix0.ContainedReflectable(), 4, 4, 4, const [], const [], null, null, ), r.ParameterMirrorImpl( r'objects', 151126022, 64, const prefix0.ContainedReflectable(), 15, 90, 15, const [4], const [], null, null, ), r.ParameterMirrorImpl( r'objects', 151126022, 65, const prefix0.ContainedReflectable(), 15, 90, 15, const [4], const [], null, null, ), r.ParameterMirrorImpl( r'memberName', 134348806, 76, const prefix0.ContainedReflectable(), -1, 20, 20, const [], const [], null, null, ), r.ParameterMirrorImpl( r'positionalArguments', 84017158, 76, const prefix0.ContainedReflectable(), 15, 91, 15, const [4], const [], null, null, ), r.ParameterMirrorImpl( r'namedArguments', 84021254, 76, const prefix0.ContainedReflectable(), 14, 92, 14, const [20, 4], const [], null, null, ), r.ParameterMirrorImpl( r'memberName', 134348806, 77, const prefix0.ContainedReflectable(), -1, 20, 20, const [], const [], null, null, ), r.ParameterMirrorImpl( r'typeArguments', 84017158, 77, const prefix0.ContainedReflectable(), 15, 93, 15, const [6], const [], null, null, ), r.ParameterMirrorImpl( r'positionalArguments', 84017158, 77, const prefix0.ContainedReflectable(), 15, 91, 15, const [4], const [], null, null, ), r.ParameterMirrorImpl( r'namedArguments', 84021254, 77, const prefix0.ContainedReflectable(), 14, 92, 14, const [20, 4], const [], null, null, ), r.ParameterMirrorImpl( r'name', 134348806, 78, const prefix0.ContainedReflectable(), -1, 20, 20, const [], const [], null, null, ), r.ParameterMirrorImpl( r'memberName', 134348806, 79, const prefix0.ContainedReflectable(), -1, 20, 20, const [], const [], null, null, ), r.ParameterMirrorImpl( r'argument', 67239942, 79, const prefix0.ContainedReflectable(), 4, 4, 4, const [], const [], null, null, ), r.ParameterMirrorImpl( r'other', 134348806, 80, const prefix0.ContainedReflectable(), 4, 4, 4, const [], const [], null, null, ), r.ParameterMirrorImpl( r'index', 134348806, 84, const prefix0.ContainedReflectable(), 9, 9, 9, const [], const [], null, null, ), r.ParameterMirrorImpl( r'index', 134348806, 85, const prefix0.ContainedReflectable(), 9, 9, 9, const [], const [], null, null, ), r.ParameterMirrorImpl( r'other', 134348806, 86, const prefix0.ContainedReflectable(), 4, 4, 4, const [], const [], null, null, ), r.ParameterMirrorImpl( r'other', 134348806, 87, const prefix0.ContainedReflectable(), 7, 7, 7, const [], const [], null, null, ), r.ParameterMirrorImpl( r'other', 134348806, 88, const prefix0.ContainedReflectable(), 7, 7, 7, const [], const [], null, null, ), r.ParameterMirrorImpl( r'pattern', 134348806, 89, const prefix0.ContainedReflectable(), -1, 94, 94, const [], const [], null, null, ), r.ParameterMirrorImpl( r'index', 134354950, 89, const prefix0.ContainedReflectable(), 9, 9, 9, const [], const [], null, null, ), r.ParameterMirrorImpl( r'pattern', 134348806, 90, const prefix0.ContainedReflectable(), -1, 94, 94, const [], const [], null, null, ), r.ParameterMirrorImpl( r'start', 134354950, 90, const prefix0.ContainedReflectable(), 9, 9, 9, const [], const [], null, null, ), r.ParameterMirrorImpl( r'pattern', 134348806, 91, const prefix0.ContainedReflectable(), -1, 94, 94, const [], const [], null, null, ), r.ParameterMirrorImpl( r'start', 67244038, 91, const prefix0.ContainedReflectable(), 9, 9, 9, const [], const [], null, null, ), r.ParameterMirrorImpl( r'other', 134348806, 92, const prefix0.ContainedReflectable(), 7, 7, 7, const [], const [], null, null, ), r.ParameterMirrorImpl( r'start', 134348806, 93, const prefix0.ContainedReflectable(), 9, 9, 9, const [], const [], null, null, ), r.ParameterMirrorImpl( r'end', 67244038, 93, const prefix0.ContainedReflectable(), 9, 9, 9, const [], const [], null, null, ), r.ParameterMirrorImpl( r'times', 134348806, 97, const prefix0.ContainedReflectable(), 9, 9, 9, const [], const [], null, null, ), r.ParameterMirrorImpl( r'width', 134348806, 98, const prefix0.ContainedReflectable(), 9, 9, 9, const [], const [], null, null, ), r.ParameterMirrorImpl( r'padding', 134354950, 98, const prefix0.ContainedReflectable(), 7, 7, 7, const [], const [], null, null, ), r.ParameterMirrorImpl( r'width', 134348806, 99, const prefix0.ContainedReflectable(), 9, 9, 9, const [], const [], null, null, ), r.ParameterMirrorImpl( r'padding', 134354950, 99, const prefix0.ContainedReflectable(), 7, 7, 7, const [], const [], null, null, ), r.ParameterMirrorImpl( r'other', 134348806, 100, const prefix0.ContainedReflectable(), -1, 94, 94, const [], const [], null, null, ), r.ParameterMirrorImpl( r'startIndex', 134354950, 100, const prefix0.ContainedReflectable(), 9, 9, 9, const [], const [], null, null, ), r.ParameterMirrorImpl( r'from', 134348806, 101, const prefix0.ContainedReflectable(), -1, 94, 94, const [], const [], null, null, ), r.ParameterMirrorImpl( r'to', 134348806, 101, const prefix0.ContainedReflectable(), 7, 7, 7, const [], const [], null, null, ), r.ParameterMirrorImpl( r'startIndex', 134354950, 101, const prefix0.ContainedReflectable(), 9, 9, 9, const [], const [], null, null, ), r.ParameterMirrorImpl( r'from', 134348806, 102, const prefix0.ContainedReflectable(), -1, 94, 94, const [], const [], null, null, ), r.ParameterMirrorImpl( r'replace', 134217734, 102, const prefix0.ContainedReflectable(), -1, 95, 95, const [], const [], null, null, ), r.ParameterMirrorImpl( r'startIndex', 134354950, 102, const prefix0.ContainedReflectable(), 9, 9, 9, const [], const [], null, null, ), r.ParameterMirrorImpl( r'from', 134348806, 103, const prefix0.ContainedReflectable(), -1, 94, 94, const [], const [], null, null, ), r.ParameterMirrorImpl( r'replace', 134348806, 103, const prefix0.ContainedReflectable(), 7, 7, 7, const [], const [], null, null, ), r.ParameterMirrorImpl( r'from', 134348806, 104, const prefix0.ContainedReflectable(), -1, 94, 94, const [], const [], null, null, ), r.ParameterMirrorImpl( r'replace', 134217734, 104, const prefix0.ContainedReflectable(), -1, 95, 95, const [], const [], null, null, ), r.ParameterMirrorImpl( r'start', 134348806, 105, const prefix0.ContainedReflectable(), 9, 9, 9, const [], const [], null, null, ), r.ParameterMirrorImpl( r'end', 67239942, 105, const prefix0.ContainedReflectable(), 9, 9, 9, const [], const [], null, null, ), r.ParameterMirrorImpl( r'replacement', 134348806, 105, const prefix0.ContainedReflectable(), 7, 7, 7, const [], const [], null, null, ), r.ParameterMirrorImpl( r'pattern', 134348806, 106, const prefix0.ContainedReflectable(), -1, 94, 94, const [], const [], null, null, ), r.ParameterMirrorImpl( r'pattern', 134348806, 107, const prefix0.ContainedReflectable(), -1, 94, 94, const [], const [], null, null, ), r.ParameterMirrorImpl( r'onMatch', 67121158, 107, const prefix0.ContainedReflectable(), -1, 96, 96, const [], const [], null, #onMatch, ), r.ParameterMirrorImpl( r'onNonMatch', 67121158, 107, const prefix0.ContainedReflectable(), -1, 97, 97, const [], const [], null, #onNonMatch, ), r.ParameterMirrorImpl( r'charCodes', 151126022, 116, const prefix0.ContainedReflectable(), 15, 98, 15, const [9], const [], null, null, ), r.ParameterMirrorImpl( r'start', 134354950, 116, const prefix0.ContainedReflectable(), 9, 9, 9, const [], const [], null, null, ), r.ParameterMirrorImpl( r'end', 67244038, 116, const prefix0.ContainedReflectable(), 9, 9, 9, const [], const [], null, null, ), r.ParameterMirrorImpl( r'charCode', 134348806, 117, const prefix0.ContainedReflectable(), 9, 9, 9, const [], const [], null, null, ), r.ParameterMirrorImpl( r'name', 134348806, 118, const prefix0.ContainedReflectable(), 7, 7, 7, const [], const [], null, null, ), r.ParameterMirrorImpl( r'defaultValue', 134363142, 118, const prefix0.ContainedReflectable(), 7, 7, 7, const [], const [], null, #defaultValue, ), r.ParameterMirrorImpl( r'source', 134348806, 119, const prefix0.ContainedReflectable(), 7, 7, 7, const [], const [], null, null, ), r.ParameterMirrorImpl( r'caseSensitive', 134363142, 119, const prefix0.ContainedReflectable(), 8, 8, 8, const [], const [], null, #caseSensitive, ), r.ParameterMirrorImpl( r'source', 134348806, 120, const prefix0.ContainedReflectable(), 7, 7, 7, const [], const [], null, null, ), r.ParameterMirrorImpl( r'caseSensitive', 134363142, 120, const prefix0.ContainedReflectable(), 8, 8, 8, const [], const [], null, #caseSensitive, ), r.ParameterMirrorImpl( r'other', 134348806, 121, const prefix0.ContainedReflectable(), 8, 8, 8, const [], const [], null, null, ), r.ParameterMirrorImpl( r'other', 134348806, 122, const prefix0.ContainedReflectable(), 8, 8, 8, const [], const [], null, null, ), r.ParameterMirrorImpl( r'other', 134348806, 123, const prefix0.ContainedReflectable(), 8, 8, 8, const [], const [], null, null, ), r.ParameterMirrorImpl( r'name', 134348806, 126, const prefix0.ContainedReflectable(), 7, 7, 7, const [], const [], null, null, ), r.ParameterMirrorImpl( r'defaultValue', 134363142, 126, const prefix0.ContainedReflectable(), 8, 8, 8, const [], const [], null, #defaultValue, ), r.ParameterMirrorImpl( r'name', 134348806, 127, const prefix0.ContainedReflectable(), 7, 7, 7, const [], const [], null, null, ), r.ParameterMirrorImpl( r'other', 134348806, 128, const prefix0.ContainedReflectable(), 9, 9, 9, const [], const [], null, null, ), r.ParameterMirrorImpl( r'other', 134348806, 129, const prefix0.ContainedReflectable(), 9, 9, 9, const [], const [], null, null, ), r.ParameterMirrorImpl( r'other', 134348806, 130, const prefix0.ContainedReflectable(), 9, 9, 9, const [], const [], null, null, ), r.ParameterMirrorImpl( r'shiftAmount', 134348806, 132, const prefix0.ContainedReflectable(), 9, 9, 9, const [], const [], null, null, ), r.ParameterMirrorImpl( r'shiftAmount', 134348806, 133, const prefix0.ContainedReflectable(), 9, 9, 9, const [], const [], null, null, ), r.ParameterMirrorImpl( r'shiftAmount', 134348806, 134, const prefix0.ContainedReflectable(), 9, 9, 9, const [], const [], null, null, ), r.ParameterMirrorImpl( r'exponent', 134348806, 135, const prefix0.ContainedReflectable(), 9, 9, 9, const [], const [], null, null, ), r.ParameterMirrorImpl( r'modulus', 134348806, 135, const prefix0.ContainedReflectable(), 9, 9, 9, const [], const [], null, null, ), r.ParameterMirrorImpl( r'modulus', 134348806, 136, const prefix0.ContainedReflectable(), 9, 9, 9, const [], const [], null, null, ), r.ParameterMirrorImpl( r'other', 134348806, 137, const prefix0.ContainedReflectable(), 9, 9, 9, const [], const [], null, null, ), r.ParameterMirrorImpl( r'width', 134348806, 138, const prefix0.ContainedReflectable(), 9, 9, 9, const [], const [], null, null, ), r.ParameterMirrorImpl( r'width', 134348806, 139, const prefix0.ContainedReflectable(), 9, 9, 9, const [], const [], null, null, ), r.ParameterMirrorImpl( r'radix', 134348806, 151, const prefix0.ContainedReflectable(), 9, 9, 9, const [], const [], null, null, ), r.ParameterMirrorImpl( r'source', 134348806, 152, const prefix0.ContainedReflectable(), 7, 7, 7, const [], const [], null, null, ), r.ParameterMirrorImpl( r'radix', 67252230, 152, const prefix0.ContainedReflectable(), 9, 9, 9, const [], const [], null, #radix, ), r.ParameterMirrorImpl( r'source', 134348806, 153, const prefix0.ContainedReflectable(), 7, 7, 7, const [], const [], null, null, ), r.ParameterMirrorImpl( r'radix', 67252230, 153, const prefix0.ContainedReflectable(), 9, 9, 9, const [], const [], null, #radix, ), r.ParameterMirrorImpl( r'name', 134348806, 158, const prefix0.ContainedReflectable(), 7, 7, 7, const [], const [], null, null, ), r.ParameterMirrorImpl( r'defaultValue', 134363142, 158, const prefix0.ContainedReflectable(), 9, 9, 9, const [], const [], null, #defaultValue, ), r.ParameterMirrorImpl( r'source', 151126022, 159, const prefix0.ContainedReflectable(), 10, 99, 10, null, const [], null, null, ), r.ParameterMirrorImpl( r'target', 151126022, 160, const prefix0.ContainedReflectable(), 10, 100, 10, null, const [], null, null, ), r.ParameterMirrorImpl( r'at', 134348806, 160, const prefix0.ContainedReflectable(), 9, 9, 9, const [], const [], null, null, ), r.ParameterMirrorImpl( r'source', 151126022, 160, const prefix0.ContainedReflectable(), 10, 100, 10, null, const [], null, null, ), r.ParameterMirrorImpl( r'start', 67244038, 160, const prefix0.ContainedReflectable(), 9, 9, 9, const [], const [], null, null, ), r.ParameterMirrorImpl( r'end', 67244038, 160, const prefix0.ContainedReflectable(), 9, 9, 9, const [], const [], null, null, ), r.ParameterMirrorImpl( r'target', 151126022, 161, const prefix0.ContainedReflectable(), 10, 101, 10, null, const [], null, null, ), r.ParameterMirrorImpl( r'at', 134348806, 161, const prefix0.ContainedReflectable(), 9, 9, 9, const [], const [], null, null, ), r.ParameterMirrorImpl( r'source', 151126022, 161, const prefix0.ContainedReflectable(), 15, 102, 15, null, const [], null, null, ), r.ParameterMirrorImpl( r'index', 134348806, 163, const prefix0.ContainedReflectable(), 9, 9, 9, const [], const [], null, null, ), r.ParameterMirrorImpl( r'index', 134348806, 164, const prefix0.ContainedReflectable(), 9, 9, 9, const [], const [], null, null, ), r.ParameterMirrorImpl( r'value', 6, 164, const prefix0.ContainedReflectable(), -1, -1, -1, const [], const [], null, null, ), r.ParameterMirrorImpl( r'value', 6, 165, const prefix0.ContainedReflectable(), -1, -1, -1, const [], const [], null, null, ), r.ParameterMirrorImpl( r'iterable', 151126022, 166, const prefix0.ContainedReflectable(), 15, 59, 15, null, const [], null, null, ), r.ParameterMirrorImpl( r'compare', 67112966, 167, const prefix0.ContainedReflectable(), -1, 103, 103, const [], const [], null, null, ), r.ParameterMirrorImpl( r'random', 67244038, 168, const prefix0.ContainedReflectable(), -1, 104, 104, const [], const [], null, null, ), r.ParameterMirrorImpl( r'element', 6, 169, const prefix0.ContainedReflectable(), -1, -1, -1, const [], const [], null, null, ), r.ParameterMirrorImpl( r'start', 134354950, 169, const prefix0.ContainedReflectable(), 9, 9, 9, const [], const [], null, null, ), r.ParameterMirrorImpl( r'test', 134217734, 170, const prefix0.ContainedReflectable(), -1, 105, 105, const [], const [], null, null, ), r.ParameterMirrorImpl( r'start', 134354950, 170, const prefix0.ContainedReflectable(), 9, 9, 9, const [], const [], null, null, ), r.ParameterMirrorImpl( r'test', 134217734, 171, const prefix0.ContainedReflectable(), -1, 105, 105, const [], const [], null, null, ), r.ParameterMirrorImpl( r'start', 67244038, 171, const prefix0.ContainedReflectable(), 9, 9, 9, const [], const [], null, null, ), r.ParameterMirrorImpl( r'element', 6, 172, const prefix0.ContainedReflectable(), -1, -1, -1, const [], const [], null, null, ), r.ParameterMirrorImpl( r'start', 67244038, 172, const prefix0.ContainedReflectable(), 9, 9, 9, const [], const [], null, null, ), r.ParameterMirrorImpl( r'index', 134348806, 174, const prefix0.ContainedReflectable(), 9, 9, 9, const [], const [], null, null, ), r.ParameterMirrorImpl( r'element', 6, 174, const prefix0.ContainedReflectable(), -1, -1, -1, const [], const [], null, null, ), r.ParameterMirrorImpl( r'index', 134348806, 175, const prefix0.ContainedReflectable(), 9, 9, 9, const [], const [], null, null, ), r.ParameterMirrorImpl( r'iterable', 151126022, 175, const prefix0.ContainedReflectable(), 15, 59, 15, null, const [], null, null, ), r.ParameterMirrorImpl( r'index', 134348806, 176, const prefix0.ContainedReflectable(), 9, 9, 9, const [], const [], null, null, ), r.ParameterMirrorImpl( r'iterable', 151126022, 176, const prefix0.ContainedReflectable(), 15, 59, 15, null, const [], null, null, ), r.ParameterMirrorImpl( r'value', 67239942, 177, const prefix0.ContainedReflectable(), 4, 4, 4, const [], const [], null, null, ), r.ParameterMirrorImpl( r'index', 134348806, 178, const prefix0.ContainedReflectable(), 9, 9, 9, const [], const [], null, null, ), r.ParameterMirrorImpl( r'test', 134217734, 180, const prefix0.ContainedReflectable(), -1, 105, 105, const [], const [], null, null, ), r.ParameterMirrorImpl( r'test', 134217734, 181, const prefix0.ContainedReflectable(), -1, 105, 105, const [], const [], null, null, ), r.ParameterMirrorImpl( r'other', 151126022, 182, const prefix0.ContainedReflectable(), 10, 58, 10, null, const [], null, null, ), r.ParameterMirrorImpl( r'start', 134348806, 183, const prefix0.ContainedReflectable(), 9, 9, 9, const [], const [], null, null, ), r.ParameterMirrorImpl( r'end', 67244038, 183, const prefix0.ContainedReflectable(), 9, 9, 9, const [], const [], null, null, ), r.ParameterMirrorImpl( r'start', 134348806, 184, const prefix0.ContainedReflectable(), 9, 9, 9, const [], const [], null, null, ), r.ParameterMirrorImpl( r'end', 134348806, 184, const prefix0.ContainedReflectable(), 9, 9, 9, const [], const [], null, null, ), r.ParameterMirrorImpl( r'start', 134348806, 185, const prefix0.ContainedReflectable(), 9, 9, 9, const [], const [], null, null, ), r.ParameterMirrorImpl( r'end', 134348806, 185, const prefix0.ContainedReflectable(), 9, 9, 9, const [], const [], null, null, ), r.ParameterMirrorImpl( r'iterable', 151126022, 185, const prefix0.ContainedReflectable(), 15, 59, 15, null, const [], null, null, ), r.ParameterMirrorImpl( r'skipCount', 134354950, 185, const prefix0.ContainedReflectable(), 9, 9, 9, const [], const [], null, null, ), r.ParameterMirrorImpl( r'start', 134348806, 186, const prefix0.ContainedReflectable(), 9, 9, 9, const [], const [], null, null, ), r.ParameterMirrorImpl( r'end', 134348806, 186, const prefix0.ContainedReflectable(), 9, 9, 9, const [], const [], null, null, ), r.ParameterMirrorImpl( r'start', 134348806, 187, const prefix0.ContainedReflectable(), 9, 9, 9, const [], const [], null, null, ), r.ParameterMirrorImpl( r'end', 134348806, 187, const prefix0.ContainedReflectable(), 9, 9, 9, const [], const [], null, null, ), r.ParameterMirrorImpl( r'fillValue', 67112966, 187, const prefix0.ContainedReflectable(), -1, -1, -1, const [], const [], null, null, ), r.ParameterMirrorImpl( r'start', 134348806, 188, const prefix0.ContainedReflectable(), 9, 9, 9, const [], const [], null, null, ), r.ParameterMirrorImpl( r'end', 134348806, 188, const prefix0.ContainedReflectable(), 9, 9, 9, const [], const [], null, null, ), r.ParameterMirrorImpl( r'replacements', 151126022, 188, const prefix0.ContainedReflectable(), 15, 59, 15, null, const [], null, null, ), r.ParameterMirrorImpl( r'other', 134348806, 190, const prefix0.ContainedReflectable(), 4, 4, 4, const [], const [], null, null, ), r.ParameterMirrorImpl( r'length', 134348806, 196, const prefix0.ContainedReflectable(), 9, 9, 9, const [], const [], null, null, ), r.ParameterMirrorImpl( r'fill', 6, 196, const prefix0.ContainedReflectable(), -1, -1, -1, const [], const [], null, null, ), r.ParameterMirrorImpl( r'growable', 134363142, 196, const prefix0.ContainedReflectable(), 8, 8, 8, const [], const [], null, #growable, ), r.ParameterMirrorImpl( r'growable', 134363142, 197, const prefix0.ContainedReflectable(), 8, 8, 8, const [], const [], null, #growable, ), r.ParameterMirrorImpl( r'elements', 151126022, 198, const prefix0.ContainedReflectable(), 15, 106, 15, null, const [], null, null, ), r.ParameterMirrorImpl( r'growable', 134363142, 198, const prefix0.ContainedReflectable(), 8, 8, 8, const [], const [], null, #growable, ), r.ParameterMirrorImpl( r'elements', 151126022, 199, const prefix0.ContainedReflectable(), 15, 59, 15, null, const [], null, null, ), r.ParameterMirrorImpl( r'growable', 134363142, 199, const prefix0.ContainedReflectable(), 8, 8, 8, const [], const [], null, #growable, ), r.ParameterMirrorImpl( r'length', 134348806, 200, const prefix0.ContainedReflectable(), 9, 9, 9, const [], const [], null, null, ), r.ParameterMirrorImpl( r'generator', 134217734, 200, const prefix0.ContainedReflectable(), -1, 107, 107, const [], const [], null, null, ), r.ParameterMirrorImpl( r'growable', 134363142, 200, const prefix0.ContainedReflectable(), 8, 8, 8, const [], const [], null, #growable, ), r.ParameterMirrorImpl( r'elements', 151126022, 201, const prefix0.ContainedReflectable(), 15, 106, 15, null, const [], null, null, ), r.ParameterMirrorImpl( r'value', 6, 191, const prefix0.ContainedReflectable(), -1, -1, -1, const [], const [], null, null, ), r.ParameterMirrorImpl( r'value', 6, 192, const prefix0.ContainedReflectable(), -1, -1, -1, const [], const [], null, null, ), r.ParameterMirrorImpl( r'newLength', 134348806, 194, const prefix0.ContainedReflectable(), 9, 9, 9, const [], const [], null, null, ), r.ParameterMirrorImpl( r'other', 134348806, 202, const prefix0.ContainedReflectable(), 4, 4, 4, const [], const [], null, null, ), r.ParameterMirrorImpl( r'invocation', 134348806, 203, const prefix0.ContainedReflectable(), 5, 5, 5, const [], const [], null, null, ), r.ParameterMirrorImpl( r'other', 134348806, 209, const prefix0.ContainedReflectable(), 12, 12, 12, const [], const [], null, null, ), r.ParameterMirrorImpl( r'other', 134348806, 210, const prefix0.ContainedReflectable(), 12, 12, 12, const [], const [], null, null, ), r.ParameterMirrorImpl( r'other', 134348806, 223, const prefix0.ContainedReflectable(), 4, 4, 4, const [], const [], null, null, ), r.ParameterMirrorImpl( r'source', 151126022, 230, const prefix0.ContainedReflectable(), 14, 108, 14, null, const [], null, null, ), r.ParameterMirrorImpl( r'value', 67239942, 232, const prefix0.ContainedReflectable(), 4, 4, 4, const [], const [], null, null, ), r.ParameterMirrorImpl( r'key', 67239942, 233, const prefix0.ContainedReflectable(), 4, 4, 4, const [], const [], null, null, ), r.ParameterMirrorImpl( r'key', 67239942, 234, const prefix0.ContainedReflectable(), 4, 4, 4, const [], const [], null, null, ), r.ParameterMirrorImpl( r'key', 6, 235, const prefix0.ContainedReflectable(), -1, -1, -1, const [], const [], null, null, ), r.ParameterMirrorImpl( r'value', 6, 235, const prefix0.ContainedReflectable(), -1, -1, -1, const [], const [], null, null, ), r.ParameterMirrorImpl( r'convert', 134217734, 236, const prefix0.ContainedReflectable(), -1, 109, 109, const [], const [], null, null, ), r.ParameterMirrorImpl( r'newEntries', 151126022, 237, const prefix0.ContainedReflectable(), 15, 72, 15, null, const [], null, null, ), r.ParameterMirrorImpl( r'key', 6, 238, const prefix0.ContainedReflectable(), -1, -1, -1, const [], const [], null, null, ), r.ParameterMirrorImpl( r'update', 134217734, 238, const prefix0.ContainedReflectable(), -1, 110, 110, const [], const [], null, null, ), r.ParameterMirrorImpl( r'ifAbsent', 67121158, 238, const prefix0.ContainedReflectable(), -1, 111, 111, const [], const [], null, #ifAbsent, ), r.ParameterMirrorImpl( r'update', 134217734, 239, const prefix0.ContainedReflectable(), -1, 112, 112, const [], const [], null, null, ), r.ParameterMirrorImpl( r'test', 134217734, 240, const prefix0.ContainedReflectable(), -1, 113, 113, const [], const [], null, null, ), r.ParameterMirrorImpl( r'key', 6, 241, const prefix0.ContainedReflectable(), -1, -1, -1, const [], const [], null, null, ), r.ParameterMirrorImpl( r'ifAbsent', 134217734, 241, const prefix0.ContainedReflectable(), -1, 114, 114, const [], const [], null, null, ), r.ParameterMirrorImpl( r'other', 151126022, 242, const prefix0.ContainedReflectable(), 14, 75, 14, null, const [], null, null, ), r.ParameterMirrorImpl( r'key', 67239942, 243, const prefix0.ContainedReflectable(), 4, 4, 4, const [], const [], null, null, ), r.ParameterMirrorImpl( r'action', 134217734, 245, const prefix0.ContainedReflectable(), -1, 115, 115, const [], const [], null, null, ), r.ParameterMirrorImpl( r'other', 151126022, 253, const prefix0.ContainedReflectable(), 14, 116, 14, null, const [], null, null, ), r.ParameterMirrorImpl( r'other', 151126022, 254, const prefix0.ContainedReflectable(), 14, 75, 14, null, const [], null, null, ), r.ParameterMirrorImpl( r'other', 151126022, 255, const prefix0.ContainedReflectable(), 14, 116, 14, null, const [], null, null, ), r.ParameterMirrorImpl( r'iterable', 151126022, 257, const prefix0.ContainedReflectable(), 15, 106, 15, null, const [], null, null, ), r.ParameterMirrorImpl( r'key', 67121158, 257, const prefix0.ContainedReflectable(), -1, 117, 117, const [], const [], null, #key, ), r.ParameterMirrorImpl( r'value', 67121158, 257, const prefix0.ContainedReflectable(), -1, 118, 118, const [], const [], null, #value, ), r.ParameterMirrorImpl( r'keys', 151126022, 258, const prefix0.ContainedReflectable(), 15, 73, 15, null, const [], null, null, ), r.ParameterMirrorImpl( r'values', 151126022, 258, const prefix0.ContainedReflectable(), 15, 74, 15, null, const [], null, null, ), r.ParameterMirrorImpl( r'entries', 151126022, 259, const prefix0.ContainedReflectable(), 15, 72, 15, null, const [], null, null, ), r.ParameterMirrorImpl( r'source', 151126022, 260, const prefix0.ContainedReflectable(), 15, 119, 15, null, const [], null, null, ), r.ParameterMirrorImpl( r'other', 151126022, 262, const prefix0.ContainedReflectable(), 15, 78, 15, null, const [], null, null, ), r.ParameterMirrorImpl( r'toElement', 134217734, 263, const prefix0.ContainedReflectable(), -1, 120, 120, const [], const [], null, null, ), r.ParameterMirrorImpl( r'test', 134217734, 264, const prefix0.ContainedReflectable(), -1, 121, 121, const [], const [], null, null, ), r.ParameterMirrorImpl( r'toElements', 134217734, 266, const prefix0.ContainedReflectable(), -1, 122, 122, const [], const [], null, null, ), r.ParameterMirrorImpl( r'element', 67239942, 267, const prefix0.ContainedReflectable(), 4, 4, 4, const [], const [], null, null, ), r.ParameterMirrorImpl( r'action', 134217734, 268, const prefix0.ContainedReflectable(), -1, 123, 123, const [], const [], null, null, ), r.ParameterMirrorImpl( r'combine', 134217734, 269, const prefix0.ContainedReflectable(), -1, 124, 124, const [], const [], null, null, ), r.ParameterMirrorImpl( r'initialValue', 6, 270, const prefix0.ContainedReflectable(), -1, -1, -1, const [], const [], null, null, ), r.ParameterMirrorImpl( r'combine', 134217734, 270, const prefix0.ContainedReflectable(), -1, 125, 125, const [], const [], null, null, ), r.ParameterMirrorImpl( r'test', 134217734, 271, const prefix0.ContainedReflectable(), -1, 121, 121, const [], const [], null, null, ), r.ParameterMirrorImpl( r'separator', 134354950, 272, const prefix0.ContainedReflectable(), 7, 7, 7, const [], const [], null, null, ), r.ParameterMirrorImpl( r'test', 134217734, 273, const prefix0.ContainedReflectable(), -1, 121, 121, const [], const [], null, null, ), r.ParameterMirrorImpl( r'growable', 134363142, 274, const prefix0.ContainedReflectable(), 8, 8, 8, const [], const [], null, #growable, ), r.ParameterMirrorImpl( r'count', 134348806, 276, const prefix0.ContainedReflectable(), 9, 9, 9, const [], const [], null, null, ), r.ParameterMirrorImpl( r'test', 134217734, 277, const prefix0.ContainedReflectable(), -1, 121, 121, const [], const [], null, null, ), r.ParameterMirrorImpl( r'count', 134348806, 278, const prefix0.ContainedReflectable(), 9, 9, 9, const [], const [], null, null, ), r.ParameterMirrorImpl( r'test', 134217734, 279, const prefix0.ContainedReflectable(), -1, 121, 121, const [], const [], null, null, ), r.ParameterMirrorImpl( r'test', 134217734, 280, const prefix0.ContainedReflectable(), -1, 121, 121, const [], const [], null, null, ), r.ParameterMirrorImpl( r'orElse', 67121158, 280, const prefix0.ContainedReflectable(), -1, 126, 126, const [], const [], null, #orElse, ), r.ParameterMirrorImpl( r'test', 134217734, 281, const prefix0.ContainedReflectable(), -1, 121, 121, const [], const [], null, null, ), r.ParameterMirrorImpl( r'orElse', 67121158, 281, const prefix0.ContainedReflectable(), -1, 126, 126, const [], const [], null, #orElse, ), r.ParameterMirrorImpl( r'test', 134217734, 282, const prefix0.ContainedReflectable(), -1, 121, 121, const [], const [], null, null, ), r.ParameterMirrorImpl( r'orElse', 67121158, 282, const prefix0.ContainedReflectable(), -1, 126, 126, const [], const [], null, #orElse, ), r.ParameterMirrorImpl( r'index', 134348806, 283, const prefix0.ContainedReflectable(), 9, 9, 9, const [], const [], null, null, ), r.ParameterMirrorImpl( r'iterable', 151126022, 285, const prefix0.ContainedReflectable(), 15, 106, 15, null, const [], null, null, ), r.ParameterMirrorImpl( r'leftDelimiter', 134354950, 285, const prefix0.ContainedReflectable(), 7, 7, 7, const [], const [], null, null, ), r.ParameterMirrorImpl( r'rightDelimiter', 134354950, 285, const prefix0.ContainedReflectable(), 7, 7, 7, const [], const [], null, null, ), r.ParameterMirrorImpl( r'iterable', 151126022, 286, const prefix0.ContainedReflectable(), 15, 106, 15, null, const [], null, null, ), r.ParameterMirrorImpl( r'leftDelimiter', 134354950, 286, const prefix0.ContainedReflectable(), 7, 7, 7, const [], const [], null, null, ), r.ParameterMirrorImpl( r'rightDelimiter', 134354950, 286, const prefix0.ContainedReflectable(), 7, 7, 7, const [], const [], null, null, ), r.ParameterMirrorImpl( r'count', 134348806, 295, const prefix0.ContainedReflectable(), 9, 9, 9, const [], const [], null, null, ), r.ParameterMirrorImpl( r'generator', 67112966, 295, const prefix0.ContainedReflectable(), -1, 127, 127, const [], const [], null, null, ), ], [ prefix0.ContainedReflectable, prefix1.Reflectable, prefix2.ReflectableImpl, prefix3.ReflectableBase, Object, Invocation, Type, String, bool, int, List, prefix4.InstanceMirror, prefix4.TypeMirror, prefix4.LibraryMirror, Map, Iterable, prefix5.ReflectCapability, const m.TypeValue>().type, prefix2.ReflectorData, const m.TypeValue>().type, Symbol, Deprecated, prefix5.InstanceInvokeCapability, prefix5.StaticInvokeCapability, prefix5.TopLevelInvokeCapability, prefix5.NewInstanceCapability, prefix5.MetadataCapability, prefix5.TypeCapability, prefix5.TypeRelationsCapability, const r.FakeType(r'reflectable.capability._ReflectedTypeCapability'), prefix5.LibraryCapability, prefix5.DeclarationsCapability, prefix5.UriCapability, prefix5.LibraryDependenciesCapability, prefix5.InvokingCapability, prefix5.TypingCapability, const r.FakeType(r'reflectable.capability._DelegateCapability'), const r.FakeType(r'reflectable.capability._SubtypeQuantifyCapability'), prefix5.SuperclassQuantifyCapability, prefix5.TypeAnnotationQuantifyCapability, const r.FakeType( r'reflectable.capability._CorrespondingSetterQuantifyCapability', ), const r.FakeType(r'reflectable.capability._AdmitSubtypeCapability'), const m.TypeValue>().type, Set, const m.TypeValue>().type, Uri, const m.TypeValue>().type, prefix4.ClassMirror, const m.TypeValue>().type, const m.TypeValue>().type, const m.TypeValue>().type, const m.TypeValue>().type, const m.TypeValue>().type, const m.TypeValue>().type, Runes, double, const r.FakeType(r'dart.core.List'), const r.FakeType(r'dart.core.List'), const r.FakeType(r'dart.core.List'), const r.FakeType(r'dart.core.Iterable'), const r.FakeType(r'dart.core.Map'), prefix4.TypeVariableMirror, const m.TypeValue>().type, const m.TypeValue>().type, prefix4.DeclarationMirror, const m.TypeValue>().type, prefix4.LibraryDependencyMirror, const m.TypeValue>().type, Null, const r.FakeType(r'dart.core.Map'), const r.FakeType(r'dart.core.Map'), const r.FakeType(r'dart.core.Map'), const r.FakeType(r'dart.core.Iterable>'), const r.FakeType(r'dart.core.Iterable'), const r.FakeType(r'dart.core.Iterable'), const r.FakeType(r'dart.core.Map'), const r.FakeType(r'dart.core.Iterable'), const r.FakeType(r'dart.core.Iterable'), const r.FakeType(r'dart.core.Iterable'), const r.FakeType(r'dart.core.Iterable'), const r.FakeType(r'dart.core.Iterable'), const r.FakeType(r'dart.core.Iterable'), const r.FakeType(r'dart.core.List'), const r.FakeType(r'dart.core.Set'), Set, const r.FakeType(r'dart.core.Iterator'), Iterator, const m.TypeValue>().type, prefix5.StringInvocationKind, const m.TypeValue>().type, const m.TypeValue>().type, const m.TypeValue>().type, const m.TypeValue>().type, const m.TypeValue>().type, Pattern, const m.TypeValue().type, const m.TypeValue().type, const m.TypeValue().type, const m.TypeValue>().type, const r.FakeType(r'dart.core.List'), const r.FakeType(r'dart.core.List'), const r.FakeType(r'dart.core.List'), const r.FakeType(r'dart.core.Iterable'), const m.TypeValue().type, prefix6.Random, const m.TypeValue().type, const m.TypeValue>().type, const m.TypeValue().type, const r.FakeType(r'dart.core.Map'), const m.TypeValue().type, const m.TypeValue().type, const m.TypeValue().type, const m.TypeValue().type, const m.TypeValue().type, const m.TypeValue().type, const m.TypeValue().type, const m.TypeValue>().type, const m.TypeValue().type, const m.TypeValue().type, const r.FakeType(r'dart.core.Iterable'), const m.TypeValue().type, const m.TypeValue().type, const m.TypeValue().type, const m.TypeValue().type, const m.TypeValue().type, const m.TypeValue().type, const m.TypeValue().type, const m.TypeValue().type, ], 17, { r'==': (dynamic instance) => (x) => instance == x, r'toString': (dynamic instance) => instance.toString, r'noSuchMethod': (dynamic instance) => instance.noSuchMethod, r'hashCode': (dynamic instance) => instance.hashCode, r'runtimeType': (dynamic instance) => instance.runtimeType, r'capabilities': (dynamic instance) => instance.capabilities, r'canReflect': (dynamic instance) => instance.canReflect, r'reflect': (dynamic instance) => instance.reflect, r'canReflectType': (dynamic instance) => instance.canReflectType, r'reflectType': (dynamic instance) => instance.reflectType, r'findLibrary': (dynamic instance) => instance.findLibrary, r'libraries': (dynamic instance) => instance.libraries, r'annotatedClasses': (dynamic instance) => instance.annotatedClasses, r'typeArguments': (dynamic instance) => instance.typeArguments, r'isAccessor': (dynamic instance) => instance.isAccessor, r'&': (dynamic instance) => (x) => instance & x, r'|': (dynamic instance) => (x) => instance | x, r'^': (dynamic instance) => (x) => instance ^ x, r'cast': (dynamic instance) => instance.cast, r'followedBy': (dynamic instance) => instance.followedBy, r'map': (dynamic instance) => instance.map, r'where': (dynamic instance) => instance.where, r'whereType': (dynamic instance) => instance.whereType, r'expand': (dynamic instance) => instance.expand, r'contains': (dynamic instance) => instance.contains, r'forEach': (dynamic instance) => instance.forEach, r'reduce': (dynamic instance) => instance.reduce, r'fold': (dynamic instance) => instance.fold, r'every': (dynamic instance) => instance.every, r'join': (dynamic instance) => instance.join, r'any': (dynamic instance) => instance.any, r'toList': (dynamic instance) => instance.toList, r'toSet': (dynamic instance) => instance.toSet, r'take': (dynamic instance) => instance.take, r'takeWhile': (dynamic instance) => instance.takeWhile, r'skip': (dynamic instance) => instance.skip, r'skipWhile': (dynamic instance) => instance.skipWhile, r'firstWhere': (dynamic instance) => instance.firstWhere, r'lastWhere': (dynamic instance) => instance.lastWhere, r'singleWhere': (dynamic instance) => instance.singleWhere, r'elementAt': (dynamic instance) => instance.elementAt, r'length': (dynamic instance) => instance.length, r'isEmpty': (dynamic instance) => instance.isEmpty, r'isNotEmpty': (dynamic instance) => instance.isNotEmpty, r'first': (dynamic instance) => instance.first, r'last': (dynamic instance) => instance.last, r'single': (dynamic instance) => instance.single, }, {}, [ r.LibraryMirrorImpl( r'', Uri.parse( 'package:angel3_container_generator/angel3_container_generator.dart', ), const prefix0.ContainedReflectable(), const [0], {r'contained': () => prefix0.contained}, {}, const [], null, ), r.LibraryMirrorImpl( r'reflectable.reflectable', Uri.parse('package:reflectable/reflectable.dart'), const prefix0.ContainedReflectable(), const [], {}, {}, const [], null, ), r.LibraryMirrorImpl( r'reflectable.src.reflectable_builder_based', Uri.parse('package:reflectable/src/reflectable_builder_based.dart'), const prefix0.ContainedReflectable(), const [1, 2, 3, 35], { r'pleaseInitializeMessage': () => prefix2.pleaseInitializeMessage, r'data': () => prefix2.data, r'memberSymbolMap': () => prefix2.memberSymbolMap, r'reflectors': () => prefix2.reflectors, }, { r'data=': (dynamic value) => prefix2.data = value, r'memberSymbolMap=': (dynamic value) => prefix2.memberSymbolMap = value, }, const [], null, ), r.LibraryMirrorImpl( r'reflectable.src.reflectable_base', Uri.parse('package:reflectable/src/reflectable_base.dart'), const prefix0.ContainedReflectable(), const [], {}, {}, const [], null, ), r.LibraryMirrorImpl( r'dart.core', Uri.parse(r'reflectable://4/library dart:core'), const prefix0.ContainedReflectable(), const [4, 5, 36, 37, 38], { r'deprecated': () => deprecated, r'override': () => override, r'identical': () => identical, r'identityHashCode': () => identityHashCode, r'print': () => print, }, {}, const [], null, ), r.LibraryMirrorImpl( r'reflectable.mirrors', Uri.parse('package:reflectable/mirrors.dart'), const prefix0.ContainedReflectable(), const [], {}, {}, const [], null, ), r.LibraryMirrorImpl( r'reflectable.capability', Uri.parse('package:reflectable/capability.dart'), const prefix0.ContainedReflectable(), const [ 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 41, 42, 43, 44, 45, ], { r'instanceInvokeCapability': () => prefix5.instanceInvokeCapability, r'staticInvokeCapability': () => prefix5.staticInvokeCapability, r'topLevelInvokeCapability': () => prefix5.topLevelInvokeCapability, r'newInstanceCapability': () => prefix5.newInstanceCapability, r'metadataCapability': () => prefix5.metadataCapability, r'typeCapability': () => prefix5.typeCapability, r'typeRelationsCapability': () => prefix5.typeRelationsCapability, r'reflectedTypeCapability': () => prefix5.reflectedTypeCapability, r'libraryCapability': () => prefix5.libraryCapability, r'declarationsCapability': () => prefix5.declarationsCapability, r'uriCapability': () => prefix5.uriCapability, r'libraryDependenciesCapability': () => prefix5.libraryDependenciesCapability, r'invokingCapability': () => prefix5.invokingCapability, r'typingCapability': () => prefix5.typingCapability, r'delegateCapability': () => prefix5.delegateCapability, r'subtypeQuantifyCapability': () => prefix5.subtypeQuantifyCapability, r'superclassQuantifyCapability': () => prefix5.superclassQuantifyCapability, r'typeAnnotationQuantifyCapability': () => prefix5.typeAnnotationQuantifyCapability, r'typeAnnotationDeepQuantifyCapability': () => prefix5.typeAnnotationDeepQuantifyCapability, r'correspondingSetterQuantifyCapability': () => prefix5.correspondingSetterQuantifyCapability, r'admitSubtypeCapability': () => prefix5.admitSubtypeCapability, r'reflectableNoSuchInvokableError': () => prefix5.reflectableNoSuchInvokableError, r'reflectableNoSuchMethodError': () => prefix5.reflectableNoSuchMethodError, r'reflectableNoSuchGetterError': () => prefix5.reflectableNoSuchGetterError, r'reflectableNoSuchSetterError': () => prefix5.reflectableNoSuchSetterError, r'reflectableNoSuchConstructorError': () => prefix5.reflectableNoSuchConstructorError, }, {}, const [], null, ), ], [], ), }; final _memberSymbolMap = null; void initializeReflectable() { r.data = _data; r.memberSymbolMap = _memberSymbolMap; } ================================================ FILE: packages/container/angel_container_generator/lib/angel3_container_generator.dart ================================================ import 'package:angel3_container/angel3_container.dart'; import 'package:reflectable/reflectable.dart'; /// A [Reflectable] instance that can be used as an annotation on types to generate metadata for them. const Reflectable contained = ContainedReflectable(); @contained class ContainedReflectable extends Reflectable { const ContainedReflectable() : super( topLevelInvokeCapability, typeAnnotationQuantifyCapability, superclassQuantifyCapability, libraryCapability, invokingCapability, metadataCapability, reflectedTypeCapability, typeCapability, typingCapability, ); } /// A [Reflector] instance that uses a [Reflectable] to reflect upon data. class GeneratedReflector extends Reflector { final Reflectable reflectable; const GeneratedReflector([this.reflectable = contained]); @override String getName(Symbol symbol) { return symbol.toString().substring(7); } @override ReflectedClass reflectClass(Type clazz) { return reflectType(clazz) as ReflectedClass; } @override ReflectedFunction reflectFunction(Function function) { if (!reflectable.canReflect(function)) { throw UnsupportedError('Cannot reflect $function.'); } var mirror = reflectable.reflect(function); if (mirror is ClosureMirror) { return _GeneratedReflectedFunction(mirror.function, this, mirror); } else { throw ArgumentError('$function is not a Function.'); } } @override ReflectedInstance reflectInstance(Object object) { if (!reflectable.canReflect(object)) { throw UnsupportedError('Cannot reflect $object.'); } else { var mirror = reflectable.reflect(object); return _GeneratedReflectedInstance(mirror, this); } } @override ReflectedType reflectType(Type type) { if (!reflectable.canReflectType(type)) { throw UnsupportedError('Cannot reflect $type.'); } else { var mirror = reflectable.reflectType(type); return mirror is ClassMirror ? _GeneratedReflectedClass(mirror, this) : _GeneratedReflectedType(mirror); } } } class _GeneratedReflectedInstance extends ReflectedInstance { final InstanceMirror mirror; final GeneratedReflector reflector; _GeneratedReflectedInstance(this.mirror, this.reflector) : super( _GeneratedReflectedType(mirror.type), _GeneratedReflectedClass(mirror.type, reflector), mirror.reflectee, ); @override ReflectedType get type => clazz; @override ReflectedInstance getField(String name) { var result = mirror.invokeGetter(name)!; var instance = reflector.reflectable.reflect(result); return _GeneratedReflectedInstance(instance, reflector); } } class _GeneratedReflectedClass extends ReflectedClass { final ClassMirror mirror; final Reflector reflector; _GeneratedReflectedClass(this.mirror, this.reflector) : super(mirror.simpleName, [], [], [], [], mirror.reflectedType); @override List get typeParameters => mirror.typeVariables.map(_convertTypeVariable).toList(); @override List get constructors => _constructorsOf(mirror.declarations, reflector); @override List get declarations => _declarationsOf(mirror.declarations, reflector); @override List get annotations => mirror.metadata .map(reflector.reflectInstance) .whereType() .toList(); @override bool isAssignableTo(ReflectedType? other) { if (other is _GeneratedReflectedClass) { return mirror.isAssignableTo(other.mirror); } else if (other is _GeneratedReflectedType) { return mirror.isAssignableTo(other.mirror); } else { return false; } } @override ReflectedInstance newInstance( String constructorName, List positionalArguments, [ Map? namedArguments, List? typeArguments, ]) { namedArguments ??= {}; var result = mirror.newInstance( constructorName, positionalArguments, namedArguments.map((k, v) => MapEntry(Symbol(k), v)), ); return reflector.reflectInstance(result)!; } } class _GeneratedReflectedType extends ReflectedType { final TypeMirror mirror; _GeneratedReflectedType(this.mirror) : super(mirror.simpleName, [], mirror.reflectedType); @override List get typeParameters => mirror.typeVariables.map(_convertTypeVariable).toList(); @override bool isAssignableTo(ReflectedType? other) { if (other is _GeneratedReflectedClass) { return mirror.isAssignableTo(other.mirror); } else if (other is _GeneratedReflectedType) { return mirror.isAssignableTo(other.mirror); } else { return false; } } @override ReflectedInstance newInstance( String constructorName, List positionalArguments, [ Map namedArguments = const {}, List typeArguments = const [], ]) { throw UnsupportedError('Cannot create a new instance of $reflectedType.'); } } class _GeneratedReflectedFunction extends ReflectedFunction { final MethodMirror mirror; final Reflector reflector; final ClosureMirror? closure; _GeneratedReflectedFunction(this.mirror, this.reflector, [this.closure]) : super( mirror.simpleName, [], [], mirror.parameters.map((p) => _convertParameter(p, reflector)).toList(), mirror.isGetter, mirror.isSetter, returnType: !mirror.isRegularMethod ? null : _GeneratedReflectedType(mirror.returnType), ); @override List get annotations => mirror.metadata .map(reflector.reflectInstance) .whereType() .toList(); @override ReflectedInstance invoke(Invocation invocation) { if (closure != null) { throw UnsupportedError('Only closures can be invoked directly.'); } else { var result = closure!.delegate(invocation)!; return reflector.reflectInstance(result)!; } } } List _constructorsOf( Map map, Reflector reflector, ) { return map.entries.fold>([], (out, entry) { var v = entry.value; if (v is MethodMirror && v.isConstructor) { return out..add(_GeneratedReflectedFunction(v, reflector)); } else { return out; } }); } List _declarationsOf( Map map, Reflector reflector, ) { return map.entries.fold>([], (out, entry) { var v = entry.value; if (v is VariableMirror) { var decl = ReflectedDeclaration(v.simpleName, v.isStatic, null); return out..add(decl); } if (v is MethodMirror) { var decl = ReflectedDeclaration( v.simpleName, v.isStatic, _GeneratedReflectedFunction(v, reflector), ); return out..add(decl); } else { return out; } }); } ReflectedTypeParameter _convertTypeVariable(TypeVariableMirror mirror) { return ReflectedTypeParameter(mirror.simpleName); } ReflectedParameter _convertParameter( ParameterMirror mirror, Reflector reflector, ) { return ReflectedParameter( mirror.simpleName, mirror.metadata .map(reflector.reflectInstance) .whereType() .toList(), reflector.reflectType(mirror.type.reflectedType)!, !mirror.isOptional, mirror.isNamed, ); } ================================================ FILE: packages/container/angel_container_generator/melos_angel3_container_generator.iml ================================================ ================================================ FILE: packages/container/angel_container_generator/pubspec.yaml ================================================ name: angel3_container_generator version: 8.5.0 description: Codegen support for using pkg:reflectable with pkg:angel3_container. homepage: https://angel3-framework.web.app/ repository: https://github.com/dart-backend/angel/tree/master/packages/container/angel_container_generator resolution: workspace environment: sdk: '>=3.11.0 <4.0.0' dependencies: angel3_container: ^8.4.0 reflectable: ^5.0.0 dev_dependencies: build_runner: ^2.0.0 build_test: ^3.5.0 test: ^1.24.0 lints: ^6.0.0 ================================================ FILE: packages/container/angel_container_generator/test/reflector_test.dart ================================================ import 'package:angel3_container/angel3_container.dart'; import 'package:angel3_container_generator/angel3_container_generator.dart'; import 'package:test/test.dart'; import 'reflector_test.reflectable.dart'; void main() { initializeReflectable(); var reflector = const GeneratedReflector(); late Container container; setUp(() { container = Container(reflector); container.registerSingleton(Artist(name: 'Stevie Wonder')); }); group('reflectClass', () { var mirror = reflector.reflectClass(Artist); test('name', () { expect(mirror.name, 'Artist'); }); }); test('inject constructor parameters', () { var album = container.make(); print(album.title); expect(album.title, 'flowers by stevie wonder'); }); // Skip as pkg:reflectable cannot reflect on closures at all (yet) //testReflector(reflector); } @contained void returnVoidFromAFunction(int x) {} void testReflector(Reflector reflector) { var blaziken = Pokemon('Blaziken', PokemonType.fire); late Container container; setUp(() { container = Container(reflector); container.registerSingleton(blaziken); }); test('get field', () { var blazikenMirror = reflector.reflectInstance(blaziken)!; expect(blazikenMirror.getField('type').reflectee, blaziken.type); }); group( 'reflectFunction', () { var mirror = reflector.reflectFunction(returnVoidFromAFunction); test('void return type returns dynamic', () { expect(mirror?.returnType, reflector.reflectType(dynamic)); }); test('counts parameters', () { expect(mirror?.parameters, hasLength(1)); }); test('counts types parameters', () { expect(mirror?.typeParameters, isEmpty); }); test('correctly reflects parameter types', () { var p = mirror?.parameters[0]; expect(p?.name, 'x'); expect(p?.isRequired, true); expect(p?.isNamed, false); expect(p?.annotations, isEmpty); expect(p?.type, reflector.reflectType(int)); }); }, skip: 'pkg:reflectable cannot reflect on closures at all (yet)', ); test('make on singleton type returns singleton', () { expect(container.make(Pokemon), blaziken); }); test('make with generic returns same as make with explicit type', () { expect(container.make(), blaziken); }); test('make on aliased singleton returns singleton', () { container.registerSingleton(blaziken, as: StateError); expect(container.make(StateError), blaziken); }); test('constructor injects singleton', () { var lower = container.make(); expect(lower.lowercaseName, blaziken.name.toLowerCase()); }); test('newInstance works', () { var type = container.reflector.reflectType(Pokemon)!; var instance = type.newInstance('changeName', [blaziken, 'Charizard']).reflectee as Pokemon; print(instance); expect(instance.name, 'Charizard'); expect(instance.type, PokemonType.fire); }); test('isAssignableTo', () { var pokemonType = container.reflector.reflectType(Pokemon); var kantoPokemonType = container.reflector.reflectType(KantoPokemon)!; expect(kantoPokemonType.isAssignableTo(pokemonType), true); expect( kantoPokemonType.isAssignableTo(container.reflector.reflectType(String)), false, ); }); } @contained class LowerPokemon { final Pokemon pokemon; LowerPokemon(this.pokemon); String get lowercaseName => pokemon.name.toLowerCase(); } @contained class Pokemon { final String name; final PokemonType type; Pokemon(this.name, this.type); factory Pokemon.changeName(Pokemon other, String name) { return Pokemon(name, other.type); } @override String toString() => 'NAME: $name, TYPE: $type'; } @contained class KantoPokemon extends Pokemon { KantoPokemon(super.name, super.type); } @contained enum PokemonType { water, fire, grass, ice, poison, flying } @contained class Artist { final String name; Artist({required this.name}); String get lowerName { return name.toLowerCase(); } } @contained class Album { final Artist artist; Album(this.artist); String get title => 'flowers by ${artist.lowerName}'; } @contained class AlbumLength { final Artist artist; final Album album; AlbumLength(this.artist, this.album); int get totalLength => artist.name.length + album.title.length; } ================================================ FILE: packages/container/angel_container_generator/test/reflector_test.reflectable.dart ================================================ // This file has been generated by the reflectable package. // https://github.com/dart-lang/reflectable. import 'dart:core'; import 'dart:math' as prefix8; import 'package:angel3_container/src/reflector.dart' as prefix7; import 'package:angel3_container_generator/angel3_container_generator.dart' as prefix0; import 'package:reflectable/capability.dart' as prefix6; import 'package:reflectable/mirrors.dart' as prefix5; import 'package:reflectable/reflectable.dart' as prefix2; import 'package:reflectable/src/reflectable_base.dart' as prefix4; import 'package:reflectable/src/reflectable_builder_based.dart' as prefix3; import 'reflector_test.dart' as prefix1; // ignore_for_file: camel_case_types // ignore_for_file: implementation_imports // ignore_for_file: prefer_adjacent_string_concatenation // ignore_for_file: prefer_collection_literals // ignore_for_file: unnecessary_const // ignore:unused_import import 'package:reflectable/mirrors.dart' as m; // ignore:unused_import import 'package:reflectable/src/reflectable_builder_based.dart' as r; // ignore:unused_import import 'package:reflectable/reflectable.dart' as r show Reflectable; final _data = { const prefix0.ContainedReflectable(): r.ReflectorData( [ r.NonGenericClassMirrorImpl( r'LowerPokemon', r'.LowerPokemon', 134217735, 0, const prefix0.ContainedReflectable(), const [27, 85, 86], const [87, 88, 89, 90, 91, 84, 85], const [], 8, {}, {}, { r'': (bool b) => (pokemon) => b ? prefix1.LowerPokemon(pokemon) : null, }, 0, 0, const [], const [prefix0.contained], null, ), r.NonGenericClassMirrorImpl( r'Pokemon', r'.Pokemon', 134217735, 1, const prefix0.ContainedReflectable(), const [28, 29, 92, 95, 96], const [87, 92, 89, 90, 91, 93, 94], const [], 8, {}, {}, { r'': (bool b) => (name, type) => b ? prefix1.Pokemon(name, type) : null, r'changeName': (bool b) => (other, name) => b ? prefix1.Pokemon.changeName(other, name) : null, }, 0, 1, const [], const [prefix0.contained], null, ), r.NonGenericClassMirrorImpl( r'KantoPokemon', r'.KantoPokemon', 134217735, 2, const prefix0.ContainedReflectable(), const [97], const [87, 92, 89, 90, 91, 93, 94], const [], 1, {}, {}, { r'': (bool b) => (name, type) => b ? prefix1.KantoPokemon(name, type) : null, }, 0, 2, const [], const [prefix0.contained], null, ), r.NonGenericClassMirrorImpl( r'Artist', r'.Artist', 134217735, 3, const prefix0.ContainedReflectable(), const [30, 99, 100], const [87, 88, 89, 90, 91, 98, 99], const [], 8, {}, {}, { r'': (bool b) => ({name}) => b ? prefix1.Artist(name: name) : null, }, 0, 3, const [], const [prefix0.contained], null, ), r.NonGenericClassMirrorImpl( r'Album', r'.Album', 134217735, 4, const prefix0.ContainedReflectable(), const [31, 102, 103], const [87, 88, 89, 90, 91, 101, 102], const [], 8, {}, {}, { r'': (bool b) => (artist) => b ? prefix1.Album(artist) : null, }, 0, 4, const [], const [prefix0.contained], null, ), r.NonGenericClassMirrorImpl( r'AlbumLength', r'.AlbumLength', 134217735, 5, const prefix0.ContainedReflectable(), const [32, 33, 106, 107], const [87, 88, 89, 90, 91, 104, 105, 106], const [], 8, {}, {}, { r'': (bool b) => (artist, album) => b ? prefix1.AlbumLength(artist, album) : null, }, 0, 5, const [], const [prefix0.contained], null, ), r.NonGenericClassMirrorImpl( r'PokemonType', r'.PokemonType', 138412039, 6, const prefix0.ContainedReflectable(), const [34, 35, 36, 37, 38, 39, 115], const [87, 88, 89, 90, 91, 116], const [108, 109, 110, 111, 112, 113, 114], 9, { r'water': () => prefix1.PokemonType.water, r'fire': () => prefix1.PokemonType.fire, r'grass': () => prefix1.PokemonType.grass, r'ice': () => prefix1.PokemonType.ice, r'poison': () => prefix1.PokemonType.poison, r'flying': () => prefix1.PokemonType.flying, r'values': () => prefix1.PokemonType.values, }, {}, {}, 0, 6, const [], const [prefix0.contained], null, ), r.NonGenericClassMirrorImpl( r'ContainedReflectable', r'.ContainedReflectable', 134217735, 7, const prefix0.ContainedReflectable(), const [117], const [87, 88, 89, 90, 91, 118, 119, 120, 121, 122, 123, 124, 125], const [], 10, {}, {}, { r'': (bool b) => () => b ? prefix0.ContainedReflectable() : null, }, 1, 7, const [], const [prefix0.contained], null, ), r.NonGenericClassMirrorImpl( r'Object', r'dart.core.Object', 134217735, 8, const prefix0.ContainedReflectable(), const [87, 88, 89, 126, 127, 128, 90, 91, 129], const [87, 88, 89, 90, 91], const [126, 127, 128], null, { r'hash': () => Object.hash, r'hashAll': () => Object.hashAll, r'hashAllUnordered': () => Object.hashAllUnordered, }, {}, { r'': (bool b) => () => b ? Object() : null, }, 2, 8, const [], const [], null, ), r.NonGenericClassMirrorImpl( r'Enum', r'dart.core.Enum', 134218247, 9, const prefix0.ContainedReflectable(), const [130, 131, 116, 132], const [87, 88, 89, 90, 91, 116], const [130, 131], 8, { r'compareByIndex': () => Enum.compareByIndex, r'compareByName': () => Enum.compareByName, }, {}, {}, 2, 9, const [], const [], null, ), r.NonGenericClassMirrorImpl( r'Reflectable', r'reflectable.reflectable.Reflectable', 134218247, 10, const prefix0.ContainedReflectable(), const [41, 42, 133, 136, 137], const [87, 88, 89, 90, 91, 118, 119, 120, 121, 122, 123, 124, 125], const [133, 134, 135], 11, { r'getInstance': () => prefix2.Reflectable.getInstance, r'thisClassName': () => prefix2.Reflectable.thisClassName, r'thisClassId': () => prefix2.Reflectable.thisClassId, }, {}, {}, 3, 10, const [], const [], null, ), r.NonGenericClassMirrorImpl( r'ReflectableImpl', r'reflectable.src.reflectable_builder_based.ReflectableImpl', 134218247, 11, const prefix0.ContainedReflectable(), const [119, 120, 121, 122, 123, 124, 125, 138, 139], const [87, 88, 89, 90, 91, 118, 119, 120, 121, 122, 123, 124, 125], const [], 12, {}, {}, {}, 4, 11, const [], const [], null, ), r.NonGenericClassMirrorImpl( r'ReflectableBase', r'reflectable.src.reflectable_base.ReflectableBase', 134217735, 12, const prefix0.ContainedReflectable(), const [118, 140, 141], const [87, 88, 89, 90, 91, 118], const [], 8, {}, {}, { r'': (bool b) => ([ _cap0, _cap1, _cap2, _cap3, _cap4, _cap5, _cap6, _cap7, _cap8, _cap9, ]) => b ? prefix4.ReflectableBase( _cap0, _cap1, _cap2, _cap3, _cap4, _cap5, _cap6, _cap7, _cap8, _cap9, ) : null, r'fromList': (bool b) => (_capabilities) => b ? prefix4.ReflectableBase.fromList(_capabilities) : null, }, 5, 12, const [], const [], null, ), r.NonGenericClassMirrorImpl( r'Invocation', r'dart.core.Invocation', 134218247, 13, const prefix0.ContainedReflectable(), const [ 142, 143, 144, 145, 146, 147, 148, 149, 150, 151, 152, 153, 154, ], const [87, 88, 89, 90, 91, 143, 149], const [], 8, {}, {}, { r'method': (bool b) => (memberName, positionalArguments, [namedArguments]) => b ? Invocation.method( memberName, positionalArguments, namedArguments, ) : null, r'genericMethod': (bool b) => ( memberName, typeArguments, positionalArguments, [ namedArguments, ]) => b ? Invocation.genericMethod( memberName, typeArguments, positionalArguments, namedArguments, ) : null, r'getter': (bool b) => (name) => b ? Invocation.getter(name) : null, r'setter': (bool b) => (memberName, argument) => b ? Invocation.setter(memberName, argument) : null, }, 2, 13, const [], const [], null, ), r.NonGenericClassMirrorImpl( r'bool', r'dart.core.bool', 134217735, 14, const prefix0.ContainedReflectable(), const [155, 156, 157, 158, 159, 160, 161, 162, 163], const [87, 160, 89, 161, 91, 157, 158, 159], const [155, 156], 8, {r'parse': () => bool.parse, r'tryParse': () => bool.tryParse}, {}, { r'fromEnvironment': (bool b) => (name, {defaultValue}) => b ? bool.fromEnvironment(name, defaultValue: defaultValue) : null, r'hasEnvironment': (bool b) => (name) => b ? bool.hasEnvironment(name) : null, }, 2, 14, const [], const [], null, ), r.NonGenericClassMirrorImpl( r'String', r'dart.core.String', 134218247, 15, const prefix0.ContainedReflectable(), const [ 164, 165, 166, 167, 168, 169, 170, 171, 172, 173, 174, 175, 176, 177, 178, 179, 180, 181, 182, 183, 184, 185, 186, 187, 188, 189, 190, 191, 192, 193, 194, 195, 196, 197, 198, ], const [87, 88, 89, 90, 91], const [], 8, {}, {}, { r'fromCharCodes': (bool b) => (charCodes, [start, end]) => b ? String.fromCharCodes(charCodes, start, end) : null, r'fromCharCode': (bool b) => (charCode) => b ? String.fromCharCode(charCode) : null, r'fromEnvironment': (bool b) => (name, {defaultValue}) => b ? String.fromEnvironment(name, defaultValue: defaultValue) : null, }, 2, 15, const [], const [], null, ), r.NonGenericClassMirrorImpl( r'int', r'dart.core.int', 134218247, 16, const prefix0.ContainedReflectable(), const [ 199, 200, 201, 202, 203, 204, 205, 206, 207, 208, 209, 210, 211, 212, 213, 214, 215, 216, 217, 218, 219, 220, 221, 222, 223, 224, 225, 226, 227, 228, 229, ], const [87, 88, 89, 90, 91], const [223, 224], -1, {r'parse': () => int.parse, r'tryParse': () => int.tryParse}, {}, { r'fromEnvironment': (bool b) => (name, {defaultValue}) => b ? int.fromEnvironment(name, defaultValue: defaultValue) : null, }, 2, 16, const [], const [], null, ), r.NonGenericClassMirrorImpl( r'Type', r'dart.core.Type', 134218247, 17, const prefix0.ContainedReflectable(), const [230, 231, 232, 233], const [87, 88, 89, 90, 91], const [], 8, {}, {}, {}, 2, 17, const [], const [], null, ), r.GenericClassMirrorImpl( r'List', r'dart.core.List', 134218247, 18, const prefix0.ContainedReflectable(), const [ 234, 235, 236, 237, 238, 239, 240, 241, 242, 243, 244, 245, 246, 247, 248, 249, 250, 251, 252, 253, 254, 255, 256, 257, 258, 259, 260, 261, 262, 263, 264, 265, 266, 267, 268, 269, 270, 271, 272, 273, 274, 275, 276, ], const [87, 88, 89, 90, 91], const [234, 235, 236], 8, { r'castFrom': () => List.castFrom, r'copyRange': () => List.copyRange, r'writeIterable': () => List.writeIterable, }, {}, { r'filled': (bool b) => (length, fill, {growable}) => b ? List.filled(length, fill, growable: growable) : null, r'empty': (bool b) => ({growable}) => b ? List.empty(growable: growable) : null, r'from': (bool b) => (elements, {growable}) => b ? List.from(elements, growable: growable) : null, r'of': (bool b) => (elements, {growable}) => b ? List.of(elements, growable: growable) : null, r'generate': (bool b) => (length, generator, {growable}) => b ? List.generate(length, generator, growable: growable) : null, r'unmodifiable': (bool b) => (elements) => b ? List.unmodifiable(elements) : null, }, 2, 18, const [23], const [], null, (o) => false, const [25], 18, ), r.NonGenericClassMirrorImpl( r'InstanceMirror', r'reflectable.mirrors.InstanceMirror', 134218247, 19, const prefix0.ContainedReflectable(), const [277, 278, 279, 280, 281, 282, 283], const [87, 88, 89, 90, 91], const [], 8, {}, {}, {}, 6, 19, const [], const [], null, ), r.NonGenericClassMirrorImpl( r'TypeMirror', r'reflectable.mirrors.TypeMirror', 134218247, 20, const prefix0.ContainedReflectable(), const [ 284, 285, 286, 287, 288, 289, 290, 291, 292, 293, 294, 295, 296, 297, ], const [87, 88, 89, 90, 91], const [], 8, {}, {}, {}, 6, 20, const [], const [], null, ), r.NonGenericClassMirrorImpl( r'LibraryMirror', r'reflectable.mirrors.LibraryMirror', 134218247, 21, const prefix0.ContainedReflectable(), const [298, 299, 300, 301, 302, 303, 304], const [87, 88, 89, 90, 91], const [], 8, {}, {}, {}, 6, 21, const [], const [], null, ), r.GenericClassMirrorImpl( r'Map', r'dart.core.Map', 134218247, 22, const prefix0.ContainedReflectable(), const [ 305, 306, 307, 308, 309, 310, 311, 312, 313, 314, 315, 316, 317, 318, 319, 320, 321, 322, 323, 324, 325, 326, 327, 328, 329, 330, 331, 332, 333, 334, ], const [87, 88, 89, 90, 91], const [305], 8, {r'castFrom': () => Map.castFrom}, {}, { r'': (bool b) => () => b ? Map() : null, r'from': (bool b) => (other) => b ? Map.from(other) : null, r'of': (bool b) => (other) => b ? Map.of(other) : null, r'unmodifiable': (bool b) => (other) => b ? Map.unmodifiable(other) : null, r'identity': (bool b) => () => b ? Map.identity() : null, r'fromIterable': (bool b) => (iterable, {key, value}) => b ? Map.fromIterable(iterable, key: key, value: value) : null, r'fromIterables': (bool b) => (keys, values) => b ? Map.fromIterables(keys, values) : null, r'fromEntries': (bool b) => (entries) => b ? Map.fromEntries(entries) : null, }, 2, 22, const [], const [], null, (o) => false, const [26, 27], 22, ), r.GenericClassMirrorImpl( r'Iterable', r'dart.core.Iterable', 134218247, 23, const prefix0.ContainedReflectable(), const [ 335, 336, 337, 338, 339, 340, 341, 342, 343, 344, 345, 346, 347, 348, 349, 350, 351, 352, 353, 354, 355, 356, 357, 358, 359, 360, 361, 362, 363, 364, 365, 366, 367, 368, 369, 370, 371, ], const [ 87, 359, 89, 90, 91, 336, 337, 338, 339, 340, 341, 342, 343, 344, 345, 346, 347, 348, 349, 350, 351, 352, 353, 354, 355, 356, 357, 358, 363, 364, 365, 366, 367, 368, ], const [335, 360, 361], 8, { r'castFrom': () => Iterable.castFrom, r'iterableToShortString': () => Iterable.iterableToShortString, r'iterableToFullString': () => Iterable.iterableToFullString, }, {}, { r'generate': (bool b) => (count, [generator]) => b ? Iterable.generate(count, generator) : null, r'empty': (bool b) => () => b ? Iterable.empty() : null, }, 2, 23, const [], const [], null, (o) => false, const [28], 23, ), r.NonGenericClassMirrorImpl( r'ReflectCapability', r'reflectable.capability.ReflectCapability', 134218247, 24, const prefix0.ContainedReflectable(), const [372], const [87, 88, 89, 90, 91], const [], 8, {}, {}, {}, 7, 24, const [], const [], null, ), r.TypeVariableMirrorImpl( r'E', r'dart.core.List.E', const prefix0.ContainedReflectable(), 8, 18, [], ), r.TypeVariableMirrorImpl( r'K', r'dart.core.Map.K', const prefix0.ContainedReflectable(), 8, 22, [], ), r.TypeVariableMirrorImpl( r'V', r'dart.core.Map.V', const prefix0.ContainedReflectable(), 8, 22, [], ), r.TypeVariableMirrorImpl( r'E', r'dart.core.Iterable.E', const prefix0.ContainedReflectable(), 8, 23, [], ), ], [ r.VariableMirrorImpl( r'contained', 142738581, 1, const prefix0.ContainedReflectable(), 10, 10, 10, const [], const [], ), r.VariableMirrorImpl( r'deprecated', 142738581, -1, const prefix0.ContainedReflectable(), -1, 25, 25, const [], const [], ), r.VariableMirrorImpl( r'override', 142738581, -1, const prefix0.ContainedReflectable(), 8, 8, 8, const [], const [], ), r.VariableMirrorImpl( r'pleaseInitializeMessage', 142738581, -1, const prefix0.ContainedReflectable(), 15, 15, 15, const [], const [], ), r.VariableMirrorImpl( r'data', 142737429, -1, const prefix0.ContainedReflectable(), 22, 26, 22, const [10, 27], const [], ), r.VariableMirrorImpl( r'memberSymbolMap', 75628565, -1, const prefix0.ContainedReflectable(), 22, 28, 22, const [29, 15], const [], ), r.VariableMirrorImpl( r'instanceInvokeCapability', 142738581, -1, const prefix0.ContainedReflectable(), -1, 30, 30, const [], const [], ), r.VariableMirrorImpl( r'staticInvokeCapability', 142738581, -1, const prefix0.ContainedReflectable(), -1, 31, 31, const [], const [], ), r.VariableMirrorImpl( r'topLevelInvokeCapability', 142738581, -1, const prefix0.ContainedReflectable(), -1, 32, 32, const [], const [], ), r.VariableMirrorImpl( r'newInstanceCapability', 142738581, -1, const prefix0.ContainedReflectable(), -1, 33, 33, const [], const [], ), r.VariableMirrorImpl( r'metadataCapability', 142738581, -1, const prefix0.ContainedReflectable(), -1, 34, 34, const [], const [], ), r.VariableMirrorImpl( r'typeCapability', 142738581, -1, const prefix0.ContainedReflectable(), -1, 35, 35, const [], const [], ), r.VariableMirrorImpl( r'typeRelationsCapability', 142738581, -1, const prefix0.ContainedReflectable(), -1, 36, 36, const [], const [], ), r.VariableMirrorImpl( r'reflectedTypeCapability', 142738581, -1, const prefix0.ContainedReflectable(), -1, 37, 37, const [], const [], ), r.VariableMirrorImpl( r'libraryCapability', 142738581, -1, const prefix0.ContainedReflectable(), -1, 38, 38, const [], const [], ), r.VariableMirrorImpl( r'declarationsCapability', 142738581, -1, const prefix0.ContainedReflectable(), -1, 39, 39, const [], const [], ), r.VariableMirrorImpl( r'uriCapability', 142738581, -1, const prefix0.ContainedReflectable(), -1, 40, 40, const [], const [], ), r.VariableMirrorImpl( r'libraryDependenciesCapability', 142738581, -1, const prefix0.ContainedReflectable(), -1, 41, 41, const [], const [], ), r.VariableMirrorImpl( r'invokingCapability', 142738581, -1, const prefix0.ContainedReflectable(), -1, 42, 42, const [], const [], ), r.VariableMirrorImpl( r'typingCapability', 142738581, -1, const prefix0.ContainedReflectable(), -1, 43, 43, const [], const [], ), r.VariableMirrorImpl( r'delegateCapability', 142738581, -1, const prefix0.ContainedReflectable(), -1, 44, 44, const [], const [], ), r.VariableMirrorImpl( r'subtypeQuantifyCapability', 142738581, -1, const prefix0.ContainedReflectable(), -1, 45, 45, const [], const [], ), r.VariableMirrorImpl( r'superclassQuantifyCapability', 142738581, -1, const prefix0.ContainedReflectable(), -1, 46, 46, const [], const [], ), r.VariableMirrorImpl( r'typeAnnotationQuantifyCapability', 142738581, -1, const prefix0.ContainedReflectable(), -1, 47, 47, const [], const [], ), r.VariableMirrorImpl( r'typeAnnotationDeepQuantifyCapability', 142738581, -1, const prefix0.ContainedReflectable(), -1, 47, 47, const [], const [], ), r.VariableMirrorImpl( r'correspondingSetterQuantifyCapability', 142738581, -1, const prefix0.ContainedReflectable(), -1, 48, 48, const [], const [], ), r.VariableMirrorImpl( r'admitSubtypeCapability', 142738581, -1, const prefix0.ContainedReflectable(), -1, 49, 49, const [], const [], ), r.VariableMirrorImpl( r'pokemon', 134349829, 0, const prefix0.ContainedReflectable(), 1, 1, 1, const [], const [], ), r.VariableMirrorImpl( r'name', 134349829, 1, const prefix0.ContainedReflectable(), 15, 15, 15, const [], const [], ), r.VariableMirrorImpl( r'type', 134349829, 1, const prefix0.ContainedReflectable(), 6, 6, 6, const [], const [], ), r.VariableMirrorImpl( r'name', 134349829, 3, const prefix0.ContainedReflectable(), 15, 15, 15, const [], const [], ), r.VariableMirrorImpl( r'artist', 134349829, 4, const prefix0.ContainedReflectable(), 3, 3, 3, const [], const [], ), r.VariableMirrorImpl( r'artist', 134349829, 5, const prefix0.ContainedReflectable(), 3, 3, 3, const [], const [], ), r.VariableMirrorImpl( r'album', 134349829, 5, const prefix0.ContainedReflectable(), 4, 4, 4, const [], const [], ), r.VariableMirrorImpl( r'water', 134349973, 6, const prefix0.ContainedReflectable(), 6, 6, 6, const [], const [], ), r.VariableMirrorImpl( r'fire', 134349973, 6, const prefix0.ContainedReflectable(), 6, 6, 6, const [], const [], ), r.VariableMirrorImpl( r'grass', 134349973, 6, const prefix0.ContainedReflectable(), 6, 6, 6, const [], const [], ), r.VariableMirrorImpl( r'ice', 134349973, 6, const prefix0.ContainedReflectable(), 6, 6, 6, const [], const [], ), r.VariableMirrorImpl( r'poison', 134349973, 6, const prefix0.ContainedReflectable(), 6, 6, 6, const [], const [], ), r.VariableMirrorImpl( r'flying', 134349973, 6, const prefix0.ContainedReflectable(), 6, 6, 6, const [], const [], ), r.VariableMirrorImpl( r'values', 151127253, 6, const prefix0.ContainedReflectable(), 18, 50, 18, const [6], const [], ), r.VariableMirrorImpl( r'thisClassName', 134349973, 10, const prefix0.ContainedReflectable(), 15, 15, 15, const [], const [], ), r.VariableMirrorImpl( r'thisClassId', 134349973, 10, const prefix0.ContainedReflectable(), 15, 15, 15, const [], const [], ), r.MethodMirrorImpl( r'main', 9699352, 0, -1, -1, -1, const [], const [], const prefix0.ContainedReflectable(), const [], ), r.MethodMirrorImpl( r'returnVoidFromAFunction', 9699352, 0, -1, -1, -1, const [], const [0], const prefix0.ContainedReflectable(), const [prefix0.contained], ), r.MethodMirrorImpl( r'testReflector', 9699352, 0, -1, -1, -1, const [], const [1], const prefix0.ContainedReflectable(), const [], ), r.ImplicitGetterMirrorImpl(const prefix0.ContainedReflectable(), 0, 19), r.MethodMirrorImpl( r'identical', 10485784, -1, 14, 14, 14, const [], const [2, 3], const prefix0.ContainedReflectable(), const [], ), r.MethodMirrorImpl( r'identityHashCode', 10485784, -1, 16, 16, 16, const [], const [4], const prefix0.ContainedReflectable(), const [], ), r.MethodMirrorImpl( r'print', 9699352, -1, -1, -1, -1, const [], const [5], const prefix0.ContainedReflectable(), const [], ), r.ImplicitGetterMirrorImpl(const prefix0.ContainedReflectable(), 1, 23), r.ImplicitGetterMirrorImpl(const prefix0.ContainedReflectable(), 2, 24), r.ImplicitGetterMirrorImpl(const prefix0.ContainedReflectable(), 3, 25), r.ImplicitGetterMirrorImpl(const prefix0.ContainedReflectable(), 4, 26), r.ImplicitSetterMirrorImpl(const prefix0.ContainedReflectable(), 4, 27), r.ImplicitGetterMirrorImpl(const prefix0.ContainedReflectable(), 5, 28), r.ImplicitSetterMirrorImpl(const prefix0.ContainedReflectable(), 5, 29), r.MethodMirrorImpl( r'reflectors', 44040211, -1, -1, 51, 52, const [10], const [], const prefix0.ContainedReflectable(), const [], ), r.MethodMirrorImpl( r'reflectableNoSuchInvokableError', 8912920, -1, -1, -1, -1, const [], const [8, 9, 10, 11, 12], const prefix0.ContainedReflectable(), const [], ), r.MethodMirrorImpl( r'reflectableNoSuchMethodError', 8912920, -1, -1, -1, -1, const [], const [13, 14, 15, 16], const prefix0.ContainedReflectable(), const [], ), r.MethodMirrorImpl( r'reflectableNoSuchGetterError', 8912920, -1, -1, -1, -1, const [], const [17, 18, 19, 20], const prefix0.ContainedReflectable(), const [], ), r.MethodMirrorImpl( r'reflectableNoSuchSetterError', 8912920, -1, -1, -1, -1, const [], const [21, 22, 23, 24], const prefix0.ContainedReflectable(), const [], ), r.MethodMirrorImpl( r'reflectableNoSuchConstructorError', 8912920, -1, -1, -1, -1, const [], const [25, 26, 27, 28], const prefix0.ContainedReflectable(), const [], ), r.ImplicitGetterMirrorImpl(const prefix0.ContainedReflectable(), 6, 36), r.ImplicitGetterMirrorImpl(const prefix0.ContainedReflectable(), 7, 37), r.ImplicitGetterMirrorImpl(const prefix0.ContainedReflectable(), 8, 38), r.ImplicitGetterMirrorImpl(const prefix0.ContainedReflectable(), 9, 39), r.ImplicitGetterMirrorImpl(const prefix0.ContainedReflectable(), 10, 40), r.ImplicitGetterMirrorImpl(const prefix0.ContainedReflectable(), 11, 41), r.ImplicitGetterMirrorImpl(const prefix0.ContainedReflectable(), 12, 42), r.ImplicitGetterMirrorImpl(const prefix0.ContainedReflectable(), 13, 43), r.ImplicitGetterMirrorImpl(const prefix0.ContainedReflectable(), 14, 44), r.ImplicitGetterMirrorImpl(const prefix0.ContainedReflectable(), 15, 45), r.ImplicitGetterMirrorImpl(const prefix0.ContainedReflectable(), 16, 46), r.ImplicitGetterMirrorImpl(const prefix0.ContainedReflectable(), 17, 47), r.ImplicitGetterMirrorImpl(const prefix0.ContainedReflectable(), 18, 48), r.ImplicitGetterMirrorImpl(const prefix0.ContainedReflectable(), 19, 49), r.ImplicitGetterMirrorImpl(const prefix0.ContainedReflectable(), 20, 50), r.ImplicitGetterMirrorImpl(const prefix0.ContainedReflectable(), 21, 51), r.ImplicitGetterMirrorImpl(const prefix0.ContainedReflectable(), 22, 52), r.ImplicitGetterMirrorImpl(const prefix0.ContainedReflectable(), 23, 53), r.ImplicitGetterMirrorImpl(const prefix0.ContainedReflectable(), 24, 54), r.ImplicitGetterMirrorImpl(const prefix0.ContainedReflectable(), 25, 55), r.ImplicitGetterMirrorImpl(const prefix0.ContainedReflectable(), 26, 56), r.ImplicitGetterMirrorImpl(const prefix0.ContainedReflectable(), 0, 57), r.MethodMirrorImpl( r'lowercaseName', 2097155, 0, 15, 15, 15, const [], const [], const prefix0.ContainedReflectable(), const [], ), r.MethodMirrorImpl( r'', 0, 0, -1, 0, 0, const [], const [29], const prefix0.ContainedReflectable(), const [], ), r.MethodMirrorImpl( r'==', 2097154, 8, 14, 14, 14, const [], const [30], const prefix0.ContainedReflectable(), const [], ), r.MethodMirrorImpl( r'toString', 2097154, 8, 15, 15, 15, const [], const [], const prefix0.ContainedReflectable(), const [], ), r.MethodMirrorImpl( r'noSuchMethod', 524290, 8, -1, -1, -1, const [], const [31], const prefix0.ContainedReflectable(), const [], ), r.MethodMirrorImpl( r'hashCode', 2097155, 8, 16, 16, 16, const [], const [], const prefix0.ContainedReflectable(), const [], ), r.MethodMirrorImpl( r'runtimeType', 2097155, 8, 17, 17, 17, const [], const [], const prefix0.ContainedReflectable(), const [], ), r.MethodMirrorImpl( r'toString', 2097154, 1, 15, 15, 15, const [], const [], const prefix0.ContainedReflectable(), const [override], ), r.ImplicitGetterMirrorImpl(const prefix0.ContainedReflectable(), 1, 66), r.ImplicitGetterMirrorImpl(const prefix0.ContainedReflectable(), 2, 67), r.MethodMirrorImpl( r'', 0, 1, -1, 1, 1, const [], const [32, 33], const prefix0.ContainedReflectable(), const [], ), r.MethodMirrorImpl( r'changeName', 1, 1, -1, 1, 1, const [], const [34, 35], const prefix0.ContainedReflectable(), const [], ), r.MethodMirrorImpl( r'', 0, 2, -1, 2, 2, const [], const [36, 37], const prefix0.ContainedReflectable(), const [], ), r.ImplicitGetterMirrorImpl(const prefix0.ContainedReflectable(), 3, 71), r.MethodMirrorImpl( r'lowerName', 2097155, 3, 15, 15, 15, const [], const [], const prefix0.ContainedReflectable(), const [], ), r.MethodMirrorImpl( r'', 0, 3, -1, 3, 3, const [], const [38], const prefix0.ContainedReflectable(), const [], ), r.ImplicitGetterMirrorImpl(const prefix0.ContainedReflectable(), 4, 74), r.MethodMirrorImpl( r'title', 2097155, 4, 15, 15, 15, const [], const [], const prefix0.ContainedReflectable(), const [], ), r.MethodMirrorImpl( r'', 0, 4, -1, 4, 4, const [], const [39], const prefix0.ContainedReflectable(), const [], ), r.ImplicitGetterMirrorImpl(const prefix0.ContainedReflectable(), 5, 77), r.ImplicitGetterMirrorImpl(const prefix0.ContainedReflectable(), 6, 78), r.MethodMirrorImpl( r'totalLength', 2097155, 5, 16, 16, 16, const [], const [], const prefix0.ContainedReflectable(), const [], ), r.MethodMirrorImpl( r'', 0, 5, -1, 5, 5, const [], const [40, 41], const prefix0.ContainedReflectable(), const [], ), r.ImplicitGetterMirrorImpl(const prefix0.ContainedReflectable(), 7, 81), r.ImplicitGetterMirrorImpl(const prefix0.ContainedReflectable(), 8, 82), r.ImplicitGetterMirrorImpl(const prefix0.ContainedReflectable(), 9, 83), r.ImplicitGetterMirrorImpl(const prefix0.ContainedReflectable(), 10, 84), r.ImplicitGetterMirrorImpl(const prefix0.ContainedReflectable(), 11, 85), r.ImplicitGetterMirrorImpl(const prefix0.ContainedReflectable(), 12, 86), r.ImplicitGetterMirrorImpl(const prefix0.ContainedReflectable(), 13, 87), r.MethodMirrorImpl( r'', 192, 6, -1, 6, 6, const [], const [], const prefix0.ContainedReflectable(), const [], ), r.MethodMirrorImpl( r'index', 2097155, 9, 16, 16, 16, const [], const [], const prefix0.ContainedReflectable(), const [], ), r.MethodMirrorImpl( r'', 128, 7, -1, 7, 7, const [], const [], const prefix0.ContainedReflectable(), const [], ), r.MethodMirrorImpl( r'capabilities', 35651587, 12, 18, 53, 18, const [24], const [], const prefix0.ContainedReflectable(), const [], ), r.MethodMirrorImpl( r'canReflect', 2097154, 11, 14, 14, 14, const [], const [42], const prefix0.ContainedReflectable(), const [override], ), r.MethodMirrorImpl( r'reflect', 2097154, 11, 19, 19, 19, const [], const [43], const prefix0.ContainedReflectable(), const [override], ), r.MethodMirrorImpl( r'canReflectType', 2097154, 11, 14, 14, 14, const [], const [44], const prefix0.ContainedReflectable(), const [override], ), r.MethodMirrorImpl( r'reflectType', 2097154, 11, 20, 20, 20, const [], const [45], const prefix0.ContainedReflectable(), const [override], ), r.MethodMirrorImpl( r'findLibrary', 2097154, 11, 21, 21, 21, const [], const [46], const prefix0.ContainedReflectable(), const [override], ), r.MethodMirrorImpl( r'libraries', 35651587, 11, 22, 55, 22, const [54, 21], const [], const prefix0.ContainedReflectable(), const [override], ), r.MethodMirrorImpl( r'annotatedClasses', 35651587, 11, 23, 57, 23, const [56], const [], const prefix0.ContainedReflectable(), const [override], ), r.MethodMirrorImpl( r'hash', 2097170, 8, 16, 16, 16, const [], const [ 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63, 64, 65, 66, ], const prefix0.ContainedReflectable(), const [], ), r.MethodMirrorImpl( r'hashAll', 2097170, 8, 16, 16, 16, const [], const [67], const prefix0.ContainedReflectable(), const [], ), r.MethodMirrorImpl( r'hashAllUnordered', 2097170, 8, 16, 16, 16, const [], const [68], const prefix0.ContainedReflectable(), const [], ), r.MethodMirrorImpl( r'', 128, 8, -1, 8, 8, const [], const [], const prefix0.ContainedReflectable(), const [], ), r.MethodMirrorImpl( r'compareByIndex', 2097170, 9, 16, 16, 16, const [], const [69, 70], const prefix0.ContainedReflectable(), const [], ), r.MethodMirrorImpl( r'compareByName', 2097170, 9, 16, 16, 16, const [], const [71, 72], const prefix0.ContainedReflectable(), const [], ), r.MethodMirrorImpl( r'', 64, 9, -1, 9, 9, const [], const [], const prefix0.ContainedReflectable(), const [], ), r.MethodMirrorImpl( r'getInstance', 2097170, 10, 10, 10, 10, const [], const [73], const prefix0.ContainedReflectable(), const [], ), r.ImplicitGetterMirrorImpl(const prefix0.ContainedReflectable(), 14, 107), r.ImplicitGetterMirrorImpl(const prefix0.ContainedReflectable(), 15, 108), r.MethodMirrorImpl( r'', 128, 10, -1, 10, 10, const [], const [74, 75, 76, 77, 78, 79, 80, 81, 82, 83], const prefix0.ContainedReflectable(), const [], ), r.MethodMirrorImpl( r'fromList', 128, 10, -1, 10, 10, const [], const [84], const prefix0.ContainedReflectable(), const [], ), r.MethodMirrorImpl( r'', 128, 11, -1, 11, 11, const [], const [85, 86, 87, 88, 89, 90, 91, 92, 93, 94], const prefix0.ContainedReflectable(), const [], ), r.MethodMirrorImpl( r'fromList', 128, 11, -1, 11, 11, const [], const [95], const prefix0.ContainedReflectable(), const [], ), r.MethodMirrorImpl( r'', 128, 12, -1, 12, 12, const [], const [96, 97, 98, 99, 100, 101, 102, 103, 104, 105], const prefix0.ContainedReflectable(), const [], ), r.MethodMirrorImpl( r'fromList', 128, 12, -1, 12, 12, const [], const [106], const prefix0.ContainedReflectable(), const [], ), r.MethodMirrorImpl( r'memberName', 2097667, 13, -1, 29, 29, const [], const [], const prefix0.ContainedReflectable(), const [], ), r.MethodMirrorImpl( r'typeArguments', 35651587, 13, 18, 58, 18, const [17], const [], const prefix0.ContainedReflectable(), const [], ), r.MethodMirrorImpl( r'positionalArguments', 35652099, 13, 18, 59, 18, null, const [], const prefix0.ContainedReflectable(), const [], ), r.MethodMirrorImpl( r'namedArguments', 35652099, 13, 22, 60, 22, null, const [], const prefix0.ContainedReflectable(), const [], ), r.MethodMirrorImpl( r'isMethod', 2097667, 13, 14, 14, 14, const [], const [], const prefix0.ContainedReflectable(), const [], ), r.MethodMirrorImpl( r'isGetter', 2097667, 13, 14, 14, 14, const [], const [], const prefix0.ContainedReflectable(), const [], ), r.MethodMirrorImpl( r'isSetter', 2097667, 13, 14, 14, 14, const [], const [], const prefix0.ContainedReflectable(), const [], ), r.MethodMirrorImpl( r'isAccessor', 2097155, 13, 14, 14, 14, const [], const [], const prefix0.ContainedReflectable(), const [], ), r.MethodMirrorImpl( r'', 0, 13, -1, 13, 13, const [], const [], const prefix0.ContainedReflectable(), const [], ), r.MethodMirrorImpl( r'method', 1, 13, -1, 13, 13, const [], const [107, 108, 109], const prefix0.ContainedReflectable(), const [], ), r.MethodMirrorImpl( r'genericMethod', 1, 13, -1, 13, 13, const [], const [110, 111, 112, 113], const prefix0.ContainedReflectable(), const [], ), r.MethodMirrorImpl( r'getter', 257, 13, -1, 13, 13, const [], const [114], const prefix0.ContainedReflectable(), const [], ), r.MethodMirrorImpl( r'setter', 257, 13, -1, 13, 13, const [], const [115, 116], const prefix0.ContainedReflectable(), const [], ), r.MethodMirrorImpl( r'parse', 2097170, 14, 14, 14, 14, const [], const [117, 118], const prefix0.ContainedReflectable(), const [], ), r.MethodMirrorImpl( r'tryParse', 2097170, 14, 14, 14, 14, const [], const [119, 120], const prefix0.ContainedReflectable(), const [], ), r.MethodMirrorImpl( r'&', 2097154, 14, 14, 14, 14, const [], const [121], const prefix0.ContainedReflectable(), const [], ), r.MethodMirrorImpl( r'|', 2097154, 14, 14, 14, 14, const [], const [122], const prefix0.ContainedReflectable(), const [], ), r.MethodMirrorImpl( r'^', 2097154, 14, 14, 14, 14, const [], const [123], const prefix0.ContainedReflectable(), const [], ), r.MethodMirrorImpl( r'toString', 2097154, 14, 15, 15, 15, const [], const [], const prefix0.ContainedReflectable(), const [], ), r.MethodMirrorImpl( r'hashCode', 2097155, 14, 16, 16, 16, const [], const [], const prefix0.ContainedReflectable(), const [], ), r.MethodMirrorImpl( r'fromEnvironment', 129, 14, -1, 14, 14, const [], const [124, 125], const prefix0.ContainedReflectable(), const [], ), r.MethodMirrorImpl( r'hasEnvironment', 129, 14, -1, 14, 14, const [], const [126], const prefix0.ContainedReflectable(), const [], ), r.MethodMirrorImpl( r'[]', 2097666, 15, 15, 15, 15, const [], const [127], const prefix0.ContainedReflectable(), const [], ), r.MethodMirrorImpl( r'codeUnitAt', 2097666, 15, 16, 16, 16, const [], const [128], const prefix0.ContainedReflectable(), const [], ), r.MethodMirrorImpl( r'==', 2097666, 15, 14, 14, 14, const [], const [129], const prefix0.ContainedReflectable(), const [], ), r.MethodMirrorImpl( r'compareTo', 2097666, 15, 16, 16, 16, const [], const [130], const prefix0.ContainedReflectable(), const [], ), r.MethodMirrorImpl( r'endsWith', 2097666, 15, 14, 14, 14, const [], const [131], const prefix0.ContainedReflectable(), const [], ), r.MethodMirrorImpl( r'startsWith', 2097666, 15, 14, 14, 14, const [], const [132, 133], const prefix0.ContainedReflectable(), const [], ), r.MethodMirrorImpl( r'indexOf', 2097666, 15, 16, 16, 16, const [], const [134, 135], const prefix0.ContainedReflectable(), const [], ), r.MethodMirrorImpl( r'lastIndexOf', 2097666, 15, 16, 16, 16, const [], const [136, 137], const prefix0.ContainedReflectable(), const [], ), r.MethodMirrorImpl( r'+', 2097666, 15, 15, 15, 15, const [], const [138], const prefix0.ContainedReflectable(), const [], ), r.MethodMirrorImpl( r'substring', 2097666, 15, 15, 15, 15, const [], const [139, 140], const prefix0.ContainedReflectable(), const [], ), r.MethodMirrorImpl( r'trim', 2097666, 15, 15, 15, 15, const [], const [], const prefix0.ContainedReflectable(), const [], ), r.MethodMirrorImpl( r'trimLeft', 2097666, 15, 15, 15, 15, const [], const [], const prefix0.ContainedReflectable(), const [], ), r.MethodMirrorImpl( r'trimRight', 2097666, 15, 15, 15, 15, const [], const [], const prefix0.ContainedReflectable(), const [], ), r.MethodMirrorImpl( r'*', 2097666, 15, 15, 15, 15, const [], const [141], const prefix0.ContainedReflectable(), const [], ), r.MethodMirrorImpl( r'padLeft', 2097666, 15, 15, 15, 15, const [], const [142, 143], const prefix0.ContainedReflectable(), const [], ), r.MethodMirrorImpl( r'padRight', 2097666, 15, 15, 15, 15, const [], const [144, 145], const prefix0.ContainedReflectable(), const [], ), r.MethodMirrorImpl( r'contains', 2097666, 15, 14, 14, 14, const [], const [146, 147], const prefix0.ContainedReflectable(), const [], ), r.MethodMirrorImpl( r'replaceFirst', 2097666, 15, 15, 15, 15, const [], const [148, 149, 150], const prefix0.ContainedReflectable(), const [], ), r.MethodMirrorImpl( r'replaceFirstMapped', 2097666, 15, 15, 15, 15, const [], const [151, 152, 153], const prefix0.ContainedReflectable(), const [], ), r.MethodMirrorImpl( r'replaceAll', 2097666, 15, 15, 15, 15, const [], const [154, 155], const prefix0.ContainedReflectable(), const [], ), r.MethodMirrorImpl( r'replaceAllMapped', 2097666, 15, 15, 15, 15, const [], const [156, 157], const prefix0.ContainedReflectable(), const [], ), r.MethodMirrorImpl( r'replaceRange', 2097666, 15, 15, 15, 15, const [], const [158, 159, 160], const prefix0.ContainedReflectable(), const [], ), r.MethodMirrorImpl( r'split', 35652098, 15, 18, 61, 18, const [15], const [161], const prefix0.ContainedReflectable(), const [], ), r.MethodMirrorImpl( r'splitMapJoin', 2097666, 15, 15, 15, 15, const [], const [162, 163, 164], const prefix0.ContainedReflectable(), const [], ), r.MethodMirrorImpl( r'toLowerCase', 2097666, 15, 15, 15, 15, const [], const [], const prefix0.ContainedReflectable(), const [], ), r.MethodMirrorImpl( r'toUpperCase', 2097666, 15, 15, 15, 15, const [], const [], const prefix0.ContainedReflectable(), const [], ), r.MethodMirrorImpl( r'length', 2097667, 15, 16, 16, 16, const [], const [], const prefix0.ContainedReflectable(), const [], ), r.MethodMirrorImpl( r'hashCode', 2097667, 15, 16, 16, 16, const [], const [], const prefix0.ContainedReflectable(), const [], ), r.MethodMirrorImpl( r'isEmpty', 2097667, 15, 14, 14, 14, const [], const [], const prefix0.ContainedReflectable(), const [], ), r.MethodMirrorImpl( r'isNotEmpty', 2097667, 15, 14, 14, 14, const [], const [], const prefix0.ContainedReflectable(), const [], ), r.MethodMirrorImpl( r'codeUnits', 35652099, 15, 18, 62, 18, const [16], const [], const prefix0.ContainedReflectable(), const [], ), r.MethodMirrorImpl( r'runes', 2097667, 15, -1, 63, 63, const [], const [], const prefix0.ContainedReflectable(), const [], ), r.MethodMirrorImpl( r'fromCharCodes', 1, 15, -1, 15, 15, const [], const [165, 166, 167], const prefix0.ContainedReflectable(), const [], ), r.MethodMirrorImpl( r'fromCharCode', 1, 15, -1, 15, 15, const [], const [168], const prefix0.ContainedReflectable(), const [], ), r.MethodMirrorImpl( r'fromEnvironment', 129, 15, -1, 15, 15, const [], const [169, 170], const prefix0.ContainedReflectable(), const [], ), r.MethodMirrorImpl( r'&', 2097666, 16, 16, 16, 16, const [], const [171], const prefix0.ContainedReflectable(), const [], ), r.MethodMirrorImpl( r'|', 2097666, 16, 16, 16, 16, const [], const [172], const prefix0.ContainedReflectable(), const [], ), r.MethodMirrorImpl( r'^', 2097666, 16, 16, 16, 16, const [], const [173], const prefix0.ContainedReflectable(), const [], ), r.MethodMirrorImpl( r'~', 2097666, 16, 16, 16, 16, const [], const [], const prefix0.ContainedReflectable(), const [], ), r.MethodMirrorImpl( r'<<', 2097666, 16, 16, 16, 16, const [], const [174], const prefix0.ContainedReflectable(), const [], ), r.MethodMirrorImpl( r'>>', 2097666, 16, 16, 16, 16, const [], const [175], const prefix0.ContainedReflectable(), const [], ), r.MethodMirrorImpl( r'>>>', 2097666, 16, 16, 16, 16, const [], const [176], const prefix0.ContainedReflectable(), const [], ), r.MethodMirrorImpl( r'modPow', 2097666, 16, 16, 16, 16, const [], const [177, 178], const prefix0.ContainedReflectable(), const [], ), r.MethodMirrorImpl( r'modInverse', 2097666, 16, 16, 16, 16, const [], const [179], const prefix0.ContainedReflectable(), const [], ), r.MethodMirrorImpl( r'gcd', 2097666, 16, 16, 16, 16, const [], const [180], const prefix0.ContainedReflectable(), const [], ), r.MethodMirrorImpl( r'toUnsigned', 2097666, 16, 16, 16, 16, const [], const [181], const prefix0.ContainedReflectable(), const [], ), r.MethodMirrorImpl( r'toSigned', 2097666, 16, 16, 16, 16, const [], const [182], const prefix0.ContainedReflectable(), const [], ), r.MethodMirrorImpl( r'unary-', 2097666, 16, 16, 16, 16, const [], const [], const prefix0.ContainedReflectable(), const [], ), r.MethodMirrorImpl( r'abs', 2097666, 16, 16, 16, 16, const [], const [], const prefix0.ContainedReflectable(), const [], ), r.MethodMirrorImpl( r'round', 2097666, 16, 16, 16, 16, const [], const [], const prefix0.ContainedReflectable(), const [], ), r.MethodMirrorImpl( r'floor', 2097666, 16, 16, 16, 16, const [], const [], const prefix0.ContainedReflectable(), const [], ), r.MethodMirrorImpl( r'ceil', 2097666, 16, 16, 16, 16, const [], const [], const prefix0.ContainedReflectable(), const [], ), r.MethodMirrorImpl( r'truncate', 2097666, 16, 16, 16, 16, const [], const [], const prefix0.ContainedReflectable(), const [], ), r.MethodMirrorImpl( r'roundToDouble', 2097666, 16, -1, 64, 64, const [], const [], const prefix0.ContainedReflectable(), const [], ), r.MethodMirrorImpl( r'floorToDouble', 2097666, 16, -1, 64, 64, const [], const [], const prefix0.ContainedReflectable(), const [], ), r.MethodMirrorImpl( r'ceilToDouble', 2097666, 16, -1, 64, 64, const [], const [], const prefix0.ContainedReflectable(), const [], ), r.MethodMirrorImpl( r'truncateToDouble', 2097666, 16, -1, 64, 64, const [], const [], const prefix0.ContainedReflectable(), const [], ), r.MethodMirrorImpl( r'toString', 2097666, 16, 15, 15, 15, const [], const [], const prefix0.ContainedReflectable(), const [], ), r.MethodMirrorImpl( r'toRadixString', 2097666, 16, 15, 15, 15, const [], const [183], const prefix0.ContainedReflectable(), const [], ), r.MethodMirrorImpl( r'parse', 2097170, 16, 16, 16, 16, const [], const [184, 185], const prefix0.ContainedReflectable(), const [], ), r.MethodMirrorImpl( r'tryParse', 2097170, 16, 16, 16, 16, const [], const [186, 187], const prefix0.ContainedReflectable(), const [], ), r.MethodMirrorImpl( r'isEven', 2097667, 16, 14, 14, 14, const [], const [], const prefix0.ContainedReflectable(), const [], ), r.MethodMirrorImpl( r'isOdd', 2097667, 16, 14, 14, 14, const [], const [], const prefix0.ContainedReflectable(), const [], ), r.MethodMirrorImpl( r'bitLength', 2097667, 16, 16, 16, 16, const [], const [], const prefix0.ContainedReflectable(), const [], ), r.MethodMirrorImpl( r'sign', 2097667, 16, 16, 16, 16, const [], const [], const prefix0.ContainedReflectable(), const [], ), r.MethodMirrorImpl( r'fromEnvironment', 129, 16, -1, 16, 16, const [], const [188, 189], const prefix0.ContainedReflectable(), const [], ), r.MethodMirrorImpl( r'==', 2097666, 17, 14, 14, 14, const [], const [190], const prefix0.ContainedReflectable(), const [], ), r.MethodMirrorImpl( r'toString', 2097666, 17, 15, 15, 15, const [], const [], const prefix0.ContainedReflectable(), const [], ), r.MethodMirrorImpl( r'hashCode', 2097667, 17, 16, 16, 16, const [], const [], const prefix0.ContainedReflectable(), const [], ), r.MethodMirrorImpl( r'', 64, 17, -1, 17, 17, const [], const [], const prefix0.ContainedReflectable(), const [], ), r.MethodMirrorImpl( r'castFrom', 35651602, 18, 18, 65, 18, null, const [191], const prefix0.ContainedReflectable(), const [], ), r.MethodMirrorImpl( r'copyRange', 1310738, 18, -1, -1, -1, const [], const [192, 193, 194, 195, 196], const prefix0.ContainedReflectable(), const [], ), r.MethodMirrorImpl( r'writeIterable', 1310738, 18, -1, -1, -1, const [], const [197, 198, 199], const prefix0.ContainedReflectable(), const [], ), r.MethodMirrorImpl( r'cast', 35652098, 18, 18, 66, 18, null, const [], const prefix0.ContainedReflectable(), const [], ), r.MethodMirrorImpl( r'[]', 514, 18, -1, -1, -1, const [], const [200], const prefix0.ContainedReflectable(), const [], ), r.MethodMirrorImpl( r'[]=', 1311234, 18, -1, -1, -1, const [], const [201, 202], const prefix0.ContainedReflectable(), const [], ), r.MethodMirrorImpl( r'add', 1311234, 18, -1, -1, -1, const [], const [203], const prefix0.ContainedReflectable(), const [], ), r.MethodMirrorImpl( r'addAll', 1311234, 18, -1, -1, -1, const [], const [204], const prefix0.ContainedReflectable(), const [], ), r.MethodMirrorImpl( r'sort', 1311234, 18, -1, -1, -1, const [], const [205], const prefix0.ContainedReflectable(), const [], ), r.MethodMirrorImpl( r'shuffle', 1311234, 18, -1, -1, -1, const [], const [206], const prefix0.ContainedReflectable(), const [], ), r.MethodMirrorImpl( r'indexOf', 2097666, 18, 16, 16, 16, const [], const [207, 208], const prefix0.ContainedReflectable(), const [], ), r.MethodMirrorImpl( r'indexWhere', 2097666, 18, 16, 16, 16, const [], const [209, 210], const prefix0.ContainedReflectable(), const [], ), r.MethodMirrorImpl( r'lastIndexWhere', 2097666, 18, 16, 16, 16, const [], const [211, 212], const prefix0.ContainedReflectable(), const [], ), r.MethodMirrorImpl( r'lastIndexOf', 2097666, 18, 16, 16, 16, const [], const [213, 214], const prefix0.ContainedReflectable(), const [], ), r.MethodMirrorImpl( r'clear', 1311234, 18, -1, -1, -1, const [], const [], const prefix0.ContainedReflectable(), const [], ), r.MethodMirrorImpl( r'insert', 1311234, 18, -1, -1, -1, const [], const [215, 216], const prefix0.ContainedReflectable(), const [], ), r.MethodMirrorImpl( r'insertAll', 1311234, 18, -1, -1, -1, const [], const [217, 218], const prefix0.ContainedReflectable(), const [], ), r.MethodMirrorImpl( r'setAll', 1311234, 18, -1, -1, -1, const [], const [219, 220], const prefix0.ContainedReflectable(), const [], ), r.MethodMirrorImpl( r'remove', 2097666, 18, 14, 14, 14, const [], const [221], const prefix0.ContainedReflectable(), const [], ), r.MethodMirrorImpl( r'removeAt', 514, 18, -1, -1, -1, const [], const [222], const prefix0.ContainedReflectable(), const [], ), r.MethodMirrorImpl( r'removeLast', 514, 18, -1, -1, -1, const [], const [], const prefix0.ContainedReflectable(), const [], ), r.MethodMirrorImpl( r'removeWhere', 1311234, 18, -1, -1, -1, const [], const [223], const prefix0.ContainedReflectable(), const [], ), r.MethodMirrorImpl( r'retainWhere', 1311234, 18, -1, -1, -1, const [], const [224], const prefix0.ContainedReflectable(), const [], ), r.MethodMirrorImpl( r'+', 35652098, 18, 18, 67, 18, null, const [225], const prefix0.ContainedReflectable(), const [], ), r.MethodMirrorImpl( r'sublist', 35652098, 18, 18, 67, 18, null, const [226, 227], const prefix0.ContainedReflectable(), const [], ), r.MethodMirrorImpl( r'getRange', 35652098, 18, 23, 68, 23, null, const [228, 229], const prefix0.ContainedReflectable(), const [], ), r.MethodMirrorImpl( r'setRange', 1311234, 18, -1, -1, -1, const [], const [230, 231, 232, 233], const prefix0.ContainedReflectable(), const [], ), r.MethodMirrorImpl( r'removeRange', 1311234, 18, -1, -1, -1, const [], const [234, 235], const prefix0.ContainedReflectable(), const [], ), r.MethodMirrorImpl( r'fillRange', 1311234, 18, -1, -1, -1, const [], const [236, 237, 238], const prefix0.ContainedReflectable(), const [], ), r.MethodMirrorImpl( r'replaceRange', 1311234, 18, -1, -1, -1, const [], const [239, 240, 241], const prefix0.ContainedReflectable(), const [], ), r.MethodMirrorImpl( r'asMap', 35652098, 18, 22, 69, 22, null, const [], const prefix0.ContainedReflectable(), const [], ), r.MethodMirrorImpl( r'==', 2097666, 18, 14, 14, 14, const [], const [242], const prefix0.ContainedReflectable(), const [], ), r.MethodMirrorImpl( r'first=', 1311236, 18, -1, -1, -1, const [], const [255], const prefix0.ContainedReflectable(), const [], ), r.MethodMirrorImpl( r'last=', 1311236, 18, -1, -1, -1, const [], const [256], const prefix0.ContainedReflectable(), const [], ), r.MethodMirrorImpl( r'length', 2097667, 18, 16, 16, 16, const [], const [], const prefix0.ContainedReflectable(), const [], ), r.MethodMirrorImpl( r'length=', 1311236, 18, -1, -1, -1, const [], const [257], const prefix0.ContainedReflectable(), const [], ), r.MethodMirrorImpl( r'reversed', 35652099, 18, 23, 68, 23, null, const [], const prefix0.ContainedReflectable(), const [], ), r.MethodMirrorImpl( r'filled', 1, 18, -1, 67, 18, null, const [243, 244, 245], const prefix0.ContainedReflectable(), const [], ), r.MethodMirrorImpl( r'empty', 1, 18, -1, 67, 18, null, const [246], const prefix0.ContainedReflectable(), const [], ), r.MethodMirrorImpl( r'from', 1, 18, -1, 67, 18, null, const [247, 248], const prefix0.ContainedReflectable(), const [], ), r.MethodMirrorImpl( r'of', 1, 18, -1, 67, 18, null, const [249, 250], const prefix0.ContainedReflectable(), const [], ), r.MethodMirrorImpl( r'generate', 1, 18, -1, 67, 18, null, const [251, 252, 253], const prefix0.ContainedReflectable(), const [], ), r.MethodMirrorImpl( r'unmodifiable', 1, 18, -1, 67, 18, null, const [254], const prefix0.ContainedReflectable(), const [], ), r.MethodMirrorImpl( r'==', 2097666, 19, 14, 14, 14, const [], const [258], const prefix0.ContainedReflectable(), const [override], ), r.MethodMirrorImpl( r'delegate', 2097666, 19, 8, 8, 8, const [], const [259], const prefix0.ContainedReflectable(), const [], ), r.MethodMirrorImpl( r'type', 2097667, 19, -1, 56, 56, const [], const [], const prefix0.ContainedReflectable(), const [], ), r.MethodMirrorImpl( r'hasReflectee', 2097667, 19, 14, 14, 14, const [], const [], const prefix0.ContainedReflectable(), const [], ), r.MethodMirrorImpl( r'reflectee', 2097667, 19, 8, 8, 8, const [], const [], const prefix0.ContainedReflectable(), const [], ), r.MethodMirrorImpl( r'hashCode', 2097667, 19, 16, 16, 16, const [], const [], const prefix0.ContainedReflectable(), const [override], ), r.MethodMirrorImpl( r'', 64, 19, -1, 19, 19, const [], const [], const prefix0.ContainedReflectable(), const [], ), r.MethodMirrorImpl( r'isSubtypeOf', 2097666, 20, 14, 14, 14, const [], const [260], const prefix0.ContainedReflectable(), const [], ), r.MethodMirrorImpl( r'isAssignableTo', 2097666, 20, 14, 14, 14, const [], const [261], const prefix0.ContainedReflectable(), const [], ), r.MethodMirrorImpl( r'hasReflectedType', 2097667, 20, 14, 14, 14, const [], const [], const prefix0.ContainedReflectable(), const [], ), r.MethodMirrorImpl( r'reflectedType', 2097667, 20, 17, 17, 17, const [], const [], const prefix0.ContainedReflectable(), const [], ), r.MethodMirrorImpl( r'typeVariables', 35652099, 20, 18, 71, 18, const [70], const [], const prefix0.ContainedReflectable(), const [], ), r.MethodMirrorImpl( r'typeArguments', 35652099, 20, 18, 72, 18, const [20], const [], const prefix0.ContainedReflectable(), const [], ), r.MethodMirrorImpl( r'reflectedTypeArguments', 35652099, 20, 18, 58, 18, const [17], const [], const prefix0.ContainedReflectable(), const [], ), r.MethodMirrorImpl( r'isOriginalDeclaration', 2097667, 20, 14, 14, 14, const [], const [], const prefix0.ContainedReflectable(), const [], ), r.MethodMirrorImpl( r'originalDeclaration', 2097667, 20, 20, 20, 20, const [], const [], const prefix0.ContainedReflectable(), const [], ), r.MethodMirrorImpl( r'isNullable', 2097667, 20, 14, 14, 14, const [], const [], const prefix0.ContainedReflectable(), const [], ), r.MethodMirrorImpl( r'isNonNullable', 2097667, 20, 14, 14, 14, const [], const [], const prefix0.ContainedReflectable(), const [], ), r.MethodMirrorImpl( r'isPotentiallyNullable', 2097667, 20, 14, 14, 14, const [], const [], const prefix0.ContainedReflectable(), const [], ), r.MethodMirrorImpl( r'isPotentiallyNonNullable', 2097667, 20, 14, 14, 14, const [], const [], const prefix0.ContainedReflectable(), const [], ), r.MethodMirrorImpl( r'', 64, 20, -1, 20, 20, const [], const [], const prefix0.ContainedReflectable(), const [], ), r.MethodMirrorImpl( r'==', 2097666, 21, 14, 14, 14, const [], const [262], const prefix0.ContainedReflectable(), const [override], ), r.MethodMirrorImpl( r'uri', 2097667, 21, -1, 54, 54, const [], const [], const prefix0.ContainedReflectable(), const [], ), r.MethodMirrorImpl( r'declarations', 35652099, 21, 22, 74, 22, const [15, 73], const [], const prefix0.ContainedReflectable(), const [], ), r.MethodMirrorImpl( r'hashCode', 2097667, 21, 16, 16, 16, const [], const [], const prefix0.ContainedReflectable(), const [override], ), r.MethodMirrorImpl( r'libraryDependencies', 35652099, 21, 18, 76, 18, const [75], const [], const prefix0.ContainedReflectable(), const [], ), r.MethodMirrorImpl( r'owner', 2097667, 21, -1, 77, 77, const [], const [], const prefix0.ContainedReflectable(), const [override], ), r.MethodMirrorImpl( r'', 64, 21, -1, 21, 21, const [], const [], const prefix0.ContainedReflectable(), const [], ), r.MethodMirrorImpl( r'castFrom', 35651602, 22, 22, 78, 22, null, const [263], const prefix0.ContainedReflectable(), const [], ), r.MethodMirrorImpl( r'cast', 35652098, 22, 22, 79, 22, null, const [], const prefix0.ContainedReflectable(), const [], ), r.MethodMirrorImpl( r'containsValue', 2097666, 22, 14, 14, 14, const [], const [264], const prefix0.ContainedReflectable(), const [], ), r.MethodMirrorImpl( r'containsKey', 2097666, 22, 14, 14, 14, const [], const [265], const prefix0.ContainedReflectable(), const [], ), r.MethodMirrorImpl( r'[]', 514, 22, -1, -1, -1, const [], const [266], const prefix0.ContainedReflectable(), const [], ), r.MethodMirrorImpl( r'[]=', 1311234, 22, -1, -1, -1, const [], const [267, 268], const prefix0.ContainedReflectable(), const [], ), r.MethodMirrorImpl( r'map', 35652098, 22, 22, 80, 22, null, const [269], const prefix0.ContainedReflectable(), const [], ), r.MethodMirrorImpl( r'addEntries', 1311234, 22, -1, -1, -1, const [], const [270], const prefix0.ContainedReflectable(), const [], ), r.MethodMirrorImpl( r'update', 514, 22, -1, -1, -1, const [], const [271, 272, 273], const prefix0.ContainedReflectable(), const [], ), r.MethodMirrorImpl( r'updateAll', 1311234, 22, -1, -1, -1, const [], const [274], const prefix0.ContainedReflectable(), const [], ), r.MethodMirrorImpl( r'removeWhere', 1311234, 22, -1, -1, -1, const [], const [275], const prefix0.ContainedReflectable(), const [], ), r.MethodMirrorImpl( r'putIfAbsent', 514, 22, -1, -1, -1, const [], const [276, 277], const prefix0.ContainedReflectable(), const [], ), r.MethodMirrorImpl( r'addAll', 1311234, 22, -1, -1, -1, const [], const [278], const prefix0.ContainedReflectable(), const [], ), r.MethodMirrorImpl( r'remove', 514, 22, -1, -1, -1, const [], const [279], const prefix0.ContainedReflectable(), const [], ), r.MethodMirrorImpl( r'clear', 1311234, 22, -1, -1, -1, const [], const [], const prefix0.ContainedReflectable(), const [], ), r.MethodMirrorImpl( r'forEach', 1311234, 22, -1, -1, -1, const [], const [280], const prefix0.ContainedReflectable(), const [], ), r.MethodMirrorImpl( r'entries', 35652099, 22, 23, 81, 23, null, const [], const prefix0.ContainedReflectable(), const [], ), r.MethodMirrorImpl( r'keys', 35652099, 22, 23, 82, 23, null, const [], const prefix0.ContainedReflectable(), const [], ), r.MethodMirrorImpl( r'values', 35652099, 22, 23, 83, 23, null, const [], const prefix0.ContainedReflectable(), const [], ), r.MethodMirrorImpl( r'length', 2097667, 22, 16, 16, 16, const [], const [], const prefix0.ContainedReflectable(), const [], ), r.MethodMirrorImpl( r'isEmpty', 2097667, 22, 14, 14, 14, const [], const [], const prefix0.ContainedReflectable(), const [], ), r.MethodMirrorImpl( r'isNotEmpty', 2097667, 22, 14, 14, 14, const [], const [], const prefix0.ContainedReflectable(), const [], ), r.MethodMirrorImpl( r'', 1, 22, -1, 84, 22, null, const [], const prefix0.ContainedReflectable(), const [], ), r.MethodMirrorImpl( r'from', 257, 22, -1, 84, 22, null, const [281], const prefix0.ContainedReflectable(), const [], ), r.MethodMirrorImpl( r'of', 257, 22, -1, 84, 22, null, const [282], const prefix0.ContainedReflectable(), const [], ), r.MethodMirrorImpl( r'unmodifiable', 1, 22, -1, 84, 22, null, const [283], const prefix0.ContainedReflectable(), const [], ), r.MethodMirrorImpl( r'identity', 257, 22, -1, 84, 22, null, const [], const prefix0.ContainedReflectable(), const [], ), r.MethodMirrorImpl( r'fromIterable', 257, 22, -1, 84, 22, null, const [284, 285, 286], const prefix0.ContainedReflectable(), const [], ), r.MethodMirrorImpl( r'fromIterables', 257, 22, -1, 84, 22, null, const [287, 288], const prefix0.ContainedReflectable(), const [], ), r.MethodMirrorImpl( r'fromEntries', 1, 22, -1, 84, 22, null, const [289], const prefix0.ContainedReflectable(), const [], ), r.MethodMirrorImpl( r'castFrom', 35651602, 23, 23, 85, 23, null, const [290], const prefix0.ContainedReflectable(), const [], ), r.MethodMirrorImpl( r'cast', 35651586, 23, 23, 86, 23, null, const [], const prefix0.ContainedReflectable(), const [], ), r.MethodMirrorImpl( r'followedBy', 35651586, 23, 23, 87, 23, null, const [291], const prefix0.ContainedReflectable(), const [], ), r.MethodMirrorImpl( r'map', 35651586, 23, 23, 88, 23, null, const [292], const prefix0.ContainedReflectable(), const [], ), r.MethodMirrorImpl( r'where', 35651586, 23, 23, 87, 23, null, const [293], const prefix0.ContainedReflectable(), const [], ), r.MethodMirrorImpl( r'whereType', 35651586, 23, 23, 89, 23, null, const [], const prefix0.ContainedReflectable(), const [], ), r.MethodMirrorImpl( r'expand', 35651586, 23, 23, 90, 23, null, const [294], const prefix0.ContainedReflectable(), const [], ), r.MethodMirrorImpl( r'contains', 2097154, 23, 14, 14, 14, const [], const [295], const prefix0.ContainedReflectable(), const [], ), r.MethodMirrorImpl( r'forEach', 1310722, 23, -1, -1, -1, const [], const [296], const prefix0.ContainedReflectable(), const [], ), r.MethodMirrorImpl( r'reduce', 2, 23, -1, -1, -1, const [], const [297], const prefix0.ContainedReflectable(), const [], ), r.MethodMirrorImpl( r'fold', 2, 23, -1, -1, -1, const [], const [298, 299], const prefix0.ContainedReflectable(), const [], ), r.MethodMirrorImpl( r'every', 2097154, 23, 14, 14, 14, const [], const [300], const prefix0.ContainedReflectable(), const [], ), r.MethodMirrorImpl( r'join', 2097154, 23, 15, 15, 15, const [], const [301], const prefix0.ContainedReflectable(), const [], ), r.MethodMirrorImpl( r'any', 2097154, 23, 14, 14, 14, const [], const [302], const prefix0.ContainedReflectable(), const [], ), r.MethodMirrorImpl( r'toList', 35651586, 23, 18, 91, 18, null, const [303], const prefix0.ContainedReflectable(), const [], ), r.MethodMirrorImpl( r'toSet', 35651586, 23, -1, 92, 93, null, const [], const prefix0.ContainedReflectable(), const [], ), r.MethodMirrorImpl( r'take', 35651586, 23, 23, 87, 23, null, const [304], const prefix0.ContainedReflectable(), const [], ), r.MethodMirrorImpl( r'takeWhile', 35651586, 23, 23, 87, 23, null, const [305], const prefix0.ContainedReflectable(), const [], ), r.MethodMirrorImpl( r'skip', 35651586, 23, 23, 87, 23, null, const [306], const prefix0.ContainedReflectable(), const [], ), r.MethodMirrorImpl( r'skipWhile', 35651586, 23, 23, 87, 23, null, const [307], const prefix0.ContainedReflectable(), const [], ), r.MethodMirrorImpl( r'firstWhere', 2, 23, -1, -1, -1, const [], const [308, 309], const prefix0.ContainedReflectable(), const [], ), r.MethodMirrorImpl( r'lastWhere', 2, 23, -1, -1, -1, const [], const [310, 311], const prefix0.ContainedReflectable(), const [], ), r.MethodMirrorImpl( r'singleWhere', 2, 23, -1, -1, -1, const [], const [312, 313], const prefix0.ContainedReflectable(), const [], ), r.MethodMirrorImpl( r'elementAt', 2, 23, -1, -1, -1, const [], const [314], const prefix0.ContainedReflectable(), const [], ), r.MethodMirrorImpl( r'toString', 2097154, 23, 15, 15, 15, const [], const [], const prefix0.ContainedReflectable(), const [], ), r.MethodMirrorImpl( r'iterableToShortString', 2097170, 23, 15, 15, 15, const [], const [315, 316, 317], const prefix0.ContainedReflectable(), const [], ), r.MethodMirrorImpl( r'iterableToFullString', 2097170, 23, 15, 15, 15, const [], const [318, 319, 320], const prefix0.ContainedReflectable(), const [], ), r.MethodMirrorImpl( r'iterator', 35652099, 23, -1, 94, 95, null, const [], const prefix0.ContainedReflectable(), const [], ), r.MethodMirrorImpl( r'length', 2097155, 23, 16, 16, 16, const [], const [], const prefix0.ContainedReflectable(), const [], ), r.MethodMirrorImpl( r'isEmpty', 2097155, 23, 14, 14, 14, const [], const [], const prefix0.ContainedReflectable(), const [], ), r.MethodMirrorImpl( r'isNotEmpty', 2097155, 23, 14, 14, 14, const [], const [], const prefix0.ContainedReflectable(), const [], ), r.MethodMirrorImpl( r'first', 3, 23, -1, -1, -1, const [], const [], const prefix0.ContainedReflectable(), const [], ), r.MethodMirrorImpl( r'last', 3, 23, -1, -1, -1, const [], const [], const prefix0.ContainedReflectable(), const [], ), r.MethodMirrorImpl( r'single', 3, 23, -1, -1, -1, const [], const [], const prefix0.ContainedReflectable(), const [], ), r.MethodMirrorImpl( r'', 128, 23, -1, 87, 23, null, const [], const prefix0.ContainedReflectable(), const [], ), r.MethodMirrorImpl( r'generate', 1, 23, -1, 87, 23, null, const [321, 322], const prefix0.ContainedReflectable(), const [], ), r.MethodMirrorImpl( r'empty', 385, 23, -1, 87, 23, null, const [], const prefix0.ContainedReflectable(), const [], ), r.MethodMirrorImpl( r'', 128, 24, -1, 24, 24, const [], const [], const prefix0.ContainedReflectable(), const [], ), ], [ r.ParameterMirrorImpl( r'x', 134348806, 17, const prefix0.ContainedReflectable(), 16, 16, 16, const [], const [], null, null, ), r.ParameterMirrorImpl( r'reflector', 134348806, 18, const prefix0.ContainedReflectable(), -1, 96, 96, const [], const [], null, null, ), r.ParameterMirrorImpl( r'a', 67239942, 20, const prefix0.ContainedReflectable(), 8, 8, 8, const [], const [], null, null, ), r.ParameterMirrorImpl( r'b', 67239942, 20, const prefix0.ContainedReflectable(), 8, 8, 8, const [], const [], null, null, ), r.ParameterMirrorImpl( r'object', 67239942, 21, const prefix0.ContainedReflectable(), 8, 8, 8, const [], const [], null, null, ), r.ParameterMirrorImpl( r'object', 67239942, 22, const prefix0.ContainedReflectable(), 8, 8, 8, const [], const [], null, null, ), r.ParameterMirrorImpl( r'_data', 151126118, 27, const prefix0.ContainedReflectable(), 22, 26, 22, const [10, 27], const [], null, null, ), r.ParameterMirrorImpl( r'_memberSymbolMap', 84017254, 29, const prefix0.ContainedReflectable(), 22, 28, 22, const [29, 15], const [], null, null, ), r.ParameterMirrorImpl( r'receiver', 67239942, 31, const prefix0.ContainedReflectable(), 8, 8, 8, const [], const [], null, null, ), r.ParameterMirrorImpl( r'memberName', 134348806, 31, const prefix0.ContainedReflectable(), 15, 15, 15, const [], const [], null, null, ), r.ParameterMirrorImpl( r'positionalArguments', 151126022, 31, const prefix0.ContainedReflectable(), 18, 59, 18, null, const [], null, null, ), r.ParameterMirrorImpl( r'namedArguments', 84017158, 31, const prefix0.ContainedReflectable(), 22, 97, 22, null, const [], null, null, ), r.ParameterMirrorImpl( r'kind', 134348806, 31, const prefix0.ContainedReflectable(), -1, 98, 98, const [], const [], null, null, ), r.ParameterMirrorImpl( r'receiver', 67239942, 32, const prefix0.ContainedReflectable(), 8, 8, 8, const [], const [], null, null, ), r.ParameterMirrorImpl( r'memberName', 134348806, 32, const prefix0.ContainedReflectable(), 15, 15, 15, const [], const [], null, null, ), r.ParameterMirrorImpl( r'positionalArguments', 151126022, 32, const prefix0.ContainedReflectable(), 18, 59, 18, null, const [], null, null, ), r.ParameterMirrorImpl( r'namedArguments', 84017158, 32, const prefix0.ContainedReflectable(), 22, 97, 22, null, const [], null, null, ), r.ParameterMirrorImpl( r'receiver', 67239942, 33, const prefix0.ContainedReflectable(), 8, 8, 8, const [], const [], null, null, ), r.ParameterMirrorImpl( r'memberName', 134348806, 33, const prefix0.ContainedReflectable(), 15, 15, 15, const [], const [], null, null, ), r.ParameterMirrorImpl( r'positionalArguments', 151126022, 33, const prefix0.ContainedReflectable(), 18, 59, 18, null, const [], null, null, ), r.ParameterMirrorImpl( r'namedArguments', 84017158, 33, const prefix0.ContainedReflectable(), 22, 97, 22, null, const [], null, null, ), r.ParameterMirrorImpl( r'receiver', 67239942, 34, const prefix0.ContainedReflectable(), 8, 8, 8, const [], const [], null, null, ), r.ParameterMirrorImpl( r'memberName', 134348806, 34, const prefix0.ContainedReflectable(), 15, 15, 15, const [], const [], null, null, ), r.ParameterMirrorImpl( r'positionalArguments', 151126022, 34, const prefix0.ContainedReflectable(), 18, 59, 18, null, const [], null, null, ), r.ParameterMirrorImpl( r'namedArguments', 84017158, 34, const prefix0.ContainedReflectable(), 22, 97, 22, null, const [], null, null, ), r.ParameterMirrorImpl( r'receiver', 67239942, 35, const prefix0.ContainedReflectable(), 8, 8, 8, const [], const [], null, null, ), r.ParameterMirrorImpl( r'constructorName', 134348806, 35, const prefix0.ContainedReflectable(), 15, 15, 15, const [], const [], null, null, ), r.ParameterMirrorImpl( r'positionalArguments', 151126022, 35, const prefix0.ContainedReflectable(), 18, 59, 18, null, const [], null, null, ), r.ParameterMirrorImpl( r'namedArguments', 84017158, 35, const prefix0.ContainedReflectable(), 22, 97, 22, null, const [], null, null, ), r.ParameterMirrorImpl( r'pokemon', 134349830, 59, const prefix0.ContainedReflectable(), 1, 1, 1, const [], const [], null, null, ), r.ParameterMirrorImpl( r'other', 134348806, 60, const prefix0.ContainedReflectable(), 8, 8, 8, const [], const [], null, null, ), r.ParameterMirrorImpl( r'invocation', 134348806, 62, const prefix0.ContainedReflectable(), 13, 13, 13, const [], const [], null, null, ), r.ParameterMirrorImpl( r'name', 134349830, 68, const prefix0.ContainedReflectable(), 15, 15, 15, const [], const [], null, null, ), r.ParameterMirrorImpl( r'type', 134349830, 68, const prefix0.ContainedReflectable(), 6, 6, 6, const [], const [], null, null, ), r.ParameterMirrorImpl( r'other', 134348806, 69, const prefix0.ContainedReflectable(), 1, 1, 1, const [], const [], null, null, ), r.ParameterMirrorImpl( r'name', 134348806, 69, const prefix0.ContainedReflectable(), 15, 15, 15, const [], const [], null, null, ), r.ParameterMirrorImpl( r'name', 134349830, 70, const prefix0.ContainedReflectable(), 15, 15, 15, const [], const [], null, null, ), r.ParameterMirrorImpl( r'type', 134349830, 70, const prefix0.ContainedReflectable(), 6, 6, 6, const [], const [], null, null, ), r.ParameterMirrorImpl( r'name', 134358022, 73, const prefix0.ContainedReflectable(), 15, 15, 15, const [], const [], null, #name, ), r.ParameterMirrorImpl( r'artist', 134349830, 76, const prefix0.ContainedReflectable(), 3, 3, 3, const [], const [], null, null, ), r.ParameterMirrorImpl( r'artist', 134349830, 80, const prefix0.ContainedReflectable(), 3, 3, 3, const [], const [], null, null, ), r.ParameterMirrorImpl( r'album', 134349830, 80, const prefix0.ContainedReflectable(), 4, 4, 4, const [], const [], null, null, ), r.ParameterMirrorImpl( r'reflectee', 134348806, 92, const prefix0.ContainedReflectable(), 8, 8, 8, const [], const [], null, null, ), r.ParameterMirrorImpl( r'reflectee', 134348806, 93, const prefix0.ContainedReflectable(), 8, 8, 8, const [], const [], null, null, ), r.ParameterMirrorImpl( r'type', 134348806, 94, const prefix0.ContainedReflectable(), 17, 17, 17, const [], const [], null, null, ), r.ParameterMirrorImpl( r'type', 134348806, 95, const prefix0.ContainedReflectable(), 17, 17, 17, const [], const [], null, null, ), r.ParameterMirrorImpl( r'libraryName', 134348806, 96, const prefix0.ContainedReflectable(), 15, 15, 15, const [], const [], null, null, ), r.ParameterMirrorImpl( r'object1', 67239942, 99, const prefix0.ContainedReflectable(), 8, 8, 8, const [], const [], null, null, ), r.ParameterMirrorImpl( r'object2', 67239942, 99, const prefix0.ContainedReflectable(), 8, 8, 8, const [], const [], null, null, ), r.ParameterMirrorImpl( r'object3', 67246086, 99, const prefix0.ContainedReflectable(), 8, 8, 8, const [], const [], null, null, ), r.ParameterMirrorImpl( r'object4', 67246086, 99, const prefix0.ContainedReflectable(), 8, 8, 8, const [], const [], null, null, ), r.ParameterMirrorImpl( r'object5', 67246086, 99, const prefix0.ContainedReflectable(), 8, 8, 8, const [], const [], null, null, ), r.ParameterMirrorImpl( r'object6', 67246086, 99, const prefix0.ContainedReflectable(), 8, 8, 8, const [], const [], null, null, ), r.ParameterMirrorImpl( r'object7', 67246086, 99, const prefix0.ContainedReflectable(), 8, 8, 8, const [], const [], null, null, ), r.ParameterMirrorImpl( r'object8', 67246086, 99, const prefix0.ContainedReflectable(), 8, 8, 8, const [], const [], null, null, ), r.ParameterMirrorImpl( r'object9', 67246086, 99, const prefix0.ContainedReflectable(), 8, 8, 8, const [], const [], null, null, ), r.ParameterMirrorImpl( r'object10', 67246086, 99, const prefix0.ContainedReflectable(), 8, 8, 8, const [], const [], null, null, ), r.ParameterMirrorImpl( r'object11', 67246086, 99, const prefix0.ContainedReflectable(), 8, 8, 8, const [], const [], null, null, ), r.ParameterMirrorImpl( r'object12', 67246086, 99, const prefix0.ContainedReflectable(), 8, 8, 8, const [], const [], null, null, ), r.ParameterMirrorImpl( r'object13', 67246086, 99, const prefix0.ContainedReflectable(), 8, 8, 8, const [], const [], null, null, ), r.ParameterMirrorImpl( r'object14', 67246086, 99, const prefix0.ContainedReflectable(), 8, 8, 8, const [], const [], null, null, ), r.ParameterMirrorImpl( r'object15', 67246086, 99, const prefix0.ContainedReflectable(), 8, 8, 8, const [], const [], null, null, ), r.ParameterMirrorImpl( r'object16', 67246086, 99, const prefix0.ContainedReflectable(), 8, 8, 8, const [], const [], null, null, ), r.ParameterMirrorImpl( r'object17', 67246086, 99, const prefix0.ContainedReflectable(), 8, 8, 8, const [], const [], null, null, ), r.ParameterMirrorImpl( r'object18', 67246086, 99, const prefix0.ContainedReflectable(), 8, 8, 8, const [], const [], null, null, ), r.ParameterMirrorImpl( r'object19', 67246086, 99, const prefix0.ContainedReflectable(), 8, 8, 8, const [], const [], null, null, ), r.ParameterMirrorImpl( r'object20', 67246086, 99, const prefix0.ContainedReflectable(), 8, 8, 8, const [], const [], null, null, ), r.ParameterMirrorImpl( r'objects', 151126022, 100, const prefix0.ContainedReflectable(), 23, 99, 23, const [8], const [], null, null, ), r.ParameterMirrorImpl( r'objects', 151126022, 101, const prefix0.ContainedReflectable(), 23, 99, 23, const [8], const [], null, null, ), r.ParameterMirrorImpl( r'value1', 134217734, 103, const prefix0.ContainedReflectable(), -1, -1, -1, const [], const [], null, null, ), r.ParameterMirrorImpl( r'value2', 134217734, 103, const prefix0.ContainedReflectable(), -1, -1, -1, const [], const [], null, null, ), r.ParameterMirrorImpl( r'value1', 134217734, 104, const prefix0.ContainedReflectable(), -1, -1, -1, const [], const [], null, null, ), r.ParameterMirrorImpl( r'value2', 134217734, 104, const prefix0.ContainedReflectable(), -1, -1, -1, const [], const [], null, null, ), r.ParameterMirrorImpl( r'type', 134348806, 106, const prefix0.ContainedReflectable(), 17, 17, 17, const [], const [], null, null, ), r.ParameterMirrorImpl( r'cap0', 67244038, 109, const prefix0.ContainedReflectable(), 24, 24, 24, const [], const [], null, null, ), r.ParameterMirrorImpl( r'cap1', 67244038, 109, const prefix0.ContainedReflectable(), 24, 24, 24, const [], const [], null, null, ), r.ParameterMirrorImpl( r'cap2', 67244038, 109, const prefix0.ContainedReflectable(), 24, 24, 24, const [], const [], null, null, ), r.ParameterMirrorImpl( r'cap3', 67244038, 109, const prefix0.ContainedReflectable(), 24, 24, 24, const [], const [], null, null, ), r.ParameterMirrorImpl( r'cap4', 67244038, 109, const prefix0.ContainedReflectable(), 24, 24, 24, const [], const [], null, null, ), r.ParameterMirrorImpl( r'cap5', 67244038, 109, const prefix0.ContainedReflectable(), 24, 24, 24, const [], const [], null, null, ), r.ParameterMirrorImpl( r'cap6', 67244038, 109, const prefix0.ContainedReflectable(), 24, 24, 24, const [], const [], null, null, ), r.ParameterMirrorImpl( r'cap7', 67244038, 109, const prefix0.ContainedReflectable(), 24, 24, 24, const [], const [], null, null, ), r.ParameterMirrorImpl( r'cap8', 67244038, 109, const prefix0.ContainedReflectable(), 24, 24, 24, const [], const [], null, null, ), r.ParameterMirrorImpl( r'cap9', 67244038, 109, const prefix0.ContainedReflectable(), 24, 24, 24, const [], const [], null, null, ), r.ParameterMirrorImpl( r'capabilities', 151126022, 110, const prefix0.ContainedReflectable(), 18, 53, 18, const [24], const [], null, null, ), r.ParameterMirrorImpl( r'cap0', 67244038, 111, const prefix0.ContainedReflectable(), 24, 24, 24, const [], const [], null, null, ), r.ParameterMirrorImpl( r'cap1', 67244038, 111, const prefix0.ContainedReflectable(), 24, 24, 24, const [], const [], null, null, ), r.ParameterMirrorImpl( r'cap2', 67244038, 111, const prefix0.ContainedReflectable(), 24, 24, 24, const [], const [], null, null, ), r.ParameterMirrorImpl( r'cap3', 67244038, 111, const prefix0.ContainedReflectable(), 24, 24, 24, const [], const [], null, null, ), r.ParameterMirrorImpl( r'cap4', 67244038, 111, const prefix0.ContainedReflectable(), 24, 24, 24, const [], const [], null, null, ), r.ParameterMirrorImpl( r'cap5', 67244038, 111, const prefix0.ContainedReflectable(), 24, 24, 24, const [], const [], null, null, ), r.ParameterMirrorImpl( r'cap6', 67244038, 111, const prefix0.ContainedReflectable(), 24, 24, 24, const [], const [], null, null, ), r.ParameterMirrorImpl( r'cap7', 67244038, 111, const prefix0.ContainedReflectable(), 24, 24, 24, const [], const [], null, null, ), r.ParameterMirrorImpl( r'cap8', 67244038, 111, const prefix0.ContainedReflectable(), 24, 24, 24, const [], const [], null, null, ), r.ParameterMirrorImpl( r'cap9', 67244038, 111, const prefix0.ContainedReflectable(), 24, 24, 24, const [], const [], null, null, ), r.ParameterMirrorImpl( r'capabilities', 151126022, 112, const prefix0.ContainedReflectable(), 18, 53, 18, const [24], const [], null, null, ), r.ParameterMirrorImpl( r'_cap0', 67245094, 113, const prefix0.ContainedReflectable(), 24, 24, 24, const [], const [], null, null, ), r.ParameterMirrorImpl( r'_cap1', 67245094, 113, const prefix0.ContainedReflectable(), 24, 24, 24, const [], const [], null, null, ), r.ParameterMirrorImpl( r'_cap2', 67245094, 113, const prefix0.ContainedReflectable(), 24, 24, 24, const [], const [], null, null, ), r.ParameterMirrorImpl( r'_cap3', 67245094, 113, const prefix0.ContainedReflectable(), 24, 24, 24, const [], const [], null, null, ), r.ParameterMirrorImpl( r'_cap4', 67245094, 113, const prefix0.ContainedReflectable(), 24, 24, 24, const [], const [], null, null, ), r.ParameterMirrorImpl( r'_cap5', 67245094, 113, const prefix0.ContainedReflectable(), 24, 24, 24, const [], const [], null, null, ), r.ParameterMirrorImpl( r'_cap6', 67245094, 113, const prefix0.ContainedReflectable(), 24, 24, 24, const [], const [], null, null, ), r.ParameterMirrorImpl( r'_cap7', 67245094, 113, const prefix0.ContainedReflectable(), 24, 24, 24, const [], const [], null, null, ), r.ParameterMirrorImpl( r'_cap8', 67245094, 113, const prefix0.ContainedReflectable(), 24, 24, 24, const [], const [], null, null, ), r.ParameterMirrorImpl( r'_cap9', 67245094, 113, const prefix0.ContainedReflectable(), 24, 24, 24, const [], const [], null, null, ), r.ParameterMirrorImpl( r'_capabilities', 84018214, 114, const prefix0.ContainedReflectable(), 18, 100, 18, const [24], const [], null, null, ), r.ParameterMirrorImpl( r'memberName', 134348806, 124, const prefix0.ContainedReflectable(), -1, 29, 29, const [], const [], null, null, ), r.ParameterMirrorImpl( r'positionalArguments', 84017158, 124, const prefix0.ContainedReflectable(), 23, 101, 23, const [8], const [], null, null, ), r.ParameterMirrorImpl( r'namedArguments', 84021254, 124, const prefix0.ContainedReflectable(), 22, 102, 22, const [29, 8], const [], null, null, ), r.ParameterMirrorImpl( r'memberName', 134348806, 125, const prefix0.ContainedReflectable(), -1, 29, 29, const [], const [], null, null, ), r.ParameterMirrorImpl( r'typeArguments', 84017158, 125, const prefix0.ContainedReflectable(), 23, 103, 23, const [17], const [], null, null, ), r.ParameterMirrorImpl( r'positionalArguments', 84017158, 125, const prefix0.ContainedReflectable(), 23, 101, 23, const [8], const [], null, null, ), r.ParameterMirrorImpl( r'namedArguments', 84021254, 125, const prefix0.ContainedReflectable(), 22, 102, 22, const [29, 8], const [], null, null, ), r.ParameterMirrorImpl( r'name', 134348806, 126, const prefix0.ContainedReflectable(), -1, 29, 29, const [], const [], null, null, ), r.ParameterMirrorImpl( r'memberName', 134348806, 127, const prefix0.ContainedReflectable(), -1, 29, 29, const [], const [], null, null, ), r.ParameterMirrorImpl( r'argument', 67239942, 127, const prefix0.ContainedReflectable(), 8, 8, 8, const [], const [], null, null, ), r.ParameterMirrorImpl( r'source', 134348806, 128, const prefix0.ContainedReflectable(), 15, 15, 15, const [], const [], null, null, ), r.ParameterMirrorImpl( r'caseSensitive', 134363142, 128, const prefix0.ContainedReflectable(), 14, 14, 14, const [], const [], null, #caseSensitive, ), r.ParameterMirrorImpl( r'source', 134348806, 129, const prefix0.ContainedReflectable(), 15, 15, 15, const [], const [], null, null, ), r.ParameterMirrorImpl( r'caseSensitive', 134363142, 129, const prefix0.ContainedReflectable(), 14, 14, 14, const [], const [], null, #caseSensitive, ), r.ParameterMirrorImpl( r'other', 134348806, 130, const prefix0.ContainedReflectable(), 14, 14, 14, const [], const [], null, null, ), r.ParameterMirrorImpl( r'other', 134348806, 131, const prefix0.ContainedReflectable(), 14, 14, 14, const [], const [], null, null, ), r.ParameterMirrorImpl( r'other', 134348806, 132, const prefix0.ContainedReflectable(), 14, 14, 14, const [], const [], null, null, ), r.ParameterMirrorImpl( r'name', 134348806, 135, const prefix0.ContainedReflectable(), 15, 15, 15, const [], const [], null, null, ), r.ParameterMirrorImpl( r'defaultValue', 134363142, 135, const prefix0.ContainedReflectable(), 14, 14, 14, const [], const [], null, #defaultValue, ), r.ParameterMirrorImpl( r'name', 134348806, 136, const prefix0.ContainedReflectable(), 15, 15, 15, const [], const [], null, null, ), r.ParameterMirrorImpl( r'index', 134348806, 137, const prefix0.ContainedReflectable(), 16, 16, 16, const [], const [], null, null, ), r.ParameterMirrorImpl( r'index', 134348806, 138, const prefix0.ContainedReflectable(), 16, 16, 16, const [], const [], null, null, ), r.ParameterMirrorImpl( r'other', 134348806, 139, const prefix0.ContainedReflectable(), 8, 8, 8, const [], const [], null, null, ), r.ParameterMirrorImpl( r'other', 134348806, 140, const prefix0.ContainedReflectable(), 15, 15, 15, const [], const [], null, null, ), r.ParameterMirrorImpl( r'other', 134348806, 141, const prefix0.ContainedReflectable(), 15, 15, 15, const [], const [], null, null, ), r.ParameterMirrorImpl( r'pattern', 134348806, 142, const prefix0.ContainedReflectable(), -1, 104, 104, const [], const [], null, null, ), r.ParameterMirrorImpl( r'index', 134354950, 142, const prefix0.ContainedReflectable(), 16, 16, 16, const [], const [], null, null, ), r.ParameterMirrorImpl( r'pattern', 134348806, 143, const prefix0.ContainedReflectable(), -1, 104, 104, const [], const [], null, null, ), r.ParameterMirrorImpl( r'start', 134354950, 143, const prefix0.ContainedReflectable(), 16, 16, 16, const [], const [], null, null, ), r.ParameterMirrorImpl( r'pattern', 134348806, 144, const prefix0.ContainedReflectable(), -1, 104, 104, const [], const [], null, null, ), r.ParameterMirrorImpl( r'start', 67244038, 144, const prefix0.ContainedReflectable(), 16, 16, 16, const [], const [], null, null, ), r.ParameterMirrorImpl( r'other', 134348806, 145, const prefix0.ContainedReflectable(), 15, 15, 15, const [], const [], null, null, ), r.ParameterMirrorImpl( r'start', 134348806, 146, const prefix0.ContainedReflectable(), 16, 16, 16, const [], const [], null, null, ), r.ParameterMirrorImpl( r'end', 67244038, 146, const prefix0.ContainedReflectable(), 16, 16, 16, const [], const [], null, null, ), r.ParameterMirrorImpl( r'times', 134348806, 150, const prefix0.ContainedReflectable(), 16, 16, 16, const [], const [], null, null, ), r.ParameterMirrorImpl( r'width', 134348806, 151, const prefix0.ContainedReflectable(), 16, 16, 16, const [], const [], null, null, ), r.ParameterMirrorImpl( r'padding', 134354950, 151, const prefix0.ContainedReflectable(), 15, 15, 15, const [], const [], null, null, ), r.ParameterMirrorImpl( r'width', 134348806, 152, const prefix0.ContainedReflectable(), 16, 16, 16, const [], const [], null, null, ), r.ParameterMirrorImpl( r'padding', 134354950, 152, const prefix0.ContainedReflectable(), 15, 15, 15, const [], const [], null, null, ), r.ParameterMirrorImpl( r'other', 134348806, 153, const prefix0.ContainedReflectable(), -1, 104, 104, const [], const [], null, null, ), r.ParameterMirrorImpl( r'startIndex', 134354950, 153, const prefix0.ContainedReflectable(), 16, 16, 16, const [], const [], null, null, ), r.ParameterMirrorImpl( r'from', 134348806, 154, const prefix0.ContainedReflectable(), -1, 104, 104, const [], const [], null, null, ), r.ParameterMirrorImpl( r'to', 134348806, 154, const prefix0.ContainedReflectable(), 15, 15, 15, const [], const [], null, null, ), r.ParameterMirrorImpl( r'startIndex', 134354950, 154, const prefix0.ContainedReflectable(), 16, 16, 16, const [], const [], null, null, ), r.ParameterMirrorImpl( r'from', 134348806, 155, const prefix0.ContainedReflectable(), -1, 104, 104, const [], const [], null, null, ), r.ParameterMirrorImpl( r'replace', 134217734, 155, const prefix0.ContainedReflectable(), -1, 105, 105, const [], const [], null, null, ), r.ParameterMirrorImpl( r'startIndex', 134354950, 155, const prefix0.ContainedReflectable(), 16, 16, 16, const [], const [], null, null, ), r.ParameterMirrorImpl( r'from', 134348806, 156, const prefix0.ContainedReflectable(), -1, 104, 104, const [], const [], null, null, ), r.ParameterMirrorImpl( r'replace', 134348806, 156, const prefix0.ContainedReflectable(), 15, 15, 15, const [], const [], null, null, ), r.ParameterMirrorImpl( r'from', 134348806, 157, const prefix0.ContainedReflectable(), -1, 104, 104, const [], const [], null, null, ), r.ParameterMirrorImpl( r'replace', 134217734, 157, const prefix0.ContainedReflectable(), -1, 105, 105, const [], const [], null, null, ), r.ParameterMirrorImpl( r'start', 134348806, 158, const prefix0.ContainedReflectable(), 16, 16, 16, const [], const [], null, null, ), r.ParameterMirrorImpl( r'end', 67239942, 158, const prefix0.ContainedReflectable(), 16, 16, 16, const [], const [], null, null, ), r.ParameterMirrorImpl( r'replacement', 134348806, 158, const prefix0.ContainedReflectable(), 15, 15, 15, const [], const [], null, null, ), r.ParameterMirrorImpl( r'pattern', 134348806, 159, const prefix0.ContainedReflectable(), -1, 104, 104, const [], const [], null, null, ), r.ParameterMirrorImpl( r'pattern', 134348806, 160, const prefix0.ContainedReflectable(), -1, 104, 104, const [], const [], null, null, ), r.ParameterMirrorImpl( r'onMatch', 67121158, 160, const prefix0.ContainedReflectable(), -1, 106, 106, const [], const [], null, #onMatch, ), r.ParameterMirrorImpl( r'onNonMatch', 67121158, 160, const prefix0.ContainedReflectable(), -1, 107, 107, const [], const [], null, #onNonMatch, ), r.ParameterMirrorImpl( r'charCodes', 151126022, 169, const prefix0.ContainedReflectable(), 23, 108, 23, const [16], const [], null, null, ), r.ParameterMirrorImpl( r'start', 134354950, 169, const prefix0.ContainedReflectable(), 16, 16, 16, const [], const [], null, null, ), r.ParameterMirrorImpl( r'end', 67244038, 169, const prefix0.ContainedReflectable(), 16, 16, 16, const [], const [], null, null, ), r.ParameterMirrorImpl( r'charCode', 134348806, 170, const prefix0.ContainedReflectable(), 16, 16, 16, const [], const [], null, null, ), r.ParameterMirrorImpl( r'name', 134348806, 171, const prefix0.ContainedReflectable(), 15, 15, 15, const [], const [], null, null, ), r.ParameterMirrorImpl( r'defaultValue', 134363142, 171, const prefix0.ContainedReflectable(), 15, 15, 15, const [], const [], null, #defaultValue, ), r.ParameterMirrorImpl( r'other', 134348806, 172, const prefix0.ContainedReflectable(), 16, 16, 16, const [], const [], null, null, ), r.ParameterMirrorImpl( r'other', 134348806, 173, const prefix0.ContainedReflectable(), 16, 16, 16, const [], const [], null, null, ), r.ParameterMirrorImpl( r'other', 134348806, 174, const prefix0.ContainedReflectable(), 16, 16, 16, const [], const [], null, null, ), r.ParameterMirrorImpl( r'shiftAmount', 134348806, 176, const prefix0.ContainedReflectable(), 16, 16, 16, const [], const [], null, null, ), r.ParameterMirrorImpl( r'shiftAmount', 134348806, 177, const prefix0.ContainedReflectable(), 16, 16, 16, const [], const [], null, null, ), r.ParameterMirrorImpl( r'shiftAmount', 134348806, 178, const prefix0.ContainedReflectable(), 16, 16, 16, const [], const [], null, null, ), r.ParameterMirrorImpl( r'exponent', 134348806, 179, const prefix0.ContainedReflectable(), 16, 16, 16, const [], const [], null, null, ), r.ParameterMirrorImpl( r'modulus', 134348806, 179, const prefix0.ContainedReflectable(), 16, 16, 16, const [], const [], null, null, ), r.ParameterMirrorImpl( r'modulus', 134348806, 180, const prefix0.ContainedReflectable(), 16, 16, 16, const [], const [], null, null, ), r.ParameterMirrorImpl( r'other', 134348806, 181, const prefix0.ContainedReflectable(), 16, 16, 16, const [], const [], null, null, ), r.ParameterMirrorImpl( r'width', 134348806, 182, const prefix0.ContainedReflectable(), 16, 16, 16, const [], const [], null, null, ), r.ParameterMirrorImpl( r'width', 134348806, 183, const prefix0.ContainedReflectable(), 16, 16, 16, const [], const [], null, null, ), r.ParameterMirrorImpl( r'radix', 134348806, 195, const prefix0.ContainedReflectable(), 16, 16, 16, const [], const [], null, null, ), r.ParameterMirrorImpl( r'source', 134348806, 196, const prefix0.ContainedReflectable(), 15, 15, 15, const [], const [], null, null, ), r.ParameterMirrorImpl( r'radix', 67252230, 196, const prefix0.ContainedReflectable(), 16, 16, 16, const [], const [], null, #radix, ), r.ParameterMirrorImpl( r'source', 134348806, 197, const prefix0.ContainedReflectable(), 15, 15, 15, const [], const [], null, null, ), r.ParameterMirrorImpl( r'radix', 67252230, 197, const prefix0.ContainedReflectable(), 16, 16, 16, const [], const [], null, #radix, ), r.ParameterMirrorImpl( r'name', 134348806, 202, const prefix0.ContainedReflectable(), 15, 15, 15, const [], const [], null, null, ), r.ParameterMirrorImpl( r'defaultValue', 134363142, 202, const prefix0.ContainedReflectable(), 16, 16, 16, const [], const [], null, #defaultValue, ), r.ParameterMirrorImpl( r'other', 134348806, 203, const prefix0.ContainedReflectable(), 8, 8, 8, const [], const [], null, null, ), r.ParameterMirrorImpl( r'source', 151126022, 207, const prefix0.ContainedReflectable(), 18, 109, 18, null, const [], null, null, ), r.ParameterMirrorImpl( r'target', 151126022, 208, const prefix0.ContainedReflectable(), 18, 110, 18, null, const [], null, null, ), r.ParameterMirrorImpl( r'at', 134348806, 208, const prefix0.ContainedReflectable(), 16, 16, 16, const [], const [], null, null, ), r.ParameterMirrorImpl( r'source', 151126022, 208, const prefix0.ContainedReflectable(), 18, 110, 18, null, const [], null, null, ), r.ParameterMirrorImpl( r'start', 67244038, 208, const prefix0.ContainedReflectable(), 16, 16, 16, const [], const [], null, null, ), r.ParameterMirrorImpl( r'end', 67244038, 208, const prefix0.ContainedReflectable(), 16, 16, 16, const [], const [], null, null, ), r.ParameterMirrorImpl( r'target', 151126022, 209, const prefix0.ContainedReflectable(), 18, 111, 18, null, const [], null, null, ), r.ParameterMirrorImpl( r'at', 134348806, 209, const prefix0.ContainedReflectable(), 16, 16, 16, const [], const [], null, null, ), r.ParameterMirrorImpl( r'source', 151126022, 209, const prefix0.ContainedReflectable(), 23, 112, 23, null, const [], null, null, ), r.ParameterMirrorImpl( r'index', 134348806, 211, const prefix0.ContainedReflectable(), 16, 16, 16, const [], const [], null, null, ), r.ParameterMirrorImpl( r'index', 134348806, 212, const prefix0.ContainedReflectable(), 16, 16, 16, const [], const [], null, null, ), r.ParameterMirrorImpl( r'value', 6, 212, const prefix0.ContainedReflectable(), -1, -1, -1, const [], const [], null, null, ), r.ParameterMirrorImpl( r'value', 6, 213, const prefix0.ContainedReflectable(), -1, -1, -1, const [], const [], null, null, ), r.ParameterMirrorImpl( r'iterable', 151126022, 214, const prefix0.ContainedReflectable(), 23, 68, 23, null, const [], null, null, ), r.ParameterMirrorImpl( r'compare', 67112966, 215, const prefix0.ContainedReflectable(), -1, 113, 113, const [], const [], null, null, ), r.ParameterMirrorImpl( r'random', 67244038, 216, const prefix0.ContainedReflectable(), -1, 114, 114, const [], const [], null, null, ), r.ParameterMirrorImpl( r'element', 6, 217, const prefix0.ContainedReflectable(), -1, -1, -1, const [], const [], null, null, ), r.ParameterMirrorImpl( r'start', 134354950, 217, const prefix0.ContainedReflectable(), 16, 16, 16, const [], const [], null, null, ), r.ParameterMirrorImpl( r'test', 134217734, 218, const prefix0.ContainedReflectable(), -1, 115, 115, const [], const [], null, null, ), r.ParameterMirrorImpl( r'start', 134354950, 218, const prefix0.ContainedReflectable(), 16, 16, 16, const [], const [], null, null, ), r.ParameterMirrorImpl( r'test', 134217734, 219, const prefix0.ContainedReflectable(), -1, 115, 115, const [], const [], null, null, ), r.ParameterMirrorImpl( r'start', 67244038, 219, const prefix0.ContainedReflectable(), 16, 16, 16, const [], const [], null, null, ), r.ParameterMirrorImpl( r'element', 6, 220, const prefix0.ContainedReflectable(), -1, -1, -1, const [], const [], null, null, ), r.ParameterMirrorImpl( r'start', 67244038, 220, const prefix0.ContainedReflectable(), 16, 16, 16, const [], const [], null, null, ), r.ParameterMirrorImpl( r'index', 134348806, 222, const prefix0.ContainedReflectable(), 16, 16, 16, const [], const [], null, null, ), r.ParameterMirrorImpl( r'element', 6, 222, const prefix0.ContainedReflectable(), -1, -1, -1, const [], const [], null, null, ), r.ParameterMirrorImpl( r'index', 134348806, 223, const prefix0.ContainedReflectable(), 16, 16, 16, const [], const [], null, null, ), r.ParameterMirrorImpl( r'iterable', 151126022, 223, const prefix0.ContainedReflectable(), 23, 68, 23, null, const [], null, null, ), r.ParameterMirrorImpl( r'index', 134348806, 224, const prefix0.ContainedReflectable(), 16, 16, 16, const [], const [], null, null, ), r.ParameterMirrorImpl( r'iterable', 151126022, 224, const prefix0.ContainedReflectable(), 23, 68, 23, null, const [], null, null, ), r.ParameterMirrorImpl( r'value', 67239942, 225, const prefix0.ContainedReflectable(), 8, 8, 8, const [], const [], null, null, ), r.ParameterMirrorImpl( r'index', 134348806, 226, const prefix0.ContainedReflectable(), 16, 16, 16, const [], const [], null, null, ), r.ParameterMirrorImpl( r'test', 134217734, 228, const prefix0.ContainedReflectable(), -1, 115, 115, const [], const [], null, null, ), r.ParameterMirrorImpl( r'test', 134217734, 229, const prefix0.ContainedReflectable(), -1, 115, 115, const [], const [], null, null, ), r.ParameterMirrorImpl( r'other', 151126022, 230, const prefix0.ContainedReflectable(), 18, 67, 18, null, const [], null, null, ), r.ParameterMirrorImpl( r'start', 134348806, 231, const prefix0.ContainedReflectable(), 16, 16, 16, const [], const [], null, null, ), r.ParameterMirrorImpl( r'end', 67244038, 231, const prefix0.ContainedReflectable(), 16, 16, 16, const [], const [], null, null, ), r.ParameterMirrorImpl( r'start', 134348806, 232, const prefix0.ContainedReflectable(), 16, 16, 16, const [], const [], null, null, ), r.ParameterMirrorImpl( r'end', 134348806, 232, const prefix0.ContainedReflectable(), 16, 16, 16, const [], const [], null, null, ), r.ParameterMirrorImpl( r'start', 134348806, 233, const prefix0.ContainedReflectable(), 16, 16, 16, const [], const [], null, null, ), r.ParameterMirrorImpl( r'end', 134348806, 233, const prefix0.ContainedReflectable(), 16, 16, 16, const [], const [], null, null, ), r.ParameterMirrorImpl( r'iterable', 151126022, 233, const prefix0.ContainedReflectable(), 23, 68, 23, null, const [], null, null, ), r.ParameterMirrorImpl( r'skipCount', 134354950, 233, const prefix0.ContainedReflectable(), 16, 16, 16, const [], const [], null, null, ), r.ParameterMirrorImpl( r'start', 134348806, 234, const prefix0.ContainedReflectable(), 16, 16, 16, const [], const [], null, null, ), r.ParameterMirrorImpl( r'end', 134348806, 234, const prefix0.ContainedReflectable(), 16, 16, 16, const [], const [], null, null, ), r.ParameterMirrorImpl( r'start', 134348806, 235, const prefix0.ContainedReflectable(), 16, 16, 16, const [], const [], null, null, ), r.ParameterMirrorImpl( r'end', 134348806, 235, const prefix0.ContainedReflectable(), 16, 16, 16, const [], const [], null, null, ), r.ParameterMirrorImpl( r'fillValue', 67112966, 235, const prefix0.ContainedReflectable(), -1, -1, -1, const [], const [], null, null, ), r.ParameterMirrorImpl( r'start', 134348806, 236, const prefix0.ContainedReflectable(), 16, 16, 16, const [], const [], null, null, ), r.ParameterMirrorImpl( r'end', 134348806, 236, const prefix0.ContainedReflectable(), 16, 16, 16, const [], const [], null, null, ), r.ParameterMirrorImpl( r'replacements', 151126022, 236, const prefix0.ContainedReflectable(), 23, 68, 23, null, const [], null, null, ), r.ParameterMirrorImpl( r'other', 134348806, 238, const prefix0.ContainedReflectable(), 8, 8, 8, const [], const [], null, null, ), r.ParameterMirrorImpl( r'length', 134348806, 244, const prefix0.ContainedReflectable(), 16, 16, 16, const [], const [], null, null, ), r.ParameterMirrorImpl( r'fill', 6, 244, const prefix0.ContainedReflectable(), -1, -1, -1, const [], const [], null, null, ), r.ParameterMirrorImpl( r'growable', 134363142, 244, const prefix0.ContainedReflectable(), 14, 14, 14, const [], const [], null, #growable, ), r.ParameterMirrorImpl( r'growable', 134363142, 245, const prefix0.ContainedReflectable(), 14, 14, 14, const [], const [], null, #growable, ), r.ParameterMirrorImpl( r'elements', 151126022, 246, const prefix0.ContainedReflectable(), 23, 116, 23, null, const [], null, null, ), r.ParameterMirrorImpl( r'growable', 134363142, 246, const prefix0.ContainedReflectable(), 14, 14, 14, const [], const [], null, #growable, ), r.ParameterMirrorImpl( r'elements', 151126022, 247, const prefix0.ContainedReflectable(), 23, 68, 23, null, const [], null, null, ), r.ParameterMirrorImpl( r'growable', 134363142, 247, const prefix0.ContainedReflectable(), 14, 14, 14, const [], const [], null, #growable, ), r.ParameterMirrorImpl( r'length', 134348806, 248, const prefix0.ContainedReflectable(), 16, 16, 16, const [], const [], null, null, ), r.ParameterMirrorImpl( r'generator', 134217734, 248, const prefix0.ContainedReflectable(), -1, 117, 117, const [], const [], null, null, ), r.ParameterMirrorImpl( r'growable', 134363142, 248, const prefix0.ContainedReflectable(), 14, 14, 14, const [], const [], null, #growable, ), r.ParameterMirrorImpl( r'elements', 151126022, 249, const prefix0.ContainedReflectable(), 23, 116, 23, null, const [], null, null, ), r.ParameterMirrorImpl( r'value', 6, 239, const prefix0.ContainedReflectable(), -1, -1, -1, const [], const [], null, null, ), r.ParameterMirrorImpl( r'value', 6, 240, const prefix0.ContainedReflectable(), -1, -1, -1, const [], const [], null, null, ), r.ParameterMirrorImpl( r'newLength', 134348806, 242, const prefix0.ContainedReflectable(), 16, 16, 16, const [], const [], null, null, ), r.ParameterMirrorImpl( r'other', 134348806, 250, const prefix0.ContainedReflectable(), 8, 8, 8, const [], const [], null, null, ), r.ParameterMirrorImpl( r'invocation', 134348806, 251, const prefix0.ContainedReflectable(), 13, 13, 13, const [], const [], null, null, ), r.ParameterMirrorImpl( r'other', 134348806, 257, const prefix0.ContainedReflectable(), 20, 20, 20, const [], const [], null, null, ), r.ParameterMirrorImpl( r'other', 134348806, 258, const prefix0.ContainedReflectable(), 20, 20, 20, const [], const [], null, null, ), r.ParameterMirrorImpl( r'other', 134348806, 271, const prefix0.ContainedReflectable(), 8, 8, 8, const [], const [], null, null, ), r.ParameterMirrorImpl( r'source', 151126022, 278, const prefix0.ContainedReflectable(), 22, 118, 22, null, const [], null, null, ), r.ParameterMirrorImpl( r'value', 67239942, 280, const prefix0.ContainedReflectable(), 8, 8, 8, const [], const [], null, null, ), r.ParameterMirrorImpl( r'key', 67239942, 281, const prefix0.ContainedReflectable(), 8, 8, 8, const [], const [], null, null, ), r.ParameterMirrorImpl( r'key', 67239942, 282, const prefix0.ContainedReflectable(), 8, 8, 8, const [], const [], null, null, ), r.ParameterMirrorImpl( r'key', 6, 283, const prefix0.ContainedReflectable(), -1, -1, -1, const [], const [], null, null, ), r.ParameterMirrorImpl( r'value', 6, 283, const prefix0.ContainedReflectable(), -1, -1, -1, const [], const [], null, null, ), r.ParameterMirrorImpl( r'convert', 134217734, 284, const prefix0.ContainedReflectable(), -1, 119, 119, const [], const [], null, null, ), r.ParameterMirrorImpl( r'newEntries', 151126022, 285, const prefix0.ContainedReflectable(), 23, 81, 23, null, const [], null, null, ), r.ParameterMirrorImpl( r'key', 6, 286, const prefix0.ContainedReflectable(), -1, -1, -1, const [], const [], null, null, ), r.ParameterMirrorImpl( r'update', 134217734, 286, const prefix0.ContainedReflectable(), -1, 120, 120, const [], const [], null, null, ), r.ParameterMirrorImpl( r'ifAbsent', 67121158, 286, const prefix0.ContainedReflectable(), -1, 121, 121, const [], const [], null, #ifAbsent, ), r.ParameterMirrorImpl( r'update', 134217734, 287, const prefix0.ContainedReflectable(), -1, 122, 122, const [], const [], null, null, ), r.ParameterMirrorImpl( r'test', 134217734, 288, const prefix0.ContainedReflectable(), -1, 123, 123, const [], const [], null, null, ), r.ParameterMirrorImpl( r'key', 6, 289, const prefix0.ContainedReflectable(), -1, -1, -1, const [], const [], null, null, ), r.ParameterMirrorImpl( r'ifAbsent', 134217734, 289, const prefix0.ContainedReflectable(), -1, 124, 124, const [], const [], null, null, ), r.ParameterMirrorImpl( r'other', 151126022, 290, const prefix0.ContainedReflectable(), 22, 84, 22, null, const [], null, null, ), r.ParameterMirrorImpl( r'key', 67239942, 291, const prefix0.ContainedReflectable(), 8, 8, 8, const [], const [], null, null, ), r.ParameterMirrorImpl( r'action', 134217734, 293, const prefix0.ContainedReflectable(), -1, 125, 125, const [], const [], null, null, ), r.ParameterMirrorImpl( r'other', 151126022, 301, const prefix0.ContainedReflectable(), 22, 126, 22, null, const [], null, null, ), r.ParameterMirrorImpl( r'other', 151126022, 302, const prefix0.ContainedReflectable(), 22, 84, 22, null, const [], null, null, ), r.ParameterMirrorImpl( r'other', 151126022, 303, const prefix0.ContainedReflectable(), 22, 126, 22, null, const [], null, null, ), r.ParameterMirrorImpl( r'iterable', 151126022, 305, const prefix0.ContainedReflectable(), 23, 116, 23, null, const [], null, null, ), r.ParameterMirrorImpl( r'key', 67121158, 305, const prefix0.ContainedReflectable(), -1, 127, 127, const [], const [], null, #key, ), r.ParameterMirrorImpl( r'value', 67121158, 305, const prefix0.ContainedReflectable(), -1, 128, 128, const [], const [], null, #value, ), r.ParameterMirrorImpl( r'keys', 151126022, 306, const prefix0.ContainedReflectable(), 23, 82, 23, null, const [], null, null, ), r.ParameterMirrorImpl( r'values', 151126022, 306, const prefix0.ContainedReflectable(), 23, 83, 23, null, const [], null, null, ), r.ParameterMirrorImpl( r'entries', 151126022, 307, const prefix0.ContainedReflectable(), 23, 81, 23, null, const [], null, null, ), r.ParameterMirrorImpl( r'source', 151126022, 308, const prefix0.ContainedReflectable(), 23, 129, 23, null, const [], null, null, ), r.ParameterMirrorImpl( r'other', 151126022, 310, const prefix0.ContainedReflectable(), 23, 87, 23, null, const [], null, null, ), r.ParameterMirrorImpl( r'toElement', 134217734, 311, const prefix0.ContainedReflectable(), -1, 130, 130, const [], const [], null, null, ), r.ParameterMirrorImpl( r'test', 134217734, 312, const prefix0.ContainedReflectable(), -1, 131, 131, const [], const [], null, null, ), r.ParameterMirrorImpl( r'toElements', 134217734, 314, const prefix0.ContainedReflectable(), -1, 132, 132, const [], const [], null, null, ), r.ParameterMirrorImpl( r'element', 67239942, 315, const prefix0.ContainedReflectable(), 8, 8, 8, const [], const [], null, null, ), r.ParameterMirrorImpl( r'action', 134217734, 316, const prefix0.ContainedReflectable(), -1, 133, 133, const [], const [], null, null, ), r.ParameterMirrorImpl( r'combine', 134217734, 317, const prefix0.ContainedReflectable(), -1, 134, 134, const [], const [], null, null, ), r.ParameterMirrorImpl( r'initialValue', 6, 318, const prefix0.ContainedReflectable(), -1, -1, -1, const [], const [], null, null, ), r.ParameterMirrorImpl( r'combine', 134217734, 318, const prefix0.ContainedReflectable(), -1, 135, 135, const [], const [], null, null, ), r.ParameterMirrorImpl( r'test', 134217734, 319, const prefix0.ContainedReflectable(), -1, 131, 131, const [], const [], null, null, ), r.ParameterMirrorImpl( r'separator', 134354950, 320, const prefix0.ContainedReflectable(), 15, 15, 15, const [], const [], null, null, ), r.ParameterMirrorImpl( r'test', 134217734, 321, const prefix0.ContainedReflectable(), -1, 131, 131, const [], const [], null, null, ), r.ParameterMirrorImpl( r'growable', 134363142, 322, const prefix0.ContainedReflectable(), 14, 14, 14, const [], const [], null, #growable, ), r.ParameterMirrorImpl( r'count', 134348806, 324, const prefix0.ContainedReflectable(), 16, 16, 16, const [], const [], null, null, ), r.ParameterMirrorImpl( r'test', 134217734, 325, const prefix0.ContainedReflectable(), -1, 131, 131, const [], const [], null, null, ), r.ParameterMirrorImpl( r'count', 134348806, 326, const prefix0.ContainedReflectable(), 16, 16, 16, const [], const [], null, null, ), r.ParameterMirrorImpl( r'test', 134217734, 327, const prefix0.ContainedReflectable(), -1, 131, 131, const [], const [], null, null, ), r.ParameterMirrorImpl( r'test', 134217734, 328, const prefix0.ContainedReflectable(), -1, 131, 131, const [], const [], null, null, ), r.ParameterMirrorImpl( r'orElse', 67121158, 328, const prefix0.ContainedReflectable(), -1, 136, 136, const [], const [], null, #orElse, ), r.ParameterMirrorImpl( r'test', 134217734, 329, const prefix0.ContainedReflectable(), -1, 131, 131, const [], const [], null, null, ), r.ParameterMirrorImpl( r'orElse', 67121158, 329, const prefix0.ContainedReflectable(), -1, 136, 136, const [], const [], null, #orElse, ), r.ParameterMirrorImpl( r'test', 134217734, 330, const prefix0.ContainedReflectable(), -1, 131, 131, const [], const [], null, null, ), r.ParameterMirrorImpl( r'orElse', 67121158, 330, const prefix0.ContainedReflectable(), -1, 136, 136, const [], const [], null, #orElse, ), r.ParameterMirrorImpl( r'index', 134348806, 331, const prefix0.ContainedReflectable(), 16, 16, 16, const [], const [], null, null, ), r.ParameterMirrorImpl( r'iterable', 151126022, 333, const prefix0.ContainedReflectable(), 23, 116, 23, null, const [], null, null, ), r.ParameterMirrorImpl( r'leftDelimiter', 134354950, 333, const prefix0.ContainedReflectable(), 15, 15, 15, const [], const [], null, null, ), r.ParameterMirrorImpl( r'rightDelimiter', 134354950, 333, const prefix0.ContainedReflectable(), 15, 15, 15, const [], const [], null, null, ), r.ParameterMirrorImpl( r'iterable', 151126022, 334, const prefix0.ContainedReflectable(), 23, 116, 23, null, const [], null, null, ), r.ParameterMirrorImpl( r'leftDelimiter', 134354950, 334, const prefix0.ContainedReflectable(), 15, 15, 15, const [], const [], null, null, ), r.ParameterMirrorImpl( r'rightDelimiter', 134354950, 334, const prefix0.ContainedReflectable(), 15, 15, 15, const [], const [], null, null, ), r.ParameterMirrorImpl( r'count', 134348806, 343, const prefix0.ContainedReflectable(), 16, 16, 16, const [], const [], null, null, ), r.ParameterMirrorImpl( r'generator', 67112966, 343, const prefix0.ContainedReflectable(), -1, 137, 137, const [], const [], null, null, ), ], [ prefix1.LowerPokemon, prefix1.Pokemon, prefix1.KantoPokemon, prefix1.Artist, prefix1.Album, prefix1.AlbumLength, prefix1.PokemonType, prefix0.ContainedReflectable, Object, Enum, prefix2.Reflectable, prefix3.ReflectableImpl, prefix4.ReflectableBase, Invocation, bool, String, int, Type, List, prefix5.InstanceMirror, prefix5.TypeMirror, prefix5.LibraryMirror, Map, Iterable, prefix6.ReflectCapability, Deprecated, const m.TypeValue>().type, prefix3.ReflectorData, const m.TypeValue>().type, Symbol, prefix6.InstanceInvokeCapability, prefix6.StaticInvokeCapability, prefix6.TopLevelInvokeCapability, prefix6.NewInstanceCapability, prefix6.MetadataCapability, prefix6.TypeCapability, prefix6.TypeRelationsCapability, const r.FakeType(r'reflectable.capability._ReflectedTypeCapability'), prefix6.LibraryCapability, prefix6.DeclarationsCapability, prefix6.UriCapability, prefix6.LibraryDependenciesCapability, prefix6.InvokingCapability, prefix6.TypingCapability, const r.FakeType(r'reflectable.capability._DelegateCapability'), const r.FakeType(r'reflectable.capability._SubtypeQuantifyCapability'), prefix6.SuperclassQuantifyCapability, prefix6.TypeAnnotationQuantifyCapability, const r.FakeType( r'reflectable.capability._CorrespondingSetterQuantifyCapability', ), const r.FakeType(r'reflectable.capability._AdmitSubtypeCapability'), const m.TypeValue>().type, const m.TypeValue>().type, Set, const m.TypeValue>().type, Uri, const m.TypeValue>().type, prefix5.ClassMirror, const m.TypeValue>().type, const m.TypeValue>().type, const m.TypeValue>().type, const m.TypeValue>().type, const m.TypeValue>().type, const m.TypeValue>().type, Runes, double, const r.FakeType(r'dart.core.List'), const r.FakeType(r'dart.core.List'), const r.FakeType(r'dart.core.List'), const r.FakeType(r'dart.core.Iterable'), const r.FakeType(r'dart.core.Map'), prefix5.TypeVariableMirror, const m.TypeValue>().type, const m.TypeValue>().type, prefix5.DeclarationMirror, const m.TypeValue>().type, prefix5.LibraryDependencyMirror, const m.TypeValue>().type, Null, const r.FakeType(r'dart.core.Map'), const r.FakeType(r'dart.core.Map'), const r.FakeType(r'dart.core.Map'), const r.FakeType(r'dart.core.Iterable>'), const r.FakeType(r'dart.core.Iterable'), const r.FakeType(r'dart.core.Iterable'), const r.FakeType(r'dart.core.Map'), const r.FakeType(r'dart.core.Iterable'), const r.FakeType(r'dart.core.Iterable'), const r.FakeType(r'dart.core.Iterable'), const r.FakeType(r'dart.core.Iterable'), const r.FakeType(r'dart.core.Iterable'), const r.FakeType(r'dart.core.Iterable'), const r.FakeType(r'dart.core.List'), const r.FakeType(r'dart.core.Set'), Set, const r.FakeType(r'dart.core.Iterator'), Iterator, prefix7.Reflector, const m.TypeValue>().type, prefix6.StringInvocationKind, const m.TypeValue>().type, const m.TypeValue>().type, const m.TypeValue>().type, const m.TypeValue>().type, const m.TypeValue>().type, Pattern, const m.TypeValue().type, const m.TypeValue().type, const m.TypeValue().type, const m.TypeValue>().type, const r.FakeType(r'dart.core.List'), const r.FakeType(r'dart.core.List'), const r.FakeType(r'dart.core.List'), const r.FakeType(r'dart.core.Iterable'), const m.TypeValue().type, prefix8.Random, const m.TypeValue().type, const m.TypeValue>().type, const m.TypeValue().type, const r.FakeType(r'dart.core.Map'), const m.TypeValue().type, const m.TypeValue().type, const m.TypeValue().type, const m.TypeValue().type, const m.TypeValue().type, const m.TypeValue().type, const m.TypeValue().type, const m.TypeValue>().type, const m.TypeValue().type, const m.TypeValue().type, const r.FakeType(r'dart.core.Iterable'), const m.TypeValue().type, const m.TypeValue().type, const m.TypeValue().type, const m.TypeValue().type, const m.TypeValue().type, const m.TypeValue().type, const m.TypeValue().type, const m.TypeValue().type, ], 25, { r'==': (dynamic instance) => (x) => instance == x, r'toString': (dynamic instance) => instance.toString, r'noSuchMethod': (dynamic instance) => instance.noSuchMethod, r'hashCode': (dynamic instance) => instance.hashCode, r'runtimeType': (dynamic instance) => instance.runtimeType, r'pokemon': (dynamic instance) => instance.pokemon, r'lowercaseName': (dynamic instance) => instance.lowercaseName, r'name': (dynamic instance) => instance.name, r'type': (dynamic instance) => instance.type, r'lowerName': (dynamic instance) => instance.lowerName, r'artist': (dynamic instance) => instance.artist, r'title': (dynamic instance) => instance.title, r'album': (dynamic instance) => instance.album, r'totalLength': (dynamic instance) => instance.totalLength, r'index': (dynamic instance) => instance.index, r'capabilities': (dynamic instance) => instance.capabilities, r'canReflect': (dynamic instance) => instance.canReflect, r'reflect': (dynamic instance) => instance.reflect, r'canReflectType': (dynamic instance) => instance.canReflectType, r'reflectType': (dynamic instance) => instance.reflectType, r'findLibrary': (dynamic instance) => instance.findLibrary, r'libraries': (dynamic instance) => instance.libraries, r'annotatedClasses': (dynamic instance) => instance.annotatedClasses, r'typeArguments': (dynamic instance) => instance.typeArguments, r'isAccessor': (dynamic instance) => instance.isAccessor, r'&': (dynamic instance) => (x) => instance & x, r'|': (dynamic instance) => (x) => instance | x, r'^': (dynamic instance) => (x) => instance ^ x, r'cast': (dynamic instance) => instance.cast, r'followedBy': (dynamic instance) => instance.followedBy, r'map': (dynamic instance) => instance.map, r'where': (dynamic instance) => instance.where, r'whereType': (dynamic instance) => instance.whereType, r'expand': (dynamic instance) => instance.expand, r'contains': (dynamic instance) => instance.contains, r'forEach': (dynamic instance) => instance.forEach, r'reduce': (dynamic instance) => instance.reduce, r'fold': (dynamic instance) => instance.fold, r'every': (dynamic instance) => instance.every, r'join': (dynamic instance) => instance.join, r'any': (dynamic instance) => instance.any, r'toList': (dynamic instance) => instance.toList, r'toSet': (dynamic instance) => instance.toSet, r'take': (dynamic instance) => instance.take, r'takeWhile': (dynamic instance) => instance.takeWhile, r'skip': (dynamic instance) => instance.skip, r'skipWhile': (dynamic instance) => instance.skipWhile, r'firstWhere': (dynamic instance) => instance.firstWhere, r'lastWhere': (dynamic instance) => instance.lastWhere, r'singleWhere': (dynamic instance) => instance.singleWhere, r'elementAt': (dynamic instance) => instance.elementAt, r'length': (dynamic instance) => instance.length, r'isEmpty': (dynamic instance) => instance.isEmpty, r'isNotEmpty': (dynamic instance) => instance.isNotEmpty, r'first': (dynamic instance) => instance.first, r'last': (dynamic instance) => instance.last, r'single': (dynamic instance) => instance.single, }, {}, [ r.LibraryMirrorImpl( r'', Uri.parse('asset:angel3_container_generator/test/reflector_test.dart'), const prefix0.ContainedReflectable(), const [43, 44, 45], { r'main': () => prefix1.main, r'returnVoidFromAFunction': () => prefix1.returnVoidFromAFunction, r'testReflector': () => prefix1.testReflector, }, {}, const [], null, ), r.LibraryMirrorImpl( r'', Uri.parse( 'package:angel3_container_generator/angel3_container_generator.dart', ), const prefix0.ContainedReflectable(), const [0], {r'contained': () => prefix0.contained}, {}, const [], null, ), r.LibraryMirrorImpl( r'dart.core', Uri.parse(r'reflectable://2/library dart:core'), const prefix0.ContainedReflectable(), const [1, 2, 47, 48, 49], { r'deprecated': () => deprecated, r'override': () => override, r'identical': () => identical, r'identityHashCode': () => identityHashCode, r'print': () => print, }, {}, const [], null, ), r.LibraryMirrorImpl( r'reflectable.reflectable', Uri.parse('package:reflectable/reflectable.dart'), const prefix0.ContainedReflectable(), const [], {}, {}, const [], null, ), r.LibraryMirrorImpl( r'reflectable.src.reflectable_builder_based', Uri.parse('package:reflectable/src/reflectable_builder_based.dart'), const prefix0.ContainedReflectable(), const [3, 4, 5, 57], { r'pleaseInitializeMessage': () => prefix3.pleaseInitializeMessage, r'data': () => prefix3.data, r'memberSymbolMap': () => prefix3.memberSymbolMap, r'reflectors': () => prefix3.reflectors, }, { r'data=': (dynamic value) => prefix3.data = value, r'memberSymbolMap=': (dynamic value) => prefix3.memberSymbolMap = value, }, const [], null, ), r.LibraryMirrorImpl( r'reflectable.src.reflectable_base', Uri.parse('package:reflectable/src/reflectable_base.dart'), const prefix0.ContainedReflectable(), const [], {}, {}, const [], null, ), r.LibraryMirrorImpl( r'reflectable.mirrors', Uri.parse('package:reflectable/mirrors.dart'), const prefix0.ContainedReflectable(), const [], {}, {}, const [], null, ), r.LibraryMirrorImpl( r'reflectable.capability', Uri.parse('package:reflectable/capability.dart'), const prefix0.ContainedReflectable(), const [ 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 58, 59, 60, 61, 62, ], { r'instanceInvokeCapability': () => prefix6.instanceInvokeCapability, r'staticInvokeCapability': () => prefix6.staticInvokeCapability, r'topLevelInvokeCapability': () => prefix6.topLevelInvokeCapability, r'newInstanceCapability': () => prefix6.newInstanceCapability, r'metadataCapability': () => prefix6.metadataCapability, r'typeCapability': () => prefix6.typeCapability, r'typeRelationsCapability': () => prefix6.typeRelationsCapability, r'reflectedTypeCapability': () => prefix6.reflectedTypeCapability, r'libraryCapability': () => prefix6.libraryCapability, r'declarationsCapability': () => prefix6.declarationsCapability, r'uriCapability': () => prefix6.uriCapability, r'libraryDependenciesCapability': () => prefix6.libraryDependenciesCapability, r'invokingCapability': () => prefix6.invokingCapability, r'typingCapability': () => prefix6.typingCapability, r'delegateCapability': () => prefix6.delegateCapability, r'subtypeQuantifyCapability': () => prefix6.subtypeQuantifyCapability, r'superclassQuantifyCapability': () => prefix6.superclassQuantifyCapability, r'typeAnnotationQuantifyCapability': () => prefix6.typeAnnotationQuantifyCapability, r'typeAnnotationDeepQuantifyCapability': () => prefix6.typeAnnotationDeepQuantifyCapability, r'correspondingSetterQuantifyCapability': () => prefix6.correspondingSetterQuantifyCapability, r'admitSubtypeCapability': () => prefix6.admitSubtypeCapability, r'reflectableNoSuchInvokableError': () => prefix6.reflectableNoSuchInvokableError, r'reflectableNoSuchMethodError': () => prefix6.reflectableNoSuchMethodError, r'reflectableNoSuchGetterError': () => prefix6.reflectableNoSuchGetterError, r'reflectableNoSuchSetterError': () => prefix6.reflectableNoSuchSetterError, r'reflectableNoSuchConstructorError': () => prefix6.reflectableNoSuchConstructorError, }, {}, const [], null, ), ], [], ), }; final _memberSymbolMap = null; void initializeReflectable() { r.data = _data; r.memberSymbolMap = _memberSymbolMap; } ================================================ FILE: packages/file_service/.gitignore ================================================ # See https://www.dartlang.org/tools/private-files.html # Files and directories created by pub .packages .pub/ build/ # If you're building an application, you may want to check-in your pubspec.lock pubspec.lock # Directory created by dartdoc # If you don't generate documentation locally you can remove this line. doc/api/ ### JetBrains template # Covers JetBrains IDEs: IntelliJ, RubyMine, PhpStorm, AppCode, PyCharm, CLion, Android Studio and Webstorm # Reference: https://intellij-support.jetbrains.com/hc/en-us/articles/206544839 # User-specific stuff: .idea/**/workspace.xml .idea/**/tasks.xml .idea/dictionaries # Sensitive or high-churn files: .idea/**/dataSources/ .idea/**/dataSources.ids .idea/**/dataSources.xml .idea/**/dataSources.local.xml .idea/**/sqlDataSources.xml .idea/**/dynamic.xml .idea/**/uiDesigner.xml # Gradle: .idea/**/gradle.xml .idea/**/libraries # Mongo Explorer plugin: .idea/**/mongoSettings.xml ## File-based project format: *.iws ## Plugin-specific files: # IntelliJ /out/ # mpeltonen/sbt-idea plugin .idea_modules/ # JIRA plugin atlassian-ide-plugin.xml # Crashlytics plugin (for Android Studio and IntelliJ) com_crashlytics_export_strings.xml crashlytics.properties crashlytics-build.properties fabric.properties .dart_tool ================================================ FILE: packages/file_service/AUTHORS.md ================================================ 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. * __[Tobe O](thosakwe@gmail.com)__ Tobe has written much of the original code prior to NNBD migration. He has moved on and is no longer involved with the project. ================================================ FILE: packages/file_service/CHANGELOG.md ================================================ # Change Log ## 8.5.0 * Require Dart >= 3.11 ## 8.4.0 * Require Dart >= 3.8 * Updated `lints` to 6.0.0 * Updated dependencies to the latest release ## 8.3.0 * Require Dart >= 3.6 * Updated `lints` to 5.0.0 * Updated dependencies to the latest release ## 8.2.0 * Require Dart >= 3.3 * Updated `lints` to 4.0.0 ## 8.1.1 * Updated repository link ## 8.1.0 * Updated `lints` to 3.0.0 * Fixed linter warnings * Updated repository link ## 8.0.0 * Require Dart >= 3.0 ## 7.0.0 * Require Dart >= 2.17 ## 6.0.0 * Require Dart >= 2.16 ## 5.0.0 * Skipped release ## 4.1.0 * Upgraded to `lints` linter ## 4.0.2 * Updated README * Removed redundant code ## 4.0.1 * Updated package description ## 4.0.0 * Migrated to support Dart >= 2.12 NNBD ## 3.0.0 * Migrated to work with Dart >= 2.12 Non NNBD ## 2.0.1 * Pass everything through `_jsonifyToSD` when returning responses. ## 2.0.0 * Dart/Angel 2 update. * Remove `package:dart2_constant` * Update `package:file` to `^5.0.0`. ## 1.1.2 * Added tests, because tests. ## 1.1.1 * Dart 2 fixes. ## 1.1.0+2 * `create` now uses the underlying store, instead of manually patching ## 1.1.0+1 * Analyzer nitpick for pana ## 1.1.0 * Updated to framework v1.1.x * Use `package:file` * Allow a custom `store` ================================================ FILE: packages/file_service/LICENSE ================================================ BSD 3-Clause License Copyright (c) 2021, dukefirehawk.com All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: 1. Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. 2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. 3. Neither the name of the copyright holder nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. ================================================ FILE: packages/file_service/README.md ================================================ # File Service for Angel3 ![Pub Version (including pre-releases)](https://img.shields.io/pub/v/angel3_file_service?include_prereleases) [![Null Safety](https://img.shields.io/badge/null-safety-brightgreen)](https://dart.dev/null-safety) [![Discord](https://img.shields.io/discord/1060322353214660698)](https://discord.gg/3X6bxTUdCM) [![License](https://img.shields.io/github/license/dart-backend/angel)](https://github.com/dart-backend/angel/tree/master/packages/file_service/LICENSE) Angel service that persists data to a file on disk, stored as a JSON list. It uses a simple mutex to prevent race conditions, and caches contents in memory until changes are made. The file will be created on read/write, if it does not already exist. This package is useful in development, as it prevents you from having to install an external database to run your server. When running a multi-threaded server, there is no guarantee that file operations will be mutually excluded. Thus, try to only use this one a single-threaded server if possible, or one with very low load. While not necessarily *slow*, this package makes no promises about performance. ## Usage ```dart configureServer(Angel app) async { // Just like a normal service app.use( '/api/todos', JsonFileService( const LocalFileSystem().file('todos_db.json') ), ); } ``` ================================================ FILE: packages/file_service/analysis_options.yaml ================================================ include: package:lints/recommended.yaml ================================================ FILE: packages/file_service/example/main.dart ================================================ import 'package:angel3_file_service/angel3_file_service.dart'; import 'package:angel3_framework/angel3_framework.dart'; import 'package:file/local.dart'; void configureServer(Angel app) async { // Just like a normal service app.use( '/api/todos', JsonFileService(const LocalFileSystem().file('todos_db.json')), ); } ================================================ FILE: packages/file_service/lib/angel3_file_service.dart ================================================ import 'dart:async'; import 'dart:convert'; import 'package:angel3_framework/angel3_framework.dart'; import 'package:file/file.dart'; import 'package:pool/pool.dart'; /// Persists in-memory changes to a file on disk. class JsonFileService extends Service> { FileStat? _lastStat; final Pool _mutex = Pool(1); late MapService _store; final File file; JsonFileService( this.file, { bool allowRemoveAll = false, bool allowQuery = true, MapService? store, }) { _store = store ?? MapService( allowRemoveAll: allowRemoveAll == true, allowQuery: allowQuery != false, ); } Map _coerceStringDynamic(Map m) { return m.keys.fold>( {}, (out, k) => out..[k.toString()] = m[k], ); } Future _load() { return _mutex.withResource(() async { if (!await file.exists()) await file.writeAsString(json.encode([])); var stat = await file.stat(); // if (_lastStat == null || stat.modified.millisecondsSinceEpoch > _lastStat!.modified.millisecondsSinceEpoch) { _lastStat = stat; var contents = await file.readAsString(); var list = json.decode(contents) as Iterable; _store.items.clear(); // Clear exist in-memory copy _store.items.addAll( list.map((x) => _coerceStringDynamic(_revive(x) as Map)), ); // Insert all new entries } }); } Future _save() { return _mutex.withResource(() { return file.writeAsString( json.encode(_store.items.map(_jsonify).toList()), ); }); } @override Future close() async { _store.close(); } @override Future>> index([ Map? params, ]) async => _load() .then((_) => _store.index(params)) .then((it) => it.map(_jsonifyToSD).toList()); @override Future> read(id, [Map? params]) => _load().then((_) => _store.read(id, params)).then(_jsonifyToSD); @override Future> create( data, [ Map? params, ]) async { await _load(); var created = await _store.create(data, params).then(_jsonifyToSD); await _save(); return created; } @override Future> remove( id, [ Map? params, ]) async { await _load(); var r = await _store.remove(id, params).then(_jsonifyToSD); await _save(); return r; } @override Future> update( id, data, [ Map? params, ]) async { await _load(); var r = await _store.update(id, data, params).then(_jsonifyToSD); await _save(); return r; } @override Future> modify( id, data, [ Map? params, ]) async { await _load(); var r = await _store.update(id, data, params).then(_jsonifyToSD); await _save(); return r; } } dynamic _safeForJson(dynamic x) { if (x is DateTime) { return x.toIso8601String(); } else if (x is Map) { return _jsonify(x); } else if (x is num || x is String || x is bool || x == null) { return x; } else if (x is Iterable) { return x.map(_safeForJson).toList(); } else { return x.toString(); } } Map _jsonify(Map map) { return map.keys.fold({}, (out, k) => out..[k] = _safeForJson(map[k])); } Map _jsonifyToSD(Map map) => _jsonify(map).cast(); dynamic _revive(dynamic x) { if (x is Map) { return x.keys.fold>( {}, (out, k) => out..[k.toString()] = _revive(x[k]), ); } else if (x is Iterable) { return x.map(_revive).toList(); } else if (x is String) { try { return DateTime.parse(x); } catch (e) { return x; } } else { return x; } } ================================================ FILE: packages/file_service/melos_angel3_file_service.iml ================================================ ================================================ FILE: packages/file_service/pubspec.yaml ================================================ name: angel3_file_service version: 8.5.0 description: Angel service that persists data to a file on disk, stored as a JSON list. homepage: https://angel3-framework.web.app/ repository: https://github.com/dart-backend/angel/tree/master/packages/file_service resolution: workspace environment: sdk: '>=3.11.0 <4.0.0' dependencies: angel3_framework: ^8.4.0 file: ^7.0.0 pool: ^1.5.0 dev_dependencies: test: ^1.24.0 lints: ^6.0.0 ================================================ FILE: packages/file_service/test/all_test.dart ================================================ import 'package:angel3_file_service/angel3_file_service.dart'; import 'package:file/file.dart'; import 'package:file/memory.dart'; import 'package:test/test.dart'; void main() { MemoryFileSystem fs; File dbFile; late JsonFileService service; setUp(() async { fs = MemoryFileSystem(); dbFile = fs.file('db.json'); service = JsonFileService(dbFile); await dbFile.writeAsString(''' [ {"id": "0", "foo": "bar"}, {"id": "1", "foo": "baz"}, {"id": "2", "foo": "quux"} ] '''); }); tearDown(() => service.close()); test('index no params', () async { expect(await service.index(), [ {'id': '0', 'foo': 'bar'}, {'id': '1', 'foo': 'baz'}, {'id': '2', 'foo': 'quux'}, ]); }); test('index with query', () async { expect( await service.index({ 'query': {'foo': 'bar'}, }), [ {'id': '0', 'foo': 'bar'}, ], ); }); test('read', () async { expect(await service.read('2'), {'id': '2', 'foo': 'quux'}); }); test('modify', () async { await service.modify('2', {'baz': 'quux'}); expect(await service.read('2'), containsPair('baz', 'quux')); }); test('update', () async { await service.update('2', {'baz': 'quux'}); expect(await service.read('2'), containsPair('baz', 'quux')); expect(await service.read('2'), isNot(containsPair('foo', 'quux'))); }); test('delete', () async { await service.remove('2'); expect(await service.index(), [ {'id': '0', 'foo': 'bar'}, {'id': '1', 'foo': 'baz'}, ]); }); } ================================================ FILE: packages/framework/AUTHORS.md ================================================ 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. * __[Tobe O](thosakwe@gmail.com)__ Tobe has written much of the original code prior to NNBD migration. He has moved on and is no longer involved with the project. ================================================ FILE: packages/framework/CHANGELOG.md ================================================ # Change Log ## 8.7.0 * Require Dart >= 3.11 ## 8.6.0 * Require Dart >= 3.8 * Updated `lints` to 6.0.0 * Updated dependencies to the latest release ## 8.5.0 * Require Dart >= 3.6 * Updated `lints` to 5.0.0 * Updated `mime` to 2.0.0 * Fixed res.json() will cause 'Bad state: Cannot modify a closed response.' error. ## 8.4.0 * Require Dart >= 3.3 * Updated `lints` to 4.0.0 ## 8.3.2 * Updated README ## 8.3.1 * Updated repository link ## 8.3.0 * Updated `lints` to 3.0.0 * Fixed linter warnings ## 8.2.0 * Add `addResponseHeader` to `AngelHttp` to add headers to HTTP default response * Add `removeResponseHeader` to `AngelHttp` to remove headers from HTTP default response ## 8.1.1 * Updated broken image on README ## 8.1.0 * Updated `uuid` to 4.0.0 ## 8.0.0 * Require Dart >= 3.0 * Updated `http` to 1.0.0 ## 7.0.4 * Updated `Expose` fields to non-nullable * Updated `Controller` to use non-nullable field ## 7.0.3 * Fixed issue #83. Allow Http request to return null headers instead of throwing an exception. ## 7.0.2 * Added performance benchmark to README ## 7.0.1 * Fixed `BytesBuilder` warnings ## 7.0.0 * Require Dart >= 2.17 ## 6.0.0 * Require Dart >= 2.16 * Updated `container` to non nullable * Updated `angel` to non nullable * Updated `logger` to non nullable * Refactored error handler ## 5.0.0 * Skipped release ## 4.2.4 * Fixed issue 48. Log not working in development ## 4.2.3 * Fixed `res.json()` throwing bad state exception ## 4.2.2 * Added `Date` to response header * Updated `Server: Angel3` response header ## 4.2.1 * Updated `package:angel3_container` ## 4.2.0 * Updated to `package:belatuk_combinator` * Updated to `package:belatuk_merge_map` * Updated linter to `package:lints` ## 4.1.3 * Updated README ## 4.1.2 * Updated README * Fixed NNBD issues ## 4.1.1 * Updated link to `Angel3` home page * Fixed pedantic warnings ## 4.1.0 * Replaced `http_server` with `belatuk_http_server` ## 4.0.4 * Fixed response returning incorrect status code ## 4.0.3 * Fixed "Primitive after parsed param injection" test case * Fixed "Cannot remove all unless explicitly set" test case * Fixed "null" test case ## 4.0.2 * Updated README ## 4.0.1 * Updated README ## 4.0.0 * Migrated to support Dart >= 2.12 NNBD ## 3.0.0 * Migrated to work with Dart >= 2.12 Non NNBD ## 2.1.1 * `AngelHttp.uri` now returns an empty `Uri` if the server is not listening. ## 2.1.0 * This release was originally planned to be `2.0.5`, but it adds several features, and has therefore been bumped to `2.1.0`. * Fix a new (did not appear before 2.6/2.7) type error causing compilation to fail. ## 2.0.5-beta * Make `@Expose()` in `Controller` optional. * Add `allowHttp1` to `AngelHttp2` constructors. * Add `deserializeBody` and `decodeBody` to `RequestContext`. * Add `HostnameRouter`, which allows for routing based on hostname. * Default to using `ThrowingReflector`, instead of `EmptyReflector`. This will give a more descriptive error when trying to use controllers, etc. without reflection enabled. * `mountController` returns the mounted controller. ## 2.0.4+1 * Run `Controller.configureRoutes` before mounting `@Expose` routes. * Make `Controller.configureServer` always return a `Future`. ## 2.0.4 * Prepare for Dart SDK change to `Stream>` that are now `Stream`. * Accept any content type if accept header is missing. See [this PR](https://github.com/angel-dart/framework/pull/239). ## 2.0.3 * Patch up a bug caused by an upstream change to Dart's stream semantics. See more: ## 2.0.2+1 * Fix a bug in the implementation of `Controller.applyRoutes`. ## 2.0.2 * Make `ResponseContext` *explicitly* implement `StreamConsumer` (though technically it already did???) * Split `Controller.configureServer` to create `Controller.applyRoutes`. ## 2.0.1 * Tracked down a bug in `Driver.runPipeline` that allowed fallback handlers to run, even after the response was closed. * Add `RequestContext.shutdownHooks`. * Call `RequestContext.close` in `Driver.sendResponse`. * AngelConfigurer is now `FutureOr`, instead of just `FutureOr`. * Use a `Container.has` check in `Driver.sendResponse`. * Remove unnecessary `new` and `const`. ## 2.0.0 * Angel 2! :angel: :rocket: ## 2.0.0-rc.10 * Fix an error that prevented `AngelHttp2.custom` from working properly. * Add `startSharedHttp2`. ## 2.0.0-rc.9 * Fix some bugs in the `HookedService` implementation that skipped the outputs of `before` events. ## 2.0.0-rc.8 * Fix `MapService` flaw where clients could remove all records, even if `allowRemoveAll` were `false`. ## 2.0.0-rc.7 * `AnonymousService` can override `readData`. * `Service.map` now overrides `readData`. * `HookedService.readData` forwards to `inner`. ## 2.0.0-rc.6 * Make `redirect` and `download` methods asynchronous. ## 2.0.0-rc.5 * Make `serializer` `FutureOr Function(Object)`. * Make `ResponseContext.serialize` return `Future`. ## 2.0.0-rc.4 * Support resolution of asynchronous injections in controllers and `ioc`. * Inject `RequestContext` and `ResponseContext` into requests. ## 2.0.0-rc.3 * `MapService.modify` was not actually modifying items. ## 2.0.0-rc.2 * Fixes Pub analyzer lints (see `angel_route@3.0.6`) ## 2.0.0-rc.1 * Fix logic error that allowed content to be written to streaming responses after `close` was closed. ## 2.0.0-rc.0 * Log a warning when no `reflector` is provided. * Add `AngelEnvironment` class. * Add `Angel.environment`. * Deprecated `app.isProduction` in favor of `app.environment.isProduction`. * Allow setting of `bodyAsObject`, `bodyAsMap`, or `bodyAsList` **exactly once**. * Resolve named singletons in `resolveInjection`. * Fix a bug where `Service.parseId` would attempt to parse an `int`. * Replace as Data cast in Service.dart with a method that throws a 400 on error. ## 2.0.0-alpha.24 * Add `AngelEnv` class to `core`. * Deprecate `Angel.isProduction`, in favor of `AngelEnv`. ## 2.0.0-alpha.23 * `ResponseContext.render` sets `charset` to `utf8` in `contentType`. ## 2.0.0-alpha.22 * Update pipeline handling mechanism, and inject a `MiddlewarePipelineIterator`. * This allows routes to know where in the resolution process they exist, at runtime. ## 2.0.0-alpha.21 * Update for `angel_route@3.0.4` compatibility. * Add `readAsBytes` and `readAsString` to `UploadedFile`. * URI-decode path components in HTTP2. ## 2.0.0-alpha.20 * Inject the `MiddlewarePipeline` into requests. ## 2.0.0-alpha.19 * `parseBody` checks for null content type, and throws a `400` if none was given. * Add `ResponseContext.contentLength`. * Update `streamFile` to set content length, and also to work on `HEAD` requests. ## 2.0.0-alpha.18 * Upgrade `http2` dependency. * Upgrade `uuid` dependency. * Fixed a bug that prevented body parsing from ever completing with `http2`. * Add `Providers.hashCode`. ## 2.0.0-alpha.17 * Revert the migration to `lumberjack` for now. In the future, when it's more stable, there'll be a conversion, perhaps. ## 2.0.0-alpha.16 * Use `package:lumberjack` for logging. ## 2.0.0-alpha.15 * Remove dependency on `body_parser`. * `RequestContext` now exposes a `Stream> get body` getter. * Calling `RequestContext.parseBody()` parses its contents. * Added `bodyAsMap`, `bodyAsList`, `bodyAsObject`, and `uploadedFiles` to `RequestContext`. * Removed `Angel.keepRawRequestBuffers` and anything that had to do with buffering request bodies. ## 2.0.0-alpha.14 * Patch `HttpResponseContext._openStream` to send content-length. ## 2.0.0-alpha.13 * Fixed a logic error in `HttpResponseContext` that prevented status codes from being sent. ## 2.0.0-alpha.12 * Remove `ResponseContext.sendFile`. * Add `Angel.mimeTypeResolver`. * Fix a bug where an unknown MIME type on `streamFile` would return a 500. ## 2.0.0-alpha.11 * Add `readMany` to `Service`. * Allow `ResponseContext.redirect` to take a `Uri`. * Add `Angel.mountController`. * Add `Angel.findServiceOf`. * Roll in HTTP/2. See `pkg:angel_framework/http2.dart`. ## 2.0.0-alpha.10 * All calls to `Service.parseId` are now affixed with the `` argument. * Added `uri` getter to `AngelHttp`. * The default for `parseQuery` now wraps query parameters in `Map.from`. This resolves a bug in `package:angel_validate`. ## 2.0.0-alpha.9 * Add `Service.map`. ## 2.0.0-alpha.8 * No longer export HTTP-specific code from `angel_framework.dart`. An import of `import 'package:angel_framework/http.dart';` will be necessary in most cases now. ## 2.0.0-alpha.7 * Force a tigher contract on services. They now must return `Data` on all methods except for `index`, which returns a `List`. ## 2.0.0-alpha.6 * Allow passing a custom `Container` to `handleContained` and co. ## 2.0.0-alpha.5 * `MapService` methods now explicitly return `Map`. ## 2.0.0-alpha.4 * Renamed `waterfall` to `chain`. * Renamed `Routable.service` to `Routable.findService`. * Also `Routable.findHookedService`. ## 2.0.0-alpha.3 * Added `` type parameters to `Service`. * `HookedService` now follows suit, and takes a third parameter, pointing to the inner service. * `Routable.use` now uses the generic parameters added to `Service`. * Added generic usage to `HookedServiceListener`, etc. * All service methods take `Map` as `params` now. ## 2.0.0-alpha.2 * Added `ResponseContext.detach`. ## 2.0.0-alpha.1 * Removed `Angel.injectEncoders`. * Added `Providers.toJson`. * Moved `Providers.graphql` to `Providers.graphQL`. * `Angel.optimizeForProduction` no longer calls `preInject`, as it does not need to. * Rename `ResponseContext.enableBuffer` to `ResponseContext.useBuffer`. ## 2.0.0-alpha * Removed `random_string` dependency. * Moved reflection to `package:angel_container`. * Upgraded `package:file` to `5.0.0`. * `ResponseContext.sendFile` now uses `package:file`. * Abandon `ContentType` in favor of `MediaType`. * Changed view engine to use `Map`. * Remove dependency on `package:json_god` by default. * Remove dependency on `package:dart2_constant`. * Moved `lib/hooks.dart` into `package:angel_hooks`. * Moved `TypedService` into `package:angel_typed_service`. * Completely removed the `AngelBase` class. * Removed all `@deprecated` symbols. * `Service.toId` was renamed to `Service.parseId`; it also now uses its single type argument to determine how to parse a value. \* In addition, this method was also made `static`. * `RequestContext` and `ResponseContext` are now generic, and take a single type argument pointing to the underlying request/response type, respectively. * `RequestContext.io` and `ResponseContext.io` are now permanently gone. * `HttpRequestContextImpl` and `HttpResponseContextImpl` were renamed to `HttpRequestContext` and `HttpResponseContext`. * Lazy-parsing request bodies is now the default; `Angel.lazyParseBodies` was replaced with `Angel.eagerParseRequestBodies`. * `Angel.storeOriginalBuffer` -> `Angel.storeRawRequestBuffers`. * The methods `lazyBody`, `lazyFiles`, and `lazyOriginalBuffer` on `ResponseContext` were all replaced with `parseBody`, `parseUploadedFiles`, and `parseRawRequestBuffer`, respectively. * Removed the synchronous equivalents of the above methods (`body`, `files`, and `originalBuffer`), as well as `query`. * Removed `Angel.injections` and `RequestContext.injections`. * Removed `Angel.inject` and `RequestContext.inject`. * Removed a dependency on `package:pool`, which also meant removing `AngelHttp.throttle`. * Remove the `RequestMiddleware` typedef; from now on, one should use `ResponseContext.end` exclusively to close responses. * `waterfall` will now only accept `RequestHandler`. * `Routable`, and all of its subclasses, now extend `Router`, and therefore only take routes in the form of `FutureOr myFunc(RequestContext, ResponseContext res)`. * `@Middleware` now takes an `Iterable` of `RequestHandler`s. * `@Expose.path` now *must* be a `String`, not just any `Pattern`. * `@Expose.middleware` now takes `Iterable`, instead of just `List`. * `createDynamicHandler` was renamed to `ioc`, and is now used to run IoC-aware handlers in a type-safe manner. * `RequestContext.params` is now a `Map`, rather than just a `Map`. * Removed `RequestContext.grab`. * Removed `RequestContext.properties`. * Removed the defunct `debug` property where it still existed. * `Routable.use` now only accepts a `Service`. * Removed `Angel.createZoneForRequest`. * Removed `Angel.defaultZoneCreator`. * Added all flags to the `Angel` constructor, ex. `Angel.eagerParseBodies`. * Fix a bug where synchronous errors in `handleRequest` would not be caught. * `AngelHttp.useZone` now defaults to `false`. * `ResponseContext` now starts in streaming mode by default; the response buffer is opt-in, as in many cases it is unnecessary and slows down response time. * `ResponseContext.streaming` was replaced by `ResponseContext.isBuffered`. * Made `LockableBytesBuilder` public. * Removed the now-obsolete `ResponseContext.willCloseItself`. * Removed `ResponseContext.dispose`. * Removed the now-obsolete `ResponseContext.end`. * Removed the now-obsolete `ResponseContext.releaseCorrespondingRequest`. * `preInject` now takes a `Reflector` as its second argument. * `Angel.reflector` defaults to `const EmptyReflector()`, disabling reflection out-of-the-box. ================================================ FILE: packages/framework/LICENSE ================================================ BSD 3-Clause License Copyright (c) 2021, dukefirehawk.com All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: 1. Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. 2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. 3. Neither the name of the copyright holder nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. ================================================ FILE: packages/framework/README.md ================================================ # Angel3 Framework [![Angel3 Framework](../../angel3_logo.png)](https://github.com/dart-backend/angel) ![Pub Version (including pre-releases)](https://img.shields.io/pub/v/angel3_framework?include_prereleases) [![Null Safety](https://img.shields.io/badge/null-safety-brightgreen)](https://dart.dev/null-safety) [![Discord](https://img.shields.io/discord/1060322353214660698)](https://discord.gg/3X6bxTUdCM) [![License](https://img.shields.io/github/license/dart-backend/angel)](https://github.com/dart-backend/angel/tree/master/packages/framework/LICENSE) [![melos](https://img.shields.io/badge/maintained%20with-melos-f700ff.svg?style=flat-square)](https://github.com/invertase/melos) Angel3 framework is a high-powered HTTP server with support for dependency injection, sophisticated routing, authentication, ORM, graphql etc. It is designed to keep the core minimal but extensible through a series of plugin packages. It won't dictate which features, databases or web templating engine to use. This flexibility enable Angel3 framework to grow with your application as new features can be added to handle the new use cases. This package is the core package of [Angel3](https://github.com/dart-backend/angel). For more information, visit us at [Angel3 Website](https://angel3-framework.web.app). ## Installation and Setup ### (Option 1) Create a new project by cloning from boilerplate templates 1. Download and install [Dart](https://dart.dev/get-dart) 2. Clone one of the following starter projects: * [Angel3 Basic Template](https://github.com/dukefirehawk/boilerplates/tree/v7/angel3-basic) * [Angel3 ORM Template](https://github.com/dukefirehawk/boilerplates/tree/v7/angel3-orm) * [Angel3 ORM MySQL Template](https://github.com/dukefirehawk/boilerplates/tree/v7/angel3-orm-mysql) * [Angel3 Graphql Template](https://github.com/dukefirehawk/boilerplates/tree/v7/angel3-graphql) 3. Run the project in development mode (*hot-reloaded* is enabled on file changes). ```bash dart --observe bin/dev.dart ``` 4. Run the project in production mode (*hot-reloaded* is disabled). ```bash dart bin/prod.dart ``` 5. Run as docker. Edit and build the image with the provided `Dockerfile` file. ### (Option 2) Create a new project with Angel3 CLI 1. Download and install [Dart](https://dart.dev/get-dart) 2. Install the [Angel3 CLI](https://pub.dev/packages/angel3_cli): ```bash dart pub global activate angel3_cli ``` 3. On terminal, create a new project: ```bash angel3 init hello ``` 4. Run the project in development mode (*hot-reloaded* is enabled on file changes). ```bash dart --observe bin/dev.dart ``` 5. Run the project in production mode (*hot-reloaded* is disabled). ```bash dart bin/prod.dart ``` 6. Run as docker. Edit and build the image with the provided `Dockerfile` file. ## Performance Benchmark The performance benchmark can be found at [TechEmpower Framework Benchmarks Round 21](https://www.techempower.com/benchmarks/#section=data-r21&test=composite) ### Migrating from Angel to Angel3 Check out [Migrating to Angel3](https://angel3-docs.dukefirehawk.com/migration/angel-2.x.x-to-angel3/migration-guide-3) ## Donation & Support If you like this project and interested in supporting its development, you can make a donation using the following services: * [![GitHub](https://img.shields.io/static/v1?label=Sponsor&message=%E2%9D%A4&logo=GitHub&color=%23fe8e86)](https://github.com/sponsors/dukefirehawk) * [paypal](https://paypal.me/dukefirehawk?country.x=MY&locale.x=en_US) service ================================================ FILE: packages/framework/analysis_options.yaml ================================================ include: package:lints/recommended.yaml ================================================ FILE: packages/framework/dev.key ================================================ -----BEGIN ENCRYPTED PRIVATE KEY----- MIIE5DAcBgoqhkiG9w0BDAEBMA4ECL7L6rj6uEHGAgIIAASCBMLbucyfqAkgCbhP xNSHYllPMAv/dsIjtnsBwepCXPGkCBCuOAw/2FaCHjN9hBqL5V7fkrKeaemhm2YE ycPtlHJYPDf3kEkyMjdZ9rIY6kePGfQizs2uJPcXj4YPyQ4HsfVXpOicKfQrouf5 Mze9bGzeMN065q3iP4dYUMwHAyZYteXCsanQNHlqvsWli0W+H8St8fdsXefZhnv1 qVatKWdNdWQ9t5MuljgNU2Vv56sHKEYXI0yLxk2QUMk8KlJfnmt8foYUsnPUXHmc gIjLKwwVkpdololnEHSNu0cEOUPowjgJru+uMpn7vdNl7TPEQ9jbEgdNg4JwoYzU 0nao8WzjaSp7kzvZz0VFwKnk5AjstGvvuAWckADdq23QElbn/mF7AG1m/TBpYxzF gTt37UdndS/AcvVznWVVrRP5iTSIawdIwvqI4s7rqsoE0GCcak+RhchgAz2gWKkS oODUo0JL6pPVbJ3l4ebbaO6c99nDVc8dViPtc1EkStJEJ2O4kI4xgLSCr4Y9ahKn oAaoSkX7Xxq3aQm+BzqSpLjdGL8atsqR/YVOIHYIl3gThvP0NfZGx1xHyvO5mCdZ kHxSA7tKWxauZ3eQ2clbnzeRsl4El0WMHy/5K1ovene4v7sunmoXVtghBC8hK6eh zMO9orex2PNQ/VQC7HCvtytunOVx1lkSBoNo7hR70igg6rW9H7UyoAoBOwMpT1xa J6V62nqruTKOqFNfur7aHJGpHGtDb5/ickHeYCyPTvmGp67u4wChzKReeg02oECe d1E5FKAcIa8s9TVOB6Z+HvTRNQZu2PsI6TJnjQRowvY9DAHiWTlJZBBY/pko3hxX TsIeybpvRdEHpDWv86/iqtw1hv9CUxS/8ZTWUgBo+osShHW79FeDASr9FC4/Zn76 ZDERTgV4YWlW/klVWcG2lFo7jix+OPXAB+ZQavLhlN1xdWBcIz1AUWjAM4hdPylW HCX4PB9CQIPl2E7F+Y2p6nMcMWSJVBi5UIH7E9LfaBguXSzMmTk2Fw5p1aOQ6wfN goVAMVwi8ppAVs741PfHdZ295xMmK/1LCxz5DeAdD/tsA/SYfT753GotioDuC7im EyJ5JyvTr5I6RFFBuqt3NlUb3Hp16wP3B2x9DZiB6jxr0l341/NHgsyeBXkuIy9j ON2mvpBPCJhS8kgWo3G0UyyKnx64tcgpGuSvZhGwPz843B6AbYyE6pMRfSWRMkMS YZYa+VNKhR4ixdj07ocFZEWLVjCH7kxkE8JZXKt8jKYmkWd0lS1QVjgaKlO6lRa3 q6SPJkhW6pvqobvcqVNXwi1XuzpZeEbuh0B7OTekFTTxx5g9XeDl56M8SVQ1KEhT Q1t7H2Nba18WCB7cf+6PN0F0K0Jz1Kq7ZWaqEI/grX1m4RQuvNF5807sB/QKMO/Z Gz3NXvHg5xTJRd/567lxPGkor0cE7qD1EZfmJ2HrBYXQ91bhgA7LToBuMZo6ZRXH QfsanjbP4FPLMiGdQigLjj3A35L/f4sQOOVac/sRaFnm7pzcxsMvyVU/YtvGcjYE xaOOVnamg661Wo0wksXoDjeSz/JIyyKO3Gwp1FSm2wGLjjy/Ehmqcqy8rvHuf07w AUukhVtTNn4= -----END ENCRYPTED PRIVATE KEY----- ================================================ FILE: packages/framework/dev.pem ================================================ -----BEGIN CERTIFICATE----- MIIDKTCCAhGgAwIBAgIJAOWmjTS+OnTEMA0GCSqGSIb3DQEBCwUAMBcxFTATBgNV BAMMDGludGVybWVkaWF0ZTAeFw0xNTA1MTgwOTAwNDBaFw0yMzA4MDQwOTAwNDBa MBQxEjAQBgNVBAMMCWxvY2FsaG9zdDCCASIwDQYJKoZIhvcNAQEBBQADggEPADCC AQoCggEBALlcwQJuzd+xH8QFgfJSn5tRlvhkldSX98cE7NiA602NBbnAVyUrkRXq Ni75lgt0kwjYfA9z674m8WSVbgpLPintPCla9CYky1TH0keIs8Rz6cGWHryWEHiu EDuljQynu2b3sAFuHu9nfWurbJwZnFakBKpdQ9m4EyOZCHC/jHYY7HacKSXg1Cki we2ca0BWDrcqy8kLy0dZ5oC6IZG8O8drAK8f3f44CRYw59D3sOKBrKXaabpvyEcb N7Wk2HDBVwHpUJo1reVwtbM8dhqQayYSD8oXnGpP3RQNu/e2rzlXRyq/BfcDY1JI 7TbC4t/7/N4EcPSpGsTcSOC9A7FpzvECAwEAAaN7MHkwCQYDVR0TBAIwADAsBglg hkgBhvhCAQ0EHxYdT3BlblNTTCBHZW5lcmF0ZWQgQ2VydGlmaWNhdGUwHQYDVR0O BBYEFCnwiEMMFZh7NhCr+qA8K0w4Q+AOMB8GA1UdIwQYMBaAFB0h1Evsaw2vfrmS YuoCTmC4EE6ZMA0GCSqGSIb3DQEBCwUAA4IBAQAcFmHMaXRxyoNaeOowQ6iQWoZd AUbvG7SHr7I6Pi2aqdqofsKWts7Ytm5WsS0M2nN+sW504houu0iCPeJJX8RQw2q4 CCcNOs9IXk+2uMzlpocHpv+yYoUiD5DxgWh7eghQMLyMpf8FX3Gy4VazeuXznHOM 4gE4L417xkDzYOzqVTp0FTyAPUv6G2euhNCD6TMru9REcRhYul+K9kocjA5tt2KG MH6y28LXbLyq4YJUxSUU9gY/xlnbbZS48KDqEcdYC9zjW9nQ0qS+XQuQuFIcwjJ5 V4kAUYxDu6FoTpyQjgsrmBbZlKNxH7Nj4NDlcdJhp/zeSKHqWa5hSWjjKIxp -----END CERTIFICATE----- -----BEGIN CERTIFICATE----- MIIDAjCCAeqgAwIBAgIJAOWmjTS+OnTDMA0GCSqGSIb3DQEBCwUAMBgxFjAUBgNV BAMMDXJvb3RhdXRob3JpdHkwHhcNMTUwNTE4MDkwMDQwWhcNMjMwODA0MDkwMDQw WjAXMRUwEwYDVQQDDAxpbnRlcm1lZGlhdGUwggEiMA0GCSqGSIb3DQEBAQUAA4IB DwAwggEKAoIBAQDSrAO1CoPvUllgLOzDm5nG0skDF7vh1DUgAIDVGz0ecD0JFbQx EF79pju/6MbtpTW2FYvRp11t/G7rGtX923ybOHY/1MNFQrdIvPlO1VV7IGKjoMwP DNeb0fIGjHoE9QxaDxR8NX8xQbItpsw+TUtRfc9SLkR+jaYJfVRoM21BOncZbSHE YKiZlEbpecB/+EtwVpgvl+8mPD5U07Fi4fp/lza3WXInXQPyiTVllIEJCt4PKmlu MocNaJOW38bysL7i0PzDpVZtOxLHOTaW68yF3FckIHNCaA7k1ABEEEegjFMmIao7 B9w7A0jvr4jZVvNmui5Djjn+oJxwEVVgyf8LAgMBAAGjUDBOMB0GA1UdDgQWBBQd IdRL7GsNr365kmLqAk5guBBOmTAfBgNVHSMEGDAWgBRk81s9d0ZbiZhh44KckwPb oTc0XzAMBgNVHRMEBTADAQH/MA0GCSqGSIb3DQEBCwUAA4IBAQBZQTK0plfdB5PC cC5icut4EmrByJa1RbU7ayuEE70e7hla6KVmVjVdCBGltI4jBYwfhKbRItHiAJ/8 x+XZKBG8DLPFuDb7lAa1ObhAYF7YThUFPQYaBhfzKcWrdmWDBFpvNv6E0Mm364dZ e7Yxmbe5S4agkYPoxEzgEYmcUk9jbjdR6eTbs8laG169ljrECXfEU9RiAcqz5iSX NLSewqB47hn3B9qgKcQn+PsgO2j7M+rfklhNgeGJeWmy7j6clSOuCsIjWHU0RLQ4 0W3SB/rpEAJ7fgQbYUPTIUNALSOWi/o1tDX2mXPRjBoxqAv7I+vYk1lZPmSzkyRh FKvRDxsW -----END CERTIFICATE----- -----BEGIN CERTIFICATE----- MIIDAzCCAeugAwIBAgIJAJ0MomS4Ck+8MA0GCSqGSIb3DQEBCwUAMBgxFjAUBgNV BAMMDXJvb3RhdXRob3JpdHkwHhcNMTUwNTE4MDkwMDQwWhcNMjMwODA0MDkwMDQw WjAYMRYwFAYDVQQDDA1yb290YXV0aG9yaXR5MIIBIjANBgkqhkiG9w0BAQEFAAOC AQ8AMIIBCgKCAQEAts1ijtBV92S2cOvpUMOSTp9c6A34nIGr0T5Nhz6XiqRVT+gv dQgmkdKJQjbvR60y6jzltYFsI2MpGVXY8h/oAL81D/k7PDB2aREgyBfTPAhBHyGw siR+2xYt5b/Zs99q5RdRqQNzNpLPJriIKvUsRyQWy1UiG2s7pRXQeA8qB0XtJdCj kFIi+G2bDsaffspGeDOCqt7t+yqvRXfSES0c/l7DIHaiMbbp4//ZNML3RNgAjPz2 hCezZ+wOYajOIyoSPK8IgICrhYFYxvgWxwbLDBEfC5B3jOQsySe10GoRAKZz1gBV DmgReu81tYJmdgkc9zknnQtIFdA0ex+GvZlfWQIDAQABo1AwTjAdBgNVHQ4EFgQU ZPNbPXdGW4mYYeOCnJMD26E3NF8wHwYDVR0jBBgwFoAUZPNbPXdGW4mYYeOCnJMD 26E3NF8wDAYDVR0TBAUwAwEB/zANBgkqhkiG9w0BAQsFAAOCAQEATzkZ97K777uZ lQcduNX3ey4IbCiEzFA2zO5Blj+ilfIwNbZXNOgm/lqNvVGDYs6J1apJJe30vL3X J+t2zsZWzzQzb9uIU37zYemt6m0fHrSrx/iy5lGNqt3HMfqEcOqSCOIK3PCTMz2/ uyGe1iw33PVeWsm1JUybQ9IrU/huJjbgOHU4wab+8SJCM49ipArp68Fr6j4lcEaE 4rfRg1ZsvxiOyUB3qPn6wyL/JB8kOJ+QCBe498376eaem8AEFk0kQRh6hDaWtq/k t6IIXQLjx+EBDVP/veK0UnVhKRP8YTOoV8ZiG1NcdlJmX/Uk7iAfevP7CkBfSN8W r6AL284qtw== -----END CERTIFICATE----- ================================================ FILE: packages/framework/example/controller.dart ================================================ import 'package:angel3_container/mirrors.dart'; import 'package:angel3_framework/angel3_framework.dart'; import 'package:angel3_framework/http.dart'; import 'package:logging/logging.dart'; void main() async { // Logging set up/boilerplate Logger.root.onRecord.listen(print); // Create our server. var app = Angel(logger: Logger('angel'), reflector: MirrorsReflector()); var http = AngelHttp(app); await app.mountController(); // Simple fallback to throw a 404 on unknown paths. app.fallback((req, res) { throw AngelHttpException.notFound( message: 'Unknown path: "${req.uri!.path}"', ); }); app.errorHandler = (e, req, res) => e.toJson(); await http.startServer('127.0.0.1', 3000); print('Listening at ${http.uri}'); app.dumpTree(); } class ArtistsController extends Controller { List index() { return ['Elvis', 'Stevie', 'Van Gogh']; } String getById(int id, RequestContext req) { return 'You fetched ID: $id from IP: ${req.ip}'; } @Expose.post Future form(RequestContext req) async { // Deserialize the body into an artist. var artist = await req.deserializeBody((m) { return Artist(name: m!['name'] as String? ?? '(unknown name)'); }); // Return it (it will be serialized to JSON). return artist; } } class Artist { final String? name; Artist({this.name}); Map toJson() { return {'name': name}; } } ================================================ FILE: packages/framework/example/handle_error.dart ================================================ import 'dart:async'; import 'dart:io'; import 'package:angel3_container/mirrors.dart'; import 'package:angel3_framework/angel3_framework.dart'; import 'package:angel3_framework/http.dart'; import 'package:logging/logging.dart'; void main() async { var app = Angel(reflector: MirrorsReflector()) ..logger = (Logger('angel') ..onRecord.listen((rec) { print(rec); if (rec.error != null) print(rec.error); if (rec.stackTrace != null) print(rec.stackTrace); })) ..encoders.addAll({'gzip': gzip.encoder}); app.fallback( (req, res) => Future.error('Throwing just because I feel like!'), ); var http = AngelHttp(app); HttpServer? server = await http.startServer('127.0.0.1', 3000); var url = 'http://${server.address.address}:${server.port}'; print('Listening at $url'); } ================================================ FILE: packages/framework/example/hostname.dart ================================================ import 'dart:async'; import 'package:angel3_framework/angel3_framework.dart'; import 'package:angel3_framework/http.dart'; import 'package:logging/logging.dart'; Future apiConfigurer(Angel app) async { app.get('/', (req, res) => 'Hello, API!'); app.fallback((req, res) { return 'fallback on ${req.uri} (within the API)'; }); } Future frontendConfigurer(Angel app) async { app.fallback((req, res) => '(usually an index page would be shown here.)'); } void main() async { // Logging set up/boilerplate hierarchicalLoggingEnabled = true; //Logger.root.onRecord.listen(prettyLog); var app = Angel(logger: Logger('angel')); var http = AngelHttp(app); var multiHost = HostnameRouter.configure({ 'api.localhost:3000': apiConfigurer, 'localhost:3000': frontendConfigurer, }); app ..fallback(multiHost.handleRequest) ..fallback((req, res) { res.write('Uncaught hostname: ${req.hostname}'); }); app.errorHandler = (e, req, res) { print(e.message); print(e.stackTrace); return e.toJson(); }; await http.startServer('127.0.0.1', 3000); print('Listening at ${http.uri}'); print( 'See what happens when you visit http://localhost:3000 instead ' 'of http://127.0.0.1:3000. Then, try ' 'http://api.localhost:3000.', ); } ================================================ FILE: packages/framework/example/http2/body_parsing.dart ================================================ import 'dart:io'; import 'package:angel3_framework/angel3_framework.dart'; import 'package:angel3_framework/http.dart'; import 'package:angel3_framework/http2.dart'; import 'package:file/local.dart'; import 'package:logging/logging.dart'; void main() async { var app = Angel(); app.logger = Logger('angel') ..onRecord.listen((rec) { print(rec); if (rec.error != null) print(rec.error); if (rec.stackTrace != null) print(rec.stackTrace); }); var publicDir = Directory('example/public'); var indexHtml = const LocalFileSystem().file( publicDir.uri.resolve('body_parsing.html'), ); app.get('/', (req, res) => res.streamFile(indexHtml)); app.post('/', (req, res) => req.parseBody().then((_) => req.bodyAsMap)); var ctx = SecurityContext() ..useCertificateChain('dev.pem') ..usePrivateKey('dev.key', password: 'dartdart'); try { ctx.setAlpnProtocols(['h2'], true); } catch (e, st) { app.logger.severe( 'Cannot set ALPN protocol on server to `h2`. The server will only serve HTTP/1.x.', e, st, ); } var http1 = AngelHttp(app); var http2 = AngelHttp2(app, ctx); // HTTP/1.x requests will fallback to `AngelHttp` http2.onHttp1.listen(http1.handleRequest); var server = await http2.startServer('127.0.0.1', 3000); print('Listening at https://${server.address.address}:${server.port}'); } ================================================ FILE: packages/framework/example/http2/common.dart ================================================ import 'package:logging/logging.dart'; void dumpError(LogRecord rec) { print(rec); if (rec.error != null) print(rec.error); if (rec.stackTrace != null) print(rec.stackTrace); } ================================================ FILE: packages/framework/example/http2/dev.key ================================================ -----BEGIN ENCRYPTED PRIVATE KEY----- MIIE5DAcBgoqhkiG9w0BDAEBMA4ECL7L6rj6uEHGAgIIAASCBMLbucyfqAkgCbhP xNSHYllPMAv/dsIjtnsBwepCXPGkCBCuOAw/2FaCHjN9hBqL5V7fkrKeaemhm2YE ycPtlHJYPDf3kEkyMjdZ9rIY6kePGfQizs2uJPcXj4YPyQ4HsfVXpOicKfQrouf5 Mze9bGzeMN065q3iP4dYUMwHAyZYteXCsanQNHlqvsWli0W+H8St8fdsXefZhnv1 qVatKWdNdWQ9t5MuljgNU2Vv56sHKEYXI0yLxk2QUMk8KlJfnmt8foYUsnPUXHmc gIjLKwwVkpdololnEHSNu0cEOUPowjgJru+uMpn7vdNl7TPEQ9jbEgdNg4JwoYzU 0nao8WzjaSp7kzvZz0VFwKnk5AjstGvvuAWckADdq23QElbn/mF7AG1m/TBpYxzF gTt37UdndS/AcvVznWVVrRP5iTSIawdIwvqI4s7rqsoE0GCcak+RhchgAz2gWKkS oODUo0JL6pPVbJ3l4ebbaO6c99nDVc8dViPtc1EkStJEJ2O4kI4xgLSCr4Y9ahKn oAaoSkX7Xxq3aQm+BzqSpLjdGL8atsqR/YVOIHYIl3gThvP0NfZGx1xHyvO5mCdZ kHxSA7tKWxauZ3eQ2clbnzeRsl4El0WMHy/5K1ovene4v7sunmoXVtghBC8hK6eh zMO9orex2PNQ/VQC7HCvtytunOVx1lkSBoNo7hR70igg6rW9H7UyoAoBOwMpT1xa J6V62nqruTKOqFNfur7aHJGpHGtDb5/ickHeYCyPTvmGp67u4wChzKReeg02oECe d1E5FKAcIa8s9TVOB6Z+HvTRNQZu2PsI6TJnjQRowvY9DAHiWTlJZBBY/pko3hxX TsIeybpvRdEHpDWv86/iqtw1hv9CUxS/8ZTWUgBo+osShHW79FeDASr9FC4/Zn76 ZDERTgV4YWlW/klVWcG2lFo7jix+OPXAB+ZQavLhlN1xdWBcIz1AUWjAM4hdPylW HCX4PB9CQIPl2E7F+Y2p6nMcMWSJVBi5UIH7E9LfaBguXSzMmTk2Fw5p1aOQ6wfN goVAMVwi8ppAVs741PfHdZ295xMmK/1LCxz5DeAdD/tsA/SYfT753GotioDuC7im EyJ5JyvTr5I6RFFBuqt3NlUb3Hp16wP3B2x9DZiB6jxr0l341/NHgsyeBXkuIy9j ON2mvpBPCJhS8kgWo3G0UyyKnx64tcgpGuSvZhGwPz843B6AbYyE6pMRfSWRMkMS YZYa+VNKhR4ixdj07ocFZEWLVjCH7kxkE8JZXKt8jKYmkWd0lS1QVjgaKlO6lRa3 q6SPJkhW6pvqobvcqVNXwi1XuzpZeEbuh0B7OTekFTTxx5g9XeDl56M8SVQ1KEhT Q1t7H2Nba18WCB7cf+6PN0F0K0Jz1Kq7ZWaqEI/grX1m4RQuvNF5807sB/QKMO/Z Gz3NXvHg5xTJRd/567lxPGkor0cE7qD1EZfmJ2HrBYXQ91bhgA7LToBuMZo6ZRXH QfsanjbP4FPLMiGdQigLjj3A35L/f4sQOOVac/sRaFnm7pzcxsMvyVU/YtvGcjYE xaOOVnamg661Wo0wksXoDjeSz/JIyyKO3Gwp1FSm2wGLjjy/Ehmqcqy8rvHuf07w AUukhVtTNn4= -----END ENCRYPTED PRIVATE KEY----- ================================================ FILE: packages/framework/example/http2/dev.pem ================================================ -----BEGIN CERTIFICATE----- MIIDKTCCAhGgAwIBAgIJAOWmjTS+OnTEMA0GCSqGSIb3DQEBCwUAMBcxFTATBgNV BAMMDGludGVybWVkaWF0ZTAeFw0xNTA1MTgwOTAwNDBaFw0yMzA4MDQwOTAwNDBa MBQxEjAQBgNVBAMMCWxvY2FsaG9zdDCCASIwDQYJKoZIhvcNAQEBBQADggEPADCC AQoCggEBALlcwQJuzd+xH8QFgfJSn5tRlvhkldSX98cE7NiA602NBbnAVyUrkRXq Ni75lgt0kwjYfA9z674m8WSVbgpLPintPCla9CYky1TH0keIs8Rz6cGWHryWEHiu EDuljQynu2b3sAFuHu9nfWurbJwZnFakBKpdQ9m4EyOZCHC/jHYY7HacKSXg1Cki we2ca0BWDrcqy8kLy0dZ5oC6IZG8O8drAK8f3f44CRYw59D3sOKBrKXaabpvyEcb N7Wk2HDBVwHpUJo1reVwtbM8dhqQayYSD8oXnGpP3RQNu/e2rzlXRyq/BfcDY1JI 7TbC4t/7/N4EcPSpGsTcSOC9A7FpzvECAwEAAaN7MHkwCQYDVR0TBAIwADAsBglg hkgBhvhCAQ0EHxYdT3BlblNTTCBHZW5lcmF0ZWQgQ2VydGlmaWNhdGUwHQYDVR0O BBYEFCnwiEMMFZh7NhCr+qA8K0w4Q+AOMB8GA1UdIwQYMBaAFB0h1Evsaw2vfrmS YuoCTmC4EE6ZMA0GCSqGSIb3DQEBCwUAA4IBAQAcFmHMaXRxyoNaeOowQ6iQWoZd AUbvG7SHr7I6Pi2aqdqofsKWts7Ytm5WsS0M2nN+sW504houu0iCPeJJX8RQw2q4 CCcNOs9IXk+2uMzlpocHpv+yYoUiD5DxgWh7eghQMLyMpf8FX3Gy4VazeuXznHOM 4gE4L417xkDzYOzqVTp0FTyAPUv6G2euhNCD6TMru9REcRhYul+K9kocjA5tt2KG MH6y28LXbLyq4YJUxSUU9gY/xlnbbZS48KDqEcdYC9zjW9nQ0qS+XQuQuFIcwjJ5 V4kAUYxDu6FoTpyQjgsrmBbZlKNxH7Nj4NDlcdJhp/zeSKHqWa5hSWjjKIxp -----END CERTIFICATE----- -----BEGIN CERTIFICATE----- MIIDAjCCAeqgAwIBAgIJAOWmjTS+OnTDMA0GCSqGSIb3DQEBCwUAMBgxFjAUBgNV BAMMDXJvb3RhdXRob3JpdHkwHhcNMTUwNTE4MDkwMDQwWhcNMjMwODA0MDkwMDQw WjAXMRUwEwYDVQQDDAxpbnRlcm1lZGlhdGUwggEiMA0GCSqGSIb3DQEBAQUAA4IB DwAwggEKAoIBAQDSrAO1CoPvUllgLOzDm5nG0skDF7vh1DUgAIDVGz0ecD0JFbQx EF79pju/6MbtpTW2FYvRp11t/G7rGtX923ybOHY/1MNFQrdIvPlO1VV7IGKjoMwP DNeb0fIGjHoE9QxaDxR8NX8xQbItpsw+TUtRfc9SLkR+jaYJfVRoM21BOncZbSHE YKiZlEbpecB/+EtwVpgvl+8mPD5U07Fi4fp/lza3WXInXQPyiTVllIEJCt4PKmlu MocNaJOW38bysL7i0PzDpVZtOxLHOTaW68yF3FckIHNCaA7k1ABEEEegjFMmIao7 B9w7A0jvr4jZVvNmui5Djjn+oJxwEVVgyf8LAgMBAAGjUDBOMB0GA1UdDgQWBBQd IdRL7GsNr365kmLqAk5guBBOmTAfBgNVHSMEGDAWgBRk81s9d0ZbiZhh44KckwPb oTc0XzAMBgNVHRMEBTADAQH/MA0GCSqGSIb3DQEBCwUAA4IBAQBZQTK0plfdB5PC cC5icut4EmrByJa1RbU7ayuEE70e7hla6KVmVjVdCBGltI4jBYwfhKbRItHiAJ/8 x+XZKBG8DLPFuDb7lAa1ObhAYF7YThUFPQYaBhfzKcWrdmWDBFpvNv6E0Mm364dZ e7Yxmbe5S4agkYPoxEzgEYmcUk9jbjdR6eTbs8laG169ljrECXfEU9RiAcqz5iSX NLSewqB47hn3B9qgKcQn+PsgO2j7M+rfklhNgeGJeWmy7j6clSOuCsIjWHU0RLQ4 0W3SB/rpEAJ7fgQbYUPTIUNALSOWi/o1tDX2mXPRjBoxqAv7I+vYk1lZPmSzkyRh FKvRDxsW -----END CERTIFICATE----- -----BEGIN CERTIFICATE----- MIIDAzCCAeugAwIBAgIJAJ0MomS4Ck+8MA0GCSqGSIb3DQEBCwUAMBgxFjAUBgNV BAMMDXJvb3RhdXRob3JpdHkwHhcNMTUwNTE4MDkwMDQwWhcNMjMwODA0MDkwMDQw WjAYMRYwFAYDVQQDDA1yb290YXV0aG9yaXR5MIIBIjANBgkqhkiG9w0BAQEFAAOC AQ8AMIIBCgKCAQEAts1ijtBV92S2cOvpUMOSTp9c6A34nIGr0T5Nhz6XiqRVT+gv dQgmkdKJQjbvR60y6jzltYFsI2MpGVXY8h/oAL81D/k7PDB2aREgyBfTPAhBHyGw siR+2xYt5b/Zs99q5RdRqQNzNpLPJriIKvUsRyQWy1UiG2s7pRXQeA8qB0XtJdCj kFIi+G2bDsaffspGeDOCqt7t+yqvRXfSES0c/l7DIHaiMbbp4//ZNML3RNgAjPz2 hCezZ+wOYajOIyoSPK8IgICrhYFYxvgWxwbLDBEfC5B3jOQsySe10GoRAKZz1gBV DmgReu81tYJmdgkc9zknnQtIFdA0ex+GvZlfWQIDAQABo1AwTjAdBgNVHQ4EFgQU ZPNbPXdGW4mYYeOCnJMD26E3NF8wHwYDVR0jBBgwFoAUZPNbPXdGW4mYYeOCnJMD 26E3NF8wDAYDVR0TBAUwAwEB/zANBgkqhkiG9w0BAQsFAAOCAQEATzkZ97K777uZ lQcduNX3ey4IbCiEzFA2zO5Blj+ilfIwNbZXNOgm/lqNvVGDYs6J1apJJe30vL3X J+t2zsZWzzQzb9uIU37zYemt6m0fHrSrx/iy5lGNqt3HMfqEcOqSCOIK3PCTMz2/ uyGe1iw33PVeWsm1JUybQ9IrU/huJjbgOHU4wab+8SJCM49ipArp68Fr6j4lcEaE 4rfRg1ZsvxiOyUB3qPn6wyL/JB8kOJ+QCBe498376eaem8AEFk0kQRh6hDaWtq/k t6IIXQLjx+EBDVP/veK0UnVhKRP8YTOoV8ZiG1NcdlJmX/Uk7iAfevP7CkBfSN8W r6AL284qtw== -----END CERTIFICATE----- ================================================ FILE: packages/framework/example/http2/main.dart ================================================ import 'dart:io'; import 'package:angel3_framework/angel3_framework.dart'; import 'package:angel3_framework/http.dart'; import 'package:angel3_framework/http2.dart'; import 'package:logging/logging.dart'; import 'common.dart'; void main() async { var app = Angel() ..encoders.addAll({'gzip': gzip.encoder, 'deflate': zlib.encoder}); app.logger = Logger('angel')..onRecord.listen(dumpError); app.get('/', (req, res) => 'Hello HTTP/2!!!'); app.fallback( (req, res) => throw AngelHttpException.notFound( message: 'No file exists at ${req.uri}', ), ); var ctx = SecurityContext() ..useCertificateChain('dev.pem') ..usePrivateKey('dev.key', password: 'dartdart'); try { ctx.setAlpnProtocols(['h2'], true); } catch (e, st) { app.logger.severe( 'Cannot set ALPN protocol on server to `h2`. The server will only serve HTTP/1.x.', e, st, ); } var http1 = AngelHttp(app); var http2 = AngelHttp2(app, ctx); // HTTP/1.x requests will fallback to `AngelHttp` http2.onHttp1.listen(http1.handleRequest); await http2.startServer('127.0.0.1', 3000); print('Listening at ${http2.uri}'); } ================================================ FILE: packages/framework/example/http2/public/app.js ================================================ window.onload = function() { var $app = document.getElementById('app'); var $loading = document.getElementById('loading'); $app.removeChild($loading); var $button = document.createElement('button'); var $h1 = document.createElement('h1'); $app.appendChild($h1); $app.appendChild($button); $h1.textContent = '~Angel HTTP/2 server push~'; $button.textContent = 'Change color'; $button.onclick = function() { var color = Math.floor(Math.random() * 0xffffff); $h1.style.color = '#' + color.toString(16); }; $button.onclick(); window.setInterval($button.onclick, 2000); var rotation = 0; window.setInterval(function() { rotation += .6; $button.style.transform = 'rotate(' + rotation + 'deg)'; }, 10); }; ================================================ FILE: packages/framework/example/http2/public/body_parsing.html ================================================ Angel HTTP/2
================================================ FILE: packages/framework/example/http2/public/index.html ================================================ Angel HTTP/2
Loading...
================================================ FILE: packages/framework/example/http2/public/style.css ================================================ button { margin-top: 2em; } html, body { background-color: #000; } #app { text-align: center; } #app h1 { font-style: italic; text-decoration: underline; } #loading { color: red; } ================================================ FILE: packages/framework/example/http2/server_push.dart ================================================ import 'dart:io'; import 'package:angel3_framework/angel3_framework.dart'; import 'package:angel3_framework/http.dart'; import 'package:angel3_framework/http2.dart'; import 'package:file/local.dart'; import 'package:logging/logging.dart'; void main() async { var app = Angel(); app.logger = Logger('angel') ..onRecord.listen((rec) { print(rec); if (rec.error != null) print(rec.error); if (rec.stackTrace != null) print(rec.stackTrace); }); var publicDir = Directory('example/http2/public'); var indexHtml = const LocalFileSystem().file( publicDir.uri.resolve('index.html'), ); var styleCss = const LocalFileSystem().file( publicDir.uri.resolve('style.css'), ); var appJs = const LocalFileSystem().file(publicDir.uri.resolve('app.js')); // Send files when requested app ..get('/style.css', (req, res) => res.streamFile(styleCss)) ..get('/app.js', (req, res) => res.streamFile(appJs)); app.get('/', (req, res) async { // Regardless of whether we pushed other resources, let's still send /index.html. await res.streamFile(indexHtml); // If the client is HTTP/2 and supports server push, let's // send down /style.css and /app.js as well, to improve initial load time. if (res is Http2ResponseContext && res.canPush) { await res.push('/style.css').streamFile(styleCss); await res.push('/app.js').streamFile(appJs); } }); var ctx = SecurityContext() ..useCertificateChain('dev.pem') ..usePrivateKey('dev.key', password: 'dartdart'); try { ctx.setAlpnProtocols(['h2'], true); } catch (e, st) { app.logger.severe( 'Cannot set ALPN protocol on server to `h2`. The server will only serve HTTP/1.x.', e, st, ); } var http1 = AngelHttp(app); var http2 = AngelHttp2(app, ctx); // HTTP/1.x requests will fallback to `AngelHttp` http2.onHttp1.listen(http1.handleRequest); var server = await http2.startServer('127.0.0.1', 3000); print('Listening at https://${server.address.address}:${server.port}'); } ================================================ FILE: packages/framework/example/json.dart ================================================ import 'dart:async'; import 'dart:io'; import 'dart:isolate'; import 'package:angel3_framework/angel3_framework.dart'; import 'package:angel3_framework/http.dart'; void main() async { var x = 0; var c = Completer(); var exit = ReceivePort(); var isolates = []; exit.listen((_) { if (++x >= 50) { c.complete(); } }); for (var i = 1; i < Platform.numberOfProcessors; i++) { var isolate = await Isolate.spawn(serverMain, null); isolates.add(isolate); print('Spawned isolate #${i + 1}...'); isolate.addOnExitListener(exit.sendPort); } serverMain(null); print('Angel listening at http://localhost:3000'); await c.future; } void serverMain(_) async { var app = Angel(); var http = AngelHttp.custom( app, startShared, useZone: false, ); // Run a cluster app.get('/', (req, res) { return res.serialize({ 'foo': 'bar', 'one': [2, 'three'], 'bar': {'baz': 'quux'}, }); }); app.errorHandler = (e, req, res) { print(e.message); print(e.stackTrace); }; var server = await http.startServer('127.0.0.1', 3000); print('Listening at http://${server.address.address}:${server.port}'); } ================================================ FILE: packages/framework/example/main.dart ================================================ import 'package:angel3_container/mirrors.dart'; import 'package:angel3_framework/angel3_framework.dart'; import 'package:angel3_framework/http.dart'; import 'package:logging/logging.dart'; void main() async { // Logging set up/boilerplate //Logger.root.onRecord.listen(prettyLog); // Create our server. var app = Angel(logger: Logger('angel'), reflector: MirrorsReflector()); // Index route. Returns JSON. app.get('/', (req, res) => 'Welcome to Angel!'); // Accepts a URL like /greet/foo or /greet/bob. app.get('/greet/:name', (req, res) { var name = req.params['name']; res ..write('Hello, $name!') ..close(); }); // Pattern matching - only call this handler if the query value of `name` equals 'emoji'. app.get( '/greet', ioc((@Query('name', match: 'emoji') String name) => '😇🔥🔥🔥'), ); // Handle any other query value of `name`. app.get('/greet', ioc((@Query('name') String name) => 'Hello, $name!')); // Simple fallback to throw a 404 on unknown paths. app.fallback((req, res) { throw AngelHttpException.notFound( message: 'Unknown path: "${req.uri!.path}"', ); }); var http = AngelHttp(app); var server = await http.startServer('127.0.0.1', 3000); var url = 'http://${server.address.address}:${server.port}'; print('Listening at $url'); print('Visit these pages to see Angel in action:'); print('* $url/greet/bob'); print('* $url/greet/?name=emoji'); print('* $url/greet/?name=jack'); print('* $url/nonexistent_page'); } ================================================ FILE: packages/framework/example/map_service.dart ================================================ import 'package:angel3_container/mirrors.dart'; import 'package:angel3_framework/angel3_framework.dart'; import 'package:angel3_framework/http.dart'; import 'package:logging/logging.dart'; void main() async { // Logging set up/boilerplate Logger.root.onRecord.listen(print); // Create our server. var app = Angel(logger: Logger('angel'), reflector: MirrorsReflector()); // Create a RESTful service that manages an in-memory collection. app.use('/api/todos', MapService()); var http = AngelHttp(app); await http.startServer('127.0.0.1', 0); print('Listening at ${http.uri}'); } ================================================ FILE: packages/framework/example/status.dart ================================================ import 'package:angel3_framework/angel3_framework.dart'; import 'package:angel3_framework/http.dart'; void main() async { var app = Angel(); var http = AngelHttp(app); app.fallback((req, res) { res.statusCode = 304; }); await http.startServer('127.0.0.1', 3000); print('Listening at ${http.uri}'); } ================================================ FILE: packages/framework/example/view.dart ================================================ import 'package:angel3_container/mirrors.dart'; import 'package:angel3_framework/angel3_framework.dart'; import 'package:angel3_framework/http.dart'; void main() async { var app = Angel(reflector: MirrorsReflector()); app.viewGenerator = (name, [data]) async => 'View generator invoked with name $name and data: $data'; // Index route. Returns JSON. app.get('/', (req, res) => res.render('index', {'foo': 'bar'})); var http = AngelHttp(app); var server = await http.startServer('127.0.0.1', 3000); var url = 'http://${server.address.address}:${server.port}'; print('Listening at $url'); } ================================================ FILE: packages/framework/example/views/index.jl ================================================ Title

Hello!

================================================ FILE: packages/framework/lib/angel3_framework.dart ================================================ /// An easily-extensible web server framework in Dart. library; export 'package:angel3_http_exception/angel3_http_exception.dart'; export 'package:angel3_model/angel3_model.dart'; export 'package:angel3_route/angel3_route.dart'; export 'src/core/core.dart'; ================================================ FILE: packages/framework/lib/http.dart ================================================ export 'src/http/http.dart'; ================================================ FILE: packages/framework/lib/http2.dart ================================================ export 'src/http2/angel_http2.dart'; export 'src/http2/http2_request_context.dart'; export 'src/http2/http2_response_context.dart'; ================================================ FILE: packages/framework/lib/src/core/anonymous_service.dart ================================================ import 'dart:async'; import 'service.dart'; /// An easy helper class to create one-off services without having to create an entire class. /// /// Well-suited for testing. class AnonymousService extends Service { FutureOr> Function([Map?])? _index; FutureOr Function(Id, [Map?])? _read, _remove; FutureOr Function(Data, [Map?])? _create; FutureOr Function(Id, Data, [Map?])? _modify, _update; AnonymousService({ FutureOr> Function([Map? params])? index, FutureOr Function(Id id, [Map? params])? read, FutureOr Function(Data data, [Map? params])? create, FutureOr Function(Id id, Data data, [Map? params])? modify, FutureOr Function(Id id, Data data, [Map? params])? update, FutureOr Function(Id id, [Map? params])? remove, super.readData, }) { _index = index; _read = read; _create = create; _modify = modify; _update = update; _remove = remove; } @override Future> index([Map? params]) => Future.sync(() => _index != null ? _index!(params) : super.index(params)); @override Future read(Id id, [Map? params]) => Future.sync( () => _read != null ? _read!(id, params) : super.read(id, params), ); @override Future create(Data data, [Map? params]) => Future.sync( () => _create != null ? _create!(data, params) : super.create(data, params), ); @override Future modify(Id id, Data data, [Map? params]) => Future.sync( () => _modify != null ? _modify!(id, data, params) : super.modify(id, data, params), ); @override Future update(Id id, Data data, [Map? params]) => Future.sync( () => _update != null ? _update!(id, data, params) : super.update(id, data, params), ); @override Future remove(Id id, [Map? params]) => Future.sync( () => _remove != null ? _remove!(id, params) : super.remove(id, params), ); } ================================================ FILE: packages/framework/lib/src/core/controller.dart ================================================ library; import 'dart:async'; import 'package:angel3_container/angel3_container.dart'; import 'package:angel3_route/angel3_route.dart'; import 'package:meta/meta.dart'; import 'package:recase/recase.dart'; import '../core/core.dart'; /// Supports grouping routes with shared functionality. class Controller { Angel? _app; /// The [Angel] application powering this controller. Angel get app { if (_app == null) { throw ArgumentError("Angel is not instantiated."); } return _app!; } /// If `true` (default), this class will inject itself as a singleton into the [app]'s container when bootstrapped. final bool injectSingleton; /// Middleware to run before all handlers in this class. List middleware = []; /// A mapping of route paths to routes, produced from the [Expose] annotations on this class. Map routeMappings = {}; SymlinkRoute? _mountPoint; /// The route at which this controller is mounted on the server. SymlinkRoute? get mountPoint => _mountPoint; Controller({this.injectSingleton = true}); /// Applies routes, DI, and other configuration to an [app]. @mustCallSuper Future configureServer(Angel app) async { _app = app; if (injectSingleton != false) { if (!app.container.has(runtimeType)) { _app!.container.registerSingleton(this, as: runtimeType); } } var name = await applyRoutes(app, app.container.reflector); app.controllers[name] = this; //return null; } /// Applies the routes from this [Controller] to some [router]. Future applyRoutes( Router router, Reflector reflector, ) async { // Load global expose decl var classMirror = reflector.reflectClass(runtimeType)!; var exposeDecl = findExpose(reflector); if (exposeDecl == null) { throw Exception('All controllers must carry an @Expose() declaration.'); } var routable = Routable(); _mountPoint = router.mount(exposeDecl.path, routable); //_mountPoint = m; var typeMirror = reflector.reflectType(runtimeType); // Pre-reflect methods var instanceMirror = reflector.reflectInstance(this); final handlers = [...exposeDecl.middleware, ...middleware]; final routeBuilder = _routeBuilder( reflector, instanceMirror, routable, handlers, ); await configureRoutes(routable); classMirror.declarations.forEach(routeBuilder); // Return the name. var result = exposeDecl.as?.isNotEmpty == true ? exposeDecl.as : typeMirror!.name; return Future.value(result); } void Function(ReflectedDeclaration) _routeBuilder( Reflector reflector, ReflectedInstance? instanceMirror, Routable routable, Iterable handlers, ) { return (ReflectedDeclaration decl) { var methodName = decl.name; // Ignore built-in methods. if (methodName != 'toString' && methodName != 'noSuchMethod' && methodName != 'call' && methodName != 'equals' && methodName != '==') { var exposeDecl = decl.function!.annotations .map((m) => m.reflectee) .firstWhere((r) => r is Expose, orElse: () => null) as Expose?; if (exposeDecl == null) { // If this has a @noExpose, return null. if (decl.function!.annotations.any((m) => m.reflectee is NoExpose)) { return; } else { // Otherwise, create an @Expose. exposeDecl = Expose(''); } } var reflectedMethod = instanceMirror!.getField(methodName).reflectee as Function?; var middleware = [ ...handlers, ...exposeDecl.middleware, ]; var name = exposeDecl.as?.isNotEmpty == true ? exposeDecl.as : methodName; // Check if normal var method = decl.function!; if (method.parameters.length == 2 && method.parameters[0].type.reflectedType == RequestContext && method.parameters[1].type.reflectedType == ResponseContext) { // Create a regular route routeMappings[name ?? ''] = routable.addRoute( exposeDecl.method, exposeDecl.path, (RequestContext req, ResponseContext res) { var result = reflectedMethod!(req, res); return result is RequestHandler ? result(req, res) : result; }, middleware: middleware, ); return; } var injection = preInject(reflectedMethod!, reflector); if (exposeDecl.allowNull.isNotEmpty == true) { injection.optional.addAll(exposeDecl.allowNull); } // If there is no path, reverse-engineer one. var path = exposeDecl.path; var httpMethod = exposeDecl.method; if (path == '') { // Try to build a route path by finding all potential // path segments, and then joining them. var parts = []; // If the name starts with get/post/patch, etc., then that // should be the path. var methodMatch = _methods.firstMatch(method.name); if (methodMatch != null) { var rest = method.name.replaceAll(_methods, ''); var restPath = ReCase( rest.isEmpty ? 'index' : rest, ).snakeCase.replaceAll(_rgxMultipleUnderscores, '_'); httpMethod = methodMatch[1]!.toUpperCase(); if (['index', 'by_id'].contains(restPath)) { parts.add('/'); } else { parts.add(restPath); } } // If the name does NOT start with get/post/patch, etc. then // snake_case-ify the name, and add it to the list of segments. // If the name is index, though, add "/". else { if (method.name == 'index') { parts.add('/'); } else { parts.add( ReCase( method.name, ).snakeCase.replaceAll(_rgxMultipleUnderscores, '_'), ); } } // Try to infer String, int, or double. We called // preInject() earlier, so we can figure out the types // of required parameters, and add those to the path. for (var p in injection.required) { if (p is List && p.length == 2 && p[0] is String && p[1] is Type) { var name = p[0] as String; var type = p[1] as Type; if (type == String) { parts.add(':$name'); } else if (type == int) { parts.add('int:$name'); } else if (type == double) { parts.add('double:$name'); } } } path = parts.join('/'); if (!path.startsWith('/')) path = '/$path'; } routeMappings[name ?? ''] = routable.addRoute( httpMethod, path, handleContained(reflectedMethod, injection), middleware: middleware, ); } }; } /// Used to add additional routes or middlewares to the router from within /// a [Controller]. /// /// ```dart /// @override /// FutureOr configureRoutes(Routable routable) { /// routable.all('*', myMiddleware); /// } /// ``` FutureOr configureRoutes(Routable routable) {} static final RegExp _methods = RegExp(r'^(get|post|patch|delete)'); static final RegExp _rgxMultipleUnderscores = RegExp(r'__+'); /// Finds the [Expose] declaration for this class. /// /// If [concreteOnly] is `false`, then if there is no actual /// [Expose], one will be automatically created. Expose? findExpose(Reflector reflector, {bool concreteOnly = false}) { var existing = reflector .reflectClass(runtimeType)! .annotations .map((m) => m.reflectee) .firstWhere((r) => r is Expose, orElse: () => null) as Expose?; return existing ?? (concreteOnly ? null : Expose( ReCase(runtimeType.toString()).snakeCase .replaceAll('_controller', '') .replaceAll('_ctrl', '') .replaceAll(_rgxMultipleUnderscores, '_'), )); } } ================================================ FILE: packages/framework/lib/src/core/core.dart ================================================ export 'anonymous_service.dart'; export 'controller.dart'; export 'driver.dart'; export 'env.dart'; export 'hooked_service.dart'; export 'hostname_parser.dart'; export 'hostname_router.dart'; export 'map_service.dart'; export 'metadata.dart'; export 'request_context.dart'; export 'response_context.dart'; export 'routable.dart'; export 'server.dart'; export 'service.dart'; ================================================ FILE: packages/framework/lib/src/core/driver.dart ================================================ import 'dart:async'; import 'dart:convert'; import 'dart:io' show Cookie; import 'package:angel3_http_exception/angel3_http_exception.dart'; import 'package:angel3_route/angel3_route.dart'; import 'package:belatuk_combinator/belatuk_combinator.dart'; import 'package:stack_trace/stack_trace.dart'; import 'package:tuple/tuple.dart'; import 'core.dart'; /// Base driver class for Angel implementations. /// /// Powers both AngelHttp and AngelHttp2. abstract class Driver< Request, Response, Server extends Stream, RequestContextType extends RequestContext, ResponseContextType extends ResponseContext > { final Angel app; final bool useZone; bool _closed = false; StreamSubscription? _sub; //final log = Logger('Driver'); /// The function used to bind this instance to a server.. final Future Function(dynamic, int) serverGenerator; Driver(this.app, this.serverGenerator, {this.useZone = true}); /// The path at which this server is listening for requests. Uri get uri; /// The native server running this instance. Server? server; Future generateServer(Object? address, int port) => serverGenerator(address, port); /// Starts, and returns the server. Future startServer([Object? address, int port = 0]) { var host = address ?? '127.0.0.1'; return generateServer(host, port) .then((server) { this.server = server; return Future.wait(app.startupHooks.map(app.configure)).then((_) { app.optimizeForProduction(); _sub = this.server?.listen((request) { var stream = createResponseStreamFromRawRequest(request); stream.listen((response) { // TODO: To be revisited handleRawRequest(request, response); }); }); return Future.value(this.server!); }); }) .catchError((error) { app.logger.severe('Failed to create server', error); throw ArgumentError('[Driver]Failed to create server'); }); } /// Shuts down the underlying server. Future close() { if (_closed) { //return Future.value(_server); return Future.value(); } _closed = true; _sub?.cancel(); return app.close().then( (_) => Future.wait( app.shutdownHooks.map(app.configure), ).then((_) => Future.value()), ); /* return app.close().then((_) => Future.wait(app.shutdownHooks.map(app.configure)) .then((_) => Future.value(_server))); */ } Future createRequestContext( Request request, Response response, ); Future createResponseContext( Request request, Response response, [ RequestContextType? correspondingRequest, ]); void setHeader(Response response, String key, String value); void setContentLength(Response response, int length); void setChunkedEncoding(Response response, bool value); void setStatusCode(Response response, int value); void addCookies(Response response, Iterable cookies); void writeStringToResponse(Response response, String value); void writeToResponse(Response response, List data); Future closeResponse(Response response); Stream createResponseStreamFromRawRequest(Request request); /// Handles a single request. Future handleRawRequest(Request request, Response response) { app.logger.info('[Server] Called handleRawRequest'); return createRequestContext(request, response).then((req) { return createResponseContext(request, response, req).then((res) { Future handle() { var path = req.path; if (path == '/') path = ''; Tuple4< List, Map, ParseResult, MiddlewarePipeline > resolveTuple() { var r = app.optimizedRouter; var resolved = r.resolveAbsolute( path, method: req.method, strip: false, ); var pipeline = MiddlewarePipeline(resolved); return Tuple4( pipeline.handlers, resolved.fold>( {}, (out, r) => out..addAll(r.allParams), ), //(resolved.isEmpty ? null : resolved.first.parseResult), resolved.first.parseResult, pipeline, ); } var cacheKey = req.method + path; var tuple = app.environment.isProduction ? app.handlerCache.putIfAbsent(cacheKey, resolveTuple) : resolveTuple(); var line = tuple.item4 as MiddlewarePipeline; var it = MiddlewarePipelineIterator(line); req.params.addAll(tuple.item2); req.container ?..registerSingleton(req) ..registerSingleton(res) ..registerSingleton(tuple.item4) ..registerSingleton>(line) ..registerSingleton(it) ..registerSingleton>(it) ..registerSingleton?>(tuple.item3) ..registerSingleton(tuple.item3); if (!app.environment.isProduction) { req.container?.registerSingleton(Stopwatch()..start()); } return runPipeline( it, req, res, app, ).then((_) => sendResponse(request, response, req, res)); } if (useZone == false) { Future f; try { f = handle(); } catch (e, st) { f = Future.error(e, st); } return f .catchError((e, StackTrace st) { if (e is FormatException) { throw AngelHttpException.badRequest(message: e.message) ..stackTrace = st; } throw AngelHttpException( stackTrace: st, statusCode: (e is AngelHttpException) ? e.statusCode : 500, message: e?.toString() ?? '500 Internal Server Error', ); }, test: (e) => e is AngelHttpException) .catchError((ee, StackTrace st) { //print(">>>> Framework error: $ee"); //var t = (st).runtimeType; //print(">>>> StackTrace: $t"); AngelHttpException e; if (ee is AngelHttpException) { e = ee; } else { e = AngelHttpException( stackTrace: st, statusCode: 500, message: ee?.toString() ?? '500 Internal Server Error', ); } var error = e.error ?? e; var trace = Trace.from(StackTrace.current).terse; app.logger.severe(e.message, error, trace); return handleAngelHttpException( e, st, req, res, request, response, ); }); } else { var zoneSpec = ZoneSpecification( print: (self, parent, zone, line) { app.logger.info(line); }, handleUncaughtError: (self, parent, zone, error, stackTrace) { var trace = Trace.from(stackTrace).terse; // TODO: To be revisited Future(() { AngelHttpException e; if (error is FormatException) { e = AngelHttpException.badRequest(message: error.message); } else if (error is AngelHttpException) { e = error; } else { e = AngelHttpException( stackTrace: stackTrace, message: error.toString(), ); } app.logger.severe(e.message, error, trace); return handleAngelHttpException( e, trace, req, res, request, response, ); }).catchError((e, StackTrace st) { var trace = Trace.from(st).terse; closeResponse(response); // Ideally, we won't be in a position where an absolutely fatal error occurs, // but if so, we'll need to log it. app.logger.severe( 'Fatal error occurred when processing $uri.', e, trace, ); }); }, ); var zone = Zone.current.fork(specification: zoneSpec); req.container?.registerSingleton(zone); req.container?.registerSingleton(zoneSpec); // If a synchronous error is thrown, it's not caught by `zone.run`, // so use a try/catch, and recover when need be. try { return zone.run(handle); } catch (e, st) { zone.handleUncaughtError(e, st); return Future.value(); } } }); }); } /// Handles an [AngelHttpException]. Future handleAngelHttpException( AngelHttpException e, StackTrace st, RequestContext? req, ResponseContext? res, Request request, Response response, { bool ignoreFinalizers = false, }) { if (req == null || res == null) { try { app.logger.severe('500 Internal Server Error', e, st); setStatusCode(response, 500); writeStringToResponse(response, '500 Internal Server Error'); closeResponse(response); } catch (e) { app.logger.severe('500 Internal Server Error', e); } return Future.value(); } Future handleError; if (!res.isOpen) { handleError = Future.value(); } else { res.statusCode = e.statusCode; handleError = Future.sync(() => app.errorHandler(e, req, res)).then(( result, ) { return app.executeHandler(result, req, res).then((_) => res.close()); }); } return handleError.then( (_) => sendResponse( request, response, req, res, ignoreFinalizers: ignoreFinalizers == true, ), ); } /// Sends a response. Future sendResponse( Request request, Response response, RequestContext req, ResponseContext res, { bool ignoreFinalizers = false, }) { //app.logger.fine("Calling SendResponse"); Future cleanup(_) { if (!app.environment.isProduction && req.container!.has()) { var sw = req.container!.make(); app.logger.fine( "${res.statusCode} ${req.method} ${req.uri} (${sw.elapsedMilliseconds} ms)", ); } return req.close(); } // TODO: Debugging header /* for (var key in res.headers.keys) { app.logger.fine("Response header key: $key"); } */ if (!res.isBuffered) { //if (res.isOpen) { return res.close().then(cleanup); //} //return Future.value(); } //app.logger.fine("Calling finalizers"); var finalizers = ignoreFinalizers == true ? Future.value() : Future.forEach(app.responseFinalizers, (dynamic f) => f(req, res)); return finalizers.then((_) { //if (res.isOpen) res.close(); for (var key in res.headers.keys) { app.logger.fine("Response header key: $key"); setHeader(response, key, res.headers[key] ?? ''); } setContentLength(response, res.buffer?.length ?? 0); setChunkedEncoding(response, res.chunked ?? true); var outputBuffer = res.buffer?.toBytes() ?? []; if (res.encoders.isNotEmpty) { var allowedEncodings = req.headers ?.value('accept-encoding') ?.split(',') .map((s) => s.trim()) .where((s) => s.isNotEmpty) .map((str) { // Ignore quality specifications in accept-encoding // ex. gzip;q=0.8 if (!str.contains(';')) return str; return str.split(';')[0]; }); if (allowedEncodings != null) { for (var encodingName in allowedEncodings) { var key = encodingName; Converter, List>? encoder; if (res.encoders.containsKey(encodingName)) { encoder = res.encoders[encodingName]; } else if (encodingName == '*') { encoder = res.encoders[key = res.encoders.keys.first]; } if (encoder != null) { setHeader(response, 'content-encoding', key); outputBuffer = res.encoders[key]?.convert(outputBuffer) ?? []; setContentLength(response, outputBuffer.length); break; } } } } setStatusCode(response, res.statusCode); addCookies(response, res.cookies); writeToResponse(response, outputBuffer); return closeResponse(response).then(cleanup); }); } /// Runs a [MiddlewarePipeline]. static Future runPipeline< RequestContextType extends RequestContext, ResponseContextType extends ResponseContext >( MiddlewarePipelineIterator it, RequestContextType req, ResponseContextType res, Angel app, ) async { var broken = false; while (it.moveNext()) { var current = it.current.handlers.iterator; while (!broken && current.moveNext()) { var result = await app.executeHandler(current.current, req, res); if (result != true) { broken = true; break; } } } } } ================================================ FILE: packages/framework/lib/src/core/env.dart ================================================ import 'dart:io'; /// A constant instance of [AngelEnv]. const AngelEnvironment angelEnv = AngelEnvironment(); /// Queries the environment's `ANGEL_ENV` value. class AngelEnvironment { final String? _customValue; /// You can optionally provide a custom value, in order to override the system's /// value. const AngelEnvironment([this._customValue]); /// Returns the value of the `ANGEL_ENV` variable; defaults to `'development'`. String get value => (_customValue ?? Platform.environment['ANGEL_ENV'] ?? 'development') .toLowerCase(); /// Returns whether the [value] is `'development'`. bool get isDevelopment => value == 'development'; /// Returns whether the [value] is `'production'`. bool get isProduction => value == 'production'; /// Returns whether the [value] is `'staging'`. bool get isStaging => value == 'staging'; } ================================================ FILE: packages/framework/lib/src/core/hooked_service.dart ================================================ library; import 'dart:async'; import '../util.dart'; import 'metadata.dart'; import 'request_context.dart'; import 'response_context.dart'; import 'routable.dart'; import 'server.dart'; import 'service.dart'; /// Wraps another service in a service that broadcasts events on actions. class HookedService> extends Service { final List> _ctrl = []; /// Tbe service that is proxied by this hooked one. final T inner; final HookedServiceEventDispatcher beforeIndexed = HookedServiceEventDispatcher(); final HookedServiceEventDispatcher beforeRead = HookedServiceEventDispatcher(); final HookedServiceEventDispatcher beforeCreated = HookedServiceEventDispatcher(); final HookedServiceEventDispatcher beforeModified = HookedServiceEventDispatcher(); final HookedServiceEventDispatcher beforeUpdated = HookedServiceEventDispatcher(); final HookedServiceEventDispatcher beforeRemoved = HookedServiceEventDispatcher(); final HookedServiceEventDispatcher afterIndexed = HookedServiceEventDispatcher(); final HookedServiceEventDispatcher afterRead = HookedServiceEventDispatcher(); final HookedServiceEventDispatcher afterCreated = HookedServiceEventDispatcher(); final HookedServiceEventDispatcher afterModified = HookedServiceEventDispatcher(); final HookedServiceEventDispatcher afterUpdated = HookedServiceEventDispatcher(); final HookedServiceEventDispatcher afterRemoved = HookedServiceEventDispatcher(); HookedService(this.inner) { // Clone app instance if (inner.isAppActive) { app = inner.app; } } @override FutureOr Function(RequestContext, ResponseContext)? get readData => inner.readData; RequestContext? _getRequest(Map? params) { if (params == null) return null; return params['__requestctx'] as RequestContext?; } ResponseContext? _getResponse(Map? params) { if (params == null) return null; return params['__responsectx'] as ResponseContext?; } Map _stripReq(Map? params) { if (params == null) { return {}; } else { return params.keys .where((key) => key != '__requestctx' && key != '__responsectx') .fold>( {}, (map, key) => map..[key] = params[key], ); } } /// Closes any open [StreamController]s on this instance. **Internal use only**. @override Future close() { for (var c in _ctrl) { c.close(); } beforeIndexed._close(); beforeRead._close(); beforeCreated._close(); beforeModified._close(); beforeUpdated._close(); beforeRemoved._close(); afterIndexed._close(); afterRead._close(); afterCreated._close(); afterModified._close(); afterUpdated._close(); afterRemoved._close(); inner.close(); return Future.value(); } /// Adds hooks to this instance. void addHooks(Angel app) { var hooks = getAnnotation(inner, app.container.reflector); var before = >[]; var after = >[]; if (hooks != null) { before.addAll(hooks.before.cast()); after.addAll(hooks.after.cast()); } void applyListeners( Function fn, HookedServiceEventDispatcher dispatcher, [ bool? isAfter, ]) { var hooks = getAnnotation(fn, app.container.reflector); final listeners = >[ ...isAfter == true ? after : before, ]; if (hooks != null) { listeners.addAll((isAfter == true ? hooks.after : hooks.before).cast()); } listeners.forEach(dispatcher.listen); } applyListeners(inner.index, beforeIndexed); applyListeners(inner.read, beforeRead); applyListeners(inner.create, beforeCreated); applyListeners(inner.modify, beforeModified); applyListeners(inner.update, beforeUpdated); applyListeners(inner.remove, beforeRemoved); applyListeners(inner.index, afterIndexed, true); applyListeners(inner.read, afterRead, true); applyListeners(inner.create, afterCreated, true); applyListeners(inner.modify, afterModified, true); applyListeners(inner.update, afterUpdated, true); applyListeners(inner.remove, afterRemoved, true); } @override List get bootstrappers => List.from(super.bootstrappers) ..add((RequestContext req, ResponseContext res) { req.serviceParams ..['__requestctx'] = req ..['__responsectx'] = res; return true; }); @override void addRoutes([Service? service]) { super.addRoutes(service ?? inner); } /// Runs the [listener] before every service method specified. void before( Iterable eventNames, HookedServiceEventListener listener, ) { eventNames .map((name) { switch (name) { case HookedServiceEvent.indexed: return beforeIndexed; case HookedServiceEvent.read: return beforeRead; case HookedServiceEvent.created: return beforeCreated; case HookedServiceEvent.modified: return beforeModified; case HookedServiceEvent.updated: return beforeUpdated; case HookedServiceEvent.removed: return beforeRemoved; default: throw ArgumentError('Invalid service method: $name'); } }) .forEach( (HookedServiceEventDispatcher dispatcher) => dispatcher.listen(listener), ); } /// Runs the [listener] after every service method specified. void after( Iterable eventNames, HookedServiceEventListener listener, ) { eventNames .map((name) { switch (name) { case HookedServiceEvent.indexed: return afterIndexed; case HookedServiceEvent.read: return afterRead; case HookedServiceEvent.created: return afterCreated; case HookedServiceEvent.modified: return afterModified; case HookedServiceEvent.updated: return afterUpdated; case HookedServiceEvent.removed: return afterRemoved; default: throw ArgumentError('Invalid service method: $name'); } }) .forEach( (HookedServiceEventDispatcher dispatcher) => dispatcher.listen(listener), ); } /// Runs the [listener] before every service method. void beforeAll(HookedServiceEventListener listener) { beforeIndexed.listen(listener); beforeRead.listen(listener); beforeCreated.listen(listener); beforeModified.listen(listener); beforeUpdated.listen(listener); beforeRemoved.listen(listener); } /// Runs the [listener] after every service method. void afterAll(HookedServiceEventListener listener) { afterIndexed.listen(listener); afterRead.listen(listener); afterCreated.listen(listener); afterModified.listen(listener); afterUpdated.listen(listener); afterRemoved.listen(listener); } /// Returns a [Stream] of all events fired before every service method. /// /// *NOTE*: Only use this if you do not plan to modify events. There is no guarantee /// that events coming out of this [Stream] will see changes you make within the [Stream] /// callback. Stream> beforeAllStream() { var ctrl = StreamController>(); _ctrl.add(ctrl); before(HookedServiceEvent.all, ctrl.add); return ctrl.stream; } /// Returns a [Stream] of all events fired after every service method. /// /// *NOTE*: Only use this if you do not plan to modify events. There is no guarantee /// that events coming out of this [Stream] will see changes you make within the [Stream] /// callback. Stream> afterAllStream() { var ctrl = StreamController>(); _ctrl.add(ctrl); before(HookedServiceEvent.all, ctrl.add); return ctrl.stream; } /// Returns a [Stream] of all events fired before every service method specified. /// /// *NOTE*: Only use this if you do not plan to modify events. There is no guarantee /// that events coming out of this [Stream] will see changes you make within the [Stream] /// callback. Stream> beforeStream( Iterable eventNames, ) { var ctrl = StreamController>(); _ctrl.add(ctrl); before(eventNames, ctrl.add); return ctrl.stream; } /// Returns a [Stream] of all events fired AFTER every service method specified. /// /// *NOTE*: Only use this if you do not plan to modify events. There is no guarantee /// that events coming out of this [Stream] will see changes you make within the [Stream] /// callback. Stream> afterStream( Iterable eventNames, ) { var ctrl = StreamController>(); _ctrl.add(ctrl); after(eventNames, ctrl.add); return ctrl.stream; } /// Runs the [listener] before [create], [modify] and [update]. void beforeModify(HookedServiceEventListener listener) { beforeCreated.listen(listener); beforeModified.listen(listener); beforeUpdated.listen(listener); } @override Future> index([Map? params]) { var localParams = _stripReq(params); return beforeIndexed ._emit( HookedServiceEvent( false, _getRequest(params), _getResponse(params), inner, HookedServiceEvent.indexed, params: localParams, ), ) .then((before) { if (before._canceled) { return afterIndexed ._emit( HookedServiceEvent( true, _getRequest(params), _getResponse(params), inner, HookedServiceEvent.indexed, params: localParams, result: before.result, ), ) .then((after) => after.result as List); } return inner.index(localParams).then((result) { return afterIndexed ._emit( HookedServiceEvent( true, _getRequest(params), _getResponse(params), inner, HookedServiceEvent.indexed, params: localParams, result: result, ), ) .then((after) => after.result as List); }); }); } @override Future read(Id id, [Map? params]) { var localParams = _stripReq(params); return beforeRead ._emit( HookedServiceEvent( false, _getRequest(params), _getResponse(params), inner, HookedServiceEvent.read, id: id, params: localParams, ), ) .then((before) { if (before._canceled) { return afterRead ._emit( HookedServiceEvent( true, _getRequest(params), _getResponse(params), inner, HookedServiceEvent.read, id: id, params: localParams, result: before.result, ), ) .then((after) => after.result as Data); } return inner.read(id, localParams).then((result) { return afterRead ._emit( HookedServiceEvent( true, _getRequest(params), _getResponse(params), inner, HookedServiceEvent.read, id: id, params: localParams, result: result, ), ) .then((after) => after.result as Data); }); }); } @override Future create(Data data, [Map? params]) { var localParams = _stripReq(params); return beforeCreated ._emit( HookedServiceEvent( false, _getRequest(params), _getResponse(params), inner, HookedServiceEvent.created, data: data, params: localParams, ), ) .then((before) { if (before._canceled) { return afterCreated ._emit( HookedServiceEvent( true, _getRequest(params), _getResponse(params), inner, HookedServiceEvent.created, data: before.data, params: localParams, result: before.result, ), ) .then((after) => after.result as Data); } return inner.create(before.data as Data, localParams).then((result) { return afterCreated ._emit( HookedServiceEvent( true, _getRequest(params), _getResponse(params), inner, HookedServiceEvent.created, data: before.data, params: localParams, result: result, ), ) .then((after) => after.result as Data); }); }); } @override Future modify(Id id, Data data, [Map? params]) { var localParams = _stripReq(params); return beforeModified ._emit( HookedServiceEvent( false, _getRequest(params), _getResponse(params), inner, HookedServiceEvent.modified, id: id, data: data, params: localParams, ), ) .then((before) { if (before._canceled) { return afterModified ._emit( HookedServiceEvent( true, _getRequest(params), _getResponse(params), inner, HookedServiceEvent.modified, id: id, data: before.data, params: localParams, result: before.result, ), ) .then((after) => after.result as Data); } return inner.modify(id, before.data as Data, localParams).then(( result, ) { return afterModified ._emit( HookedServiceEvent( true, _getRequest(params), _getResponse(params), inner, HookedServiceEvent.created, id: id, data: before.data, params: localParams, result: result, ), ) .then((after) => after.result as Data); }); }); } @override Future update(Id id, Data data, [Map? params]) { var localParams = _stripReq(params); return beforeUpdated ._emit( HookedServiceEvent( false, _getRequest(params), _getResponse(params), inner, HookedServiceEvent.updated, id: id, data: data, params: localParams, ), ) .then((before) { if (before._canceled) { return afterUpdated ._emit( HookedServiceEvent( true, _getRequest(params), _getResponse(params), inner, HookedServiceEvent.updated, id: id, data: before.data, params: localParams, result: before.result, ), ) .then((after) => after.result as Data); } return inner.update(id, before.data as Data, localParams).then(( result, ) { return afterUpdated ._emit( HookedServiceEvent( true, _getRequest(params), _getResponse(params), inner, HookedServiceEvent.updated, id: id, data: before.data, params: localParams, result: result, ), ) .then((after) => after.result as Data); }); }); } @override Future remove(Id id, [Map? params]) { var localParams = _stripReq(params); return beforeRemoved ._emit( HookedServiceEvent( false, _getRequest(params), _getResponse(params), inner, HookedServiceEvent.removed, id: id, params: localParams, ), ) .then((before) { if (before._canceled) { return afterRemoved ._emit( HookedServiceEvent( true, _getRequest(params), _getResponse(params), inner, HookedServiceEvent.removed, id: id, params: localParams, result: before.result, ), ) .then((after) => after.result) as Data; } return inner.remove(id, localParams).then((result) { return afterRemoved ._emit( HookedServiceEvent( true, _getRequest(params), _getResponse(params), inner, HookedServiceEvent.removed, id: id, params: localParams, result: result, ), ) .then((after) => after.result as Data); }); }); } /// Fires an `after` event. This will not be propagated to clients, /// but will be broadcasted to WebSockets, etc. Future> fire( String eventName, result, [ HookedServiceEventListener? callback, ]) { HookedServiceEventDispatcher dispatcher; switch (eventName) { case HookedServiceEvent.indexed: dispatcher = afterIndexed; break; case HookedServiceEvent.read: dispatcher = afterRead; break; case HookedServiceEvent.created: dispatcher = afterCreated; break; case HookedServiceEvent.modified: dispatcher = afterModified; break; case HookedServiceEvent.updated: dispatcher = afterUpdated; break; case HookedServiceEvent.removed: dispatcher = afterRemoved; break; default: throw ArgumentError("Invalid service event name: '$eventName'"); } var ev = HookedServiceEvent( true, null, null, inner, eventName, ); return fireEvent(dispatcher, ev, callback); } /// Sends an arbitrary event down the hook chain. Future> fireEvent( HookedServiceEventDispatcher dispatcher, HookedServiceEvent event, [ HookedServiceEventListener? callback, ]) { Future? f; if (callback != null && event._canceled != true) { f = Future.sync(() => callback(event)); } f ??= Future.value(); return f.then((_) => dispatcher._emit(event)); } } /// Fired when a hooked service is invoked. class HookedServiceEvent> { static const String indexed = 'indexed'; static const String read = 'read'; static const String created = 'created'; static const String modified = 'modified'; static const String updated = 'updated'; static const String removed = 'removed'; static const List all = [ indexed, read, created, modified, updated, removed, ]; /// Use this to end processing of an event. void cancel([Object? result]) { _canceled = true; this.result = result ?? this.result; } /// Resolves a service from the application. /// /// Shorthand for `e.service.app.service(...)`. Service? getService(Pattern path) => service.app.findService(path); bool _canceled = false; final String _eventName; Id? _id; final bool _isAfter; Data? data; Map? _params; final RequestContext? _request; final ResponseContext? _response; dynamic result; String get eventName => _eventName; Id? get id => _id; bool get isAfter => _isAfter == true; bool get isBefore => !isAfter; Map get params => _params ?? {}; RequestContext? get request => _request; ResponseContext? get response => _response; /// The inner service whose method was hooked. T service; HookedServiceEvent( this._isAfter, this._request, this._response, this.service, this._eventName, { Id? id, this.data, Map? params, this.result, }) { //_data = data; _id = id; _params = params ?? {}; } } /// Triggered on a hooked service event. typedef HookedServiceEventListener> = FutureOr Function(HookedServiceEvent event); /// Can be listened to, but events may be canceled. class HookedServiceEventDispatcher> { final List>> _ctrl = []; final List> listeners = []; void _close() { for (var c in _ctrl) { c.close(); } listeners.clear(); } /// Fires an event, and returns it once it is either canceled, or all listeners have run. Future> _emit( HookedServiceEvent event, ) { if (event._canceled == true || listeners.isEmpty) { return Future.value(event); } var f = Future>.value(event); for (var listener in listeners) { f = f.then((event) { if (event._canceled) return event; return Future.sync(() => listener(event)).then((_) => event); }); } return f; } /// Returns a [Stream] containing all events fired by this dispatcher. /// /// *NOTE*: Callbacks on the returned [Stream] cannot be guaranteed to run before other [listeners]. /// Use this only if you need a read-only stream of events. Stream> asStream() { var ctrl = StreamController>(); _ctrl.add(ctrl); listen(ctrl.add); return ctrl.stream; } /// Registers the listener to be called whenever an event is triggered. void listen(HookedServiceEventListener listener) { listeners.add(listener); } } ================================================ FILE: packages/framework/lib/src/core/hostname_parser.dart ================================================ import 'dart:collection'; import 'package:string_scanner/string_scanner.dart'; /// Parses a string into a [RegExp] that is matched against hostnames. class HostnameSyntaxParser { final SpanScanner _scanner; final _safe = RegExp(r'[0-9a-zA-Z-_:]+'); HostnameSyntaxParser(String hostname) : _scanner = SpanScanner(hostname, sourceUrl: hostname); FormatException _formatExc(String message) { var span = _scanner.lastSpan ?? _scanner.emptySpan; return FormatException( '${span.start.toolString}: $message\n${span.highlight(color: true)}', ); } RegExp parse() { var b = StringBuffer(); var parts = Queue(); while (!_scanner.isDone) { if (_scanner.scan('|')) { if (parts.isEmpty) { throw _formatExc('No hostname parts found before "|".'); } else { var next = _parseHostnamePart(); if (next.isEmpty) { throw _formatExc('No hostname parts found after "|".'); } else { var prev = parts.removeLast(); parts.addLast('(($prev)|($next))'); } } } else { var part = _parseHostnamePart(); if (part.isNotEmpty) { if (_scanner.scan('.')) { var subPart = _parseHostnamePart(shouldThrow: false); while (subPart.isNotEmpty) { part += '\\.$subPart'; if (_scanner.scan('.')) { subPart = _parseHostnamePart(shouldThrow: false); } else { break; } } } parts.add(part); } } } while (parts.isNotEmpty) { b.write(parts.removeFirst()); } if (b.isEmpty) { throw _formatExc('Invalid or empty hostname.'); } else { return RegExp('^$b\$', caseSensitive: false); } } String _parseHostnamePart({bool shouldThrow = true}) { if (_scanner.scan('*.')) { return r'([^$.]+\.)?'; } else if (_scanner.scan('*')) { return r'[^$]*'; } else if (_scanner.scan('+')) { return r'[^$]+'; } else if (_scanner.scan(_safe)) { return _scanner.lastMatch?[0] ?? ''; } else if (!_scanner.isDone && shouldThrow) { var s = String.fromCharCode(_scanner.peekChar()!); throw _formatExc('Unexpected character "$s".'); } else { return ''; } } } ================================================ FILE: packages/framework/lib/src/core/hostname_router.dart ================================================ import 'dart:async'; import 'package:angel3_container/angel3_container.dart'; import 'package:angel3_route/angel3_route.dart'; import 'package:logging/logging.dart'; import 'env.dart'; import 'hostname_parser.dart'; import 'request_context.dart'; import 'response_context.dart'; import 'routable.dart'; import 'server.dart'; /// A utility that allows requests to be handled based on their /// origin's hostname. /// /// For example, an application could handle example.com and api.example.com /// separately. /// /// The provided patterns can be any `Pattern`. If a `String` is provided, a simple /// grammar (see [HostnameSyntaxParser]) is used to create [RegExp]. /// /// For example: /// * `example.com` -> `/example\.com/` /// * `*.example.com` -> `/([^$.]\.)?example\.com/` /// * `example.*` -> `/example\./[^$]*` /// * `example.+` -> `/example\./[^$]+` class HostnameRouter { final Map _apps = {}; final Map Function()> _creators = {}; final List _patterns = []; HostnameRouter({ Map apps = const {}, Map Function()> creators = const {}, }) { Map parseMap(Map map) { return map.map((p, c) { Pattern pp; if (p is String) { pp = HostnameSyntaxParser(p).parse(); } else { pp = p; } return MapEntry(pp, c); }); } apps = parseMap(apps); creators = parseMap(creators); var patterns = apps.keys.followedBy(creators.keys).toSet().toList(); _apps.addAll(apps); _creators.addAll(creators); _patterns.addAll(patterns); // print(_creators); } factory HostnameRouter.configure( Map Function(Angel)> configurers, { Reflector reflector = const EmptyReflector(), AngelEnvironment environment = angelEnv, Logger? logger, bool allowMethodOverrides = true, FutureOr Function(dynamic)? serializer, ViewGenerator? viewGenerator, }) { var creators = configurers.map((p, c) { return MapEntry(p, () async { var app = Angel( reflector: reflector, environment: environment, logger: logger, allowMethodOverrides: allowMethodOverrides, serializer: serializer, viewGenerator: viewGenerator, ); await app.configure(c); return app; }); }); return HostnameRouter(creators: creators); } /// Attempts to handle a request, according to its hostname. /// /// If none is matched, then `true` is returned. /// Also returns `true` if all of the sub-app's handlers returned /// `true`. Future handleRequest(RequestContext req, ResponseContext res) async { for (var pattern in _patterns) { // print('${req.hostname} vs $_creators'); if (pattern.allMatches(req.hostname).isNotEmpty) { // Resolve the entire pipeline within the context of the selected app. var app = _apps[pattern] ??= (await _creators[pattern]!()); // print('App for ${req.hostname} = $app from $pattern'); // app.dumpTree(); var r = app.optimizedRouter; var resolved = r.resolveAbsolute(req.path, method: req.method); var pipeline = MiddlewarePipeline(resolved); // print('Pipeline: $pipeline'); for (var handler in pipeline.handlers) { // print(handler); // Avoid stack overflow. if (handler == handleRequest) { continue; } else if (!await app.executeHandler(handler, req, res)) { // print('$handler TERMINATED'); return false; } else { // print('$handler CONTINUED'); } } } } // Otherwise, return true. return true; } } ================================================ FILE: packages/framework/lib/src/core/injection.dart ================================================ part of 'request_context.dart'; const List _primitiveTypes = [String, int, num, double, Null]; /// Shortcut for calling [preInject], and then [handleContained]. /// /// Use this to instantly create a request handler for a DI-enabled method. /// /// Calling [ioc] also auto-serializes the result of a [handler]. RequestHandler ioc(Function handler, {Iterable optional = const []}) { return (req, res) { RequestHandler? contained; if (req.app?.container != null) { var injection = preInject(handler, req.app!.container.reflector); //if (injection != null) { injection.optional.addAll(optional); contained = handleContained(handler, injection); //} } return req.app!.executeHandler(contained, req, res); }; } Future resolveInjection( Object requirement, InjectionRequest injection, RequestContext req, ResponseContext res, bool throwOnUnresolved, [ Container? container, ]) async { dynamic propFromApp; container ??= req.container ?? res.app!.container; if (requirement == RequestContext) { return req; } else if (requirement == ResponseContext) { return res; } else if (requirement is String && injection.parameters.containsKey(requirement)) { var param = injection.parameters[requirement]!; var value = param.getValue(req); if (value == null && param.required != false) throw param.error as Object; return value; } else if (requirement is String) { if (req.container!.hasNamed(requirement)) { return req.container!.findByName(requirement); } if (req.params.containsKey(requirement)) { return req.params[requirement]; } else if ((propFromApp = req.app!.findProperty(requirement)) != null) { return propFromApp; } else if (injection.optional.contains(requirement)) { return null; } else if (throwOnUnresolved) { throw ArgumentError( "Cannot resolve parameter '$requirement' within handler.", ); } } else if (requirement is List && requirement.length == 2 && requirement.first is String && requirement.last is Type) { var key = requirement.first; var type = requirement.last; if (req.params.containsKey(key) || req.app!.configuration.containsKey(key) || _primitiveTypes.contains(type)) { return await resolveInjection( key, injection, req, res, throwOnUnresolved, container, ); } else { return await resolveInjection( type, injection, req, res, throwOnUnresolved, container, ); } } else if (requirement is Type && requirement != dynamic) { try { var futureType = container.reflector.reflectFutureOf(requirement); if (container.has(futureType.reflectedType)) { return await container.make(futureType.reflectedType); } } on UnsupportedError { // Ignore. } return await container.make(requirement); } else if (throwOnUnresolved) { throw ArgumentError( '$requirement cannot be injected into a request handler.', ); } } /// Checks if an [InjectionRequest] can be sufficiently executed within the current request/response context. bool suitableForInjection( RequestContext req, ResponseContext res, InjectionRequest injection, ) { return injection.parameters.values.any((p) { if (p.match == null) return false; var value = p.getValue(req); return value == p.match; }); } /// Handles a request with a DI-enabled handler. RequestHandler handleContained( Function handler, InjectionRequest injection, [ Container? container, ]) { return (RequestContext req, ResponseContext res) async { if (injection.parameters.isNotEmpty && injection.parameters.values.any((p) => p.match != null) && !suitableForInjection(req, res, injection)) { return Future.value(true); } var args = []; var named = {}; for (var r in injection.required) { args.add(await resolveInjection(r, injection, req, res, true, container)); } for (var entry in injection.named.entries) { var name = Symbol(entry.key); named[name] = await resolveInjection( [entry.key, entry.value], injection, req, res, false, container, ); } return Function.apply(handler, args, named); }; } /// Contains a list of the data required for a DI-enabled method to run. /// /// This improves performance by removing the necessity to reflect a method /// every time it is requested. /// /// Regular request handlers can also skip DI entirely, lowering response time /// and memory use. class InjectionRequest { /// Optional, typed data that can be passed to a DI-enabled method. final Map named; /// A list of the arguments required for a DI-enabled method to run. final List required; /// A list of the arguments that can be null in a DI-enabled method. final List optional; /// Extended parameter definitions. final Map parameters; const InjectionRequest.constant({ this.named = const {}, this.required = const [], this.optional = const [], this.parameters = const {}, }); InjectionRequest() : named = {}, required = [], optional = [], parameters = {}; } /// Predetermines what needs to be injected for a handler to run. InjectionRequest preInject(Function handler, Reflector reflector) { var injection = InjectionRequest(); var closureMirror = reflector.reflectFunction(handler)!; if (closureMirror.parameters.isEmpty) return injection; // Load parameters for (var parameter in closureMirror.parameters) { var name = parameter.name; var type = parameter.type.reflectedType; var p = parameter.annotations .firstWhereOrNull( (m) => m.type.isAssignableTo(reflector.reflectType(Parameter)), ) ?.reflectee as Parameter?; //print(p); if (p != null) { injection.parameters[name] = Parameter( cookie: p.cookie, header: p.header, query: p.query, session: p.session, match: p.match, defaultValue: p.defaultValue, required: parameter.isNamed ? false : p.required != false, ); } if (!parameter.isNamed) { if (!parameter.isRequired) injection.optional.add(name); if (type == RequestContext || type == ResponseContext) { injection.required.add(type); } else if (name == 'req') { injection.required.add(RequestContext); } else if (name == 'res') { injection.required.add(ResponseContext); } else if (type == dynamic) { injection.required.add(name); } else { injection.required.add([name, type]); } } else { injection.named[name] = type; } } return injection; } ================================================ FILE: packages/framework/lib/src/core/map_service.dart ================================================ import 'dart:async'; import 'package:angel3_http_exception/angel3_http_exception.dart'; import 'service.dart'; /// A basic service that manages an in-memory list of maps. class MapService extends Service> { /// If set to `true`, clients can remove all items by passing a `null` `id` to `remove`. /// /// `false` by default. final bool allowRemoveAll; /// If set to `true`, parameters in `req.query` are applied to the database query. final bool allowQuery; /// If set to `true` (default), then the service will manage an `id` string and `createdAt` and `updatedAt` fields. final bool autoIdAndDateFields; /// If set to `true` (default), then the keys `created_at` and `updated_at` will automatically be snake_cased. final bool autoSnakeCaseNames; final List> items = []; MapService({ this.allowRemoveAll = false, this.allowQuery = true, this.autoIdAndDateFields = true, this.autoSnakeCaseNames = true, }) : super(); String get createdAtKey => autoSnakeCaseNames == false ? 'createdAt' : 'created_at'; String get updatedAtKey => autoSnakeCaseNames == false ? 'updatedAt' : 'updated_at'; bool Function(Map) _matchesId(Object? id) { return (Map item) { if (item['id'] == null) { return false; } else if (autoIdAndDateFields != false) { return item['id'] == id.toString(); } else { return item['id'] == id; } }; } @override Future>> index([Map? params]) { if (allowQuery == false || params == null || params['query'] is! Map) { return Future.value(items); } else { var query = params['query'] as Map?; return Future.value( items.where((item) { for (var key in query!.keys) { if (!item.containsKey(key)) { return false; } else if (item[key] != query[key]) { return false; } } return true; }).toList(), ); } } @override Future> read( String? id, [ Map? params, ]) { return Future.value( items.firstWhere( _matchesId(id), orElse: (() => throw AngelHttpException.notFound( message: 'No record found for ID $id', )), ), ); } @override Future> create( Map data, [ Map? params, ]) { var now = DateTime.now().toIso8601String(); var result = Map.from(data); if (autoIdAndDateFields == true) { result ..['id'] = items.length.toString() ..[autoSnakeCaseNames == false ? 'createdAt' : 'created_at'] = now ..[autoSnakeCaseNames == false ? 'updatedAt' : 'updated_at'] = now; } items.add(result); return Future.value(result); } @override Future> modify( String? id, Map data, [ Map? params, ]) { //if (data is! Map) { // throw AngelHttpException.badRequest( // message: // 'MapService does not support `modify` with ${data.runtimeType}.'); //} if (!items.any(_matchesId(id))) return create(data, params); return read(id).then((item) { var idx = items.indexOf(item); if (idx < 0) return create(data, params); var result = Map.from(item)..addAll(data); if (autoIdAndDateFields == true) { result[autoSnakeCaseNames == false ? 'updatedAt' : 'updated_at'] = DateTime.now().toIso8601String(); } return Future.value(items[idx] = result); }); } @override Future> update( String? id, Map data, [ Map? params, ]) { //if (data is! Map) { // throw AngelHttpException.badRequest( // message: // 'MapService does not support `update` with ${data.runtimeType}.'); //} if (!items.any(_matchesId(id))) return create(data, params); return read(id).then((old) { if (!items.remove(old)) { throw AngelHttpException.notFound( message: 'No record found for ID $id', ); } var result = Map.from(data); if (autoIdAndDateFields == true) { result ..['id'] = id?.toString() ..[autoSnakeCaseNames == false ? 'createdAt' : 'created_at'] = old[autoSnakeCaseNames == false ? 'createdAt' : 'created_at'] ..[autoSnakeCaseNames == false ? 'updatedAt' : 'updated_at'] = DateTime.now().toIso8601String(); } items.add(result); return Future.value(result); }); } @override Future> remove( String? id, [ Map? params, ]) { if (id == null || id == 'null') { // Remove everything... if (!(allowRemoveAll == true || params?.containsKey('provider') != true)) { throw AngelHttpException.forbidden( message: 'Clients are not allowed to delete all items.', ); } else { items.clear(); return Future.value({}); } } return read(id, params).then((result) { if (items.remove(result)) { return result; } else { throw AngelHttpException.notFound( message: 'No record found for ID $id', ); } }); } } ================================================ FILE: packages/framework/lib/src/core/metadata.dart ================================================ library; import 'package:angel3_http_exception/angel3_http_exception.dart'; import 'hooked_service.dart' show HookedServiceEventListener; import 'request_context.dart'; import 'routable.dart'; /// Annotation to map middleware onto a handler. class Middleware { final Iterable handlers; const Middleware(this.handlers); } /// Attaches hooks to a [HookedService]. class Hooks { final List before; final List after; const Hooks({this.before = const [], this.after = const []}); } /// Specifies to NOT expose a method to the Internet. class NoExpose { const NoExpose(); } const NoExpose noExpose = NoExpose(); /// Exposes a [Controller] or a [Controller] method to the Internet. /// Example: /// /// ```dart /// @Expose('/elements') /// class ElementController extends Controller { /// /// @Expose('/') /// List getList() => someComputationHere(); /// /// @Expose('/int:elementId') /// getElement(int elementId) => someOtherComputation(); /// /// } /// ``` class Expose { final String method; final String path; final Iterable middleware; final String? as; final List allowNull; static const Expose get = Expose('', method: 'GET'), post = Expose('', method: 'POST'), patch = Expose('', method: 'PATCH'), put = Expose('', method: 'PUT'), delete = Expose('', method: 'DELETE'), head = Expose('', method: 'HEAD'); const Expose( this.path, { this.method = 'GET', this.middleware = const [], this.as, this.allowNull = const [], }); const Expose.method( this.method, { this.middleware = const [], this.as, this.allowNull = const [], }) : path = ''; } /// Used to apply special dependency injections or functionality to a function parameter. class Parameter { /// Inject the value of a request cookie. final String? cookie; /// Inject the value of a request header. final String? header; /// Inject the value of a key from the session. final String? session; /// Inject the value of a key from the query. final String? query; /// Only execute the handler if the value of this parameter matches the given value. final dynamic match; /// Specify a default value. final dynamic defaultValue; /// If `true` (default), then an error will be thrown if this parameter is not present. final bool required; const Parameter({ this.cookie, this.query, this.header, this.session, this.match, this.defaultValue, this.required = true, }); /// Returns an error that can be thrown when the parameter is not present. Object? get error { if (cookie?.isNotEmpty == true) { return AngelHttpException.badRequest( message: 'Missing required cookie "$cookie".', ); } if (header?.isNotEmpty == true) { return AngelHttpException.badRequest( message: 'Missing required header "$header".', ); } if (query?.isNotEmpty == true) { return AngelHttpException.badRequest( message: 'Missing required query parameter "$query".', ); } if (session?.isNotEmpty == true) { return StateError('Session does not contain required key "$session".'); } return null; } /// Obtains a value for this parameter from a [RequestContext]. dynamic getValue(RequestContext req) { if (cookie?.isNotEmpty == true) { return req.cookies.firstWhere((c) => c.name == cookie).value; } if (header?.isNotEmpty == true) { return req.headers?.value(header ?? '') ?? defaultValue; } if (session?.isNotEmpty == true) { return req.session?[session] ?? defaultValue; } if (query?.isNotEmpty == true) { return req.uri?.queryParameters[query] ?? defaultValue; } return defaultValue; } } /// Shortcut for declaring a request header [Parameter]. class Header extends Parameter { const Header(String header, {super.match, super.defaultValue, super.required}) : super(header: header); } /// Shortcut for declaring a request session [Parameter]. class Session extends Parameter { const Session( String session, { super.match, super.defaultValue, super.required, }) : super(session: session); } /// Shortcut for declaring a request query [Parameter]. class Query extends Parameter { const Query(String query, {super.match, super.defaultValue, super.required}) : super(query: query); } /// Shortcut for declaring a request cookie [Parameter]. class CookieValue extends Parameter { const CookieValue( String cookie, { super.match, super.defaultValue, super.required, }) : super(cookie: cookie); } ================================================ FILE: packages/framework/lib/src/core/request_context.dart ================================================ library; import 'dart:async'; import 'dart:convert'; import 'dart:typed_data' show BytesBuilder; import 'dart:io' show Cookie, HeaderValue, HttpHeaders, HttpSession, InternetAddress; import 'package:angel3_container/angel3_container.dart'; import 'package:http_parser/http_parser.dart'; import 'package:belatuk_http_server/belatuk_http_server.dart'; import 'package:meta/meta.dart'; import 'package:mime/mime.dart'; import 'package:path/path.dart' as p; import 'package:collection/collection.dart'; import 'package:logging/logging.dart'; import 'metadata.dart'; import 'response_context.dart'; import 'routable.dart'; import 'server.dart' show Angel; part 'injection.dart'; /// A convenience wrapper around an incoming [RawRequest]. abstract class RequestContext { /// Similar to [Angel.shutdownHooks], allows for logic to be executed /// when a [RequestContext] is done being processed. final _log = Logger('RequestContext'); final List Function()> shutdownHooks = []; String? _acceptHeaderCache, _extensionCache; bool? _acceptsAllCache; Map? _queryParameters; Object? _bodyObject; bool _hasParsedBody = false, _closed = false; Map _bodyFields = {}; List _bodyList = []; List _uploadedFiles = []; MediaType _contentType = MediaType('text', 'plain'); /// The underlying [RawRequest] provided by the driver. RawRequest get rawRequest; /// Additional params to be passed to services. final Map serviceParams = {}; /// The [Angel] instance that is responding to this request. Angel? app; /// Any cookies sent with this request. List get cookies => []; /// All HTTP headers sent with this request. HttpHeaders? get headers; /// The requested hostname. String get hostname => 'localhost'; /// The IoC container that can be used to provide functionality to produce /// objects of a given type. /// /// This is a *child* of the container found in `app`. Container? get container; /// The user's IP. String get ip => remoteAddress.address; /// This request's HTTP method. /// /// This may have been processed by an override. See [originalMethod] to get the real method. String get method => 'GET'; /// The original HTTP verb sent to the server. String get originalMethod => 'GET'; /// The content type of an incoming request. MediaType get contentType { if (headers?.contentType != null) { try { _contentType = MediaType.parse(headers!.contentType.toString()); } catch (e) { _log.warning( 'Invalid media type [${headers!.contentType.toString()}]', e, ); } } return _contentType; } /// The URL parameters extracted from the request URI. Map params = {}; /// The requested path. String get path => ''; /// Is this an **XMLHttpRequest**? bool get isXhr { return headers?.value('X-Requested-With')?.trim().toLowerCase() == 'xmlhttprequest'; } /// The remote address requesting this resource. InternetAddress get remoteAddress; /// The user's HTTP session. HttpSession? get session; /// The [Uri] instance representing the path this request is responding to. Uri? get uri; /// The [Stream] of incoming binary data sent from the client. Stream>? get body; /// Returns `true` if [parseBody] has been called so far. bool get hasParsedBody => _hasParsedBody; /// Returns a *mutable* [Map] of the fields parsed from the request [body]. /// /// Note that [parseBody] must be called first. Map get bodyAsMap { if (!hasParsedBody) { throw StateError('The request body has not been parsed yet.'); } // else if (_bodyFields == null) { // throw StateError('The request body, $_bodyObject, is not a Map.'); //} return _bodyFields; } /// This setter allows you to explicitly set the request body **exactly once**. /// /// Use this if the format of the body is not natively parsed by Angel. set bodyAsMap(Map? value) => bodyAsObject = value; /// Returns a *mutable* [List] parsed from the request [body]. /// /// Note that [parseBody] must be called first. List? get bodyAsList { if (!hasParsedBody) { throw StateError('The request body has not been parsed yet.'); // TODO: Relook at this //} else if (_bodyList == null) { } else if (_bodyList.isEmpty) { throw StateError('The request body, $_bodyObject, is not a List.'); } return _bodyList; } /// This setter allows you to explicitly set the request body **exactly once**. /// /// Use this if the format of the body is not natively parsed by Angel. set bodyAsList(List? value) => bodyAsObject = value; /// Returns the parsed request body, whatever it may be (typically a [Map] or [List]). /// /// Note that [parseBody] must be called first. Object? get bodyAsObject { if (!hasParsedBody) { throw StateError('The request body has not been parsed yet.'); } return _bodyObject; } /// This setter allows you to explicitly set the request body **exactly once**. /// /// Use this if the format of the body is not natively parsed by Angel. set bodyAsObject(Object? value) { if (_bodyObject != null) { throw StateError( 'The request body has already been parsed/set, and cannot be overwritten.', ); } else { if (value is List) _bodyList = value; if (value is Map) _bodyFields = value; _bodyObject = value; _hasParsedBody = true; } } /// Returns a *mutable* map of the files parsed from the request [body]. /// /// Note that [parseBody] must be called first. List? get uploadedFiles { if (!hasParsedBody) { throw StateError('The request body has not been parsed yet.'); } return _uploadedFiles; } /// Returns a *mutable* map of the fields contained in the query. Map get queryParameters => _queryParameters ??= Map.from(uri?.queryParameters ?? {}); /// Returns the file extension of the requested path, if any. /// /// Includes the leading `.`, if there is one. String get extension => _extensionCache ??= p.extension(uri?.path ?? ''); /// Returns `true` if the client's `Accept` header indicates that the given [contentType] is considered a valid response. /// /// You cannot provide a `null` [contentType]. /// If the `Accept` header's value is `*/*`, this method will always return `true`. /// To ignore the wildcard (`*/*`), pass [strict] as `true`. /// /// [contentType] can be either of the following: /// * A [ContentType], in which case the `Accept` header will be compared against its `mimeType` property. /// * Any other Dart value, in which case the `Accept` header will be compared against the result of a `toString()` call. bool accepts(Object? contentType, {bool strict = false}) { var contentTypeString = contentType is MediaType ? contentType.mimeType : contentType?.toString(); // Change to assert if (contentTypeString == null) { _log.severe('RequestContext.accepts is null'); throw ArgumentError( 'RequestContext.accepts expects the `contentType` parameter to NOT be null.', ); } _acceptHeaderCache ??= headers?.value('accept'); if (_acceptHeaderCache == null) { return true; } else if (strict != true && _acceptHeaderCache!.contains('*/*')) { return true; } else { return _acceptHeaderCache!.contains(contentTypeString); } } /// Returns as `true` if the client's `Accept` header indicates that it will accept any response content type. bool get acceptsAll => _acceptsAllCache ??= accepts('*/*'); /// Shorthand for deserializing [bodyAsMap], using some transformer function [f]. Future deserializeBody( FutureOr Function(Map?) f, { Encoding encoding = utf8, }) async { await parseBody(encoding: encoding); return await f(bodyAsMap); } /// Shorthand for decoding [bodyAsMap], using some [codec]. Future decodeBody(Codec codec, {Encoding encoding = utf8}) => deserializeBody(codec.decode, encoding: encoding); /// Manually parses the request body, if it has not already been parsed. Future parseBody({Encoding encoding = utf8}) async { //if (contentType == null) { // throw FormatException('Missing "content-type" header.'); //} if (!_hasParsedBody) { _hasParsedBody = true; var contentBody = body ?? Stream.empty(); if (contentType.type == 'application' && contentType.subtype == 'json') { _uploadedFiles = []; var parsed = (_bodyObject = await encoding.decoder .bind(contentBody) .join() .then(json.decode)); if (parsed is Map) { _bodyFields = Map.from(parsed); } else if (parsed is List) { _bodyList = parsed; } } else if (contentType.type == 'application' && contentType.subtype == 'x-www-form-urlencoded') { _uploadedFiles = []; var parsed = await encoding.decoder .bind(contentBody) .join() .then((s) => Uri.splitQueryString(s, encoding: encoding)); _bodyFields = Map.from(parsed); } else if (contentType.type == 'multipart' && contentType.subtype == 'form-data' && contentType.parameters.containsKey('boundary')) { var boundary = contentType.parameters['boundary'] ?? ''; var transformer = MimeMultipartTransformer(boundary); var parts = transformer .bind(contentBody) .map( (part) => HttpMultipartFormData.parse(part, defaultEncoding: encoding), ); _bodyFields = {}; _uploadedFiles = []; await for (var part in parts) { if (part.isBinary) { _uploadedFiles.add(UploadedFile(part)); } else if (part.isText && part.contentDisposition.parameters.containsKey('name')) { // If there is no name, then don't parse it. var key = part.contentDisposition.parameters['name']; if (key != null) { var value = await part.join(); _bodyFields[key] = value; } } } } else { _bodyFields = {}; _uploadedFiles = []; } } } /// Disposes of all resources. @mustCallSuper Future close() async { if (!_closed) { _closed = true; _acceptsAllCache = null; _acceptHeaderCache = null; serviceParams.clear(); params.clear(); await Future.forEach(shutdownHooks, (dynamic hook) => hook()); } } } /// Reads information about a binary chunk uploaded to the server. class UploadedFile { /// The underlying `form-data` item. final HttpMultipartFormData formData; final log = Logger('UploadedFile'); MediaType _contentType = MediaType('multipart', 'form-data'); UploadedFile(this.formData); /// Returns the binary stream from [formData]. Stream> get data => formData.cast>(); /// The filename associated with the data on the user's system. /// Returns [:null:] if not present. String? get filename => formData.contentDisposition.parameters['filename']; /// The name of the field associated with this data. /// Returns [:null:] if not present. String? get name => formData.contentDisposition.parameters['name']; /// The parsed [:Content-Type:] header of the [:HttpMultipartFormData:]. /// Returns [:null:] if not present. //MediaType get contentType => _contentType ??= (formData.contentType == null // ? null // : MediaType.parse(formData.contentType.toString())); MediaType get contentType { if (formData.contentType != null) { try { _contentType = MediaType.parse(formData.contentType.toString()); } catch (e) { log.warning( 'Invalue media type [${formData.contentType.toString()}]', e, ); } } return _contentType; } /// The parsed [:Content-Transfer-Encoding:] header of the /// [:HttpMultipartFormData:]. This field is used to determine how to decode /// the data. Returns [:null:] if not present. HeaderValue? get contentTransferEncoding => formData.contentTransferEncoding; /// Reads the contents of the file into a single linear buffer. /// /// Note that this leads to holding the whole file in memory, which might /// not be ideal for large files.w Future> readAsBytes() { return data .fold(BytesBuilder(), (bb, out) => bb..add(out)) .then((bb) => bb.takeBytes()); } /// Reads the contents of the file as [String], using the given [encoding]. Future readAsString({Encoding encoding = utf8}) { return encoding.decoder.bind(data).join(); } } ================================================ FILE: packages/framework/lib/src/core/response_context.dart ================================================ library; import 'dart:async'; import 'dart:convert'; import 'dart:convert' as c show json; import 'dart:io' show BytesBuilder, Cookie; import 'dart:typed_data'; import 'package:angel3_route/angel3_route.dart'; import 'package:file/file.dart'; import 'package:http_parser/http_parser.dart'; import 'package:mime/mime.dart'; import 'controller.dart'; import 'request_context.dart'; import 'server.dart' show Angel; final RegExp _straySlashes = RegExp(r'(^/+)|(/+$)'); /// A convenience wrapper around an outgoing HTTP request. abstract class ResponseContext implements StreamConsumer>, StreamSink>, StringSink { final Map properties = {}; final CaseInsensitiveMap _headers = CaseInsensitiveMap.from({ 'content-type': 'text/plain', 'server': 'Angel3', }); //final log = Logger('ResponseContext'); Completer? _done; int _statusCode = 200; /// The [Angel] instance that is sending a response. Angel? app; /// Is `Transfer-Encoding` chunked? bool? chunked; /// Any and all cookies to be sent to the user. final List cookies = []; /// A set of [Converter] objects that can be used to encode response data. /// /// At most one encoder will ever be used to convert data. final Map, List>> encoders = {}; /// A [Map] of data to inject when `res.render` is called. /// /// This can be used to reduce boilerplate when using templating engines. final Map renderParams = {}; /// Points to the [RequestContext] corresponding to this response. RequestContext? get correspondingRequest; @override Future get done => (_done ?? Completer()).future; /// Headers that will be sent to the user. /// /// Note that if you have already started writing to the underlying stream, headers will not persist. CaseInsensitiveMap get headers => _headers; /// Serializes response data into a String. /// /// The default is conversion into JSON via `json.encode`. /// /// If you are 100% sure that your response handlers will only /// be JSON-encodable objects (i.e. primitives, `List`s and `Map`s), /// then consider setting [serializer] to `JSON.encode`. /// /// To set it globally for the whole [app], use the following helper: /// ```dart /// app.injectSerializer(JSON.encode); /// ``` FutureOr Function(dynamic) serializer = c.json.encode; /// This response's status code. int get statusCode => _statusCode; set statusCode(int value) { if (!isOpen) { throw closed(); } else { _statusCode = value; // ?? 200; } } /// Returns `true` if the response is still available for processing by Angel. /// /// If it is `false`, then Angel will stop executing handlers, and will only run /// response finalizers if the response [isBuffered]. bool get isOpen; /// Returns `true` if response data is being written to a buffer, rather than to the underlying stream. bool get isBuffered; /// A set of UTF-8 encoded bytes that will be written to the response. BytesBuilder? get buffer; /// The underlying [RawResponse] under this instance. RawResponse get rawResponse; /// Signals Angel that the response is being held alive deliberately, and that the framework should not automatically close it. /// /// This is mostly used in situations like WebSocket handlers, where the connection should remain /// open indefinitely. FutureOr detach(); /// Gets or sets the content length to send back to a client. /// /// Returns `null` if the header is invalidly formatted. int? get contentLength { return int.tryParse(headers['content-length'] ?? '-1'); } /// Gets or sets the content length to send back to a client. /// /// If [value] is `null`, then the header will be removed. set contentLength(int? value) { if (value == null || value == -1) { headers.remove('content-length'); } else { headers['content-length'] = value.toString(); } } /// Gets or sets the content type to send back to a client. MediaType get contentType { try { return MediaType.parse(headers['content-type']!); } catch (_) { return MediaType('text', 'plain'); } } /// Gets or sets the content type to send back to a client. set contentType(MediaType value) { headers['content-type'] = value.toString(); } static StateError closed() => StateError('Cannot modify a closed response.'); /// Sends a download as a response. Future download(File file, {String? filename}) async { if (!isOpen) throw closed(); headers['Content-Disposition'] = 'attachment; filename="${filename ?? file.path}"'; contentType = MediaType.parse(lookupMimeType(file.path)!); headers['content-length'] = file.lengthSync().toString(); if (!isBuffered) { await file.openRead().cast>().pipe(this); } else { buffer!.add(file.readAsBytesSync()); await close(); } } /// Prevents more data from being written to the response, and locks it entire from further editing. @override Future close() { if (buffer is LockableBytesBuilder) { (buffer as LockableBytesBuilder).lock(); } if (_done?.isCompleted == false) _done!.complete(); return Future.value(); } /// Serializes JSON to the response. Future json(Object? value) => serialize(value, contentType: MediaType('application', 'json')); /// Returns a JSONP response. /// /// You can override the [contentType] sent; by default it is `application/javascript`. Future jsonp( Object value, { String callbackName = 'callback', MediaType? contentType, }) { if (!isOpen) throw closed(); this.contentType = contentType ?? MediaType('application', 'javascript'); write('$callbackName(${serializer(value)})'); return close(); } /// Renders a view to the response stream, and closes the response. Future render(String view, [Map? data]) { if (!isOpen) throw closed(); contentType = MediaType('text', 'html', {'charset': 'utf-8'}); return Future.sync( () => app!.viewGenerator!( view, Map.from(renderParams) ..addAll(data ?? {}), ), ).then((content) { write(content); return close(); }); } /// Redirects to user to the given URL. /// /// [url] can be a `String`, or a `List`. /// If it is a `List`, a URI will be constructed /// based on the provided params. /// /// See [Router]#navigate for more. :) Future redirect(Object? url, {bool absolute = true, int? code}) { if (!isOpen) throw closed(); headers ..['content-type'] = 'text/html' ..['location'] = (url is String || url is Uri) ? url.toString() : app!.navigate(url as Iterable, absolute: absolute); statusCode = code ?? 302; write(''' Redirecting...

Currently redirecting you...


Click here if you are not automatically redirected... '''); return close(); } /// Redirects to the given named [Route]. Future redirectTo(String name, [Map? params, int? code]) async { if (!isOpen) throw closed(); Route? findRoute(Router r) { for (var route in r.routes) { if (route is SymlinkRoute) { final m = findRoute(route.router); if (m != null) return m; } else if (route.name == name) { return route; } } return null; } var matched = findRoute(app!); if (matched != null) { await redirect( matched.makeUri( params!.keys.fold>({}, (out, k) { return out..[k.toString()] = params[k]; }), ), code: code, ); return; } throw ArgumentError.notNull('Route to redirect to ($name)'); } /// Redirects to the given [Controller] action. Future redirectToAction(String action, [Map? params, int? code]) { if (!isOpen) throw closed(); // UserController@show var split = action.split('@'); if (split.length < 2) { throw Exception( "Controller redirects must take the form of 'Controller@action'. You gave: $action", ); } var controller = app!.controllers[split[0].replaceAll(_straySlashes, '')]; if (controller == null) { throw Exception("Could not find a controller named '${split[0]}'"); } var matched = controller.routeMappings[split[1]]; if (matched == null) { throw Exception( "Controller '${split[0]}' does not contain any action named '${split[1]}'", ); } final head = controller .findExpose(app!.container.reflector)! .path .toString() .replaceAll(_straySlashes, ''); var tail = ''; if (params != null) { tail = matched .makeUri( params.keys.fold>({}, (out, k) { return out..[k.toString()] = params[k]; }), ) .replaceAll(_straySlashes, ''); } return redirect('$head/$tail'.replaceAll(_straySlashes, ''), code: code); } /// Serializes data to the response. Future serialize(Object? value, {MediaType? contentType}) async { if (!isOpen) { throw closed(); } this.contentType = contentType ?? MediaType('application', 'json'); var text = await serializer(value); if (text.isEmpty) return true; write(text); await close(); return false; } /// Streams a file to this response. /// /// `HEAD` responses will not actually write data. Future streamFile(File file) async { if (!isOpen) { throw closed(); } var mimeType = app!.mimeTypeResolver.lookup(file.path); contentLength = await file.length(); contentType = mimeType == null ? MediaType('application', 'octet-stream') : MediaType.parse(mimeType); if (correspondingRequest!.method != 'HEAD') { return addStream(file.openRead().cast>()).then((_) => close()); } } /// Configure the response to write to an intermediate response buffer, rather than to the stream directly. void useBuffer(); /// Adds a stream directly the underlying response. /// /// If this instance has access to a [correspondingRequest], then it will attempt to transform /// the content using at most one of the response [encoders]. @override Future addStream(Stream> stream); @override void addError(Object error, [StackTrace? stackTrace]) { if (_done?.isCompleted == false) { _done!.completeError(error, stackTrace); } else if (_done == null) { if (stackTrace != null) { Zone.current.handleUncaughtError(error, stackTrace); } else { app?.logger.warning('[ResponseContext] stackTrace is null'); } } } /// Writes data to the response. @override void write(value, {Encoding? encoding}) { encoding ??= utf8; if (!isOpen && isBuffered) { throw closed(); } else if (!isBuffered) { add(encoding.encode(value.toString())); } else { buffer!.add(encoding.encode(value.toString())); } } @override void writeCharCode(int charCode) { if (!isOpen && isBuffered) { throw closed(); } else if (!isBuffered) { add([charCode]); } else { buffer!.addByte(charCode); } } @override void writeln([Object? obj = '']) { write(obj.toString()); write('\r\n'); } @override void writeAll(Iterable objects, [String separator = '']) { write(objects.join(separator)); } } abstract class LockableBytesBuilder implements BytesBuilder { factory LockableBytesBuilder() { return _LockableBytesBuilderImpl(); } void lock(); } class _LockableBytesBuilderImpl implements LockableBytesBuilder { final BytesBuilder _buf = BytesBuilder(copy: false); bool _closed = false; StateError _deny() => StateError('Cannot modified a closed response\'s buffer.'); @override void lock() { _closed = true; } @override void add(List bytes) { if (_closed) { throw _deny(); } else { _buf.add(bytes); } } @override void addByte(int byte) { if (_closed) { throw _deny(); } else { _buf.addByte(byte); } } @override void clear() { _buf.clear(); } @override bool get isEmpty => _buf.isEmpty; @override bool get isNotEmpty => _buf.isNotEmpty; @override int get length => _buf.length; @override Uint8List takeBytes() { return _buf.takeBytes(); } @override Uint8List toBytes() { return _buf.toBytes(); } } ================================================ FILE: packages/framework/lib/src/core/routable.dart ================================================ library; import 'dart:async'; import 'package:angel3_container/angel3_container.dart'; import 'package:angel3_route/angel3_route.dart'; import '../util.dart'; import 'hooked_service.dart'; import 'metadata.dart'; import 'request_context.dart'; import 'response_context.dart'; import 'service.dart'; final RegExp _straySlashes = RegExp(r'(^/+)|(/+$)'); /// A function that receives an incoming [RequestContext] and responds to it. typedef RequestHandler = FutureOr Function( RequestContext req, ResponseContext res, ); /// Sequentially runs a list of [handlers] of middleware, and returns early if any does not /// return `true`. Works well with [Router].chain. RequestHandler chain(Iterable handlers) { return (req, res) { Future Function()? runPipeline; for (var handler in handlers) { //if (handler == null) break; if (runPipeline == null) { runPipeline = () => Future.sync(() => handler(req, res)); } else { var current = runPipeline; runPipeline = () => current().then( (result) => !res.isOpen ? Future.value(result) : req.app!.executeHandler(handler, req, res), ); } } runPipeline ??= () => Future.value(); return runPipeline(); }; } /// A routable server that can handle dynamic requests. class Routable extends Router { final Map _services = {}; final Map _serviceLookups = {}; /// A [Map] of application-specific data that can be accessed. /// /// Packages like `package:angel3_configuration` populate this map /// for you. final Map configuration = {}; final Container _container; Routable([Reflector? reflector]) // : _container = reflector == null ? null : Container(reflector), : _container = Container(reflector ?? ThrowingReflector()), super(); /// A [Container] used to inject dependencies. Container get container => _container; void close() { _services.clear(); configuration.clear(); _onService.close(); } /// A set of [Service] objects that have been mapped into routes. Map get services => _services; final StreamController _onService = StreamController.broadcast(); /// Fired whenever a service is added to this instance. /// /// **NOTE**: This is a broadcast stream. Stream get onService => _onService.stream; /// Retrieves the service assigned to the given path. T? findService(Pattern path) { return _serviceLookups.putIfAbsent(path, () { return _services[path] ?? _services[path.toString().replaceAll(_straySlashes, '')]; }) as T?; } /// Shorthand for finding a [Service] in a statically-typed manner. Service? findServiceOf(Pattern path) { return findService>(path); } /// Shorthand for finding a [HookedService] in a statically-typed manner. HookedService? findHookedService( Pattern path, ) { return findService(path) as HookedService?; } @override Route addRoute( String method, String path, RequestHandler handler, { Iterable middleware = const {}, }) { final handlers = []; // Merge @Middleware declaration, if any var reflector = _container.reflector; if (reflector is! ThrowingReflector) { var middlewareDeclaration = getAnnotation( handler, _container.reflector, ); if (middlewareDeclaration != null) { handlers.addAll(middlewareDeclaration.handlers); } } final handlerSequence = []; handlerSequence.addAll(middleware); handlerSequence.addAll(handlers); return super.addRoute( method, path.toString(), handler, middleware: handlerSequence, ); } /// Mounts a [service] at the given [path]. /// /// Returns a [HookedService] that can be used to hook into /// events dispatched by this service. HookedService use>( String path, T service, ) { var hooked = HookedService(service); _services[path.toString().trim().replaceAll(RegExp(r'(^/+)|(/+$)'), '')] = hooked; hooked.addRoutes(); mount(path.toString(), hooked); service.onHooked(hooked); _onService.add(hooked); return hooked; } } ================================================ FILE: packages/framework/lib/src/core/server.dart ================================================ library; import 'dart:async'; import 'dart:collection' show HashMap; import 'dart:convert'; import 'package:angel3_container/angel3_container.dart'; import 'package:angel3_http_exception/angel3_http_exception.dart'; import 'package:angel3_route/angel3_route.dart'; import 'package:belatuk_combinator/belatuk_combinator.dart'; import 'package:http_parser/http_parser.dart'; import 'package:logging/logging.dart'; import 'package:mime/mime.dart'; import 'package:tuple/tuple.dart'; import 'controller.dart'; import 'env.dart'; import 'hooked_service.dart'; import 'request_context.dart'; import 'response_context.dart'; import 'routable.dart'; import 'service.dart'; //final RegExp _straySlashes = RegExp(r'(^/+)|(/+$)'); /// A function that configures an [Angel] server. typedef AngelConfigurer = FutureOr Function(Angel app); /// A function that asynchronously generates a view from the given path and data. typedef ViewGenerator = FutureOr Function(String path, [Map? data]); /// A function that handles error typedef AngelErrorHandler = dynamic Function( AngelHttpException e, RequestContext req, ResponseContext res, ); /// The default error handler for [Angel] server Future _defaultErrorHandler( AngelHttpException e, RequestContext req, ResponseContext res, ) async { if (!req.accepts('text/html', strict: true) && (req.accepts('application/json') || req.accepts('application/javascript'))) { await res.json(e.toJson()); return Future.value(false); } else { res.contentType = MediaType('text', 'html', {'charset': 'utf8'}); res.statusCode = e.statusCode; res.write('${e.message}'); res.write('

${e.message}

    '); for (var error in e.errors) { res.write('
  • $error
  • '); } res.write('
'); return Future.value(false); } } /// Default ROOT level logger Logger _defaultLogger() { Logger logger = Logger('ROOT') ..onRecord.listen((rec) { if (rec.error == null) { print(rec.message); } if (rec.error != null) { var err = rec.error; if (err is AngelHttpException && err.statusCode != 500) return; print('${rec.message} \n'); print(rec.error); if (rec.stackTrace != null) { print(rec.stackTrace); } } }); return logger; } /// A powerful real-time/REST/MVC server class. class Angel extends Routable { static Future _noViewEngineConfigured(String view, [Map? data]) => Future.value('No view engine has been configured yet.'); final List _children = []; final Map< String, Tuple4< List, Map, ParseResult, MiddlewarePipeline > > handlerCache = HashMap(); Router? _flattened; Angel? _parent; /// A global Map of converters that can transform responses bodies. final Map, List>> encoders = {}; final Map _preContained = {}; /// A [MimeTypeResolver] that can be used to specify the MIME types of files not known by `package:mime`. final MimeTypeResolver mimeTypeResolver = MimeTypeResolver(); /// A middleware to inject a serialize on every request. FutureOr Function(dynamic)? serializer; /// A [Map] of dependency data obtained via reflection. /// /// You may modify this [Map] yourself if you intend to avoid reflection entirely. Map get preContained => _preContained; /// Returns the [flatten]ed version of this router in production. Router get optimizedRouter => _flattened ?? this; /// Determines whether to allow HTTP request method overrides. bool allowMethodOverrides = true; /// All child application mounted on this instance. List get children => List.unmodifiable(_children); final Map _controllers = {}; /// A set of [Controller] objects that have been loaded into the application. Map get controllers => _controllers; /// The [AngelEnvironment] in which the application is running. /// /// By default, it is automatically inferred. final AngelEnvironment environment; /// Returns the parent instance of this application, if any. Angel? get parent => _parent; /// Outputs diagnostics and debug messages. Logger _logger = _defaultLogger(); Logger get logger => _logger; /// Assign a custom logger. /// Passing null will reset to default logger set logger(Logger? log) { _logger.clearListeners(); _logger = log ?? _defaultLogger(); } /// Plug-ins to be called right before server startup. /// /// If the server is never started, they will never be called. final List startupHooks = []; /// Plug-ins to be called right before server shutdown. /// /// If the server is never [close]d, they will never be called. final List shutdownHooks = []; /// Always run before responses are sent. /// /// These will only not run if a response's `willCloseItself` is set to `true`. final List responseFinalizers = []; /// A function that renders views. /// /// Called by [ResponseContext]@`render`. ViewGenerator? viewGenerator = _noViewEngineConfigured; /// The handler currently configured to run on [AngelHttpException]s. AngelErrorHandler errorHandler = _defaultErrorHandler; @override Route addRoute( String method, String path, RequestHandler handler, { Iterable middleware = const [], }) { if (_flattened != null) { logger.warning( 'WARNING: You added a route ($method $path) to the router, after it had been optimized.', ); logger.warning( 'This route will be ignored, and no requests will ever reach it.', ); } return super.addRoute(method, path, handler, middleware: middleware); } @override SymlinkRoute mount( String path, Router router, ) { if (_flattened != null) { logger.warning( 'WARNING: You added mounted a child router ($path) on the router, after it had been optimized.', ); logger.warning( 'This route will be ignored, and no requests will ever reach it.', ); } if (router is Angel) { router._parent = this; _children.add(router); } return super.mount(path.toString(), router); } /// Loads some base dependencies into the service container. void bootstrapContainer() { if (runtimeType != Angel) { container.registerSingleton(this); } container.registerSingleton(this); container.registerSingleton(this); container.registerSingleton(this); } /// Shuts down the server, and closes any open [StreamController]s. /// /// The server will be **COMPLETELY DEFUNCT** after this operation! @override Future close() { Future.forEach(services.values, (Service service) { service.close(); }); super.close(); viewGenerator = _noViewEngineConfigured; _preContained.clear(); handlerCache.clear(); encoders.clear(); _children.clear(); //_parent = null; //logger = null; //_flattened = null; startupHooks.clear(); shutdownHooks.clear(); responseFinalizers.clear(); return Future.value(); } @override void dumpTree({ Function(String tree)? callback, String header = 'Dumping route tree:', String tab = ' ', bool showMatchers = false, }) { if (environment.isProduction) { _flattened ??= flatten(this); _flattened!.dumpTree( callback: callback, header: header.isNotEmpty == true ? header : (environment.isProduction ? 'Dumping flattened route tree:' : 'Dumping route tree:'), tab: tab, ); } else { super.dumpTree( callback: callback, header: header.isNotEmpty == true ? header : (environment.isProduction ? 'Dumping flattened route tree:' : 'Dumping route tree:'), tab: tab, ); } } Future getHandlerResult( dynamic handler, RequestContext req, ResponseContext res, ) { if (handler is RequestHandler) { var result = handler(req, res); return getHandlerResult(result, req, res); } if (handler is Future) { return handler.then((result) => getHandlerResult(result, req, res)); } if (handler is Function) { var result = runContained(handler, req, res); return getHandlerResult(result, req, res); } if (handler is Stream) { return getHandlerResult(handler.toList(), req, res); } return Future.value(handler); } /// Runs some [handler]. Returns `true` if request execution should continue. Future executeHandler( dynamic handler, RequestContext req, ResponseContext res, ) { return getHandlerResult(handler, req, res).then((result) { if (result == null) { return false; } else if (result is bool) { return result; } else if (result != null) { return res.serialize(result); } else { return res.isOpen; } }); } /// Attempts to find a property by the given name within this application. dynamic findProperty(dynamic key) { if (configuration.containsKey(key)) return configuration[key]; //return parent != null ? parent?.findProperty(key) : null; if (parent != null) { return parent?.findProperty(key); } return null; } /// Runs several optimizations, *if* [angelEnv.isProduction] is `true`. /// /// * Preprocesses all dependency injection, and eliminates the burden of reflecting handlers /// at run-time. /// * [flatten]s the route tree into a linear one. /// /// You may [force] the optimization to run, if you are not running in production. void optimizeForProduction({bool force = false}) { if (environment.isProduction || force == true) { _flattened ??= flatten(this); logger.info('Angel is running in production mode.'); } } /// Run a function after injecting from service container. /// If this function has been reflected before, then /// the execution will be faster, as the injection requirements were stored beforehand. Future runContained( Function handler, RequestContext req, ResponseContext res, [ Container? container, ]) { container ??= Container(EmptyReflector()); return Future.sync(() { if (_preContained.containsKey(handler)) { return handleContained(handler, _preContained[handler]!, container)( req, res, ); } return runReflected(handler, req, res, container); }); } /// Runs with DI, and *always* reflects. Prefer [runContained]. Future runReflected( Function handler, RequestContext req, ResponseContext res, [ Container? container, ]) { container ??= req.container ?? res.app?.container ?? Container(EmptyReflector()); if (container.reflector is EmptyReflector) { throw ArgumentError("No `reflector` passed"); } var h = handleContained( handler, _preContained[handler] = preInject(handler, container.reflector), container, ); return Future.sync(() => h(req, res)); // return closureMirror.apply(args).reflectee; } /// Applies an [AngelConfigurer] to this instance. Future configure(AngelConfigurer configurer) { return Future.sync(() => configurer(this)); } /// Shorthand for using the [container] to instantiate, and then mount a [Controller]. /// Returns the created controller. /// /// Just like [Container].make, in contexts without properly-reified generics (dev releases of Dart 2), /// provide a [type] argument as well. /// /// If you are on `Dart >=2.0.0`, simply call `mountController()`. Future mountController([Type? type]) { var controller = container.make(type); return configure(controller.configureServer).then((_) => controller); } /// Shorthand for calling `all('*', handler)`. Route fallback(RequestHandler handler) { return all('*', handler); } @override HookedService use>( String path, T service, ) { service.app = this; return super.use(path, service)..app = this; } static const String _reflectionErrorMessage = '${ContainerConst.defaultErrorMessage} $_reflectionInfo'; static const String _reflectionInfo = 'Features like controllers, constructor dependency injection, and `ioc` require reflection, ' 'and will not work without it.\n\n' 'For more, see the documentation:\n' 'https://docs.angel-dart.dev/guides/dependency-injection#enabling-dart-mirrors-or-other-reflection'; Angel({ Reflector reflector = const ThrowingReflector( errorMessage: _reflectionErrorMessage, ), this.environment = angelEnv, Logger? logger, this.allowMethodOverrides = true, this.serializer, this.viewGenerator, }) : super(reflector) { // Override default logger if (logger != null) { this.logger = logger; } if (reflector is EmptyReflector || reflector is ThrowingReflector) { var msg = 'No `reflector` was passed to the Angel constructor, so reflection will not be available.\n$_reflectionInfo'; this.logger.warning(msg); } bootstrapContainer(); viewGenerator ??= _noViewEngineConfigured; serializer ??= json.encode; } } ================================================ FILE: packages/framework/lib/src/core/service.dart ================================================ library; import 'dart:async'; import 'package:angel3_http_exception/angel3_http_exception.dart'; import 'package:belatuk_merge_map/belatuk_merge_map.dart'; import 'package:quiver/core.dart'; import '../util.dart'; import 'anonymous_service.dart'; import 'hooked_service.dart' show HookedService; import 'metadata.dart'; import 'request_context.dart'; import 'response_context.dart'; import 'routable.dart'; import 'server.dart'; /// Indicates how the service was accessed. /// /// This will be passed to the `params` object in a service method. /// When requested on the server side, this will be null. class Providers { /// The transport through which the client is accessing this service. final String via; const Providers(this.via); static const String viaRest = 'rest'; static const String viaWebsocket = 'websocket'; static const String viaGraphQL = 'graphql'; /// Represents a request via REST. static const Providers rest = Providers(viaRest); /// Represents a request over WebSockets. static const Providers websocket = Providers(viaWebsocket); /// Represents a request parsed from GraphQL. static const Providers graphQL = Providers(viaGraphQL); @override int get hashCode => hashObjects([via]); @override bool operator ==(other) => other is Providers && other.via == via; Map toJson() { return {'via': via}; } @override String toString() { return 'via:$via'; } } /// A front-facing interface that can present data to and operate on data on behalf of the user. /// /// Heavily inspired by FeathersJS. <3 class Service extends Routable { /// A [List] of keys that services should ignore, should they see them in the query. static const List specialQueryKeys = [ r'$limit', r'$sort', 'page', 'token', ]; /// Handlers that must run to ensure this service's functionality. List get bootstrappers => []; /// The [Angel] app powering this service. Angel? _app; Angel get app { if (_app == null) { throw ArgumentError("Angel is not initialized"); } return _app!; } set app(Angel angel) { _app = angel; } bool get isAppActive => _app != null; /// Closes this service, including any database connections or stream controllers. @override void close() {} /// An optional [readData] function can be passed to handle non-map/non-json bodies. Service({ FutureOr Function(RequestContext, ResponseContext)? readData, }) { _readData = readData; _readData ??= (req, res) { if (req.bodyAsObject is! Data) { throw AngelHttpException.badRequest( message: 'Invalid request body. Expected $Data; found ${req.bodyAsObject} instead.', ); } else { return req.bodyAsObject as Data; } }; } FutureOr Function(RequestContext, ResponseContext)? _readData; /// A [Function] that reads the request body and converts it into [Data]. FutureOr Function(RequestContext, ResponseContext)? get readData => _readData; /// Retrieves the first object from the result of calling [index] with the given [params]. /// /// If the result of [index] is `null`, OR an empty [Iterable], a 404 `AngelHttpException` will be thrown. /// /// If the result is both non-null and NOT an [Iterable], it will be returned as-is. /// /// If the result is a non-empty [Iterable], [findOne] will return `it.first`, where `it` is the aforementioned [Iterable]. /// /// A custom [errorMessage] may be provided. Future findOne([ Map? params, String errorMessage = 'No record was found matching the given query.', ]) { return index(params).then((result) { if (result.isEmpty) { throw AngelHttpException.notFound(message: errorMessage); } else { return result.first; } }); } /// Retrieves all resources. Future> index([Map? params]) { throw AngelHttpException.methodNotAllowed(); } /// Retrieves the desired resource. Future read(Id id, [Map? params]) { throw AngelHttpException.methodNotAllowed(); } /// Reads multiple resources at once. /// /// Service implementations should override this to ensure data is fetched within a /// single round trip. Future> readMany(List ids, [Map? params]) { return Future.wait(ids.map((id) => read(id, params))); } /// Creates a resource. Future create(Data data, [Map? params]) { throw AngelHttpException.methodNotAllowed(); } /// Modifies a resource. Future modify(Id id, Data data, [Map? params]) { throw AngelHttpException.methodNotAllowed(); } /// Overwrites a resource. Future update(Id id, Data data, [Map? params]) { throw AngelHttpException.methodNotAllowed(); } /// Removes the given resource. Future remove(Id id, [Map? params]) { throw AngelHttpException.methodNotAllowed(); } /// Creates an [AnonymousService] that wraps over this one, and maps input and output /// using two converter functions. /// /// Handy utility for handling data in a type-safe manner. Service map( U Function(Data) encoder, Data Function(U) decoder, { FutureOr Function(RequestContext, ResponseContext)? readData, }) { readData ??= (req, res) async { var inner = await this.readData!(req, res)!; return encoder(inner); }; return AnonymousService( readData: readData, index: ([params]) { return index(params).then((it) => it.map(encoder).toList()); }, read: (id, [params]) { return read(id, params).then(encoder); }, create: (data, [params]) { return create(decoder(data), params).then(encoder); }, modify: (id, data, [params]) { return modify(id, decoder(data), params).then(encoder); }, update: (id, data, [params]) { return update(id, decoder(data), params).then(encoder); }, remove: (id, [params]) { return remove(id, params).then(encoder); }, ); } /// Transforms an [id] (whether it is a String, num, etc.) into one acceptable by a service. /// /// The single type argument, [T], is used to determine how to parse the [id]. /// /// For example, `parseId` attempts to parse the value as a [bool]. static T parseId(Object? id) { if (id == null || id == 'null') { return 'null' as T; //throw ArgumentError("[Service] Null is not supported"); } else if (T == String) { return id.toString() as T; } else if (T == int) { return int.parse(id.toString()) as T; } else if (T == bool) { return (id == true || id.toString() == 'true') as T; } else if (T == double) { return double.parse(id.toString()) as T; } else if (T == num) { return num.parse(id.toString()) as T; } else { return id as T; } } /// Generates RESTful routes pointing to this class's methods. void addRoutes([Service? service]) { _addRoutesInner(service ?? this, bootstrappers); } void _addRoutesInner(Service service, Iterable handlerss) { var restProvider = {'provider': Providers.rest}; var handlers = List.from(handlerss); // Add global middleware if declared on the instance itself var before = getAnnotation(service, app.container.reflector); if (before != null) handlers.addAll(before.handlers); var indexMiddleware = getAnnotation( service.index, app.container.reflector, ); get( '/', (req, res) { return index( mergeMap([ {'query': req.queryParameters}, restProvider, req.serviceParams, ]), ); }, middleware: [ ...handlers, ...(indexMiddleware == null) ? [] : indexMiddleware.handlers.toList(), ], ); var createMiddleware = getAnnotation( service.create, app.container.reflector, ); post( '/', (req, ResponseContext res) { return req.parseBody().then((_) async { return await create( (await readData!(req, res))!, mergeMap([ {'query': req.queryParameters}, restProvider, req.serviceParams, ]), ).then((r) { res.statusCode = 201; return r; }); }); }, middleware: [ ...handlers, ...(createMiddleware == null) ? [] : createMiddleware.handlers.toList(), ], ); var readMiddleware = getAnnotation( service.read, app.container.reflector, ); get( '/:id', (req, res) { return read( parseId(req.params['id']), mergeMap([ {'query': req.queryParameters}, restProvider, req.serviceParams, ]), ); }, middleware: [ ...handlers, ...(readMiddleware == null) ? [] : readMiddleware.handlers.toList(), ], ); var modifyMiddleware = getAnnotation( service.modify, app.container.reflector, ); patch( '/:id', (req, res) { return req.parseBody().then((_) async { return await modify( parseId(req.params['id']), (await readData!(req, res))!, mergeMap([ {'query': req.queryParameters}, restProvider, req.serviceParams, ]), ); }); }, middleware: [ ...handlers, ...(modifyMiddleware == null) ? [] : modifyMiddleware.handlers.toList(), ], ); var updateMiddleware = getAnnotation( service.update, app.container.reflector, ); post( '/:id', (req, res) { return req.parseBody().then((_) async { return await update( parseId(req.params['id']), (await readData!(req, res))!, mergeMap([ {'query': req.queryParameters}, restProvider, req.serviceParams, ]), ); }); }, middleware: [ ...handlers, ...(updateMiddleware == null) ? [] : updateMiddleware.handlers.toList(), ], ); put( '/:id', (req, res) { return req.parseBody().then((_) async { return await update( parseId(req.params['id']), (await readData!(req, res))!, mergeMap([ {'query': req.queryParameters}, restProvider, req.serviceParams, ]), ); }); }, middleware: [ ...handlers, ...(updateMiddleware == null) ? [] : updateMiddleware.handlers.toList(), ], ); var removeMiddleware = getAnnotation( service.remove, app.container.reflector, ); delete( '/', (req, res) { return remove( '' as Id, mergeMap([ {'query': req.queryParameters}, restProvider, req.serviceParams, ]), ); }, middleware: [ ...handlers, ...(removeMiddleware == null) ? [] : removeMiddleware.handlers.toList(), ], ); delete( '/:id', (req, res) { return remove( parseId(req.params['id']), mergeMap([ {'query': req.queryParameters}, restProvider, req.serviceParams, ]), ); }, middleware: [ ...handlers, ...(removeMiddleware == null) ? [] : removeMiddleware.handlers.toList(), ], ); // REST compliance put('/', (req, res) => throw AngelHttpException.notFound()); patch('/', (req, res) => throw AngelHttpException.notFound()); } /// Invoked when this service is wrapped within a [HookedService]. void onHooked(HookedService hookedService) {} } ================================================ FILE: packages/framework/lib/src/fast_name_from_symbol.dart ================================================ final Map _cache = {}; String fastNameFromSymbol(Symbol s) { return _cache.putIfAbsent(s, () { var str = s.toString(); var open = str.indexOf('"'); var close = str.lastIndexOf('"'); return str.substring(open + 1, close); }); } ================================================ FILE: packages/framework/lib/src/http/angel_http.dart ================================================ import 'dart:async'; import 'dart:convert'; import 'dart:io' show Cookie, HttpRequest, HttpResponse, HttpServer, Platform, SecurityContext; import 'package:angel3_framework/angel3_framework.dart'; import '../core/core.dart'; import 'http_request_context.dart'; import 'http_response_context.dart'; final RegExp _straySlashes = RegExp(r'(^/+)|(/+$)'); typedef ServerGeneratorType = Future Function(dynamic, int); /// Adapts `dart:io`'s [HttpServer] to serve Angel. class AngelHttp extends Driver< HttpRequest, HttpResponse, HttpServer, HttpRequestContext, HttpResponseContext > { @override Uri get uri { return Uri( scheme: 'http', host: server?.address.address, port: server?.port, ); } AngelHttp._(super.app, super.serverGenerator, bool useZone) : super(useZone: useZone); factory AngelHttp(Angel app, {bool useZone = true}) { return AngelHttp._(app, HttpServer.bind, useZone); } /// An instance mounted on a server started by the [serverGenerator]. factory AngelHttp.custom( Angel app, ServerGeneratorType serverGenerator, { bool useZone = true, Map headers = const {}, }) { return AngelHttp._(app, serverGenerator, useZone); } factory AngelHttp.fromSecurityContext( Angel app, SecurityContext context, { bool useZone = true, }) { return AngelHttp._(app, (address, int port) { return HttpServer.bindSecure(address, port, context); }, useZone); } /// Creates an HTTPS server. /// /// Provide paths to a certificate chain and server key (both .pem). /// If no password is provided, a random one will be generated upon running /// the server. factory AngelHttp.secure( Angel app, String certificateChainPath, String serverKeyPath, { String? password, bool useZone = true, }) { var certificateChain = Platform.script .resolve(certificateChainPath) .toFilePath(); var serverKey = Platform.script.resolve(serverKeyPath).toFilePath(); var serverContext = SecurityContext(); serverContext.useCertificateChain(certificateChain, password: password); serverContext.usePrivateKey(serverKey, password: password); return AngelHttp.fromSecurityContext(app, serverContext, useZone: useZone); } Future handleRequest(HttpRequest request) => handleRawRequest(request, request.response); @override void addCookies(HttpResponse response, Iterable cookies) => response.cookies.addAll(cookies); @override Future close() async { return await super.close(); } /// Remove headers from HTTP Response void removeResponseHeader(Map headers) { headers.forEach((key, value) { server?.defaultResponseHeaders.remove(key, value); }); } /// Add headers to HTTP Response void addResponseHeader(Map headers) { headers.forEach((key, value) { server?.defaultResponseHeaders.add(key, value); }); } @override Future closeResponse(HttpResponse response) => response.close(); @override Future createRequestContext( HttpRequest request, HttpResponse response, ) { var path = request.uri.path.replaceAll(_straySlashes, ''); if (path.isEmpty) path = '/'; return HttpRequestContext.from(request, app, path); } @override Future createResponseContext( HttpRequest request, HttpResponse response, [ HttpRequestContext? correspondingRequest, ]) { var context = HttpResponseContext(response, app, correspondingRequest); context.serializer = (app.serializer ?? json.encode); context.encoders.addAll(app.encoders); return Future.value(context); } @override Stream createResponseStreamFromRawRequest( HttpRequest request, ) => Stream.fromIterable([request.response]); @override void setChunkedEncoding(HttpResponse response, bool value) => response.headers.chunkedTransferEncoding = value; @override void setContentLength(HttpResponse response, int length) => response.headers.contentLength = length; @override void setHeader(HttpResponse response, String key, String value) => response.headers.set(key, value); @override void setStatusCode(HttpResponse response, int value) => response.statusCode = value; @override void writeStringToResponse(HttpResponse response, String value) => response.write(value); @override void writeToResponse(HttpResponse response, List data) => response.add(data); } ================================================ FILE: packages/framework/lib/src/http/http.dart ================================================ /// Various libraries useful for creating highly-extensible servers. library; import 'dart:async'; import 'dart:io'; export 'angel_http.dart'; export 'http_request_context.dart'; export 'http_response_context.dart'; /// Boots a shared server instance. Use this if launching multiple isolates. Future startShared(Object? address, int port) => HttpServer.bind(address ?? '127.0.0.1', port, shared: true); Future Function(Object?, int) startSharedSecure( SecurityContext securityContext, ) { return (address, int port) => HttpServer.bindSecure( address ?? '127.0.0.1', port, securityContext, shared: true, ); } ================================================ FILE: packages/framework/lib/src/http/http_request_context.dart ================================================ import 'dart:async'; import 'dart:io'; import 'package:angel3_container/angel3_container.dart'; import 'package:http_parser/http_parser.dart'; import '../core/core.dart'; /// An implementation of [RequestContext] that wraps a [HttpRequest]. class HttpRequestContext extends RequestContext { Container? _container; MediaType _contentType = MediaType('text', 'plain'); HttpRequest? _io; String? _override; String _path = ''; @override Container? get container => _container; @override MediaType get contentType { return _contentType; } @override List get cookies { return rawRequest?.cookies ?? []; } @override HttpHeaders? get headers { return rawRequest?.headers; } @override String get hostname { return rawRequest?.headers.value('host') ?? 'localhost'; } /// The underlying [HttpRequest] instance underneath this context. @override HttpRequest? get rawRequest => _io; @override Stream>? get body => _io; @override String get method { return _override ?? originalMethod; } @override String get originalMethod { return rawRequest?.method ?? ''; } @override String get path { return _path; } @override InternetAddress get remoteAddress { return rawRequest?.connectionInfo?.remoteAddress ?? InternetAddress("127.0.0.1"); } @override HttpSession? get session { return rawRequest?.session; } @override Uri get uri { return rawRequest?.uri ?? Uri(); } /// Magically transforms an [HttpRequest] into a [RequestContext]. static Future from( HttpRequest request, Angel app, String path, ) { var ctx = HttpRequestContext().._container = app.container.createChild(); var override = request.method; if (app.allowMethodOverrides == true) { override = request.headers.value('x-http-method-override')?.toUpperCase() ?? request.method; } ctx.app = app; ctx._contentType = request.headers.contentType == null ? MediaType('text', 'plain') : MediaType.parse(request.headers.contentType.toString()); ctx._override = override; ctx._path = path; ctx._io = request; return Future.value(ctx); } @override Future close() { //_contentType = null; _io = null; _override = null; //_path = null; return super.close(); } } ================================================ FILE: packages/framework/lib/src/http/http_response_context.dart ================================================ import 'dart:async'; import 'dart:convert'; import 'dart:io' hide BytesBuilder; import 'dart:typed_data' show BytesBuilder; import 'package:http_parser/http_parser.dart'; import '../core/core.dart'; import 'http_request_context.dart'; /// An implementation of [ResponseContext] that abstracts over an [HttpResponse]. class HttpResponseContext extends ResponseContext { /// The underlying [HttpResponse] under this instance. @override final HttpResponse rawResponse; LockableBytesBuilder? _buffer; final HttpRequestContext? _correspondingRequest; bool _isDetached = false, _isClosed = false, _streamInitialized = false; HttpResponseContext( this.rawResponse, Angel? app, [ this._correspondingRequest, ]) { this.app = app; } @override HttpResponse detach() { _isDetached = true; return rawResponse; } @override RequestContext? get correspondingRequest { return _correspondingRequest; } @override bool get isOpen { return !_isClosed && !_isDetached; } @override bool get isBuffered => _buffer != null; @override BytesBuilder? get buffer => _buffer; @override void addError(Object error, [StackTrace? stackTrace]) { rawResponse.addError(error, stackTrace); super.addError(error, stackTrace); } @override void useBuffer() { _buffer = LockableBytesBuilder(); } Iterable? __allowedEncodings; Iterable? get _allowedEncodings { return __allowedEncodings ??= correspondingRequest?.headers ?.value('accept-encoding') ?.split(',') .map((s) => s.trim()) .where((s) => s.isNotEmpty) .map((str) { // Ignore quality specifications in accept-encoding // ex. gzip;q=0.8 if (!str.contains(';')) return str; return str.split(';')[0]; }); } @override set contentType(MediaType value) { super.contentType = value; if (!_streamInitialized) { rawResponse.headers.contentType = ContentType( value.type, value.subtype, parameters: value.parameters, ); } } bool _openStream() { if (!_streamInitialized) { // If this is the first stream added to this response, // then add headers, status code, etc. rawResponse ..statusCode = statusCode ..cookies.addAll(cookies); headers.forEach(rawResponse.headers.set); rawResponse.headers.date = DateTime.now(); if (headers.containsKey('content-length')) { rawResponse.contentLength = int.tryParse(headers['content-length']!) ?? rawResponse.contentLength; } rawResponse.headers.contentType = ContentType( contentType.type, contentType.subtype, charset: contentType.parameters['charset'], parameters: contentType.parameters, ); if (encoders.isNotEmpty && correspondingRequest != null) { if (_allowedEncodings != null) { for (var encodingName in _allowedEncodings!) { Converter, List>? encoder; var key = encodingName; if (encoders.containsKey(encodingName)) { encoder = encoders[encodingName]; } else if (encodingName == '*') { encoder = encoders[key = encoders.keys.first]; } if (encoder != null) { rawResponse.headers.set('content-encoding', key); break; } } } } //_isClosed = true; return _streamInitialized = true; } return false; } @override Future addStream(Stream> stream) { if (_isClosed && isBuffered) throw ResponseContext.closed(); _openStream(); var output = stream; if (encoders.isNotEmpty && correspondingRequest != null) { if (_allowedEncodings != null) { for (var encodingName in _allowedEncodings!) { Converter, List>? encoder; var key = encodingName; if (encoders.containsKey(encodingName)) { encoder = encoders[encodingName]; } else if (encodingName == '*') { encoder = encoders[key = encoders.keys.first]; } if (encoder != null) { output = encoders[key]!.bind(output); break; } } } } return rawResponse.addStream(output); } @override void add(List data) { if (_isClosed && isBuffered) { throw ResponseContext.closed(); } else if (!isBuffered) { if (!_isClosed) { _openStream(); if (encoders.isNotEmpty && correspondingRequest != null) { if (_allowedEncodings != null) { for (var encodingName in _allowedEncodings!) { Converter, List>? encoder; var key = encodingName; if (encoders.containsKey(encodingName)) { encoder = encoders[encodingName]; } else if (encodingName == '*') { encoder = encoders[key = encoders.keys.first]; } if (encoder != null) { data = encoders[key]!.convert(data); break; } } } } rawResponse.add(data); } } else { buffer!.add(data); } } @override Future close() { if (!_isDetached) { if (!_isClosed) { if (!isBuffered) { try { _openStream(); rawResponse.close(); } catch (_) { // This only seems to occur on `MockHttpRequest`, but // this try/catch prevents a crash. } } else { _buffer!.lock(); } _isClosed = true; } super.close(); } return Future.value(); } } ================================================ FILE: packages/framework/lib/src/http2/angel_http2.dart ================================================ import 'dart:async'; import 'dart:convert'; import 'dart:io'; import 'package:angel3_framework/angel3_framework.dart' hide Header; import 'package:angel3_framework/http.dart'; import 'package:http2/transport.dart'; import 'package:angel3_mock_request/angel3_mock_request.dart'; import 'http2_request_context.dart'; import 'http2_response_context.dart'; import 'package:uuid/uuid.dart'; /// Boots a shared server instance. Use this if launching multiple isolates. Future startSharedHttp2( Object? address, int port, SecurityContext ctx, ) { return SecureServerSocket.bind(address, port, ctx, shared: true); } /// Adapts `package:http2`'s [ServerTransportConnection] to serve Angel. class AngelHttp2 extends Driver< Socket, ServerTransportStream, SecureServerSocket, Http2RequestContext, Http2ResponseContext > { final ServerSettings? settings; late AngelHttp _http; final StreamController _onHttp1 = StreamController(); final Map _sessions = {}; final Uuid _uuid = Uuid(); _AngelHttp2ServerSocket? _artificial; SecureServerSocket? get socket => _artificial; AngelHttp2._( Angel app, Future Function(dynamic, int) serverGenerator, bool useZone, bool allowHttp1, this.settings, ) : super(app, serverGenerator, useZone: useZone) { if (allowHttp1) { _http = AngelHttp(app, useZone: useZone); onHttp1.listen(_http.handleRequest); } } factory AngelHttp2( Angel app, SecurityContext securityContext, { bool useZone = true, bool allowHttp1 = false, ServerSettings? settings, }) { return AngelHttp2.custom( app, securityContext, SecureServerSocket.bind, allowHttp1: allowHttp1, settings: settings, ); } factory AngelHttp2.custom( Angel app, SecurityContext ctx, Future Function( InternetAddress? address, int port, SecurityContext ctx, ) serverGenerator, { bool useZone = true, bool allowHttp1 = false, ServerSettings? settings, }) { return AngelHttp2._( app, (address, port) { var addr = address is InternetAddress ? address : InternetAddress(address.toString()); return Future.sync(() => serverGenerator(addr, port, ctx)); }, useZone, allowHttp1, settings, ); } /// Fires when an HTTP/1.x request is received. Stream get onHttp1 => _onHttp1.stream; @override Future generateServer([ Object? address, int? port, ]) async { var s = await serverGenerator(address ?? '127.0.0.1', port ?? 0); return _artificial = _AngelHttp2ServerSocket(s, this); } @override Future close() async { await _artificial?.close(); await _http.close(); return await super.close(); } @override void addCookies(ServerTransportStream response, Iterable cookies) { var headers = cookies.map( (cookie) => Header.ascii('set-cookie', cookie.toString()), ); response.sendHeaders(headers.toList()); } @override Future closeResponse(ServerTransportStream response) { response.terminate(); return Future.value(); } @override Future createRequestContext( Socket request, ServerTransportStream response, ) { return Http2RequestContext.from(response, request, app, _sessions, _uuid); } @override Future createResponseContext( Socket request, ServerTransportStream response, [ Http2RequestContext? correspondingRequest, ]) async { return Http2ResponseContext(app, response, correspondingRequest) ..encoders.addAll(app.encoders); } @override Stream createResponseStreamFromRawRequest( Socket request, ) { var connection = ServerTransportConnection.viaSocket( request, settings: settings, ); return connection.incomingStreams; } @override void setChunkedEncoding(ServerTransportStream response, bool value) { // Do nothing in HTTP/2 } @override void setContentLength(ServerTransportStream response, int length) { setHeader(response, 'content-length', length.toString()); } @override void setHeader(ServerTransportStream response, String key, String? value) { response.sendHeaders([Header.ascii(key, value!)]); } @override void setStatusCode(ServerTransportStream response, int value) { response.sendHeaders([Header.ascii(':status', value.toString())]); } @override Uri get uri => Uri( scheme: 'https', host: server?.address.address, port: server?.port != 443 ? server?.port : null, ); @override void writeStringToResponse(ServerTransportStream response, String value) { writeToResponse(response, utf8.encode(value)); } @override void writeToResponse(ServerTransportStream response, List data) { response.sendData(data); } } class _FakeServerSocket extends Stream implements ServerSocket { final _AngelHttp2ServerSocket angel; final _ctrl = StreamController(); _FakeServerSocket(this.angel); @override InternetAddress get address => angel.address; @override Future close() async { await (_ctrl.close()); return this; } @override int get port => angel.port; @override StreamSubscription listen( void Function(Socket event)? onData, { Function? onError, void Function()? onDone, bool? cancelOnError, }) { return _ctrl.stream.listen( onData, cancelOnError: cancelOnError, onError: onError, onDone: onDone, ); } } class _AngelHttp2ServerSocket extends Stream implements SecureServerSocket { final SecureServerSocket socket; final AngelHttp2 driver; final _ctrl = StreamController(); late _FakeServerSocket _fake; StreamSubscription? _sub; _AngelHttp2ServerSocket(this.socket, this.driver) { _fake = _FakeServerSocket(this); HttpServer.listenOn(_fake).pipe(driver._onHttp1); _sub = socket.listen( (socket) { if (socket.selectedProtocol == null || socket.selectedProtocol == 'http/1.0' || socket.selectedProtocol == 'http/1.1') { _fake._ctrl.add(socket); } else if (socket.selectedProtocol == 'h2' || socket.selectedProtocol == 'h2-14') { _ctrl.add(socket); } else { socket.destroy(); throw Exception( 'AngelHttp2 does not support ${socket.selectedProtocol} as an ALPN protocol.', ); } }, onDone: _ctrl.close, onError: (e, st) { driver.app.logger.warning( 'HTTP/2 incoming connection failure: ', e, st as StackTrace, ); }, ); } @override InternetAddress get address => socket.address; @override int get port => socket.port; @override Future close() { _sub?.cancel(); _fake.close(); _ctrl.close(); return socket.close(); } @override StreamSubscription listen( void Function(SecureSocket event)? onData, { Function? onError, void Function()? onDone, bool? cancelOnError, }) { return _ctrl.stream.listen( onData, cancelOnError: cancelOnError, onError: onError, onDone: onDone, ); } } ================================================ FILE: packages/framework/lib/src/http2/http2_request_context.dart ================================================ import 'dart:async'; import 'dart:convert'; import 'dart:io'; import 'package:angel3_container/angel3_container.dart'; import 'package:angel3_framework/angel3_framework.dart'; import 'package:collection/collection.dart' show IterableExtension; import 'package:http2/transport.dart'; import 'package:angel3_mock_request/angel3_mock_request.dart'; import 'package:uuid/uuid.dart'; final RegExp _comma = RegExp(r',\s*'); final RegExp _straySlashes = RegExp(r'(^/+)|(/+$)'); class Http2RequestContext extends RequestContext { final StreamController> _body = StreamController(); @override final Container container; List _cookies = []; HttpHeaders? _headers; String? _method, _override, _path; late Socket _socket; ServerTransportStream? _stream; Uri? _uri; HttpSession? _session; Http2RequestContext._(this.container); @override Stream> get body => _body.stream; static Future from( ServerTransportStream stream, Socket socket, Angel app, Map sessions, Uuid uuid, ) { var c = Completer(); var req = Http2RequestContext._(app.container.createChild()) ..app = app .._socket = socket .._stream = stream; var headers = req._headers = MockHttpHeaders(); // String scheme = 'https', host = socket.address.address, path = ''; var uri = Uri( scheme: 'https', host: socket.address.address, port: socket.port, ); var cookies = []; void finalize() { req .._cookies = List.unmodifiable(cookies) .._uri = uri; if (!c.isCompleted) c.complete(req); } void parseHost(String value) { var inUri = Uri.tryParse(value); if (inUri == null) return; // if (uri == null || uri.scheme == 'localhost') return; if (inUri.hasScheme) uri = uri.replace(scheme: inUri.scheme); if (inUri.hasAuthority) { uri = uri.replace(host: inUri.host, userInfo: inUri.userInfo); } if (inUri.hasPort) uri = uri.replace(port: inUri.port); } stream.incomingMessages.listen( (msg) { if (msg is DataStreamMessage) { finalize(); req._body.add(msg.bytes); } else if (msg is HeadersStreamMessage) { for (var header in msg.headers) { var name = ascii.decode(header.name).toLowerCase(); var value = Uri.decodeComponent(ascii.decode(header.value)); switch (name) { case ':method': req._method = value; break; case ':path': var inUri = Uri.parse(value); uri = uri.replace(path: inUri.path); if (inUri.hasQuery) uri = uri.replace(query: inUri.query); var path = uri.path.replaceAll(_straySlashes, ''); req._path = path; if (path.isEmpty) req._path = '/'; break; case ':scheme': uri = uri.replace(scheme: value); break; case ':authority': parseHost(value); break; case 'cookie': var cookieStrings = value.split(';').map((s) => s.trim()); for (var cookieString in cookieStrings) { try { cookies.add(Cookie.fromSetCookieValue(cookieString)); } catch (_) { // Ignore malformed cookies, and just don't add them to the container. } } break; default: var name = ascii.decode(header.name).toLowerCase(); if (name == 'host') { parseHost(value); } headers.add(name, value.split(_comma)); break; } } if (msg.endStream) finalize(); } }, onDone: () { finalize(); req._body.close(); }, cancelOnError: true, onError: c.completeError, ); // Apply session var dartSessId = cookies.firstWhereOrNull((c) => c.name == 'DARTSESSID'); dartSessId ??= Cookie('DARTSESSID', uuid.v4()); req._session = sessions.putIfAbsent( dartSessId.value, () => MockHttpSession(id: dartSessId!.value), ); return c.future; } @override List get cookies => _cookies; /// The underlying HTTP/2 [ServerTransportStream]. ServerTransportStream? get stream => _stream; @override Uri? get uri => _uri; @override HttpSession? get session { return _session; } @override InternetAddress get remoteAddress => _socket.remoteAddress; @override String get path { return _path ?? ''; } @override String get originalMethod { return _method ?? 'GET'; } @override String get method { return _override ?? _method ?? 'GET'; } @override String get hostname => _headers?.value('host') ?? 'localhost'; @override HttpHeaders? get headers => _headers; @override Future close() { _body.close(); return super.close(); } @override ServerTransportStream? get rawRequest => _stream; } ================================================ FILE: packages/framework/lib/src/http2/http2_response_context.dart ================================================ import 'dart:async'; import 'dart:convert'; import 'dart:io' hide BytesBuilder; import 'dart:typed_data'; import 'package:angel3_framework/angel3_framework.dart' hide Header; import 'package:http2/transport.dart'; import 'http2_request_context.dart'; class Http2ResponseContext extends ResponseContext { final ServerTransportStream stream; @override ServerTransportStream get rawResponse => stream; LockableBytesBuilder? _buffer; final Http2RequestContext? _req; bool _isDetached = false, _isClosed = false, _streamInitialized = false, _isPush = false; Uri? _targetUri; Http2ResponseContext(Angel? app, this.stream, this._req) { this.app = app; _targetUri = _req?.uri; } final List _pushes = []; /// Returns `true` if an attempt to [push] a resource will succeed. /// /// See [ServerTransportStream].`push`. bool get canPush => stream.canPush; /// Returns a [List] of all resources that have [push]ed to the client. List get pushes => List.unmodifiable(_pushes); @override ServerTransportStream detach() { _isDetached = true; return stream; } @override RequestContext? get correspondingRequest => _req; Uri? get targetUri => _targetUri; @override bool get isOpen { return !_isClosed && !_isDetached; } @override bool get isBuffered => _buffer != null; @override BytesBuilder? get buffer => _buffer; // @override // void addError(Object error, [StackTrace? stackTrace]) { // super.addError(error, stackTrace); // } @override void useBuffer() { _buffer = LockableBytesBuilder(); } /// Write headers, status, etc. to the underlying [stream]. bool _openStream() { if (_isPush || _streamInitialized) return false; var headers =
[Header.ascii(':status', statusCode.toString())]; if (encoders.isNotEmpty && correspondingRequest != null) { if (_allowedEncodings != null) { for (var encodingName in _allowedEncodings!) { Converter, List>? encoder; var key = encodingName; if (encoders.containsKey(encodingName)) { encoder = encoders[encodingName]; } else if (encodingName == '*') { encoder = encoders[key = encoders.keys.first]; } if (encoder != null) { this.headers['content-encoding'] = key; break; } } } } // Add all normal headers for (var key in this.headers.keys) { headers.add(Header.ascii(key.toLowerCase(), this.headers[key]!)); } // Persist session ID cookies.add(Cookie('DARTSESSID', _req!.session!.id)); // Send all cookies for (var cookie in cookies) { headers.add(Header.ascii('set-cookie', cookie.toString())); } stream.sendHeaders(headers); return _streamInitialized = true; } Iterable? __allowedEncodings; Iterable? get _allowedEncodings { return __allowedEncodings ??= correspondingRequest?.headers ?.value('accept-encoding') ?.split(',') .map((s) => s.trim()) .where((s) => s.isNotEmpty) .map((str) { // Ignore quality specifications in accept-encoding // ex. gzip;q=0.8 if (!str.contains(';')) return str; return str.split(';')[0]; }); } @override Future addStream(Stream> stream) { if (!isOpen && isBuffered) throw ResponseContext.closed(); _openStream(); var output = stream; if (encoders.isNotEmpty && correspondingRequest != null) { if (_allowedEncodings != null) { for (var encodingName in _allowedEncodings!) { Converter, List>? encoder; var key = encodingName; if (encoders.containsKey(encodingName)) { encoder = encoders[encodingName]; } else if (encodingName == '*') { encoder = encoders[key = encoders.keys.first]; } if (encoder != null) { output = encoders[key]!.bind(output); break; } } } } return output.forEach(this.stream.sendData); } @override void add(List data) { if (!isOpen && isBuffered) { throw ResponseContext.closed(); } else if (!isBuffered) { _openStream(); if (!_isClosed) { if (encoders.isNotEmpty && correspondingRequest != null) { if (_allowedEncodings != null) { for (var encodingName in _allowedEncodings!) { Converter, List>? encoder; var key = encodingName; if (encoders.containsKey(encodingName)) { encoder = encoders[encodingName]; } else if (encodingName == '*') { encoder = encoders[key = encoders.keys.first]; } if (encoder != null) { data = encoders[key]!.convert(data); break; } } } } stream.sendData(data); } } else { buffer!.add(data); } } @override Future close() async { if (!_isDetached && !_isClosed && !isBuffered) { _openStream(); await stream.outgoingMessages.close(); } _isClosed = true; await super.close(); } /// Pushes a resource to the client. Http2ResponseContext push( String path, { Map headers = const {}, String method = 'GET', }) { var targetUri = _req!.uri!.replace(path: path); var h =
[ Header.ascii(':authority', targetUri.authority), Header.ascii(':method', method), Header.ascii(':path', targetUri.path), Header.ascii(':scheme', targetUri.scheme), ]; for (var key in headers.keys) { h.add(Header.ascii(key, headers[key]!)); } var s = stream.push(h); var r = Http2ResponseContext(app, s, _req) .._isPush = true .._targetUri = targetUri; _pushes.add(r); return r; } } ================================================ FILE: packages/framework/lib/src/safe_stream_controller.dart ================================================ import 'dart:async'; typedef _InitCallback = void Function(); /// A [StreamController] boilerplate that prevents memory leaks. abstract class SafeCtrl { factory SafeCtrl() => _SingleSafeCtrl(); factory SafeCtrl.broadcast() => _BroadcastSafeCtrl(); Stream get stream; void add(T event); void addError(Error error, [StackTrace? stackTrace]); Future close(); void whenInitialized(void Function() callback); } class _SingleSafeCtrl implements SafeCtrl { late StreamController _stream; bool _hasListener = false, _initialized = false; _InitCallback? _initializer; _SingleSafeCtrl() { _stream = StreamController( onListen: () { _hasListener = true; if (!_initialized && _initializer != null) { _initializer!(); _initialized = true; } }, onPause: () { _hasListener = false; }, onResume: () { _hasListener = true; }, onCancel: () { _hasListener = false; }, ); } @override Stream get stream => _stream.stream; @override void add(T event) { if (_hasListener) _stream.add(event); } @override void addError(error, [StackTrace? stackTrace]) { if (_hasListener) _stream.addError(error as Object, stackTrace); } @override Future close() { return _stream.close(); } @override void whenInitialized(void Function() callback) { if (!_initialized) { if (!_hasListener) { _initializer = callback; } else { _initializer!(); _initialized = true; } } } } class _BroadcastSafeCtrl implements SafeCtrl { late StreamController _stream; int _listeners = 0; bool _initialized = false; _InitCallback? _initializer; _BroadcastSafeCtrl() { _stream = StreamController.broadcast( onListen: () { _listeners++; if (!_initialized && _initializer != null) { _initializer!(); _initialized = true; } }, onCancel: () { _listeners--; }, ); } @override Stream get stream => _stream.stream; @override void add(T event) { if (_listeners > 0) _stream.add(event); } @override void addError(error, [StackTrace? stackTrace]) { if (_listeners > 0) _stream.addError(error as Object, stackTrace); } @override Future close() { return _stream.close(); } @override void whenInitialized(void Function() callback) { if (!_initialized) { if (_listeners <= 0) { _initializer = callback; } else { _initializer!(); _initialized = true; } } } } ================================================ FILE: packages/framework/lib/src/util.dart ================================================ import 'package:angel3_container/angel3_container.dart'; final RegExp straySlashes = RegExp(r'(^/+)|(/+$)'); T? matchingAnnotation(List metadata) { for (var metaDatum in metadata) { if (metaDatum.type.reflectedType == T) { return metaDatum.reflectee as T?; } } return null; } T? getAnnotation(Object obj, Reflector? reflector) { if (reflector == null) { return null; } else { if (obj is Function) { var methodMirror = reflector.reflectFunction(obj)!; return matchingAnnotation(methodMirror.annotations); } else { var classMirror = reflector.reflectClass(obj.runtimeType)!; return matchingAnnotation(classMirror.annotations); } } } ================================================ FILE: packages/framework/melos_angel3_framework.iml ================================================ ================================================ FILE: packages/framework/performance/hello/angel.md ================================================ # Angel Performance Results 5 consecutive trials run on a Windows 10 box with 4GB RAM, and several programs open in the background. Setup: * Angel framework `1.0.8` * Running `wrk` 4.0.2.2 * 2 threads * 256 connections * 30 seconds Average: * `11070.18` req/sec * `11.86` ms latency ```bash tobe@LAPTOP-VBHCSVRH:/mnt/c/Users/thosa$ wrk -c 256 -d 30 -t 2 http://localhost:3000 Running 30s test @ http://localhost:3000 2 threads and 256 connections Thread Stats Avg Stdev Max +/- Stdev Latency 12.23ms 7.56ms 206.05ms 93.09% Req/Sec 5.48k 761.94 7.18k 87.50% 324822 requests in 30.06s, 62.88MB read Requests/sec: 10806.24 Transfer/sec: 2.09MB tobe@LAPTOP-VBHCSVRH:/mnt/c/Users/thosa$ wrk -c 256 -d 30 -t 2 http://localhost:3000 Running 30s test @ http://localhost:3000 2 threads and 256 connections Thread Stats Avg Stdev Max +/- Stdev Latency 11.06ms 4.88ms 134.86ms 78.68% Req/Sec 5.98k 539.40 7.50k 91.40% 356355 requests in 30.11s, 68.99MB read Requests/sec: 11836.11 Transfer/sec: 2.29MB tobe@LAPTOP-VBHCSVRH:/mnt/c/Users/thosa$ wrk -c 256 -d 30 -t 2 http://localhost:3000 Running 30s test @ http://localhost:3000 2 threads and 256 connections Thread Stats Avg Stdev Max +/- Stdev Latency 12.03ms 6.18ms 159.93ms 87.89% Req/Sec 5.52k 0.88k 7.32k 90.31% 327749 requests in 30.06s, 63.45MB read Requests/sec: 10901.35 Transfer/sec: 2.11MB tobe@LAPTOP-VBHCSVRH:/mnt/c/Users/thosa$ wrk -c 256 -d 30 -t 2 http://localhost:3000 Running 30s test @ http://localhost:3000 2 threads and 256 connections Thread Stats Avg Stdev Max +/- Stdev Latency 12.92ms 7.06ms 189.00ms 82.48% Req/Sec 5.12k 1.00k 6.42k 75.59% 302273 requests in 30.05s, 58.52MB read Requests/sec: 10059.96 Transfer/sec: 1.95MB tobe@LAPTOP-VBHCSVRH:/mnt/c/Users/thosa$ wrk -c 256 -d 30 -t 2 http://localhost:3000 Running 30s test @ http://localhost:3000 2 threads and 256 connections Thread Stats Avg Stdev Max +/- Stdev Latency 11.05ms 4.92ms 104.90ms 69.57% Req/Sec 5.95k 0.87k 7.65k 76.80% 352798 requests in 30.03s, 68.30MB read Requests/sec: 11747.23 Transfer/sec: 2.27MB tobe@LAPTOP-VBHCSVRH:/mnt/c/Users/thosa$ ``` ================================================ FILE: packages/framework/performance/hello/main.dart ================================================ /// A basic server that prints "Hello, world!" library; import 'package:angel3_framework/angel3_framework.dart'; import 'package:angel3_framework/http.dart'; void main() async { var app = Angel(); var http = AngelHttp.custom(app, startShared, useZone: false); app.get('/', (req, res) => res.write('Hello, world!')); app.optimizeForProduction(force: true); var oldHandler = app.errorHandler; app.errorHandler = (e, req, res) { print('Oops: ${e.error ?? e}'); print(e.stackTrace); return oldHandler(e, req, res); }; await http.startServer('127.0.0.1', 3000); print('Listening at ${http.uri}'); } ================================================ FILE: packages/framework/performance/hello/raw.dart ================================================ /// A basic server that prints "Hello, world!" library; import 'dart:io'; Future main() { return HttpServer.bind('127.0.0.1', 3000, shared: true).then((server) { print('Listening at http://${server.address.address}:${server.port}'); server.listen((request) { if (request.uri.path == '/') { request.response.write('Hello, world!'); } request.response.close(); }); }); } ================================================ FILE: packages/framework/performance/hello/raw.md ================================================ # `dart:io` Results 5 consecutive trials run on a Windows 10 box with 4GB RAM, and several programs open in the background. Setup: * Running `wrk` 4.0.2.2 * 2 threads * 256 connections * 30 seconds Average: * `14598.16` req/sec * `8.88` ms latency ```bash tobe@LAPTOP-VBHCSVRH:/mnt/c/Users/thosa$ wrk -c 256 -d 30 -t 2 http://localhost:3000 Running 30s test @ http://localhost:3000 2 threads and 256 connections Thread Stats Avg Stdev Max +/- Stdev Latency 9.67ms 8.19ms 202.28ms 96.17% Req/Sec 7.15k 1.47k 9.97k 73.76% 417716 requests in 30.07s, 82.06MB read Requests/sec: 13892.50 Transfer/sec: 2.73MB tobe@LAPTOP-VBHCSVRH:/mnt/c/Users/thosa$ wrk -c 256 -d 30 -t 2 http://localhost:3000 Running 30s test @ http://localhost:3000 2 threads and 256 connections Thread Stats Avg Stdev Max +/- Stdev Latency 8.47ms 3.14ms 100.77ms 65.40% Req/Sec 7.61k 670.47 8.85k 73.88% 453301 requests in 30.07s, 89.05MB read Requests/sec: 15077.15 Transfer/sec: 2.96MB tobe@LAPTOP-VBHCSVRH:/mnt/c/Users/thosa$ wrk -c 256 -d 30 -t 2 http://localhost:3000 Running 30s test @ http://localhost:3000 2 threads and 256 connections Thread Stats Avg Stdev Max +/- Stdev Latency 8.62ms 3.51ms 73.34ms 63.74% Req/Sec 7.52k 650.22 8.91k 79.17% 448445 requests in 30.07s, 88.10MB read Requests/sec: 14911.53 Transfer/sec: 2.93MB tobe@LAPTOP-VBHCSVRH:/mnt/c/Users/thosa$ wrk -c 256 -d 30 -t 2 http://localhost:3000 Running 30s test @ http://localhost:3000 2 threads and 256 connections Thread Stats Avg Stdev Max +/- Stdev Latency 8.75ms 3.51ms 70.50ms 64.53% Req/Sec 7.41k 825.50 10.23k 72.24% 441338 requests in 30.09s, 86.70MB read Requests/sec: 14665.62 Transfer/sec: 2.88MB tobe@LAPTOP-VBHCSVRH:/mnt/c/Users/thosa$ wrk -c 256 -d 30 -t 2 http://localhost:3000 Running 30s test @ http://localhost:3000 2 threads and 256 connections Thread Stats Avg Stdev Max +/- Stdev Latency 8.90ms 3.62ms 78.36ms 66.71% Req/Sec 7.31k 742.11 10.79k 77.84% 434674 requests in 30.09s, 85.39MB read Requests/sec: 14443.98 Transfer/sec: 2.84MB ``` ================================================ FILE: packages/framework/pubspec.yaml ================================================ name: angel3_framework version: 8.7.0 description: A high-powered HTTP server extensible framework with dependency injection, routing and much more. homepage: https://angel3-framework.web.app/ repository: https://github.com/dart-backend/angel/tree/master/packages/framework resolution: workspace environment: sdk: '>=3.11.0 <4.0.0' dependencies: angel3_container: ^8.0.0 angel3_http_exception: ^8.0.0 angel3_model: ^8.0.0 angel3_route: ^8.0.0 angel3_mock_request: ^8.0.0 belatuk_merge_map: ^5.1.0 belatuk_combinator: ^5.1.0 belatuk_http_server: ^4.1.0 charcode: ^1.3.0 file: ^7.0.0 http_parser: ^4.0.0 http2: ^2.0.0 logging: ^1.1.0 matcher: ^0.12.16 meta: ^1.9.0 mime: ^2.0.0 path: ^1.8.0 quiver: ^3.2.0 recase: ^4.1.0 stack_trace: ^1.11.0 string_scanner: ^1.2.0 tuple: ^2.0.0 uuid: ^4.0.0 collection: ^1.17.0 dev_dependencies: http: ^1.0.0 io: ^1.0.0 test: ^1.24.0 lints: ^6.0.0 ================================================ FILE: packages/framework/test/accepts_test.dart ================================================ import 'dart:async'; import 'dart:io'; import 'package:angel3_container/mirrors.dart'; import 'package:angel3_framework/angel3_framework.dart'; import 'package:angel3_framework/http.dart'; import 'package:angel3_mock_request/angel3_mock_request.dart'; import 'package:test/test.dart'; final Uri endpoint = Uri.parse('http://example.com/accept'); void main() { test('no content type', () async { var req = await acceptContentTypes(); expect(req.acceptsAll, isFalse); //expect(req.accepts(ContentType.JSON), isFalse); expect(req.accepts('application/json'), isFalse); //expect(req.accepts(ContentType.HTML), isFalse); expect(req.accepts('text/html'), isFalse); }); test('wildcard', () async { var req = await acceptContentTypes(['*/*']); expect(req.acceptsAll, isTrue); //expect(req.accepts(ContentType.JSON), isTrue); expect(req.accepts('application/json'), isTrue); //expect(req.accepts(ContentType.HTML), isTrue); expect(req.accepts('text/html'), isTrue); }); test('specific type', () async { var req = await acceptContentTypes(['text/html']); expect(req.acceptsAll, isFalse); //expect(req.accepts(ContentType.JSON), isFalse); expect(req.accepts('application/json'), isFalse); //expect(req.accepts(ContentType.HTML), isTrue); expect(req.accepts('text/html'), isTrue); }); test('strict', () async { var req = await acceptContentTypes(['text/html', '*/*']); expect(req.accepts('text/html'), isTrue); //expect(req.accepts(ContentType.HTML), isTrue); //expect(req.accepts(ContentType.JSON, strict: true), isFalse); expect(req.accepts('application/json', strict: true), isFalse); }); group('disallow null', () { late RequestContext req; setUp(() async { req = await acceptContentTypes(); }); test('throws error', () { expect(() => req.accepts(null), throwsArgumentError); }); }); } Future acceptContentTypes([ Iterable contentTypes = const [], ]) { var headerString = contentTypes.isEmpty ? ContentType.text : contentTypes.join(','); var rq = MockHttpRequest('GET', endpoint, persistentConnection: false); rq.headers.set('accept', headerString); rq.close(); var app = Angel(reflector: MirrorsReflector()); var http = AngelHttp(app); return http.createRequestContext(rq, rq.response); } ================================================ FILE: packages/framework/test/all.dart ================================================ import 'dart:io'; import 'package:io/ansi.dart'; import 'http_404_hole_test.dart' as hole404; import 'accepts_test.dart' as accepts; import 'anonymous_service_test.dart' as anonymous_service; import 'body_test.dart' as body; import 'controller_test.dart' as controller; import 'detach_test.dart' as detach; import 'di_test.dart' as di; import 'encoders_buffer_test.dart' as encoders_buffer; import 'env_test.dart' as env; import 'exception_test.dart' as exception; import 'extension_test.dart' as extension_test; import 'find_one_test.dart' as find_one; import 'general_test.dart' as general; import 'hooked_test.dart' as hooked; import 'parameter_meta_test.dart' as parameter_meta; import 'parse_id_test.dart' as parse_id; import 'precontained_test.dart' as precontained; import 'primitives_test.dart' as primitives; import 'repeat_request_test.dart' as repeat_request; import 'req_shutdown_test.dart' as req_shutdown; import 'routing_test.dart' as routing; import 'serialize_test.dart' as serialize; import 'server_test.dart' as server; import 'service_map_test.dart' as service_map; import 'services_test.dart' as services; import 'streaming_test.dart' as streaming; import 'view_generator_test.dart' as view_generator; //import 'response_header_test.dart' as response_header; import 'package:test/test.dart'; /// For running with coverage void main() { print(cyan.wrap('Running tests on ${Platform.version}')); group('http_404_hole', hole404.main); group('accepts', accepts.main); group('anonymous service', anonymous_service.main); group('body', body.main); //group('response_header', response_header.main); group('controller', controller.main); group('detach', detach.main); group('di', di.main); group('encoders_buffer', encoders_buffer.main); group('env', env.main); group('exception', exception.main); group('extension', extension_test.main); group('find_one', find_one.main); group('general', general.main); group('hooked', hooked.main); group('parameter_meta', parameter_meta.main); group('parse_id', parse_id.main); group('precontained', precontained.main); group('primitives', primitives.main); group('repeat_request', repeat_request.main); group('req_shutdown', req_shutdown.main); group('routing', routing.main); group('serialize', serialize.main); group('server', server.main); group('service_map', service_map.main); group('services', services.main); group('streaming', streaming.main); group('view generator', view_generator.main); } ================================================ FILE: packages/framework/test/anonymous_service_test.dart ================================================ import 'package:angel3_framework/angel3_framework.dart'; import 'package:test/test.dart'; void main() { test('custom methods', () async { var svc = AnonymousService( index: ([p]) async => ['index'], read: (id, [p]) async => 'read', create: (data, [p]) async => 'create', modify: (id, data, [p]) async => 'modify', update: (id, data, [p]) async => 'update', remove: (id, [p]) async => 'remove', ); expect(await svc.index(), ['index']); expect(await svc.read(null), 'read'); expect(await svc.create(null), 'create'); expect(await svc.modify(null, null), 'modify'); expect(await svc.update(null, null), 'update'); expect(await svc.remove(null), 'remove'); }); test('defaults to throwing', () async { try { var svc = AnonymousService(); await svc.read(1); throw 'Should have thrown 405!'; } on AngelHttpException { // print('Ok!'); } try { var svc = AnonymousService(); await svc.modify(2, null); throw 'Should have thrown 405!'; } on AngelHttpException { // print('Ok!'); } try { var svc = AnonymousService(); await svc.update(3, null); throw 'Should have thrown 405!'; } on AngelHttpException { // print('Ok!'); } }); } ================================================ FILE: packages/framework/test/body_test.dart ================================================ import 'dart:async'; import 'dart:convert'; import 'dart:io'; import 'package:angel3_framework/angel3_framework.dart'; import 'package:angel3_framework/http.dart'; import 'package:angel3_mock_request/angel3_mock_request.dart'; import 'package:test/test.dart'; void main() { var app = Angel(); var http = AngelHttp(app); Future request({ bool asJson = true, bool parse = true, Map? bodyFields, List? bodyList, }) async { var rq = MockHttpRequest( 'POST', Uri(path: '/'), persistentConnection: false, ); if (bodyFields != null) { if (asJson) { rq ..headers.contentType = ContentType('application', 'json') ..write(json.encode(bodyFields)); } else { var b = StringBuffer(); var i = 0; for (var entry in bodyFields.entries) { if (i++ > 0) b.write('&'); b.write(entry.key); b.write('='); b.write(Uri.encodeComponent(entry.value.toString())); } rq ..headers.contentType = ContentType( 'application', 'x-www-form-urlencoded', ) ..write(json.encode(b.toString())); } } else if (bodyList != null) { rq ..headers.contentType = ContentType('application', 'json') ..write(json.encode(bodyList)); } await rq.close(); var req = await http.createRequestContext(rq, rq.response); if (parse) await req.parseBody(); return req; } test('parses json maps', () async { var req = await request(bodyFields: {'hello': 'world'}); expect(req.bodyAsObject, TypeMatcher>()); expect(req.bodyAsMap, {'hello': 'world'}); }); test('parses json lists', () async { var req = await request(bodyList: ['foo', 'bar']); expect(req.bodyAsObject, TypeMatcher()); expect(req.bodyAsList, ['foo', 'bar']); }); test('deserializeBody', () async { var req = await request( asJson: true, bodyFields: {'text': 'Hey', 'complete': false}, ); var todo = await req.deserializeBody(Todo.fromMap); expect(todo.text, 'Hey'); expect(todo.completed, false); }); test('decodeBody', () async { var req = await request( asJson: true, bodyFields: {'text': 'Hey', 'complete': false}, ); var todo = await req.decodeBody(TodoCodec()); expect(todo.text, 'Hey'); expect(todo.completed, false); }); test('throws when body has not been parsed', () async { var req = await request(parse: false); expect(() => req.bodyAsObject, throwsStateError); expect(() => req.bodyAsMap, throwsStateError); expect(() => req.bodyAsList, throwsStateError); }); test('can set body object exactly once', () async { var req = await request(parse: false); req.bodyAsObject = 23; expect(req.bodyAsObject, 23); expect(() => req.bodyAsObject = {45.6: '34'}, throwsStateError); }); test('can set body map exactly once', () async { var req = await request(parse: false); req.bodyAsMap = {'hey': 'yes'}; expect(req.bodyAsMap, {'hey': 'yes'}); expect(() => req.bodyAsMap = {'hm': 'ok'}, throwsStateError); }); test('can set body list exactly once', () async { var req = await request(parse: false); req.bodyAsList = [ {'hey': 'yes'}, ]; expect(req.bodyAsList, [ {'hey': 'yes'}, ]); expect( () => req.bodyAsList = [ {'hm': 'ok'}, ], throwsStateError, ); }); } class Todo { String? text; bool? completed; Todo({this.text, this.completed}); static Todo fromMap(Map? m) => Todo(text: m!['text'] as String?, completed: m['complete'] as bool?); } class TodoCodec extends Codec { @override Converter get decoder => TodoDecoder(); @override Converter get encoder => throw UnsupportedError('no encoder'); } class TodoDecoder extends Converter { @override Todo convert(Map input) => Todo.fromMap(input); } ================================================ FILE: packages/framework/test/common.dart ================================================ library; import 'package:angel3_framework/angel3_framework.dart'; import 'package:matcher/matcher.dart'; class Todo extends Model { String? text; String? over; Todo({this.text, this.over}); Map toJson() { return {'text': text, 'over': over}; } } class BookService extends Service { @override Future index([params]) async { print('Book params: $params'); return [ {'foo': 'bar'}, ]; } } void incrementTodoTimes(dynamic e) { IncrementService.times++; } @Hooks(before: [incrementTodoTimes]) class IncrementService extends Service { static int times = 0; @override @Hooks(after: [incrementTodoTimes]) Future index([params]) async => []; } class IsInstanceOf implements Matcher { const IsInstanceOf(); @override Description describeMismatch( item, Description mismatchDescription, Map matchState, bool verbose, ) { return mismatchDescription.add('$item is not an instance of $T'); } @override Description describe(Description description) { return description.add('is an instance of $T'); } @override bool matches(item, Map matchState) => item is T; } ================================================ FILE: packages/framework/test/controller_test.dart ================================================ import 'dart:async'; import 'dart:convert'; import 'dart:io'; import 'package:angel3_container/mirrors.dart'; import 'package:angel3_framework/angel3_framework.dart'; import 'package:angel3_framework/http.dart'; import 'package:http/http.dart' as http; import 'package:angel3_mock_request/angel3_mock_request.dart'; import 'package:test/test.dart'; import 'common.dart'; @Expose('/todos', middleware: [foo]) class TodoController extends Controller { List todos = [Todo(text: 'Hello', over: 'world')]; @Expose('/:id', middleware: [bar]) Future fetchTodo( String id, RequestContext req, ResponseContext res, ) async { expect(req, isNotNull); expect(res, isNotNull); return todos[int.parse(id)]; } @Expose('/namedRoute/:foo', as: 'foo') Future someRandomRoute( RequestContext req, ResponseContext res, ) async { return "${req.params['foo']}!"; } } class NoExposeController extends Controller { String getIndex() => 'Hey!'; int timesTwo(int n) => n * 2; String repeatName(String name, int times) { var b = StringBuffer(); for (var i = 0; i < times; i++) { b.writeln(name); } return b.toString(); } @Expose('/yellow', method: 'POST') String someColor() => 'yellow'; @Expose.patch int three() => 333; @noExpose String hideThis() => 'Should not be exposed'; } @Expose('/named', as: 'foo') class NamedController extends Controller { @Expose('/optional/:arg?', allowNull: ['arg']) int optional() => 2; } bool foo(RequestContext req, ResponseContext res) { res.write('Hello, '); return true; } bool bar(RequestContext req, ResponseContext res) { res.write('world!'); return true; } void main() { late Angel app; late TodoController todoController; late NoExposeController noExposeCtrl; late HttpServer server; var client = http.Client(); String? url; setUp(() async { app = Angel(reflector: MirrorsReflector()); app.get( '/redirect', (req, res) async => res.redirectToAction('TodoController@foo', {'foo': 'world'}), ); // Register as a singleton, just for the purpose of this test if (!app.container.has()) { app.container.registerSingleton(todoController = TodoController()); } // Using mountController(); await app.mountController(); noExposeCtrl = await app.mountController(); // Place controller in group. The applyRoutes() call, however, is async. // Until https://github.com/angel-dart/route/issues/28 is closed, // this will need to be done by manually mounting the router. var subRouter = Router(); await todoController.applyRoutes(subRouter, app.container.reflector); app.mount('/ctrl_group', subRouter); print(app.controllers); app.dumpTree(); server = await AngelHttp(app).startServer(); url = 'http://${server.address.address}:${server.port}'; }); tearDown(() async { await server.close(force: true); url = null; }); test('basic', () { expect(todoController.app, app); }); test('create dynamic handler', () async { var app = Angel(reflector: MirrorsReflector()); app.get( '/foo', ioc(({String? bar}) { return 2; }, optional: ['bar']), ); var rq = MockHttpRequest('GET', Uri(path: 'foo')); await AngelHttp(app).handleRequest(rq); var body = await utf8.decoder.bind(rq.response).join(); expect(json.decode(body), 2); }); test('optional name', () async { var app = Angel(reflector: MirrorsReflector()); await app.configure(NamedController().configureServer); expect(app.controllers['foo'], const IsInstanceOf()); }); test('middleware', () async { var rgx = RegExp('^Hello, world!'); var response = await client.get(Uri.parse('$url/todos/0')); print('Response: ${response.body}'); expect(rgx.firstMatch(response.body)?.start, equals(0)); var todo = json.decode(response.body.replaceAll(rgx, '')) as Map; print('Todo: $todo'); expect(todo['text'], equals('Hello')); expect(todo['over'], equals('world')); }); test('controller in group', () async { var rgx = RegExp('^Hello, world!'); var response = await client.get(Uri.parse('$url/ctrl_group/todos/0')); print('Response: ${response.body}'); expect(rgx.firstMatch(response.body)?.start, equals(0)); var todo = json.decode(response.body.replaceAll(rgx, '')) as Map; print('Todo: $todo'); expect(todo['text'], equals('Hello')); expect(todo['over'], equals('world')); }); test('named actions', () async { var response = await client.get(Uri.parse('$url/redirect')); print('Response: ${response.body}'); expect(response.body, equals('Hello, "world!"')); }); group('optional expose', () { test('removes suffixes from controller names', () { expect(noExposeCtrl.mountPoint!.path, 'no_expose'); }); test('mounts correct routes', () { print(noExposeCtrl.routeMappings.keys); expect(noExposeCtrl.routeMappings.keys.toList(), [ 'getIndex', 'timesTwo', 'repeatName', 'someColor', 'three', ]); }); test('mounts correct methods', () { void expectMethod(String name, String method) { expect(noExposeCtrl.routeMappings[name]!.method, method); } expectMethod('getIndex', 'GET'); expectMethod('timesTwo', 'GET'); expectMethod('repeatName', 'GET'); expectMethod('someColor', 'POST'); expectMethod('three', 'PATCH'); }); test('mounts correct paths', () { void expectPath(String name, String path) { expect(noExposeCtrl.routeMappings[name]!.path, path); } expectPath('getIndex', '/'); expectPath('timesTwo', '/times_two/int:n'); expectPath('repeatName', '/repeat_name/:name/int:times'); expectPath('someColor', '/yellow'); expectPath('three', '/three'); }); }); } ================================================ FILE: packages/framework/test/detach_test.dart ================================================ import 'dart:convert'; import 'package:angel3_framework/angel3_framework.dart'; import 'package:angel3_framework/http.dart'; import 'package:angel3_mock_request/angel3_mock_request.dart'; import 'package:test/test.dart'; void main() { late AngelHttp http; setUp(() async { var app = Angel(); http = AngelHttp(app); app.get('/detach', (req, res) async { if (res is HttpResponseContext) { var io = res.detach(); io.write('Hey!'); await io.close(); } else { throw StateError('This endpoint only supports HTTP/1.1.'); } }); }); tearDown(() => http.close()); test('detach response', () async { var rq = MockHttpRequest('GET', Uri.parse('/detach')); await rq.close(); var rs = rq.response; await http.handleRequest(rq); var body = await rs.transform(utf8.decoder).join(); expect(body, 'Hey!'); }); } ================================================ FILE: packages/framework/test/di_test.dart ================================================ import 'dart:async'; import 'dart:convert'; import 'dart:io'; import 'package:angel3_container/angel3_container.dart'; import 'package:angel3_framework/http.dart'; import 'package:angel3_container/mirrors.dart'; import 'package:angel3_framework/angel3_framework.dart'; import 'package:http/http.dart' as http; import 'package:angel3_mock_request/angel3_mock_request.dart'; import 'package:http/http.dart'; import 'package:test/test.dart'; import 'common.dart'; final String sampleText = 'make your bed'; final String sampleOver = 'never'; void main() { late Angel app; late http.Client client; late HttpServer server; String? url; setUp(() async { app = Angel(reflector: MirrorsReflector()); client = http.Client(); // Inject some todos app.container.registerSingleton(Todo(text: sampleText, over: sampleOver)); app.container.registerFactory>((container) async { var req = container.make(); var text = await utf8.decoder.bind(req.body!).join(); return Foo(text); }); app.get('/errands', ioc((Todo singleton) => singleton)); app.get( '/errands3', ioc( ({required Errand singleton, Todo? foo, RequestContext? req}) => singleton.text, ), ); app.post('/async', ioc((Foo foo) => {'baz': foo.bar})); await app.configure(SingletonController().configureServer); await app.configure(ErrandController().configureServer); server = await AngelHttp(app).startServer(); url = 'http://${server.address.host}:${server.port}'; }); tearDown(() async { url = null; client.close(); await server.close(force: true); }); test('runContained with custom container', () async { var app = Angel(); var c = Container(const MirrorsReflector()); c.registerSingleton(Todo(text: 'Hey!')); app.get('/', (req, res) async { return app.runContained((Todo t) => t.text, req, res, c); }); var rq = MockHttpRequest('GET', Uri(path: '/')); await rq.close(); var rs = rq.response; await AngelHttp(app).handleRequest(rq); var text = await rs.transform(utf8.decoder).join(); expect(text, json.encode('Hey!')); }); test('singleton in route', () async { validateTodoSingleton(await client.get(Uri.parse('$url/errands'))); }); test('singleton in controller', () async { validateTodoSingleton(await client.get(Uri.parse('$url/errands2'))); }); test('make in route', () async { var response = await client.get(Uri.parse('$url/errands3')); var text = await json.decode(response.body) as String?; expect(text, equals(sampleText)); }); test('make in controller', () async { var response = await client.get(Uri.parse('$url/errands4')); var text = await json.decode(response.body) as String?; expect(text, equals(sampleText)); }); test('resolve from future in controller', () async { var response = await client.post( Uri.parse('$url/errands4/async'), body: 'hey', ); expect(response.body, json.encode({'bar': 'hey'})); }); test('resolve from future in route', () async { var response = await client.post(Uri.parse('$url/async'), body: 'yes'); expect(response.body, json.encode({'baz': 'yes'})); }); } void validateTodoSingleton(Response response) { var todo = json.decode(response.body.toString()) as Map; expect(todo['id'], equals(null)); expect(todo['text'], equals(sampleText)); expect(todo['over'], equals(sampleOver)); } @Expose('/errands2') class SingletonController extends Controller { @Expose('/') Todo todo(Todo singleton) => singleton; } @Expose('/errands4') class ErrandController extends Controller { @Expose('/') String? errand(Errand errand) { return errand.text; } @Expose('/async', method: 'POST') Map asyncResolve(Foo foo) { return {'bar': foo.bar}; } } class Foo { final String bar; Foo(this.bar); } class Errand { Todo todo; String? get text => todo.text; Errand(this.todo); } ================================================ FILE: packages/framework/test/encoders_buffer_test.dart ================================================ import 'dart:async'; import 'dart:convert'; import 'dart:io' hide BytesBuilder; import 'dart:typed_data' show BytesBuilder; import 'package:angel3_container/mirrors.dart'; import 'package:angel3_framework/angel3_framework.dart'; import 'package:angel3_framework/http.dart'; import 'package:angel3_mock_request/angel3_mock_request.dart'; import 'package:test/test.dart'; Future> getBody(MockHttpResponse rs) async { var list = await rs.toList(); var bb = BytesBuilder(); list.forEach(bb.add); return bb.takeBytes(); } void main() { late Angel app; setUp(() { app = Angel(reflector: MirrorsReflector()); app.encoders.addAll({'deflate': zlib.encoder, 'gzip': gzip.encoder}); app.get('/hello', (req, res) { res ..useBuffer() ..write('Hello, world!'); }); }); tearDown(() => app.close()); encodingTests(() => app); } void encodingTests(Angel Function() getApp) { group('encoding', () { Angel app; late AngelHttp http; setUp(() { app = getApp(); http = AngelHttp(app); }); test('sends plaintext if no accept-encoding', () async { var rq = MockHttpRequest('GET', Uri.parse('/hello')); await rq.close(); var rs = rq.response; await http.handleRequest(rq); var body = await rs.transform(utf8.decoder).join(); expect(body, 'Hello, world!'); }); test('encodes if wildcard', () async { var rq = MockHttpRequest('GET', Uri.parse('/hello')) ..headers.set('accept-encoding', '*'); await rq.close(); var rs = rq.response; await http.handleRequest(rq); var body = await getBody(rs); //print(rs.headers); expect(rs.headers.value('content-encoding'), 'deflate'); expect(body, zlib.encode(utf8.encode('Hello, world!'))); }); test('encodes if wildcard + multiple', () async { var rq = MockHttpRequest('GET', Uri.parse('/hello')) ..headers.set('accept-encoding', ['foo', 'bar', '*']); await rq.close(); var rs = rq.response; await http.handleRequest(rq); var body = await getBody(rs); expect(rs.headers.value('content-encoding'), 'deflate'); expect(body, zlib.encode(utf8.encode('Hello, world!'))); }); test('encodes if explicit', () async { var rq = MockHttpRequest('GET', Uri.parse('/hello')) ..headers.set('accept-encoding', 'gzip'); await rq.close(); var rs = rq.response; await http.handleRequest(rq); var body = await getBody(rs); expect(rs.headers.value('content-encoding'), 'gzip'); expect(body, gzip.encode(utf8.encode('Hello, world!'))); }); test('only uses one encoder', () async { var rq = MockHttpRequest('GET', Uri.parse('/hello')); rq.headers.set('accept-encoding', ['gzip', 'deflate']); await rq.close(); var rs = rq.response; await http.handleRequest(rq); var body = await getBody(rs); expect(rs.headers.value('content-encoding'), 'gzip'); expect(body, gzip.encode(utf8.encode('Hello, world!'))); }); }); } ================================================ FILE: packages/framework/test/env_test.dart ================================================ import 'dart:io'; import 'package:angel3_framework/angel3_framework.dart'; import 'package:test/test.dart'; void main() { test('custom value', () => expect(AngelEnvironment('hey').value, 'hey')); test('lowercases', () => expect(AngelEnvironment('HeY').value, 'hey')); test( 'default to env or development', () => expect( AngelEnvironment().value, (Platform.environment['ANGEL_ENV'] ?? 'development').toLowerCase(), ), ); test( 'isDevelopment', () => expect(AngelEnvironment('development').isDevelopment, true), ); test('isStaging', () => expect(AngelEnvironment('staging').isStaging, true)); test( 'isDevelopment', () => expect(AngelEnvironment('production').isProduction, true), ); } ================================================ FILE: packages/framework/test/exception_test.dart ================================================ import 'package:angel3_framework/angel3_framework.dart'; import 'dart:convert'; import 'package:test/test.dart'; void main() { test('named constructors', () { expect( AngelHttpException.badRequest(), isException(400, '400 Bad Request'), ); expect( AngelHttpException.notAuthenticated(), isException(401, '401 Not Authenticated'), ); expect( AngelHttpException.paymentRequired(), isException(402, '402 Payment Required'), ); expect(AngelHttpException.forbidden(), isException(403, '403 Forbidden')); expect(AngelHttpException.notFound(), isException(404, '404 Not Found')); expect( AngelHttpException.methodNotAllowed(), isException(405, '405 Method Not Allowed'), ); expect( AngelHttpException.notAcceptable(), isException(406, '406 Not Acceptable'), ); expect(AngelHttpException.methodTimeout(), isException(408, '408 Timeout')); expect(AngelHttpException.conflict(), isException(409, '409 Conflict')); expect( AngelHttpException.notProcessable(), isException(422, '422 Not Processable'), ); expect( AngelHttpException.notImplemented(), isException(501, '501 Not Implemented'), ); expect( AngelHttpException.unavailable(), isException(503, '503 Unavailable'), ); }); test('fromMap', () { expect( AngelHttpException.fromMap({'status_code': -1, 'message': 'ok'}), isException(-1, 'ok'), ); }); test('toMap = toJson', () { var exc = AngelHttpException.badRequest(); expect(exc.toMap(), exc.toJson()); var json_ = json.encode(exc.toJson()); var exc2 = AngelHttpException.fromJson(json_); expect(exc2.toJson(), exc.toJson()); }); test('toString', () { expect( AngelHttpException(statusCode: 420, message: 'Blaze It').toString(), '420: Blaze It', ); }); } Matcher isException(int statusCode, String message) => _IsException(statusCode, message); class _IsException extends Matcher { final int statusCode; final String message; _IsException(this.statusCode, this.message); @override Description describe(Description description) => description.add('has status code $statusCode and message "$message"'); @override bool matches(item, Map matchState) { return item is AngelHttpException && item.statusCode == statusCode && item.message == message; } } ================================================ FILE: packages/framework/test/extension_test.dart ================================================ import 'dart:async'; import 'package:angel3_container/mirrors.dart'; import 'package:angel3_framework/angel3_framework.dart'; import 'package:angel3_framework/http.dart'; import 'package:angel3_mock_request/angel3_mock_request.dart'; import 'package:test/test.dart'; final Uri endpoint = Uri.parse('http://example.com'); void main() { test('single extension', () async { var req = await makeRequest('foo.js'); expect(req.extension, '.js'); }); test('multiple extensions', () async { var req = await makeRequest('foo.min.js'); expect(req.extension, '.js'); }); test('no extension', () async { var req = await makeRequest('foo'); expect(req.extension, ''); }); } Future makeRequest(String path) { var rq = MockHttpRequest('GET', endpoint.replace(path: path))..close(); var app = Angel(reflector: MirrorsReflector()); var http = AngelHttp(app); return http.createRequestContext(rq, rq.response); } ================================================ FILE: packages/framework/test/find_one_test.dart ================================================ import 'package:angel3_framework/angel3_framework.dart'; import 'package:test/test.dart'; import 'common.dart'; void main() { var throwsAnAngelHttpException = throwsA( const IsInstanceOf(), ); /* test('throw 404 on null', () { var service = AnonymousService(index: ([p]) => null); expect(() => service.findOne(), throwsAnAngelHttpException); }); */ test('throw 404 on empty iterable', () { var service = AnonymousService(index: ([p]) => []); expect(() => service.findOne(), throwsAnAngelHttpException); }); test('return first element of iterable', () async { var service = AnonymousService(index: ([p]) => [2]); expect(await service.findOne(), 2); }); } ================================================ FILE: packages/framework/test/general_test.dart ================================================ import 'dart:io'; import 'package:angel3_container/mirrors.dart'; import 'package:angel3_framework/angel3_framework.dart'; import 'package:angel3_framework/http.dart'; import 'dart:convert'; import 'package:http/http.dart' as http; import 'package:test/test.dart'; void main() { late Angel app; late http.Client client; late HttpServer server; late String url; setUp(() async { app = Angel(reflector: MirrorsReflector()) ..post('/foo', (req, res) => res.serialize({'hello': 'world'})) ..all('*', (req, res) => throw AngelHttpException.notFound()); client = http.Client(); server = await AngelHttp(app).startServer(); url = 'http://${server.address.host}:${server.port}'; }); tearDown(() async { client.close(); await server.close(force: true); }); test('allow override of method', () async { var response = await client.get( Uri.parse('$url/foo'), headers: {'X-HTTP-Method-Override': 'POST'}, ); print('Response: ${response.body}'); expect(json.decode(response.body), equals({'hello': 'world'})); }); } ================================================ FILE: packages/framework/test/hm.dart ================================================ import 'dart:async'; import 'package:io/ansi.dart'; import 'all.dart' as hm; void main() async { var zone = Zone.current.fork( specification: ZoneSpecification( print: (self, parent, zone, line) { if (line == 'null') { parent.print(zone, cyan.wrap(StackTrace.current.toString())!); } }, ), ); return await zone.run(hm.main); } ================================================ FILE: packages/framework/test/hooked_test.dart ================================================ import 'dart:convert'; import 'dart:io'; import 'package:angel3_container/mirrors.dart'; import 'package:angel3_framework/angel3_framework.dart'; import 'package:angel3_framework/http.dart'; import 'package:http/http.dart' as http; import 'package:test/test.dart'; import 'common.dart'; void main() { Map headers = { 'Accept': 'application/json', 'Content-Type': 'application/json', }; late Angel app; late HttpServer server; late String url; late http.Client client; late HookedService todoService; setUp(() async { app = Angel(reflector: MirrorsReflector()); client = http.Client(); app.use('/todos', MapService()); app.use('/books', BookService()); todoService = app.findHookedService('todos') as HookedService; todoService.beforeAllStream().listen((e) { print('Fired ${e.eventName}! Data: ${e.data}; Params: ${e.params}'); }); app.errorHandler = (e, req, res) { throw e.error as Object; }; server = await AngelHttp(app).startServer(); url = 'http://${server.address.host}:${server.port}'; }); tearDown(() async { await server.close(force: true); client.close(); }); test('listen before and after', () async { var count = 0; todoService ..beforeIndexed.listen((_) { count++; }) ..afterIndexed.listen((_) { count++; }); var response = await client.get(Uri.parse('$url/todos')); print(response.body); expect(count, equals(2)); }); test('cancel before', () async { todoService.beforeCreated ..listen((HookedServiceEvent event) { event.cancel({'hello': 'hooked world'}); }) ..listen((HookedServiceEvent event) { event.cancel({'this_hook': 'should never run'}); }); var response = await client.post( Uri.parse('$url/todos'), body: json.encode({'arbitrary': 'data'}), headers: headers as Map, ); print(response.body); var result = json.decode(response.body) as Map; expect(result['hello'], equals('hooked world')); }); test('cancel after', () async { todoService.afterIndexed ..listen((HookedServiceEvent event) async { // Hooks can be Futures ;) event.cancel([ {'angel': 'framework'}, ]); }) ..listen((HookedServiceEvent event) { event.cancel({'this_hook': 'should never run either'}); }); var response = await client.get(Uri.parse('$url/todos')); print(response.body); var result = json.decode(response.body) as List; expect(result[0]['angel'], equals('framework')); }); test('asStream() fires', () async { var stream = todoService.afterCreated.asStream(); await todoService.create({'angel': 'framework'}); expect(await stream.first.then((e) => e.result['angel']), 'framework'); }); test('metadata', () async { final service = HookedService(IncrementService())..addHooks(app); expect(service.inner, isNot(const IsInstanceOf())); IncrementService.times = 0; await service.index(); expect(IncrementService.times, equals(2)); }); test('inject request + response', () async { var books = app.findService('books') as HookedService>; books.beforeIndexed.listen((e) { expect([e.request, e.response], everyElement(isNotNull)); print('Indexing books at path: ${e.request?.path}'); }); var response = await client.get(Uri.parse('$url/books')); print(response.body); var result = json.decode(response.body); expect(result, isList); expect(result, isNotEmpty); expect(result[0], equals({'foo': 'bar'})); }); test('contains provider in before and after', () async { var svc = HookedService(AnonymousService(index: ([p]) async => [])); void ensureProviderIsPresent(HookedServiceEvent e) { var type = e.isBefore ? 'before' : 'after'; print('Params to $type ${e.eventName}: ${e.params}'); expect(e.params, isMap); expect(e.params.keys, contains('provider')); expect(e.params['provider'], const IsInstanceOf()); } svc ..beforeAll(ensureProviderIsPresent) ..afterAll(ensureProviderIsPresent); await svc.index({'provider': const Providers('testing')}); }); } ================================================ FILE: packages/framework/test/http2/adapter_test.dart ================================================ import 'dart:async'; import 'dart:convert'; import 'dart:io' hide BytesBuilder; import 'dart:typed_data'; import 'package:angel3_container/mirrors.dart'; import 'package:angel3_framework/angel3_framework.dart' hide Header; import 'package:angel3_framework/http2.dart'; import 'package:collection/collection.dart' show IterableExtension; import 'package:http/src/multipart_file.dart' as http; import 'package:http/src/multipart_request.dart' as http; import 'package:http/io_client.dart'; import 'package:http2/transport.dart'; import 'package:http_parser/http_parser.dart'; import 'package:logging/logging.dart'; import 'package:test/test.dart'; import 'http2_client.dart'; const String jfk = 'Ask not what your country can do for you, but what you can do for your country.'; Stream> jfkStream() { return Stream.fromIterable([utf8.encode(jfk)]); } void main() { var client = Http2Client(); late IOClient h1c; Angel app; late AngelHttp2 http2; late Uri serverRoot; setUp(() async { app = Angel(reflector: MirrorsReflector())..encoders['gzip'] = gzip.encoder; hierarchicalLoggingEnabled = true; app.logger = Logger.detached('angel.http2') ..onRecord.listen((rec) { print(rec); if (rec.error == null) return; print(rec.error); if (rec.stackTrace != null) print(rec.stackTrace); }); app.get('/', (req, res) async { res.write('Hello world'); await res.close(); }); app.all('/method', (req, res) => req.method); app.get('/json', (_, _) => {'foo': 'bar'}); app.get('/stream', (req, res) => jfkStream().pipe(res)); app.get('/headers', (req, res) async { res.headers.addAll({'foo': 'bar', 'x-angel': 'http2'}); await res.close(); }); app.get('/status', (req, res) async { res.statusCode = 1337; await res.close(); }); app.post('/body', (req, res) => req.parseBody().then((_) => req.bodyAsMap)); app.post('/upload', (req, res) async { await req.parseBody(); var body = req.bodyAsMap; var files = req.uploadedFiles ?? []; var file = files.firstWhereOrNull((f) => f.name == 'file')!; return [ await file.data.map((l) => l.length).reduce((a, b) => a + b), file.contentType.mimeType, body, ]; }); app.get('/push', (req, res) async { res.write('ok'); if (res is Http2ResponseContext && res.canPush) { var a = res.push('a')..write('a'); await a.close(); var b = res.push('b')..write('b'); await b.close(); } await res.close(); }); app.get('/param/:name', (req, res) => req.params); app.get('/query', (req, res) { print('incoming URI: ${req.uri}'); return req.queryParameters; }); var ctx = SecurityContext() ..useCertificateChain('dev.pem') ..usePrivateKey('dev.key', password: 'dartdart') ..setAlpnProtocols(['h2'], true); // Create an HTTP client that trusts our server. h1c = IOClient(HttpClient()..badCertificateCallback = (_, _, _) => true); http2 = AngelHttp2(app, ctx, allowHttp1: true); var server = await http2.startServer(); serverRoot = Uri.parse('https://127.0.0.1:${server.port}'); }); tearDown(() async { await http2.close(); h1c.close(); }); test('buffered response', () async { var response = await client.get(serverRoot); expect(response.body, 'Hello world'); }); test('allowHttp1', () async { var response = await h1c.get(serverRoot); expect(response.body, 'Hello world'); }); test('streamed response', () async { var response = await client.get(serverRoot.replace(path: '/stream')); expect(response.body, jfk); }); group('gzip', () { test('buffered response', () async { var response = await client.get( serverRoot, headers: {'accept-encoding': 'gzip, deflate, br'}, ); expect(response.headers['content-encoding'], 'gzip'); var decoded = gzip.decode(response.bodyBytes); expect(utf8.decode(decoded), 'Hello world'); }); test('streamed response', () async { var response = await client.get( serverRoot.replace(path: '/stream'), headers: {'accept-encoding': 'gzip'}, ); expect(response.headers['content-encoding'], 'gzip'); //print(response.body); var decoded = gzip.decode(response.bodyBytes); expect(utf8.decode(decoded), jfk); }); }); test('query uri decoded', () async { var uri = serverRoot.replace( path: '/query', queryParameters: {'foo!': 'bar?'}, ); var response = await client.get(uri); print('Sent $uri'); expect(response.body, json.encode({'foo!': 'bar?'})); }); test('params uri decoded', () async { var response = await client.get(serverRoot.replace(path: '/param/foo!')); expect(response.body, json.encode({'name': 'foo!'})); }); test('method parsed', () async { var response = await client.delete(serverRoot.replace(path: '/method')); expect(response.body, json.encode('DELETE')); }); test('json response', () async { var response = await client.get(serverRoot.replace(path: '/json')); expect(response.body, json.encode({'foo': 'bar'})); expect( ContentType.parse(response.headers['content-type']!).mimeType, ContentType.json.mimeType, ); }); test('status sent', () async { var response = await client.get(serverRoot.replace(path: '/status')); expect(response.statusCode, 1337); }); test('headers sent', () async { var response = await client.get(serverRoot.replace(path: '/headers')); expect(response.headers['foo'], 'bar'); expect(response.headers['x-angel'], 'http2'); }); test('server push', () async { var socket = await SecureSocket.connect( serverRoot.host, serverRoot.port, onBadCertificate: (_) => true, supportedProtocols: ['h2'], ); var connection = ClientTransportConnection.viaSocket( socket, settings: ClientSettings(allowServerPushes: true), ); var headers =
[ Header.ascii(':authority', serverRoot.authority), Header.ascii(':method', 'GET'), Header.ascii(':path', serverRoot.replace(path: '/push').path), Header.ascii(':scheme', serverRoot.scheme), ]; var stream = connection.makeRequest(headers, endStream: true); var bb = await stream.incomingMessages .where((s) => s is DataStreamMessage) .cast() .fold(BytesBuilder(), (out, msg) => out..add(msg.bytes)); // Check that main body was sent expect(utf8.decode(bb.takeBytes()), 'ok'); var pushes = await stream.peerPushes.toList(); expect(pushes, hasLength(2)); var pushA = pushes[0], pushB = pushes[1]; String getPath(TransportStreamPush p) => ascii.decode( p.requestHeaders.firstWhere((h) => ascii.decode(h.name) == ':path').value, ); /* Future getBody(ClientTransportStream stream) async { await stream.outgoingMessages.close(); var bb = await stream.incomingMessages .map((s) { if (s is HeadersStreamMessage) { for (var h in s.headers) { print('${ASCII.decode(h.name)}: ${ASCII.decode(h.value)}'); } } else if (s is DataStreamMessage) { print(UTF8.decode(s.bytes)); } return s; }) .where((s) => s is DataStreamMessage) .cast() .fold( BytesBuilder(), (out, msg) => out..add(msg.bytes)); return UTF8.decode(bb.takeBytes()); } */ expect(getPath(pushA), '/a'); expect(getPath(pushB), '/b'); // However, Chrome, Firefox, Edge all can //expect(await getBody(pushA.stream), 'a'); //expect(await getBody(pushB.stream), 'b'); }); group('body parsing', () { test('urlencoded body parsed', () async { var response = await client.post( serverRoot.replace(path: '/body'), headers: { 'accept': 'application/json', 'content-type': 'application/x-www-form-urlencoded', }, body: 'foo=bar', ); expect(response.body, json.encode({'foo': 'bar'})); }); test('json body parsed', () async { var response = await client.post( serverRoot.replace(path: '/body'), headers: { 'accept': 'application/json', 'content-type': 'application/json', }, body: json.encode({'foo': 'bar'}), ); expect(response.body, json.encode({'foo': 'bar'})); }); test('multipart body parsed', () async { var rq = http.MultipartRequest( 'POST', serverRoot.replace(path: '/upload'), ); rq.headers.addAll({'accept': 'application/json'}); rq.fields['foo'] = 'bar'; rq.files.add( http.MultipartFile( 'file', Stream.fromIterable([utf8.encode('hello world')]), 11, contentType: MediaType('angel', 'framework'), ), ); var response = await client.send(rq); var responseBody = await response.stream.transform(utf8.decoder).join(); expect( responseBody, json.encode([ 11, 'angel/framework', {'foo': 'bar'}, ]), ); }); }); } ================================================ FILE: packages/framework/test/http2/http2_client.dart ================================================ import 'dart:async'; import 'dart:convert'; import 'dart:io' hide BytesBuilder; import 'dart:typed_data'; import 'package:http/http.dart'; import 'package:http2/transport.dart'; /// Simple HTTP/2 client class Http2Client extends BaseClient { static Future convertRequestToStream( BaseRequest request, ) async { // Connect a socket var socket = await SecureSocket.connect( request.url.host, request.url.port, onBadCertificate: (_) => true, supportedProtocols: ['h2'], ); var connection = ClientTransportConnection.viaSocket(socket); var headers =
[ Header.ascii(':authority', request.url.authority), Header.ascii(':method', request.method), Header.ascii( ':path', request.url.path + (request.url.hasQuery ? ('?${request.url.query}') : ''), ), Header.ascii(':scheme', request.url.scheme), ]; var bb = await request.finalize().fold( BytesBuilder(), (out, list) => out..add(list), ); var body = bb.takeBytes(); if (body.isNotEmpty) { headers.add(Header.ascii('content-length', body.length.toString())); } request.headers.forEach((k, v) { headers.add(Header.ascii(k, v)); }); var stream = connection.makeRequest(headers, endStream: body.isEmpty); if (body.isNotEmpty) { stream.sendData(body, endStream: true); } else { await (stream.outgoingMessages.close()); } return stream; } /// Returns `true` if the response stream was closed. static Future readResponse( ClientTransportStream stream, Map headers, BytesBuilder body, ) { var c = Completer(); var closed = false; stream.incomingMessages.listen( (msg) { if (msg is HeadersStreamMessage) { for (var header in msg.headers) { var name = ascii.decode(header.name).toLowerCase(), value = ascii.decode(header.value); headers[name] = value; //print('$name: $value'); } } else if (msg is DataStreamMessage) { body.add(msg.bytes); } if (!closed && msg.endStream) closed = true; }, cancelOnError: true, onError: c.completeError, onDone: () => c.complete(closed), ); return c.future; } @override Future send(BaseRequest request) async { var stream = await convertRequestToStream(request); var headers = {}; var body = BytesBuilder(); var closed = await readResponse(stream, headers, body); return StreamedResponse( Stream.fromIterable([body.takeBytes()]), int.parse(headers[':status']!), headers: headers, isRedirect: headers.containsKey('location'), contentLength: headers.containsKey('content-length') ? int.parse(headers['content-length']!) : null, request: request, reasonPhrase: null, // doesn't exist in HTTP/2 persistentConnection: !closed, ); } } ================================================ FILE: packages/framework/test/http_404_hole_test.dart ================================================ import 'dart:async'; import 'package:angel3_framework/angel3_framework.dart'; import 'package:angel3_framework/http.dart'; import 'package:charcode/ascii.dart'; import 'package:http/io_client.dart' as http; import 'package:logging/logging.dart'; import 'package:test/test.dart'; import 'pretty_log.dart'; void main() { late http.IOClient client; late AngelHttp driver; late Logger logger; setUp(() async { client = http.IOClient(); hierarchicalLoggingEnabled = true; logger = Logger.detached('http_404_hole') ..level = Level.ALL ..onRecord.listen(prettyLog); var app = Angel(logger: logger); app.fallback(hello); app.fallback(throw404); // The error handler in the boilerplate. var oldErrorHandler = app.errorHandler; app.errorHandler = (e, req, res) async { if (req.accepts('text/html', strict: true)) { if (e.statusCode == 404 && req.accepts('text/html', strict: true)) { await res.render('error', { 'message': 'No file exists at ${req.uri}.', }); } else { await res.render('error', {'message': e.message}); } } else { return await oldErrorHandler(e, req, res); } }; driver = AngelHttp(app); await driver.startServer(); }); tearDown(() { logger.clearListeners(); client.close(); scheduleMicrotask(driver.close); }); test('does not continue processing after streaming', () async { var url = driver.uri.replace(path: '/hey'); for (var i = 0; i < 100; i++) { var r = await client.get(url); print('#$i: ${r.statusCode}: ${r.body}'); expect(r.statusCode, 200); expect(r.body, 'Hello!'); } }); } /// Simulate angel_static Future hello(RequestContext req, ResponseContext res) { if (req.path == 'hey') { var bytes = [$H, $e, $l, $l, $o, $exclamation]; var s = Stream>.fromIterable([bytes]); return s.pipe(res); } else { return Future.value(); } } /// 404 void throw404(RequestContext req, ResponseContext res) { Zone.current.handleUncaughtError( 'This 404 should not occur.', StackTrace.current, ); throw AngelHttpException.notFound(); } ================================================ FILE: packages/framework/test/jsonp_test.dart ================================================ import 'dart:async'; import 'dart:convert'; import 'package:angel3_framework/angel3_framework.dart'; import 'package:angel3_framework/http.dart'; import 'package:http_parser/http_parser.dart'; import 'package:angel3_mock_request/angel3_mock_request.dart'; import 'package:test/test.dart'; void main() { var app = Angel(); var http = AngelHttp(app); app.get('/default', (req, res) => res.jsonp({'foo': 'bar'})); app.get( '/callback', (req, res) => res.jsonp({'foo': 'bar'}, callbackName: 'doIt'), ); app.get( '/contentType', (req, res) => res.jsonp({'foo': 'bar'}, contentType: MediaType('foo', 'bar')), ); Future getContentType(String path) async { var rq = MockHttpRequest('GET', Uri(path: '/$path')); await rq.close(); await http.handleRequest(rq); return MediaType.parse(rq.response.headers.contentType.toString()); } Future getText(String path) async { var rq = MockHttpRequest('GET', Uri(path: '/$path')); await rq.close(); await http.handleRequest(rq); return await rq.response.transform(utf8.decoder).join(); } test('default', () async { var response = await getText('default'); var contentType = await getContentType('default'); expect(response, r'callback({"foo":"bar"})'); expect(contentType.mimeType, 'application/javascript'); }); test('callback', () async { var response = await getText('callback'); var contentType = await getContentType('callback'); expect(response, r'doIt({"foo":"bar"})'); expect(contentType.mimeType, 'application/javascript'); }); test('content type', () async { var response = await getText('contentType'); var contentType = await getContentType('contentType'); expect(response, r'callback({"foo":"bar"})'); expect(contentType.mimeType, 'foo/bar'); }); } ================================================ FILE: packages/framework/test/parameter_meta_test.dart ================================================ import 'dart:async'; import 'dart:convert'; import 'package:angel3_container/mirrors.dart'; import 'package:angel3_framework/angel3_framework.dart'; import 'package:angel3_framework/http.dart'; import 'package:angel3_mock_request/angel3_mock_request.dart'; import 'package:logging/logging.dart'; import 'package:test/test.dart'; Future readResponse(MockHttpResponse rs) { return rs.transform(utf8.decoder).join(); } Future printResponse(MockHttpResponse rs) { return readResponse(rs).then((text) { print(text.isEmpty ? '' : text); }); } void main() { group('parameter_meta', parameterMetaTests); } void parameterMetaTests() { Angel app; late AngelHttp http; setUp(() { app = Angel(reflector: MirrorsReflector()); http = AngelHttp(app); app.get( '/cookie', ioc((@CookieValue('token') String jwt) { return jwt; }), ); app.get( '/header', ioc((@Header('x-foo') String header) { return header; }), ); app.get( '/query', ioc((@Query('q') String query) { return query; }), ); app.get( '/session', ioc((@Session('foo') String foo) { return foo; }), ); app.get( '/match', ioc((@Query('mode', match: 'pos') String mode) { return 'YES $mode'; }), ); app.get( '/match', ioc((@Query('mode', match: 'neg') String mode) { return 'NO $mode'; }), ); app.get( '/match', ioc((@Query('mode') String mode) { return 'DEFAULT $mode'; }), ); app.logger = Logger('parameter_meta_test') ..onRecord.listen((rec) { print(rec); if (rec.error != null) print(rec.error); if (rec.stackTrace != null) print(rec.stackTrace); }); }); test('injects header or throws', () async { // Invalid request var rq = MockHttpRequest('GET', Uri.parse('/header')); await rq.close(); var rs = rq.response; //TODO: Using await will hang. To be resolved. http.handleRequest(rq); await printResponse(rs); expect(rs.statusCode, 400); // Valid request rq = MockHttpRequest('GET', Uri.parse('/header')) ..headers.add('x-foo', 'bar'); await rq.close(); rs = rq.response; http.handleRequest(rq); var body = await readResponse(rs); print('Body: $body'); expect(rs.statusCode, 200); expect(body, json.encode('bar')); }); test('injects session or throws', () async { // Invalid request var rq = MockHttpRequest('GET', Uri.parse('/session')); await rq.close(); var rs = rq.response; http .handleRequest(rq) .timeout(const Duration(seconds: 5)) .catchError((_) => null); await printResponse(rs); expect(rs.statusCode, 500); rq = MockHttpRequest('GET', Uri.parse('/session')); rq.session['foo'] = 'bar'; await rq.close(); rs = rq.response; http.handleRequest(rq); await printResponse(rs); expect(rs.statusCode, 200); }); // Originally, the plan was to test cookie, session, header, etc., // but that behavior has been consolidated into `getValue`. Thus, // they will all function the same way. test('pattern matching', () async { var rq = MockHttpRequest('GET', Uri.parse('/match?mode=pos')); await rq.close(); var rs = rq.response; http.handleRequest(rq); var body = await readResponse(rs); print('Body: $body'); expect(rs.statusCode, 200); expect(body, json.encode('YES pos')); rq = MockHttpRequest('GET', Uri.parse('/match?mode=neg')); await rq.close(); rs = rq.response; http.handleRequest(rq); body = await readResponse(rs); print('Body: $body'); expect(rs.statusCode, 200); expect(body, json.encode('NO neg')); // Fallback rq = MockHttpRequest('GET', Uri.parse('/match?mode=ambi')); await rq.close(); rs = rq.response; http.handleRequest(rq); body = await readResponse(rs); print('Body: $body'); expect(rs.statusCode, 200); expect(body, json.encode('DEFAULT ambi')); }); } ================================================ FILE: packages/framework/test/parse_id_test.dart ================================================ import 'package:angel3_framework/angel3_framework.dart'; import 'package:test/test.dart'; void main() { test('null', () { expect(Service.parseId('null'), 'null'); expect(Service.parseId(null), 'null'); }); test('String', () { expect(Service.parseId('23'), '23'); }); test('int', () { expect(Service.parseId('23'), 23); }); test('double', () { expect(Service.parseId('23.4'), 23.4); }); test('num', () { expect(Service.parseId('23.4'), 23.4); }); test('bool', () { expect(Service.parseId('true'), true); expect(Service.parseId(true), true); expect(Service.parseId('false'), false); expect(Service.parseId(false), false); expect(Service.parseId('hmm'), false); }); } ================================================ FILE: packages/framework/test/precontained_test.dart ================================================ import 'dart:convert'; import 'package:angel3_container/mirrors.dart'; import 'package:angel3_framework/angel3_framework.dart'; import 'package:angel3_framework/http.dart'; import 'package:angel3_mock_request/angel3_mock_request.dart'; import 'package:test/test.dart'; void main() { test('preinjects functions', () async { var app = Angel(reflector: MirrorsReflector()) ..configuration['foo'] = 'bar' ..get('/foo', ioc(echoAppFoo)); app.optimizeForProduction(force: true); print(app.preContained); expect(app.preContained.keys, contains(echoAppFoo)); var rq = MockHttpRequest('GET', Uri(path: '/foo')); await rq.close(); await AngelHttp(app).handleRequest(rq); var rs = rq.response; var body = await rs.transform(utf8.decoder).join(); expect(body, json.encode('bar')); }, skip: 'Angel no longer has to preinject functions'); } String echoAppFoo(String foo) => foo; ================================================ FILE: packages/framework/test/pretty_log.dart ================================================ import 'package:logging/logging.dart'; import 'package:io/ansi.dart'; /// Prints the contents of a [LogRecord] with pretty colors. void prettyLog(LogRecord record) { var code = chooseLogColor(record.level); if (record.error == null) print(code.wrap(record.toString())); if (record.error != null) { var err = record.error; print(code.wrap('$record\n')); print(code.wrap(err.toString())); if (record.stackTrace != null) { print(code.wrap(record.stackTrace.toString())); } } } /// Chooses a color based on the logger [level]. AnsiCode chooseLogColor(Level level) { if (level == Level.SHOUT) { return backgroundRed; } else if (level == Level.SEVERE) { return red; } else if (level == Level.WARNING) { return yellow; } else if (level == Level.INFO) { return cyan; } else if (level == Level.CONFIG || level == Level.FINE || level == Level.FINER || level == Level.FINEST) { return lightGray; } return resetAll; } ================================================ FILE: packages/framework/test/primitives_test.dart ================================================ import 'dart:convert'; import 'dart:io' show stderr; import 'package:angel3_container/mirrors.dart'; import 'package:angel3_framework/angel3_framework.dart'; import 'package:angel3_framework/http.dart'; import 'package:angel3_mock_request/angel3_mock_request.dart'; import 'package:test/test.dart'; void main() { late Angel app; late AngelHttp http; setUp(() { app = Angel(reflector: MirrorsReflector()) ..configuration['global'] = 305; // Pitbull! http = AngelHttp(app); app.get('/string/:string', ioc((String string) => string)); app.get( '/num/parsed/:num', chain([ (req, res) { req.params['n'] = num.parse(req.params['num'].toString()); return true; }, ioc((num n) => n), ]), ); app.get('/num/global', ioc((num global) => global)); app.errorHandler = (e, req, res) { stderr ..writeln(e.error) ..writeln(e.stackTrace); }; }); tearDown(() => app.close()); test('String type annotation', () async { var rq = MockHttpRequest('GET', Uri.parse('/string/hello')); await rq.close(); await http.handleRequest(rq); var rs = await rq.response.transform(utf8.decoder).join(); expect(rs, json.encode('hello')); }); test('Primitive after parsed param injection', () async { var rq = MockHttpRequest('GET', Uri.parse('/num/parsed/24')); await rq.close(); await http.handleRequest(rq); var rs = await rq.response.transform(utf8.decoder).join(); expect(rs, json.encode(24)); }); test('globally-injected primitive', () async { var rq = MockHttpRequest('GET', Uri.parse('/num/global')); await rq.close(); await http.handleRequest(rq); var rs = await rq.response.transform(utf8.decoder).join(); expect(rs, json.encode(305)); }); test('unparsed primitive throws error', () async { var rq = MockHttpRequest('GET', Uri.parse('/num/unparsed/32')); await rq.close(); var req = await http.createRequestContext(rq, rq.response); var res = await http.createResponseContext(rq, rq.response, req); expect( () => app.runContained((num unparsed) => unparsed, req, res), throwsA(isA()), ); }); } ================================================ FILE: packages/framework/test/repeat_request_test.dart ================================================ import 'dart:async'; import 'dart:convert'; import 'package:angel3_container/mirrors.dart'; import 'package:angel3_framework/angel3_framework.dart'; import 'package:angel3_framework/http.dart'; import 'package:angel3_mock_request/angel3_mock_request.dart'; import 'package:test/test.dart'; void main() { MockHttpRequest mk(int id) { return MockHttpRequest('GET', Uri.parse('/test/$id'))..close(); } test('can request the same url twice', () async { var app = Angel(reflector: MirrorsReflector()) ..get('/test/:id', ioc((id) => 'Hello $id')); var rq1 = mk(1), rq2 = mk(2), rq3 = mk(1); await Future.wait([rq1, rq2, rq3].map(AngelHttp(app).handleRequest)); var body1 = await rq1.response.transform(utf8.decoder).join(), body2 = await rq2.response.transform(utf8.decoder).join(), body3 = await rq3.response.transform(utf8.decoder).join(); print('Response #1: $body1'); print('Response #2: $body2'); print('Response #3: $body3'); expect(body1, allOf(isNot(body2), equals(body3))); }); } ================================================ FILE: packages/framework/test/req_shutdown_test.dart ================================================ import 'dart:async'; import 'package:angel3_framework/angel3_framework.dart'; import 'package:angel3_framework/http.dart'; import 'package:http/io_client.dart' as http; import 'package:logging/logging.dart'; import 'package:test/test.dart'; import 'pretty_log.dart'; void main() { late http.IOClient client; late AngelHttp driver; late Logger logger; late StringBuffer buf; setUp(() async { buf = StringBuffer(); client = http.IOClient(); hierarchicalLoggingEnabled = true; logger = Logger.detached('req_shutdown') ..level = Level.ALL ..onRecord.listen(prettyLog); var app = Angel(logger: logger); app.fallback((req, res) { req.shutdownHooks.add(() => buf.write('Hello, ')); req.shutdownHooks.add(() => buf.write('world!')); }); driver = AngelHttp(app); await driver.startServer(); }); tearDown(() { logger.clearListeners(); client.close(); scheduleMicrotask(driver.close); }); test('does not continue processing after streaming', () async { await client.get(driver.uri); await Future.delayed(Duration(milliseconds: 100)); expect(buf.toString(), 'Hello, world!'); }); } ================================================ FILE: packages/framework/test/response_header_test.dart ================================================ import 'dart:io'; import 'package:angel3_container/mirrors.dart'; import 'package:angel3_framework/angel3_framework.dart'; import 'package:angel3_framework/src/http/angel_http.dart'; import 'package:test/test.dart'; void main() { late Angel app; late AngelHttp http; late HttpClient client; setUp(() async { app = Angel(reflector: MirrorsReflector()); http = AngelHttp(app); await http.startServer(); var formData = {'id': 100, 'name': 'William'}; app.get('/api/v1/user/list', (RequestContext req, res) async { //await req.parseBody(); //res.write('Hello, World!'); res.json(formData); }); client = HttpClient(); }); tearDown(() async { client.close(); await http.close(); }); test('Remove Response Header', () async { http.removeResponseHeader({'x-frame-options': 'SAMEORIGIN'}); var request = await client.get('localhost', 3000, '/api/v1/user/list'); HttpClientResponse response = await request.close(); //print(response.headers); expect(response.headers['x-frame-options'], isNull); }, skip: true); test('Add Response Header', () async { http.addResponseHeader({ 'X-XSRF_TOKEN': 'a591a6d40bf420404a011733cfb7b190d62c65bf0bcda32b57b277d9ad9f146e', }); var request = await client.get('localhost', 3000, '/api/v1/user/list'); HttpClientResponse response = await request.close(); //print(response.headers); expect( response.headers['X-XSRF_TOKEN'], equals([ 'a591a6d40bf420404a011733cfb7b190d62c65bf0bcda32b57b277d9ad9f146e', ]), ); }, skip: true); } ================================================ FILE: packages/framework/test/routing_test.dart ================================================ import 'dart:convert'; import 'dart:io'; import 'package:angel3_container/mirrors.dart'; import 'package:angel3_framework/angel3_framework.dart'; import 'package:angel3_framework/http.dart'; import 'package:http/http.dart' as http; import 'package:io/ansi.dart'; import 'package:logging/logging.dart'; import 'package:test/test.dart'; import 'common.dart'; @Middleware([interceptor]) Future testMiddlewareMetadata( RequestContext req, ResponseContext res, ) async { return 'This should not be shown.'; } @Middleware([interceptService]) class QueryService extends Service { @override @Middleware([interceptor]) Future read(id, [Map? params]) async => params; } void interceptor(RequestContext req, ResponseContext res) { res ..write('Middleware') ..close(); } bool interceptService(RequestContext req, ResponseContext res) { res.write('Service with '); return true; } void main() { late Angel app; late Angel nested; late Angel todos; late String url; late http.Client client; setUp(() async { app = Angel(reflector: MirrorsReflector()); nested = Angel(reflector: MirrorsReflector()); todos = Angel(reflector: MirrorsReflector()); for (var app in [app, nested, todos]) { app.logger = Logger('routing_test') ..onRecord.listen((rec) { if (rec.error != null) { stdout ..writeln(cyan.wrap(rec.toString())) ..writeln(cyan.wrap(rec.error.toString())) ..writeln(cyan.wrap(rec.stackTrace.toString())); } }); } todos.get('/action/:action', (req, res) => res.json(req.params)); late Route ted; ted = nested.post('/ted/:route', (RequestContext req, res) { print('Params: ${req.params}'); print('Path: ${ted.path}, uri: ${req.path}'); print('matcher: ${ted.parser}'); return req.params; }); app.mount('/nes', nested); app.get('/meta', testMiddlewareMetadata); app.get( '/intercepted', (req, res) => 'This should not be shown', middleware: [interceptor], ); app.get('/hello', (req, res) => 'world'); app.get('/name/:first/last/:last', (req, res) => req.params); app.post( '/lambda', (RequestContext req, res) => req.parseBody().then((_) => req.bodyAsMap), ); app.mount('/todos/:id', todos); app .get( '/greet/:name', (RequestContext req, res) async => "Hello ${req.params['name']}", ) .name = 'Named routes'; app.get('/named', (req, ResponseContext res) async { await res.redirectTo('Named routes', {'name': 'tests'}); }); app.get('/log', (RequestContext req, res) async { print('Query: ${req.queryParameters}'); return 'Logged'; }); app.get('/method', (req, res) => 'Only GET'); app.post('/method', (req, res) => 'Only POST'); app.use('/query', QueryService()); RequestHandler write(String message) { return (req, res) { res.write(message); return true; }; } app .chain([write('a')]) .chain([write('b'), write('c')]) .get('/chained', (req, res) => res.close()); app.fallback((req, res) => 'MJ'); //app.dumpTree(header: "DUMPING ROUTES:", showMatchers: true); client = http.Client(); var server = await AngelHttp(app).startServer('127.0.0.1', 0); url = 'http://${server.address.host}:${server.port}'; }); tearDown(() async { await app.close(); client.close(); }); test('Can match basic url', () async { var response = await client.get(Uri.parse('$url/hello')); expect(response.body, equals('"world"')); }); test('Can match url with multiple parameters', () async { var response = await client.get(Uri.parse('$url/name/HELLO/last/WORLD')); print('Response: ${response.body}'); var json_ = json.decode(response.body); expect(json_, const IsInstanceOf()); expect(json_['first'], equals('HELLO')); expect(json_['last'], equals('WORLD')); }); test('Chained routes', () async { var response = await client.get(Uri.parse('$url/chained')); expect(response.body, equals('abc')); }); test('Can nest another Angel instance', () async { var response = await client.post(Uri.parse('$url/nes/ted/foo')); var json_ = json.decode(response.body); expect(json_['route'], equals('foo')); }); test('Can parse parameters from a nested Angel instance', () async { var response = await client.get(Uri.parse('$url/todos/1337/action/test')); var json_ = json.decode(response.body); print('JSON: $json_'); expect(json_['id'], equals('1337')); expect(json_['action'], equals('test')); }); test('Can add and use named middleware', () async { var response = await client.get(Uri.parse('$url/intercepted')); expect(response.body, equals('Middleware')); }); test('Middleware via metadata', () async { // Metadata var response = await client.get(Uri.parse('$url/meta')); expect(response.body, equals('Middleware')); }); test('Can serialize function result as JSON', () async { Map headers = {'Content-Type': 'application/json'}; var postData = json.encode({'it': 'works'}); var response = await client.post( Uri.parse('$url/lambda'), headers: headers as Map, body: postData, ); print('Response: ${response.body}'); expect(json.decode(response.body)['it'], equals('works')); }); test('Fallback routes', () async { var response = await client.get(Uri.parse('$url/my_favorite_artist')); expect(response.body, equals('"MJ"')); }); /* TODO: Revisit this later test('Can name routes', () { Route foo = app.get('/framework/:id', null)..name = 'frm'; print('Foo: $foo'); String uri = foo.makeUri({'id': 'angel'}); print(uri); expect(uri, equals('framework/angel')); }); */ test('Redirect to named routes', () async { var response = await client.get(Uri.parse('$url/named')); print(response.body); expect(json.decode(response.body), equals('Hello tests')); }); test('Match routes, even with query params', () async { var response = await client.get( Uri.parse('$url/log?foo=bar&bar=baz&baz.foo=bar&baz.bar=foo'), ); print(response.body); expect(json.decode(response.body), equals('Logged')); response = await client.get(Uri.parse('$url/query/foo?bar=baz')); print(response.body); expect(response.body, equals('Service with Middleware')); }); test('only match route with matching method', () async { var response = await client.get(Uri.parse('$url/method')); print(response.body); expect(response.body, '"Only GET"'); response = await client.post(Uri.parse('$url/method')); print(response.body); expect(response.body, '"Only POST"'); response = await client.patch(Uri.parse('$url/method')); print(response.body); expect(response.body, '"MJ"'); }); } ================================================ FILE: packages/framework/test/serialize_test.dart ================================================ import 'dart:io'; import 'package:angel3_container/mirrors.dart'; import 'package:angel3_framework/angel3_framework.dart'; import 'package:angel3_framework/http.dart'; import 'package:http/http.dart' as http; import 'package:http_parser/http_parser.dart'; import 'package:test/test.dart'; void main() { late Angel app; late http.Client client; late HttpServer server; late String url; setUp(() async { app = Angel(reflector: MirrorsReflector()) ..get('/foo', ioc(() => {'hello': 'world'})) ..get('/bar', (req, res) async { await res.serialize({ 'hello': 'world', }, contentType: MediaType('text', 'html')); }); client = http.Client(); server = await AngelHttp(app).startServer(); url = 'http://${server.address.host}:${server.port}'; }); tearDown(() async { client.close(); await server.close(force: true); }); test('correct content-type', () async { var response = await client.get(Uri.parse('$url/foo')); print('Response: ${response.body}'); expect(response.headers['content-type'], contains('application/json')); response = await client.get(Uri.parse('$url/bar')); print('Response: ${response.body}'); expect(response.headers['content-type'], contains('text/html')); }); } ================================================ FILE: packages/framework/test/server_test.dart ================================================ import 'dart:async'; import 'dart:convert'; import 'dart:io'; import 'package:angel3_container/mirrors.dart'; import 'package:angel3_framework/angel3_framework.dart'; import 'package:angel3_framework/http.dart'; import 'package:angel3_mock_request/angel3_mock_request.dart'; import 'package:test/test.dart'; final Uri $foo = Uri.parse('http://localhost:3000/foo'); /// Additional tests to improve coverage of server.dart void main() { group('scoping', () { var parent = Angel(reflector: MirrorsReflector())..configuration['two'] = 2; var child = Angel(reflector: MirrorsReflector()); parent.mount('/child', child); test('sets children', () { expect(parent.children, contains(child)); }); test('sets parent', () { expect(child.parent, parent); }); test('properties can climb up hierarchy', () { expect(child.findProperty('two'), 2); }); }); test('custom server generator', () { var app = Angel(reflector: MirrorsReflector()); var http = AngelHttp.custom(app, HttpServer.bind); expect(http.serverGenerator, HttpServer.bind); }); test('default error handler', () async { var app = Angel(reflector: MirrorsReflector()); var http = AngelHttp(app); var rq = MockHttpRequest('GET', $foo); await (rq.close()); var rs = rq.response; var req = await http.createRequestContext(rq, rs); var res = await http.createResponseContext(rq, rs); var e = AngelHttpException( statusCode: 321, message: 'Hello', errors: ['foo', 'bar'], ); await app.errorHandler(e, req, res); await http.sendResponse(rq, rs, req, res); expect( ContentType.parse(rs.headers.value('content-type')!).mimeType, 'text/html', ); expect(rs.statusCode, e.statusCode); var body = await rs.transform(utf8.decoder).join(); expect(body, contains('${e.message}')); expect(body, contains('
  • foo
  • ')); expect(body, contains('
  • bar
  • ')); }); test('plug-ins run on startup', () async { var app = Angel(reflector: MirrorsReflector()); app.startupHooks.add((app) => app.configuration['two'] = 2); var http = AngelHttp(app); await http.startServer(); expect(app.configuration['two'], 2); await app.close(); await http.close(); }); test('warning when adding routes to flattened router', () { var app = Angel(reflector: MirrorsReflector()) ..optimizeForProduction(force: true); app.dumpTree(); app.get('/', (req, res) => 2); app.mount('/foo', Router()..get('/', (req, res) => 3)); }); test('services close on close call', () async { var app = Angel(reflector: MirrorsReflector()); var svc = CustomCloseService(); expect(svc.value, 2); app.use('/', svc); await app.close(); expect(svc.value, 3); }); test('global injection added to injection map', () async { var app = Angel(reflector: MirrorsReflector())..configuration['a'] = 'b'; var http = AngelHttp(app); app.get('/', ioc((String a) => a)); var rq = MockHttpRequest('GET', Uri.parse('/')); await (rq.close()); await http.handleRequest(rq); var body = await rq.response.transform(utf8.decoder).join(); expect(body, json.encode('b')); }); test('global injected serializer', () async { var app = Angel(reflector: MirrorsReflector())..serializer = (_) => 'x'; var http = AngelHttp(app); app.get($foo.path, (req, ResponseContext res) => res.serialize(null)); var rq = MockHttpRequest('GET', $foo); await (rq.close()); await http.handleRequest(rq); var body = await rq.response.transform(utf8.decoder).join(); expect(body, 'x'); }); group('handler results', () { var app = Angel(reflector: MirrorsReflector()); var http = AngelHttp(app); app.responseFinalizers.add( (req, res) => throw AngelHttpException.forbidden(), ); late RequestContext req; late ResponseContext res; setUp(() async { var rq = MockHttpRequest('GET', $foo); await (rq.close()); req = await http.createRequestContext(rq, rq.response); res = await http.createResponseContext(rq, rq.response); }); group('getHandlerResult', () { test('return request handler', () async { handler(req, res) => (req, res) async { return 2; }; var r = await app.getHandlerResult(handler, req, res); expect(r, 2); }); test('return future', () async { var handler = Future.value(2); expect(await app.getHandlerResult(handler, req, res), 2); }); }); group('executeHandler', () { test('return Stream', () async { handler(req, res) => Stream.fromIterable([2, 3]); expect(await app.executeHandler(handler, req, res), isFalse); }); test('end response', () async { handler(req, ResponseContext res) => res.close(); expect(await app.executeHandler(handler, req, res), isFalse); }); }); }); group('handleAngelHttpException', () { late Angel app; late AngelHttp http; setUp(() async { app = Angel(reflector: MirrorsReflector()); app.get('/wtf', (req, res) => throw AngelHttpException.forbidden()); app.get('/wtf2', (req, res) => throw AngelHttpException.forbidden()); http = AngelHttp(app); await http.startServer('127.0.0.1', 0); var oldHandler = app.errorHandler; app.errorHandler = (e, req, res) { print('FATAL: ${e.error ?? e}'); print(e.stackTrace); return oldHandler(e, req, res); }; }); tearDown(() => app.close()); test('can send json', () async { var rq = MockHttpRequest('GET', Uri(path: 'wtf')) ..headers.set('accept', 'application/json'); await rq.close(); http.handleRequest(rq); await rq.response.toList(); expect(rq.response.statusCode, 403); expect(rq.response.headers.contentType!.mimeType, 'application/json'); }); test('can throw in finalizer', () async { var rq = MockHttpRequest('GET', Uri(path: 'wtf')) ..headers.set('accept', 'application/json'); await rq.close(); http.handleRequest(rq); await rq.response.toList(); expect(rq.response.statusCode, 403); expect(rq.response.headers.contentType!.mimeType, 'application/json'); }); test('can send html', () async { var rq = MockHttpRequest('GET', Uri(path: 'wtf2')); //rq.headers.set('accept', 'text/html'); await rq.close(); http.handleRequest(rq); await rq.response.toList(); expect(rq.response.statusCode, 403); expect(rq.response.headers.contentType?.mimeType, 'text/html'); }); }); } class CustomCloseService extends Service { int value = 2; @override void close() { value = 3; super.close(); } } @Expose('/foo') class FooController extends Controller { @Expose('/bar') Future bar() async => 'baz'; } ================================================ FILE: packages/framework/test/service_map_test.dart ================================================ import 'package:angel3_framework/angel3_framework.dart'; import 'package:test/test.dart'; import 'package:quiver/core.dart'; void main() { MapService inner; late Service mapped; setUp(() { inner = MapService(); mapped = inner.map(Todo.fromMap, Todo.toMap); }); test('create', () async { var result = await mapped.create(Todo(text: 'hello', complete: false)); print(result); expect(result, Todo(text: 'hello', complete: false)); }); group('after create', () { late Todo result; String? id; setUp(() async { result = await mapped.create(Todo(text: 'hello', complete: false)); id = result.id; }); test('index', () async { expect(await mapped.index(), [result]); }); test('modify', () async { var newTodo = Todo(text: 'yes', complete: true); expect(await mapped.update(id, newTodo), newTodo); }); test('update', () async { var newTodo = Todo(id: 'hmmm', text: 'yes', complete: true); expect(await mapped.update(id, newTodo), newTodo); }); test('read', () async { expect(await mapped.read(id), result); }); test('remove', () async { expect(await mapped.remove(id), result); }); }); } class Todo { final String? id, text; final bool? complete; Todo({this.id, this.text, this.complete}); static Todo fromMap(Map json) { return Todo( id: json['id'] as String?, text: json['text'] as String?, complete: json['complete'] as bool?, ); } static Map toMap(Todo model) { return {'id': model.id, 'text': model.text, 'complete': model.complete}; } @override bool operator ==(other) => other is Todo && other.text == text && other.complete == complete; @override String toString() => '$id:$text($complete)'; @override int get hashCode => hash2(text.hashCode, complete.hashCode); } ================================================ FILE: packages/framework/test/services_test.dart ================================================ import 'package:angel3_container/mirrors.dart'; import 'package:angel3_framework/angel3_framework.dart'; import 'package:angel3_framework/http.dart'; import 'dart:convert'; import 'package:http/http.dart' as http; import 'package:stack_trace/stack_trace.dart'; import 'package:test/test.dart'; class Todo extends Model { String? text; String? over; } void main() { Map headers = { 'Accept': 'application/json', 'Content-Type': 'application/json', }; late Angel app; late MapService service; late String url; late http.Client client; setUp(() async { app = Angel(reflector: MirrorsReflector()) ..use('/todos', service = MapService()) ..errorHandler = (e, req, res) { if (e.error != null) print('Whoops: ${e.error}'); if (e.stackTrace != null) print(Chain.forTrace(e.stackTrace!).terse); }; var server = await AngelHttp(app).startServer(); client = http.Client(); url = 'http://${server.address.host}:${server.port}'; }); tearDown(() async { await app.close(); client.close(); }); group('memory', () { test('can index an empty service', () async { var response = await client.get(Uri.parse('$url/todos/')); print(response.body); expect(response.body, equals('[]')); print(response.body); expect(json.decode(response.body).length, 0); }); test('can create data', () async { var postData = json.encode({'text': 'Hello, world!'}); var response = await client.post( Uri.parse('$url/todos'), headers: headers as Map, body: postData, ); expect(response.statusCode, 201); var jsons = json.decode(response.body); print(jsons); expect(jsons['text'], equals('Hello, world!')); }); test('can fetch data', () async { var postData = json.encode({'text': 'Hello, world!'}); await client.post( Uri.parse('$url/todos'), headers: headers as Map, body: postData, ); var response = await client.get(Uri.parse('$url/todos/0')); expect(response.statusCode, 200); var jsons = json.decode(response.body); print(jsons); expect(jsons['text'], equals('Hello, world!')); }); test('can modify data', () async { var postData = json.encode({'text': 'Hello, world!'}); await client.post( Uri.parse('$url/todos'), headers: headers as Map, body: postData, ); postData = json.encode({'text': 'modified'}); var response = await client.patch( Uri.parse('$url/todos/0'), headers: headers, body: postData, ); expect(response.statusCode, 200); var jsons = json.decode(response.body); print(jsons); expect(jsons['text'], equals('modified')); }); test('can overwrite data', () async { var postData = json.encode({'text': 'Hello, world!'}); await client.post( Uri.parse('$url/todos'), headers: headers as Map, body: postData, ); postData = json.encode({'over': 'write'}); var response = await client.post( Uri.parse('$url/todos/0'), headers: headers, body: postData, ); expect(response.statusCode, 200); var jsons = json.decode(response.body); print(jsons); expect(jsons['text'], equals(null)); expect(jsons['over'], equals('write')); }); test('readMany', () async { var items = [ await service.create({'foo': 'bar'}), await service.create({'bar': 'baz'}), await service.create({'baz': 'quux'}), ]; var ids = items.map((m) => m['id'] as String?).toList(); expect(await service.readMany(ids), items); }); test('can delete data', () async { var postData = json.encode({'text': 'Hello, world!'}); var created = await client .post( Uri.parse('$url/todos'), headers: headers as Map, body: postData, ) .then((r) => json.decode(r.body)); var response = await client.delete( Uri.parse("$url/todos/${created['id']}"), ); expect(response.statusCode, 200); var json_ = json.decode(response.body); print(json_); expect(json_['text'], equals('Hello, world!')); }); test('cannot remove all unless explicitly set', () async { var response = await client.delete(Uri.parse('$url/todos/null')); expect(response.statusCode, 403); }); }); } ================================================ FILE: packages/framework/test/streaming_test.dart ================================================ import 'dart:async'; import 'dart:convert'; import 'dart:io'; import 'package:angel3_container/mirrors.dart'; import 'package:angel3_framework/angel3_framework.dart'; import 'package:angel3_framework/http.dart'; import 'package:logging/logging.dart'; import 'package:angel3_mock_request/angel3_mock_request.dart'; import 'package:test/test.dart'; import 'encoders_buffer_test.dart' show encodingTests; void main() { late Angel app; late AngelHttp http; setUp(() { app = Angel(reflector: MirrorsReflector()); http = AngelHttp(app, useZone: true); app.logger = Logger('streaming_test') ..onRecord.listen((rec) { print(rec); if (rec.stackTrace != null) print(rec.stackTrace); }); app.encoders.addAll({'deflate': zlib.encoder, 'gzip': gzip.encoder}); app.get('/hello', (req, res) { return Stream>.fromIterable([ 'Hello, world!'.codeUnits, ]).pipe(res); }); app.get('/write', (req, res) async { await res.addStream( Stream>.fromIterable(['Hello, world!'.codeUnits]), ); res.write('bye'); await res.close(); }); app.get('/multiple', (req, res) async { await res.addStream( Stream>.fromIterable(['Hello, world!'.codeUnits]), ); await res.addStream(Stream>.fromIterable(['bye'.codeUnits])); await res.close(); }); app.get('/overwrite', (req, res) async { res.statusCode = 32; await Stream>.fromIterable([ 'Hello, world!'.codeUnits, ]).pipe(res); var f = Stream>.fromIterable([ 'Hello, world!'.codeUnits, ]).pipe(res).then((_) => false).catchError((_) => true); expect(f, completion(true)); }); app.get('/error', (req, res) => res.addError(StateError('wtf'))); app.errorHandler = (e, req, res) async { stderr ..writeln(e.error) ..writeln(e.stackTrace); }; }); tearDown(() => http.close()); void expectHelloBye(String path) async { var rq = MockHttpRequest('GET', Uri.parse(path)); await (rq.close()); await http.handleRequest(rq); var body = await rq.response.transform(utf8.decoder).join(); expect(body, 'Hello, world!bye'); } test('write after addStream', () => expectHelloBye('/write')); test('multiple addStream', () => expectHelloBye('/multiple')); test('cannot write after close', () async { try { var rq = MockHttpRequest('GET', Uri.parse('/overwrite')); await rq.close(); await http.handleRequest(rq); var body = await rq.response.transform(utf8.decoder).join(); if (rq.response.statusCode != 32) { throw 'overwrite should throw error; response: $body'; } } on StateError { // Success } }); test('res => addError', () async { try { var rq = MockHttpRequest('GET', Uri.parse('/error')); await (rq.close()); await http.handleRequest(rq); var body = await rq.response.transform(utf8.decoder).join(); throw 'addError should throw error; response: $body'; } on StateError { // Should throw error... } }); encodingTests(() => app); } ================================================ FILE: packages/framework/test/view_generator_test.dart ================================================ import 'package:angel3_framework/angel3_framework.dart'; import 'package:test/test.dart'; void main() { test('default view generator', () async { var app = Angel(); var view = await app.viewGenerator!('foo', {'bar': 'baz'}); expect(view, contains('No view engine')); }); } ================================================ FILE: packages/html/AUTHORS.md ================================================ 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. * __[Tobe O](thosakwe@gmail.com)__ Tobe has written much of the original code prior to NNBD migration. He has moved on and is no longer involved with the project. ================================================ FILE: packages/html/CHANGELOG.md ================================================ # Change Log ## 8.4.0 * Require Dart >= 3.11 ## 8.3.0 * Require Dart >= 3.8 * Updated `lints` to 6.0.0 * Updated dependencies to the latest release ## 8.2.0 * Require Dart >= 3.6 * Updated `lints` to 5.0.0 * Updated dependencies to the latest release ## 8.1.0 * Require Dart >= 3.3 * Updated `lints` to 4.0.0 ## 8.0.0 * Require Dart >= 3.0 * Updated `lints` to 3.0.0 * Fixed linter warnings * Updated repository link ## 7.0.0 * Require Dart >= 2.17 ## 6.0.0 * Require Dart >= 2.16 ## 5.0.0 * Skipped release ## 4.0.0 * No release Skipped ## 3.0.0 * Migrated to support Dart >= 2.12 NNBD ## 2.0.0 * Angel 2 + Dart 2 updates. ================================================ FILE: packages/html/LICENSE ================================================ BSD 3-Clause License Copyright (c) 2021, dukefirehawk.com All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: 1. Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. 2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. 3. Neither the name of the copyright holder nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. ================================================ FILE: packages/html/README.md ================================================ # Angel3 HTML ![Pub Version (including pre-releases)](https://img.shields.io/pub/v/angel3_html?include_prereleases) [![Null Safety](https://img.shields.io/badge/null-safety-brightgreen)](https://dart.dev/null-safety) [![Discord](https://img.shields.io/discord/1060322353214660698)](https://discord.gg/3X6bxTUdCM) [![License](https://img.shields.io/github/license/dart-backend/angel)](https://github.com/dart-backend/angel/tree/master/packages/html/LICENSE) A plug-in that allows you to return `belatuk_html_builder` AST's from request handlers, and have them sent as HTML automatically. [`package:belatuk_html_builder`](https://pub.dev/packages/belatuk_html_builder) is a simple virtual DOM library with a handy Dart DSL that makes it easy to build HTML AST's: ```dart import 'package:belatuk_html_builder/elements.dart'; Node myDom = html(lang: 'en', c: [ head(c: [ meta(name: 'viewport', content: 'width=device-width, initial-scale=1'), title(c: [ text('html_builder example page') ]), ]), body(c: [ h1(c: [ text('Hello world!'), ]), ]), ]); ``` This plug-in means that you can now `return` these AST's, and Angel will automatically send them to clients. Ultimately, the implication is that you can use `belatuk_html_builder` as a substitute for a templating system within Dart. With [hot reloading](https://pub.dev/packages/angel3_hot), you won't even need to reload your server (as it should be). ## Installation In your `pubspec.yaml`: ```yaml dependencies: angel3_html: ^6.0.0 ``` ## Usage The `renderHtml` function does all the magic for you. ```dart configureServer(Angel app) async { // Wire it up! app.fallback(renderHtml()); // You can pass a custom StringRenderer if you need more control over the output. app.fallback(renderHtml(renderer: new StringRenderer(html5: false))); app.get('/greet/:name', (RequestContext req) { return html(lang: 'en', c: [ head(c: [ meta(name: 'viewport', content: 'width=device-width, initial-scale=1'), title(c: [ text('Greetings!') ]), ]), body(c: [ h1(c: [ text('Hello, ${req.params['id']}!'), ]), ]), ]); }); } ``` By default, `renderHtml` will ignore the client's `Accept` header. However, if you pass `enforceAcceptHeader` as `true`, then a `406 Not Acceptable` error will be thrown if the client doesn't accept `*/*` or `text/html`. ```dart configureServer(Angel app) async { // Wire it up! app.fallback(renderHtml(enforceAcceptHeader: true)); // ... } ``` ================================================ FILE: packages/html/analysis_options.yaml ================================================ include: package:lints/recommended.yaml ================================================ FILE: packages/html/example/main.dart ================================================ import 'package:angel3_framework/angel3_framework.dart'; import 'package:angel3_framework/http.dart'; import 'package:angel3_html/angel3_html.dart'; import 'package:belatuk_html_builder/elements.dart'; import 'package:logging/logging.dart'; void main() async { var app = Angel(); var http = AngelHttp(app); app.logger = Logger('angel_html') ..onRecord.listen((rec) { print(rec); if (rec.error != null) print(rec.error); if (rec.stackTrace != null) print(rec.stackTrace); }); app.fallback(renderHtml()); app.get('/html', (req, res) { return html( c: [ head( c: [ title(c: [text('ok')]), ], ), ], ); }); app.get( '/strict', chain([ renderHtml( enforceAcceptHeader: true, renderer: StringRenderer( //doctype: null, pretty: false, ), ), (req, res) { return div(c: [text('strict')]); }, ]), ); app.fallback((req, res) => throw AngelHttpException.notFound()); await http.startServer('127.0.0.1', 3000); print('Listening at ${http.uri}'); } ================================================ FILE: packages/html/lib/angel3_html.dart ================================================ import 'dart:async'; import 'package:angel3_framework/angel3_framework.dart'; import 'package:belatuk_html_builder/belatuk_html_builder.dart'; /// Returns a [RequestMiddleware] that allows you to return `html_builder` [Node]s as responses. /// /// You can provide a custom [renderer]. The default renders minified HTML5 pages. /// /// Set [enforceAcceptHeader] to `true` to throw a `406 Not Acceptable` if the client doesn't accept HTML responses. RequestHandler renderHtml({ StringRenderer? renderer, bool? enforceAcceptHeader, }) { renderer ??= StringRenderer(pretty: false, html5: true); return (RequestContext req, ResponseContext res) { var oldSerializer = res.serializer; res.serializer = (data) { if (data is! Node) { return oldSerializer(data); } else { if (enforceAcceptHeader == true && !req.accepts('text/html')) { throw AngelHttpException.notAcceptable(); } var content = renderer!.render(data); res ..headers['content-type'] = 'text/html' ..write(content); res.close(); return ''; } }; return Future.value(true); }; } ================================================ FILE: packages/html/melos_angel3_html.iml ================================================ ================================================ FILE: packages/html/pubspec.yaml ================================================ name: angel3_html version: 8.4.0 description: Support for rendering html_builder AST's as responses in Angel. homepage: https://angel3-framework.web.app/ repository: https://github.com/dart-backend/angel/tree/angel3/packages/html_builder resolution: workspace environment: sdk: '>=3.11.0 <4.0.0' dependencies: angel3_framework: ^8.4.0 belatuk_html_builder: ^5.0.0 dev_dependencies: angel3_test: ^8.2.0 html: ^0.15.0 logging: ^1.0.1 test: ^1.21.0 lints: ^6.0.0 ================================================ FILE: packages/html/test/all_test.dart ================================================ import 'package:angel3_framework/angel3_framework.dart'; import 'package:angel3_html/angel3_html.dart'; import 'package:angel3_test/angel3_test.dart'; import 'package:belatuk_html_builder/elements.dart'; import 'package:test/test.dart'; void main() { Angel app; late TestClient client; setUp(() async { app = Angel(); app.fallback(renderHtml()); app.get('/html', (req, res) { return html( c: [ head( c: [ title(c: [text('ok')]), ], ), ], ); }); app.get( '/strict', chain([ renderHtml( enforceAcceptHeader: true, renderer: StringRenderer( //doctype: null, pretty: false, ), ), (req, res) { return div(c: [text('strict')]); }, ]), ); client = await connectTo(app); }); tearDown(() => client.close()); test('sets content type and body', () async { var response = await client.get(Uri.parse('/html')); print('Response: ${response.body}'); expect( response, allOf( hasContentType('text/html'), hasBody('ok'), ), ); }); group('enforce accept header', () { test('sends if correct accept or wildcard', () async { var response = await client.get( Uri.parse('/strict'), headers: {'accept': '*/*'}, ); print('Response: ${response.body}'); expect( response, allOf(hasContentType('text/html'), hasBody('
    strict
    ')), ); response = await client.get( Uri.parse('/strict'), headers: {'accept': 'text/html,application/json,text/xml'}, ); print('Response: ${response.body}'); expect( response, allOf(hasContentType('text/html'), hasBody('
    strict
    ')), ); }); test('throws if incorrect or no accept', () async { var response = await client.get(Uri.parse('/strict')); print('Response: ${response.statusCode} ${response.body}'); expect(response, hasStatus(406)); response = await client.get( Uri.parse('/strict'), headers: {'accept': 'application/json,text/xml'}, ); print('Response: ${response.body}'); expect( response, isAngelHttpException(statusCode: 406, message: '406 Not Acceptable'), ); }); }); } ================================================ FILE: packages/jael/LICENSE ================================================ BSD 3-Clause License Copyright (c) 2021, dukefirehawk.com All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: 1. Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. 2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. 3. Neither the name of the copyright holder nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. ================================================ FILE: packages/jael/README.md ================================================ # JAEL3 ![Pub Version (including pre-releases)](https://img.shields.io/pub/v/jael3?include_prereleases) A simple server-side HTML templating engine for Dart. Though its syntax is but a superset of HTML, it supports features such as: * **Custom elements** * Loops * Conditionals * Template inheritance * Block scoping * `switch` syntax * Interpolation of any Dart expression Jael3 is a good choice for applications of any scale, especially when the development team is small, or the time invested in building an SPA would be too much. ## Documentation Each of the [packages within this repository](#this-repository) contains some sort of documentation. Documentation for Jael syntax and directives has been **moved** to the [Angel3 framework wiki](https://angel3-docs.dukefirehawk.com/packages/front-end/jael). ## This Repository Within this repository are three packages: * `package:jael3` - Contains the Jael parser, AST, and HTML renderer. * `package:jael3_preprocessor` - Handles template inheritance, and facilitates the use of "compile-time" constructs. * `package:angel3_jael` - [Angel3](https://angel3-framework.web.app/) support for Jael. ================================================ FILE: packages/jael/angel_jael/AUTHORS.md ================================================ 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. * __[Tobe O](thosakwe@gmail.com)__ Tobe has written much of the original code prior to NNBD migration. He has moved on and is no longer involved with the project. ================================================ FILE: packages/jael/angel_jael/CHANGELOG.md ================================================ # Change Log ## 8.5.0 * Require Dart >= 3.11 ## 8.4.0 * Require Dart >= 3.8 * Updated `lints` to 6.0.0 * Updated dependencies to the latest release ## 8.3.0 * Require Dart >= 3.6 * Updated `lints` to 5.0.0 * Updated dependencies to the latest release ## 8.2.0 * Require Dart >= 3.3 * Updated `lints` to 4.0.0 ## 8.1.1 * Updated repository link ## 8.1.0 * Updated `lints` to 3.0.0 * Fixed linter warnings ## 8.0.0 * Require Dart >= 3.0 ## 7.0.0 * Require Dart >= 2.17 ## 6.0.1 * Updated `jael3` * Updated `jael_preprocessor` ## 6.0.0 * Require Dart >= 2.16 ## 5.0.0 * Skipped release ## 4.3.1 * Removed debug message ## 4.3.0 * Added `jaelTemplatePreload` to preload all JAEL templates into a cache ## 4.2.3 * Turned on generated HTML minification by default ## 4.2.2 * Turned on JAEL template caching by default ## 4.2.1 * Added `minified` parameter for generating minified HTML output ## 4.2.0 * Updated to use `package:belatuk_code_buffer` ## 4.1.0 * Updated to use `package:belatuk_symbol_table` * Updated linter to `package:lints` ## 4.0.0 * Migrated to support Dart >= 2.12 NNBD ## 3.0.0 * Migrated to work with Dart >= 2.12 Non NNBD ## 2.0.0 * Angel 2 and Dart 2 updates. * Default to `.jael` instead of `.jl`. ## 1.0.3 * Update for annoying map casting bug. ## 1.0.2 * Update for DSX support. * Clear the buffer on errors. ## 1.0.1 * Use `Renderer.errorDocument`. ================================================ FILE: packages/jael/angel_jael/LICENSE ================================================ BSD 3-Clause License Copyright (c) 2021, dukefirehawk.com All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: 1. Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. 2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. 3. Neither the name of the copyright holder nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. ================================================ FILE: packages/jael/angel_jael/README.md ================================================ # Angel3 Jael ![Pub Version (including pre-releases)](https://img.shields.io/pub/v/angel3_jael?include_prereleases) [![Null Safety](https://img.shields.io/badge/null-safety-brightgreen)](https://dart.dev/null-safety) [![Discord](https://img.shields.io/discord/1060322353214660698)](https://discord.gg/3X6bxTUdCM) [![License](https://img.shields.io/github/license/dart-backend/angel)](https://github.com/dart-backend/angel/tree/master/packages/jael/angel_jael/LICENSE) [Angel 3](https://pub.dev/packages/angel3_framework) support for [Jael 3](https://pub.dev/packages/jael3). ## Installation In your `pubspec.yaml`: ```yaml dependencies: angel3_jael: ^8.0.0 ``` ## Usage Just like `mustache` and other renderers, configuring Angel to use Jael is as simple as calling `app.configure`: ```dart import 'package:angel3_framework/angel3_framework.dart'; import 'package:angel3_jael/angel3_jael.dart'; import 'package:file/file.dart'; AngelConfigurer myPlugin(FileSystem fileSystem) { return (Angel app) async { // Connect Jael to your server... await app.configure( jael(fileSystem.directory('views')), ); }; } ``` `package:angel3_jael` supports caching views and minified html output by default, to improve performance. You might want to disable them in development, so consider setting these flags to `false`: ```dart jael(viewsDirectory, cacheViews: false, minified: false); ``` Keep in mind that this package uses `package:file`, rather than `dart:io`. The following is a basic example of a server setup that can render Jael templates from a directory named `views`: ```dart import 'package:angel3_framework/angel3_framework.dart'; import 'package:angel3_jael/angel3_jael.dart'; import 'package:file/local.dart'; import 'package:logging/logging.dart'; void main() async { var app = Angel(); var fileSystem = const LocalFileSystem(); await app.configure( jael(fileSystem.directory('views')), ); // Render the contents of views/index.jael app.get('/', (res) => res.render('index', {'title': 'ESKETTIT'})); app.use(() => throw AngelHttpException.notFound()); app.logger = Logger('angel') ..onRecord.listen((rec) { print(rec); if (rec.error != null) print(rec.error); if (rec.stackTrace != null) print(rec.stackTrace); }); var server = await app.startServer(null, 3000); print('Listening at http://${server.address.address}:${server.port}'); } ``` To apply additional transforms to parsed documents, provide a set of `patch` functions, like in `package:jael3_preprocessor`. ## Performance Optimization For handling large volume of initial requests, consider using `jaelTemplatePreload` to preload all the JAEL templates into an external cache. ```dart var templateDir = fileSystem.directory('views'); // Preload JAEL view templates into cache var viewCache = {}; jaelTemplatePreload(templateDir, viewCache); // Inject cache into JAEL renderer await app.configure( jael(fileSystem.directory('views'), cache: viewCache), ); ``` ================================================ FILE: packages/jael/angel_jael/analysis_options.yaml ================================================ include: package:lints/recommended.yaml ================================================ FILE: packages/jael/angel_jael/example/main.dart ================================================ import 'dart:convert'; import 'package:angel3_framework/angel3_framework.dart'; import 'package:angel3_framework/http.dart'; import 'package:angel3_jael/angel3_jael.dart'; import 'package:file/local.dart'; import 'package:logging/logging.dart'; void main() async { var app = Angel(); var http = AngelHttp(app); var fileSystem = const LocalFileSystem(); await app.configure(jael(fileSystem.directory('views'))); app.get( '/', (req, res) => res.render('index', {'title': 'Sample App', 'message': null}), ); app.post('/', (req, res) async { var body = await req.parseBody().then((_) => req.bodyAsMap); print('Body: $body'); var msg = body['message'] ?? ''; return await res.render('index', { 'title': 'Form Submission', 'message': msg, 'json_message': json.encode(msg), }); }); app.fallback((req, res) => throw AngelHttpException.notFound()); app.logger = Logger('angel') ..onRecord.listen((rec) { print(rec); if (rec.error != null) print(rec.error); if (rec.stackTrace != null) print(rec.stackTrace); }); var server = await http.startServer('127.0.0.1', 3000); print('Listening at http://${server.address.address}:${server.port}'); } ================================================ FILE: packages/jael/angel_jael/example/views/index.jael ================================================ You said: {{ message }}

    ================================================ FILE: packages/jael/angel_jael/example/views/layout.jael ================================================ {{title}}

    {{title}}

    Content goes here. ================================================ FILE: packages/jael/angel_jael/lib/angel3_jael.dart ================================================ import 'package:angel3_framework/angel3_framework.dart'; import 'package:belatuk_code_buffer/belatuk_code_buffer.dart'; import 'package:file/file.dart'; import 'package:jael3/jael3.dart'; import 'package:jael3_preprocessor/jael3_preprocessor.dart'; import 'package:belatuk_symbol_table/belatuk_symbol_table.dart'; /// Configures an Angel server to use Jael to render templates. /// /// To enable "minified" output, set minified to true /// /// For custom HTML formating, you need to override the [createBuffer] parameter /// with a function that returns a new instance of [CodeBuffer]. /// /// To apply additional transforms to parsed documents, provide a set of [patch] functions. AngelConfigurer jael( Directory viewsDirectory, { String fileExtension = '.jael', bool strictResolution = false, bool cacheViews = true, Map? cache, Iterable patch = const [], bool asDSX = false, bool minified = true, CodeBuffer Function()? createBuffer, }) { var localCache = cache ?? {}; var bufferFunc = createBuffer ?? () => CodeBuffer(); if (minified) { bufferFunc = () => CodeBuffer(space: '', newline: ''); } return (Angel app) async { app.viewGenerator = (String name, [Map? locals]) async { var errors = []; Document? processed; //var stopwatch = Stopwatch()..start(); if (cacheViews && localCache.containsKey(name)) { processed = localCache[name]; } else { processed = await _loadViewTemplate( viewsDirectory, name, fileExtension: fileExtension, asDSX: asDSX, patch: patch, ); if (cacheViews) { localCache[name] = processed!; } } //print('Time executed: ${stopwatch.elapsed.inMilliseconds}'); //stopwatch.stop(); var buf = bufferFunc(); var scope = SymbolTable( values: locals?.keys.fold>( {}, (out, k) => out..[k.toString()] = locals[k], ) ?? {}, ); if (errors.isEmpty) { try { const Renderer().render( processed!, buf, scope, strictResolution: strictResolution, ); return buf.toString(); } on JaelError catch (e) { errors.add(e); } } Renderer.errorDocument(errors, buf..clear()); return buf.toString(); }; }; } /// Preload all of Jael templates into a cache /// /// /// To apply additional transforms to parsed documents, provide a set of [patch] functions. Future jaelTemplatePreload( Directory viewsDirectory, Map cache, { String fileExtension = '.jael', bool asDSX = false, Iterable patch = const [], }) async { await viewsDirectory.list(recursive: true).forEach((f) async { if (f.basename.endsWith(fileExtension)) { var name = f.basename.split("."); if (name.length > 1) { //print("View: ${name[0]}"); Document? processed = await _loadViewTemplate(viewsDirectory, name[0]); if (processed != null) { cache[name[0]] = processed; } } } }); } Future _loadViewTemplate( Directory viewsDirectory, String name, { String fileExtension = '.jael', bool asDSX = false, Iterable patch = const [], }) async { var errors = []; Document? processed; var file = viewsDirectory.childFile(name + fileExtension); var contents = await file.readAsString(); var doc = parseDocument( contents, sourceUrl: file.uri, asDSX: asDSX, onError: errors.add, ); if (doc == null) { throw ArgumentError("${file.basename} does not exists"); } try { processed = await (resolve( doc, viewsDirectory, patch: patch, onError: errors.add, )); } catch (e) { // Ignore these errors, so that we can show syntax errors. } if (processed == null) { throw ArgumentError("${file.basename} does not exists"); } return processed; } ================================================ FILE: packages/jael/angel_jael/melos_angel3_jael.iml ================================================ ================================================ FILE: packages/jael/angel_jael/pubspec.yaml ================================================ name: angel3_jael version: 8.4.0 description: Angel support for the Jael templating engine, similar to Blade or Liquid. homepage: https://angel3-framework.web.app/ repository: https://github.com/dart-backend/angel/tree/master/packages/jael/angel_jael resolution: workspace environment: sdk: '>=3.11.0 <4.0.0' dependencies: angel3_framework: ^8.4.0 jael3: ^8.0.0 jael3_preprocessor: ^8.0.0 belatuk_code_buffer: ^5.1.0 belatuk_symbol_table: ^5.1.0 file: ^7.0.0 logging: ^1.2.0 dev_dependencies: angel3_test: ^8.2.0 html: ^0.15.0 test: ^1.24.0 lints: ^6.0.0 ================================================ FILE: packages/jael/angel_jael/test/all_test.dart ================================================ import 'package:angel3_framework/angel3_framework.dart'; import 'package:angel3_jael/angel3_jael.dart'; import 'package:angel3_test/angel3_test.dart'; import 'package:file/memory.dart'; import 'package:html/parser.dart' as html; import 'package:logging/logging.dart'; import 'package:test/test.dart'; void main() { // These tests need not actually test that the preprocessor or renderer works, // because those packages are already tested. // // Instead, just test that we can render at all. late TestClient client; setUp(() async { var app = Angel(); app.configuration['properties'] = app.configuration; var fileSystem = MemoryFileSystem(); var viewsDirectory = fileSystem.directory('views')..createSync(); viewsDirectory.childFile('layout.jael').writeAsStringSync(''' Hello Fallback content '''); viewsDirectory.childFile('github.jael').writeAsStringSync(''' {{username}} '''); app.get('/github/:username', (req, res) { var username = req.params['username']; return res.render('github', {'username': username}); }); await app.configure(jael(viewsDirectory, minified: false)); app.fallback((req, res) => throw AngelHttpException.notFound()); app.logger = Logger('angel') ..onRecord.listen((rec) { print(rec); if (rec.error != null) print(rec.error); if (rec.stackTrace != null) print(rec.stackTrace); }); client = await connectTo(app); }); test('can render', () async { var response = await client.get(Uri.parse('/github/thosakwe')); print('Body:\n${response.body}'); expect( html.parse(response.body).outerHtml, html .parse( ''' Hello thosakwe ''' .trim(), ) .outerHtml, ); }); } ================================================ FILE: packages/jael/angel_jael/test/minified_test.dart ================================================ import 'package:angel3_framework/angel3_framework.dart'; import 'package:angel3_jael/angel3_jael.dart'; import 'package:angel3_test/angel3_test.dart'; import 'package:file/memory.dart'; import 'package:html/parser.dart' as html; import 'package:jael3/jael3.dart'; import 'package:logging/logging.dart'; import 'package:test/test.dart'; void main() { // These tests need not actually test that the preprocessor or renderer works, // because those packages are already tested. // // Instead, just test that we can render at all. late TestClient client; setUp(() async { var app = Angel(); app.configuration['properties'] = app.configuration; var fileSystem = MemoryFileSystem(); var viewsDirectory = fileSystem.directory('views')..createSync(); viewsDirectory.childFile('layout.jael').writeAsStringSync(''' Hello Fallback content '''); viewsDirectory.childFile('github.jael').writeAsStringSync(''' {{username}} '''); app.get('/github/:username', (req, res) async { var username = req.params['username']; return res.render('github', {'username': username}); }); //Preload the view template var viewCache = {}; jaelTemplatePreload(viewsDirectory, viewCache); await app.configure(jael(viewsDirectory, cache: viewCache)); app.fallback((req, res) => throw AngelHttpException.notFound()); app.logger = Logger('angel') ..onRecord.listen((rec) { print(rec); if (rec.error != null) print(rec.error); if (rec.stackTrace != null) print(rec.stackTrace); }); client = await connectTo(app); }); test('can render', () async { var response = await client.get(Uri.parse('/github/thosakwe')); //print('Body:\n${response.body}'); expect( html.parse(response.body).outerHtml, html .parse( '''Hellothosakwe''' .trim(), ) .outerHtml, ); }); test('initial load concurreny', () async { // Concurrently hit the same JAEL page for (var i = 0; i < 512; i++) { client.get(Uri.parse('/github/thosakwe')); } Stopwatch stopwatch = Stopwatch()..start(); var response = await client.get(Uri.parse('/github/thosakwe')); var elapsedTime = stopwatch.elapsed.inMilliseconds; print('Latency is $elapsedTime'); print('Body:\n${response.body}'); expect( html.parse(response.body).outerHtml, html .parse( '''Hellothosakwe''' .trim(), ) .outerHtml, ); }); } ================================================ FILE: packages/jael/jael/AUTHORS.md ================================================ 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. * __[Tobe O](thosakwe@gmail.com)__ Tobe has written much of the original code prior to NNBD migration. He has moved on and is no longer involved with the project. ================================================ FILE: packages/jael/jael/CHANGELOG.md ================================================ # Change Log ## 8.4.0 * Require Dart >= 3.11 ## 8.3.0 * Require Dart >= 3.8 * Updated `lints` to 6.0.0 * Updated dependencies to the latest release ## 8.2.0 * Require Dart >= 3.3 * Updated `lints` to 4.0.0 ## 8.1.1 * Updated repository link ## 8.1.0 * Updated `lints` to 3.0.0 * Fixed linter warnings ## 8.0.0 * Require Dart >= 3.0 ## 7.0.0 * Require Dart >= 2.17 ## 6.0.1 * Fixed analyze errors ## 6.0.0 * Require Dart >= 2.16 ## 5.0.0 * Skipped release ## 4.2.0 * Updated to use `package:belatuk_code_buffer` ## 4.1.0 * Updated to use `package:belatuk_symbol_table` * Updated linter to `package:lints` ## 4.0.0 * Migrated to support Dart >= 2.12 NNBD ## 3.0.0 * Migrated to work with Dart >= 2.12 Non NNBD ## 2.0.2 * Fixed handling of `if` in non-strict mode. * Roll `JaelFormatter` and `jaelfmt`. ## 2.0.1 * Fixed bug where the `textarea` name check would never return `true`. ## 2.0.0+1 * Meta-update for Pub score. ## 2.0.0 * Dart 2 updates. * Remove usage of `package:dart2_constant`. ## 1.0.6+1 * Ensure `` passes attributes. ## 1.0.6 * Add `index-as` to `for-each`. * Support registering + rendering custom elements. * Improve handling of booleans in non-strict mode. ## 1.0.5 * Add support for DSX, a port of JSX to Dart. ## 1.0.4 * Skip HTML comments in free text. ## 1.0.3 * Fix a scanner bug that prevented proper parsing of HTML nodes followed by free text. * Don't trim `