diff --git a/.github/workflows/dart.yml b/.github/workflows/dart.yml
index fffbe52c..5d16959e 100644
--- a/.github/workflows/dart.yml
+++ b/.github/workflows/dart.yml
@@ -21,7 +21,7 @@ jobs:
- uses: dart-lang/setup-dart@v1
with:
- sdk: "2.17.0"
+ sdk: "2.18.0"
- id: angel3_container_upgrade
name: angel3_container; Upgrade depedencies
@@ -87,7 +87,7 @@ jobs:
- uses: dart-lang/setup-dart@v1
with:
- sdk: "2.17.0"
+ sdk: "2.18.0"
# Angel3 ORM
- id: angel3_orm_upgrade
diff --git a/archived_packages/eventsource.zip b/archived_packages/eventsource.zip
new file mode 100644
index 00000000..a1012dfd
Binary files /dev/null and b/archived_packages/eventsource.zip differ
diff --git a/archived_packages/eventsource/.gitignore b/archived_packages/eventsource/.gitignore
deleted file mode 100644
index dbce896b..00000000
--- a/archived_packages/eventsource/.gitignore
+++ /dev/null
@@ -1,65 +0,0 @@
-# Created by .ignore support plugin (hsz.mobi)
-### 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 template
-# 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/
-.dart_tool
\ No newline at end of file
diff --git a/archived_packages/eventsource/LICENSE b/archived_packages/eventsource/LICENSE
deleted file mode 100644
index 8f65b579..00000000
--- a/archived_packages/eventsource/LICENSE
+++ /dev/null
@@ -1,21 +0,0 @@
-MIT License (MIT)
-
-Copyright (c) 2021 dukefirehawk.com
-
-Permission is hereby granted, free of charge, to any person obtaining a copy
-of this software and associated documentation files (the "Software"), to deal
-in the Software without restriction, including without limitation the rights
-to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
-copies of the Software, and to permit persons to whom the Software is
-furnished to do so, subject to the following conditions:
-
-The above copyright notice and this permission notice shall be included in all
-copies or substantial portions of the Software.
-
-THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
-IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
-FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
-AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
-LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
-OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
-SOFTWARE.
\ No newline at end of file
diff --git a/archived_packages/eventsource/README.md b/archived_packages/eventsource/README.md
deleted file mode 100644
index ea437ace..00000000
--- a/archived_packages/eventsource/README.md
+++ /dev/null
@@ -1,33 +0,0 @@
-# eventsource
-Server-sent Events (SSE) plugin for Angel.
-
-## Installation
-In your `pubspec.yaml`:
-
-```yaml
-dependencies:
- angel_eventsource: ^1.0.0
-```
-
-## Usage
-SSE and WebSockets are somewhat similar in that they allow pushing of events from server
-to client. SSE is not bi-directional, but the same abstractions used for WebSockets can be
-applied to SSE easily.
-
-For this reason, the `AngelEventSourcePublisher` class is a simple adapter that
-hands control of SSE requests to an existing `AngelWebSocket` driver.
-
-So, using this is pretty straightforward. You can dispatch events
-via WebSocket as per usual, and have them propagated to SSE clients
-as well.
-
-```dart
-var app = new Angel();
-var ws = new AngelWebSocket(app);
-var events = new AngelEventSourcePublisher(ws);
-
-await app.configure(ws.configureServer);
-
-app.all('/ws', ws.handleRequest);
-app.get('/events', events.handleRequest);
-```
\ No newline at end of file
diff --git a/archived_packages/eventsource/analysis_options.yaml b/archived_packages/eventsource/analysis_options.yaml
deleted file mode 100644
index eae1e42a..00000000
--- a/archived_packages/eventsource/analysis_options.yaml
+++ /dev/null
@@ -1,3 +0,0 @@
-analyzer:
- strong-mode:
- implicit-casts: false
\ No newline at end of file
diff --git a/archived_packages/eventsource/eventsource.iml b/archived_packages/eventsource/eventsource.iml
deleted file mode 100644
index 5a5ced28..00000000
--- a/archived_packages/eventsource/eventsource.iml
+++ /dev/null
@@ -1,14 +0,0 @@
-
-
-
-
-
-
-
-
-
-
-
-
-
-
\ No newline at end of file
diff --git a/archived_packages/eventsource/example/main.dart b/archived_packages/eventsource/example/main.dart
deleted file mode 100644
index f208544f..00000000
--- a/archived_packages/eventsource/example/main.dart
+++ /dev/null
@@ -1,50 +0,0 @@
-import 'package:angel_eventsource/server.dart';
-import 'package:angel_framework/angel_framework.dart';
-import 'package:angel_framework/http.dart';
-import 'package:angel_websocket/server.dart';
-import 'package:eventsource/eventsource.dart';
-import 'package:logging/logging.dart';
-import 'pretty_logging.dart';
-
-main() async {
- var app = new Angel();
- var ws = new AngelWebSocket(app);
- var events = new AngelEventSourcePublisher(ws);
-
- await app.configure(ws.configureServer);
-
- app.use('/api/todos', new MapService());
- app.all('/ws', ws.handleRequest);
- app.get('/events', events.handleRequest);
-
- app.logger = new Logger('angel_eventsource')..onRecord.listen(prettyLog);
-
- var http = new AngelHttp(app);
- var server = await http.startServer('127.0.0.1', 3000);
- var url = Uri.parse('http://${server.address.address}:${server.port}');
- print('Listening at $url');
-
- /*
- var sock = await Socket.connect(server.address, server.port);
- sock
- ..writeln('GET /sse HTTP/1.1')
- ..writeln('Accept: text/event-stream')
- ..writeln('Host: 127.0.0.1')
- ..writeln()
- ..flush();
- sock.transform(UTF8.decoder).transform(const LineSplitter()).listen(print);
- */
-
- /*
- var client = new HttpClient();
- var rq = await client.openUrl('GET', url);
- var rs = await rq.close();
- rs.transform(UTF8.decoder).transform(const LineSplitter()).listen(print);
- */
-
- var eventSource = await EventSource.connect(url);
-
- await for (var event in eventSource) {
- print(event.data);
- }
-}
diff --git a/archived_packages/eventsource/example/pretty_logging.dart b/archived_packages/eventsource/example/pretty_logging.dart
deleted file mode 100644
index 883b979b..00000000
--- a/archived_packages/eventsource/example/pretty_logging.dart
+++ /dev/null
@@ -1,29 +0,0 @@
-import 'package:console/console.dart';
-import 'package:logging/logging.dart';
-
-/// Prints the contents of a [LogRecord] with pretty colors.
-prettyLog(LogRecord record) async {
- var pen = new TextPen();
- chooseLogColor(pen.reset(), record.level);
- pen(record.toString());
-
- if (record.error != null) pen(record.error.toString());
- if (record.stackTrace != null) pen(record.stackTrace.toString());
-
- pen();
-}
-
-/// Chooses a color based on the logger [level].
-void chooseLogColor(TextPen pen, Level level) {
- if (level == Level.SHOUT)
- pen.darkRed();
- else if (level == Level.SEVERE)
- pen.red();
- else if (level == Level.WARNING)
- pen.yellow();
- else if (level == Level.INFO)
- pen.magenta();
- else if (level == Level.FINER)
- pen.blue();
- else if (level == Level.FINEST) pen.darkBlue();
-}
diff --git a/archived_packages/eventsource/lib/angel_eventsource.dart b/archived_packages/eventsource/lib/angel_eventsource.dart
deleted file mode 100644
index 1071f8fc..00000000
--- a/archived_packages/eventsource/lib/angel_eventsource.dart
+++ /dev/null
@@ -1 +0,0 @@
-export 'package:angel_websocket/angel_websocket.dart';
diff --git a/archived_packages/eventsource/lib/server.dart b/archived_packages/eventsource/lib/server.dart
deleted file mode 100644
index ea6c4e19..00000000
--- a/archived_packages/eventsource/lib/server.dart
+++ /dev/null
@@ -1,51 +0,0 @@
-import 'dart:async';
-import 'package:angel_framework/angel_framework.dart';
-import 'package:angel_websocket/server.dart';
-import 'package:eventsource/eventsource.dart';
-import 'package:eventsource/src/encoder.dart';
-import 'package:eventsource/publisher.dart';
-import 'package:stream_channel/stream_channel.dart';
-
-class AngelEventSourcePublisher {
- final AngelWebSocket webSocketDriver;
-
- final String channel;
-
- int _count = 0;
-
- AngelEventSourcePublisher(this.webSocketDriver, {this.channel: ''});
-
- Future handleRequest(RequestContext req, ResponseContext res) async {
- if (!req.accepts('text/event-stream', strict: false))
- throw new AngelHttpException.badRequest();
-
- res.headers.addAll({
- 'cache-control': 'no-cache, no-store, must-revalidate',
- 'content-type': 'text/event-stream',
- 'connection': 'keep-alive',
- });
-
- var acceptsGzip =
- (req.headers['accept-encoding']?.contains('gzip') == true);
-
- if (acceptsGzip) res.headers['content-encoding'] = 'gzip';
-
- var eventSink = new EventSourceEncoder(compressed: acceptsGzip)
- .startChunkedConversion(res);
-
- // Listen for events.
- var ctrl = new StreamChannelController();
-
- // Incoming events are strings, and should be sent via the eventSink.
- ctrl.local.stream.cast().listen((data) {
- eventSink.add(new Event(
- id: (_count++).toString(),
- data: data,
- ));
- });
-
- // Create a new WebSocketContext, and hand it off to the driver.
- var socket = new WebSocketContext(ctrl.foreign, req, res);
- return await webSocketDriver.handleClient(socket);
- }
-}
diff --git a/archived_packages/eventsource/pubspec.yaml b/archived_packages/eventsource/pubspec.yaml
deleted file mode 100644
index d13748e2..00000000
--- a/archived_packages/eventsource/pubspec.yaml
+++ /dev/null
@@ -1,26 +0,0 @@
-name: angel_eventsource
-version: 2.0.0
-description: Server-sent Events (SSE) plugin for Angel.
-homepage: https://github.com/angel-dart/eventsource
-publish_to: none
-environment:
- sdk: ">=2.10.0 <3.0.0"
-dependencies:
- angel_framework:
- git:
- url: https://github.com/dukefirehawk/angel.git
- ref: sdk-2.12.x
- path: packages/framework
- angel_websocket:
- git:
- url: https://github.com/dukefirehawk/angel.git
- ref: sdk-2.12.x
- path: packages/websocket
- eventsource:
- git:
- url: https://github.com/dukefirehawk/dart-eventsource.git
- stream_channel: ^2.0.0
-dev_dependencies:
- console: ^4.0.0
- logging: ^1.0.0
- test: ^1.16.5
diff --git a/archived_packages/orm.zip b/archived_packages/orm.zip
new file mode 100644
index 00000000..7b0436e8
Binary files /dev/null and b/archived_packages/orm.zip differ
diff --git a/archived_packages/orm/angel_orm_sqlite/LICENSE b/archived_packages/orm/angel_orm_sqlite/LICENSE
deleted file mode 100644
index 8f65b579..00000000
--- a/archived_packages/orm/angel_orm_sqlite/LICENSE
+++ /dev/null
@@ -1,21 +0,0 @@
-MIT License (MIT)
-
-Copyright (c) 2021 dukefirehawk.com
-
-Permission is hereby granted, free of charge, to any person obtaining a copy
-of this software and associated documentation files (the "Software"), to deal
-in the Software without restriction, including without limitation the rights
-to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
-copies of the Software, and to permit persons to whom the Software is
-furnished to do so, subject to the following conditions:
-
-The above copyright notice and this permission notice shall be included in all
-copies or substantial portions of the Software.
-
-THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
-IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
-FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
-AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
-LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
-OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
-SOFTWARE.
\ No newline at end of file
diff --git a/archived_packages/orm/angel_orm_sqlite/pubspec.yaml b/archived_packages/orm/angel_orm_sqlite/pubspec.yaml
deleted file mode 100644
index 6e2d9082..00000000
--- a/archived_packages/orm/angel_orm_sqlite/pubspec.yaml
+++ /dev/null
@@ -1,5 +0,0 @@
-name: angel_orm_sqlite
-environment:
- sdk: ">=2.16.0 <3.0.0"
-dependencies:
- angel_orm: ^2.0.0-dev
diff --git a/archived_packages/poll.zip b/archived_packages/poll.zip
new file mode 100644
index 00000000..4442e486
Binary files /dev/null and b/archived_packages/poll.zip differ
diff --git a/archived_packages/poll/.gitignore b/archived_packages/poll/.gitignore
deleted file mode 100644
index b4d6e266..00000000
--- a/archived_packages/poll/.gitignore
+++ /dev/null
@@ -1,64 +0,0 @@
-# Created by .ignore support plugin (hsz.mobi)
-### 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 template
-# 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/
diff --git a/archived_packages/poll/.travis.yml b/archived_packages/poll/.travis.yml
deleted file mode 100644
index de2210c9..00000000
--- a/archived_packages/poll/.travis.yml
+++ /dev/null
@@ -1 +0,0 @@
-language: dart
\ No newline at end of file
diff --git a/archived_packages/poll/AUTHORS.md b/archived_packages/poll/AUTHORS.md
deleted file mode 100644
index ac95ab58..00000000
--- a/archived_packages/poll/AUTHORS.md
+++ /dev/null
@@ -1,12 +0,0 @@
-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.
diff --git a/archived_packages/poll/CHANGELOG.md b/archived_packages/poll/CHANGELOG.md
deleted file mode 100644
index d531223a..00000000
--- a/archived_packages/poll/CHANGELOG.md
+++ /dev/null
@@ -1,9 +0,0 @@
-# Change Log
-
-## 2.0.0
-
-* Migrated to support Dart >= 2.12 NNBD
-
-## 1.0.0
-
-* Created package + tests
diff --git a/archived_packages/poll/LICENSE b/archived_packages/poll/LICENSE
deleted file mode 100644
index df5e0635..00000000
--- a/archived_packages/poll/LICENSE
+++ /dev/null
@@ -1,29 +0,0 @@
-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.
diff --git a/archived_packages/poll/README.md b/archived_packages/poll/README.md
deleted file mode 100644
index de25152b..00000000
--- a/archived_packages/poll/README.md
+++ /dev/null
@@ -1,42 +0,0 @@
-# poll
-[![Pub](https://img.shields.io/pub/v/angel_poll.svg)](https://pub.dartlang.org/packages/angel_poll)
-[![build status](https://travis-ci.org/angel-dart/poll.svg?branch=master)](https://travis-ci.org/angel-dart/poll)
-
-`package:angel_client` support for "realtime" interactions with Angel via long polling.
-
-Angel supports [WebSockets](https://github.com/angel-dart/websocket) on the server and client, which
-makes it very straightforward to implement realtime collections. However, not every user's browser
-supports WebSockets. In such a case, applications might *gracefully degrade* to long-polling
-the server for changes.
-
-A `PollingService` wraps a client-side `Service` (typically a REST-based one), and calls its
-`index` method at a regular interval. After indexing, the `PollingService` performs a diff
-and identifies whether items have been created, modified, or removed. The updates are sent out
-through `onCreated`, `onModified`, etc., effectively managing a real-time collection of data.
-
-A common use-case would be passing this service to `ServiceList`, a class that manages the state
-of a collection managed in real-time.
-
-```dart
-import 'package:angel_client/io.dart';
-import 'package:angel_poll/angel_poll.dart';
-
-main() {
- var app = new Rest('http://localhost:3000');
-
- var todos = new ServiceList(
- new PollingService(
- // Typically, you'll pass a REST-based service instance here.
- app.service('api/todos'),
-
- // `index` called every 5 seconds
- const Duration(seconds: 5),
- ),
- );
-
- todos.onChange.listen((_) {
- // Something happened here.
- // Maybe an item was created, modified, etc.
- });
-}
-```
\ No newline at end of file
diff --git a/archived_packages/poll/analysis_options.yaml b/archived_packages/poll/analysis_options.yaml
deleted file mode 100644
index ea2c9e94..00000000
--- a/archived_packages/poll/analysis_options.yaml
+++ /dev/null
@@ -1 +0,0 @@
-include: package:lints/recommended.yaml
\ No newline at end of file
diff --git a/archived_packages/poll/example/main.dart b/archived_packages/poll/example/main.dart
deleted file mode 100644
index 4b8e2739..00000000
--- a/archived_packages/poll/example/main.dart
+++ /dev/null
@@ -1,21 +0,0 @@
-import 'package:angel_client/io.dart';
-import 'package:angel_poll/angel_poll.dart';
-
-void main() {
- var app = Rest('http://localhost:3000');
-
- var todos = ServiceList(
- PollingService(
- // Typically, you'll pass a REST-based service instance here.
- app.service('api/todos'),
-
- // `index` called every 5 seconds
- const Duration(seconds: 5),
- ),
- );
-
- todos.onChange.listen((_) {
- // Something happened here.
- // Maybe an item was created, modified, etc.
- });
-}
diff --git a/archived_packages/poll/lib/angel_poll.dart b/archived_packages/poll/lib/angel_poll.dart
deleted file mode 100644
index 7c245258..00000000
--- a/archived_packages/poll/lib/angel_poll.dart
+++ /dev/null
@@ -1,265 +0,0 @@
-import 'dart:async';
-import 'package:collection/collection.dart';
-import 'package:angel_client/angel_client.dart';
-
-/// A [Service] that facilitates real-time updates via the long polling of an [inner] service.
-///
-/// Works well with [ServiceList].
-class PollingService extends Service {
- /// The underlying [Service] that does the actual communication with the server.
- final Service inner;
-
- /// Perform computations after polling to discern whether new items were created.
- final bool checkForCreated;
-
- /// Perform computations after polling to discern whether items were modified.
- final bool checkForModified;
-
- /// Perform computations after polling to discern whether items were removed.
- final bool checkForRemoved;
-
- /// An [EqualityBy] used to compare the ID's of two items.
- ///
- /// Defaults to comparing the [idField] of two `Map` instances.
- final EqualityBy compareId;
-
- /// An [Equality] used to discern whether two items, with the same [idField], are the same item.
- ///
- /// Defaults to [MapEquality], which deep-compares `Map` instances.
- final Equality compareItems;
-
- /// A [String] used as an index through which to compare `Map` instances.
- ///
- /// Defaults to `id`.
- final String idField;
-
- /// If `true` (default: `false`), then `index` events will be handled as a [Map] containing a `data` field.
- ///
- /// See https://github.com/angel-dart/paginate.
- final bool asPaginated;
-
- final List _items = [];
- final List _subs = [];
-
- final StreamController> _onIndexed = StreamController(),
- _onRead = StreamController(),
- _onCreated = StreamController(),
- _onModified = StreamController(),
- _onUpdated = StreamController(),
- _onRemoved = StreamController();
-
- late Timer _timer;
-
- @override
- Angel get app => inner.app;
-
- @override
- Stream> get onIndexed => _onIndexed.stream;
-
- @override
- Stream get onRead => _onRead.stream;
-
- @override
- Stream get onCreated => _onCreated.stream;
-
- @override
- Stream get onModified => _onModified.stream;
-
- @override
- Stream get onUpdated => _onUpdated.stream;
-
- @override
- Stream get onRemoved => _onRemoved.stream;
-
- PollingService(this.inner, Duration interval,
- {this.checkForCreated = true,
- this.checkForModified = true,
- this.checkForRemoved = true,
- this.idField = 'id',
- this.asPaginated = false,
- EqualityBy? compareId,
- this.compareItems = const MapEquality()})
- : compareId = compareId ?? EqualityBy((map) => map[idField]) {
- _timer = Timer.periodic(interval, (_) {
- index().catchError((error) {
- _onIndexed.addError(error as Object);
- });
- });
-
- var streams = {
- inner.onRead: _onRead,
- inner.onCreated: _onCreated,
- inner.onModified: _onModified,
- inner.onUpdated: _onUpdated,
- inner.onRemoved: _onRemoved,
- };
-
- streams.forEach((stream, ctrl) {
- _subs.add(stream.listen(ctrl.add, onError: ctrl.addError));
- });
-
- _subs.add(
- inner.onIndexed.listen(
- _handleIndexed,
- onError: _onIndexed.addError,
- ),
- );
- }
-
- @override
- Future close() async {
- _timer.cancel();
- for (var s in _subs) {
- s.cancel();
- }
- await _onIndexed.close();
- await _onRead.close();
- await _onCreated.close();
- await _onModified.close();
- await _onUpdated.close();
- await _onRemoved.close();
- }
-
- // TODO: To revisit this logic
- @override
- Future> index([Map? params]) {
- return inner.index().then((data) {
- //return asPaginated == true ? data['data'] : data;
- //return asPaginated == true ? data[0] : data;
- return data;
- });
- }
-
-/*
- @override
- Future index([Map params]) {
- }
-*/
- @override
- Future remove(id, [Map? params]) {
- return inner.remove(id, params).then((result) {
- _items.remove(result);
- return result;
- }).catchError(_onRemoved.addError);
- }
-
- dynamic _handleUpdate(result) {
- var index = -1;
-
- for (var i = 0; i < _items.length; i++) {
- if (compareId.equals(_items[i], result)) {
- index = i;
- break;
- }
- }
-
- if (index > -1) {
- _items[index] = result;
- }
-
- return result;
- }
-
- @override
- Future update(id, data, [Map? params]) {
- return inner
- .update(id, data, params)
- .then(_handleUpdate)
- .catchError(_onUpdated.addError);
- }
-
- @override
- Future modify(id, data, [Map? params]) {
- return inner
- .modify(id, data, params)
- .then(_handleUpdate)
- .catchError(_onModified.addError);
- }
-
- @override
- Future create(data, [Map? params]) {
- return inner.create(data, params).then((result) {
- _items.add(result);
- return result;
- }).catchError(_onCreated.addError);
- }
-
- @override
- Future read(id, [Map? params]) {
- return inner.read(id, params);
- }
-
- void _handleIndexed(List data) {
- //var items = asPaginated == true ? data['data'] : data;
- var items = data;
- var changesComputed = false;
-
- if (checkForCreated != false) {
- var newItems = {};
-
- for (var i = 0; i < items.length; i++) {
- var item = items[i];
-
- if (!_items.any((i) => compareId.equals(i, item))) {
- newItems[i] = item;
- }
- }
-
- newItems.forEach((index, item) {
- _items.insert(index, item);
- _onCreated.add([item]);
- });
-
- changesComputed = newItems.isNotEmpty;
- }
-
- if (checkForRemoved != false) {
- var removedItems = {};
-
- for (var i = 0; i < _items.length; i++) {
- var item = _items[i];
-
- if (!items.any((i) => compareId.equals(i, item))) {
- removedItems[i] = item;
- }
- }
-
- removedItems.forEach((index, item) {
- _items.removeAt(index);
- _onRemoved.add([item]);
- });
-
- changesComputed = changesComputed || removedItems.isNotEmpty;
- }
-
- if (checkForModified != false) {
- var modifiedItems = {};
-
- for (var item in items) {
- for (var i = 0; i < _items.length; i++) {
- var localItem = _items[i];
-
- if (compareId.equals(item, localItem)) {
- if (!compareItems.equals(item, localItem)) {
- modifiedItems[i] = item;
- }
- break;
- }
- }
- }
-
- modifiedItems.forEach((index, item) {
- _onModified.add([_items[index] = item]);
- });
-
- changesComputed = changesComputed || modifiedItems.isNotEmpty;
- }
-
- if (!changesComputed) {
- _items
- ..clear()
- ..add(items);
- _onIndexed.add([items]);
- }
- }
-}
diff --git a/archived_packages/poll/poll.iml b/archived_packages/poll/poll.iml
deleted file mode 100644
index 5a5ced28..00000000
--- a/archived_packages/poll/poll.iml
+++ /dev/null
@@ -1,14 +0,0 @@
-
-
-
-
-
-
-
-
-
-
-
-
-
-
\ No newline at end of file
diff --git a/archived_packages/poll/pubspec.yaml b/archived_packages/poll/pubspec.yaml
deleted file mode 100644
index 683825f2..00000000
--- a/archived_packages/poll/pubspec.yaml
+++ /dev/null
@@ -1,23 +0,0 @@
-name: angel_poll
-version: 2.0.0
-description: package:angel_client support for "realtime" interactions with Angel via long polling.
-publish_to: none
-environment:
- sdk: '>=2.12.0 <3.0.0'
-homepage: https://github.com/angel-dart/poll
-dependencies:
- angel_client: # ^1.0.0
- git:
- url: https://github.com/dukefirehawk/angel.git
- ref: sdk-2.12.x_nnbd
- path: packages/client
- async: ^2.7.0
- collection: ^1.15.0
-dev_dependencies:
- angel_test:
- git:
- url: https://github.com/dukefirehawk/angel.git
- ref: sdk-2.12.x_nnbd
- path: packages/test
- test: ^1.17.8
- lints: ^1.0.0
\ No newline at end of file
diff --git a/archived_packages/poll/test/all_test.dart b/archived_packages/poll/test/all_test.dart
deleted file mode 100644
index f709af1e..00000000
--- a/archived_packages/poll/test/all_test.dart
+++ /dev/null
@@ -1,105 +0,0 @@
-import 'package:angel_framework/angel_framework.dart' as srv;
-import 'package:angel_container/mirrors.dart';
-import 'package:angel_poll/angel_poll.dart';
-import 'package:angel_test/angel_test.dart';
-import 'package:async/async.dart';
-import 'package:logging/logging.dart';
-import 'package:test/test.dart';
-
-void main() {
- late srv.Service store;
- late TestClient client;
- late PollingService pollingService;
-
- var created;
- late StreamQueue onCreated;
- late StreamQueue onModified;
- late StreamQueue onRemoved;
-
- setUp(() async {
- var app = srv.Angel(reflector: MirrorsReflector());
- app.logger = Logger.detached('angel_poll')
- ..onRecord.listen((rec) {
- print(rec);
- if (rec.error != null) {
- print(rec.error);
- print(rec.stackTrace);
- }
- });
-
- store = app.use(
- '/api/todos',
- srv.MapService(
- autoIdAndDateFields: false,
- ),
- );
-
- client = await connectTo(app);
-
- pollingService = PollingService(
- client.service('api/todos'),
- const Duration(milliseconds: 100),
- );
-
- onCreated = StreamQueue(pollingService.onCreated);
- onModified = StreamQueue(pollingService.onModified);
- onRemoved = StreamQueue(pollingService.onRemoved);
-
- created = await store.create({
- 'id': '0',
- 'text': 'Clean your room',
- 'completed': false,
- });
- });
-
- tearDown(() {
- onCreated.cancel();
- onModified.cancel();
- onRemoved.cancel();
- client.close();
- });
-
- group('events', () {
- test('fires indexed', () async {
- var indexed = await pollingService.index();
- print(indexed);
- expect(await pollingService.onIndexed.first, indexed);
- });
-
- test('fires created', () async {
- var result = await onCreated.next;
- print(result);
- expect(created, result);
- });
-
- test('fires modified', () async {
- await pollingService.index();
- await store.modify('0', {
- 'text': 'go to school',
- });
-
- var result = await onModified.next;
- print(result);
- expect(result, Map.from({'': created})..['text'] = 'go to school');
- });
-
- test('manual modify', () async {
- await pollingService.index();
- await pollingService.modify('0', {
- 'text': 'eat',
- });
-
- var result = await onModified.next;
- print(result);
- expect(result, Map.from({'': created})..['text'] = 'eat');
- });
-
- test('fires removed', () async {
- await pollingService.index();
- var removed = await store.remove('0');
- var result = await onRemoved.next;
- print(result);
- expect(result, removed);
- });
- });
-}
diff --git a/archived_packages/relations.zip b/archived_packages/relations.zip
new file mode 100644
index 00000000..cb9c59e6
Binary files /dev/null and b/archived_packages/relations.zip differ
diff --git a/archived_packages/relations/.gitignore b/archived_packages/relations/.gitignore
deleted file mode 100644
index e822a056..00000000
--- a/archived_packages/relations/.gitignore
+++ /dev/null
@@ -1,93 +0,0 @@
-# See https://www.dartlang.org/tools/private-files.html
-
-# Files and directories created by pub
-.buildlog
-.packages
-.project
-.pub/
-.scripts-bin/
-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
-### Dart template
-# See https://www.dartlang.org/tools/private-files.html
-
-# Files and directories created by pub
-
-# SDK 1.20 and later (no longer creates packages directories)
-
-# Older SDK versions
-# (Include if the minimum SDK version specified in pubsepc.yaml is earlier than 1.20)
-
-
-# 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)
-
-# Directory created by dartdoc
-
-# Don't commit pubspec lock file
-# (Library packages only! Remove pattern if developing an application package)
-### 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
diff --git a/archived_packages/relations/.travis.yml b/archived_packages/relations/.travis.yml
deleted file mode 100644
index de2210c9..00000000
--- a/archived_packages/relations/.travis.yml
+++ /dev/null
@@ -1 +0,0 @@
-language: dart
\ No newline at end of file
diff --git a/archived_packages/relations/AUTHORS.md b/archived_packages/relations/AUTHORS.md
deleted file mode 100644
index ac95ab58..00000000
--- a/archived_packages/relations/AUTHORS.md
+++ /dev/null
@@ -1,12 +0,0 @@
-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.
diff --git a/archived_packages/relations/CHANGELOG.md b/archived_packages/relations/CHANGELOG.md
deleted file mode 100644
index 9a5d3f9b..00000000
--- a/archived_packages/relations/CHANGELOG.md
+++ /dev/null
@@ -1,9 +0,0 @@
-# Change Log
-
-## 2.0.0
-
-* Migrated to support Dart >= 2.12 NNBD
-
-## 1.0.0
-
-* Initial checkin
diff --git a/archived_packages/relations/LICENSE b/archived_packages/relations/LICENSE
deleted file mode 100644
index df5e0635..00000000
--- a/archived_packages/relations/LICENSE
+++ /dev/null
@@ -1,29 +0,0 @@
-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.
diff --git a/archived_packages/relations/README.md b/archived_packages/relations/README.md
deleted file mode 100644
index ea8a4e74..00000000
--- a/archived_packages/relations/README.md
+++ /dev/null
@@ -1,25 +0,0 @@
-# relations
-[![version 1.0.1](https://img.shields.io/badge/pub-v1.0.1-brightgreen.svg)](https://pub.dartlang.org/packages/angel_relations)
-[![build status](https://travis-ci.org/angel-dart/relations.svg)](https://travis-ci.org/angel-dart/relations)
-
-Database-agnostic relations between Angel services.
-
-```dart
-// Authors owning one book
-app.service('authors').afterAll(
- relations.hasOne('books', as: 'book', foreignKey: 'authorId'));
-
-// Or multiple
-app.service('authors').afterAll(
- relations.hasMany('books', foreignKey: 'authorId'));
-
-// Or, books belonging to authors
-app.service('books').afterAll(relations.belongsTo('authors'));
-```
-
-Supports:
-* `hasOne`
-* `hasMany`
-* `hasManyThrough`
-* `belongsTo`
-* `belongsToMany`
\ No newline at end of file
diff --git a/archived_packages/relations/analysis_options.yaml b/archived_packages/relations/analysis_options.yaml
deleted file mode 100644
index ea2c9e94..00000000
--- a/archived_packages/relations/analysis_options.yaml
+++ /dev/null
@@ -1 +0,0 @@
-include: package:lints/recommended.yaml
\ No newline at end of file
diff --git a/archived_packages/relations/lib/angel_relations.dart b/archived_packages/relations/lib/angel_relations.dart
deleted file mode 100644
index 5f2b6a7e..00000000
--- a/archived_packages/relations/lib/angel_relations.dart
+++ /dev/null
@@ -1,9 +0,0 @@
-/// Hooks to populate data returned from services, in a fashion
-/// reminiscent of a relational database.
-library angel_relations;
-
-export 'src/belongs_to_many.dart';
-export 'src/belongs_to.dart';
-export 'src/has_many.dart';
-export 'src/has_many_through.dart';
-export 'src/has_one.dart';
\ No newline at end of file
diff --git a/archived_packages/relations/lib/src/belongs_to.dart b/archived_packages/relations/lib/src/belongs_to.dart
deleted file mode 100644
index bf05f84c..00000000
--- a/archived_packages/relations/lib/src/belongs_to.dart
+++ /dev/null
@@ -1,75 +0,0 @@
-import 'dart:async';
-import 'dart:mirrors';
-import 'package:angel_framework/angel_framework.dart';
-import 'plural.dart' as pluralize;
-import 'no_service.dart';
-
-/// Represents a relationship in which the current [service] "belongs to"
-/// a single member of the service at [servicePath]. Use [as] to set the name
-/// on the target object.
-///
-/// Defaults:
-/// * [localKey]: `userId`
-/// * [foreignKey]: `id`
-HookedServiceEventListener belongsTo(Pattern servicePath,
- {String? as,
- String? foreignKey,
- String? localKey,
- Function(dynamic obj)? getForeignKey,
- Function(dynamic foreign, dynamic obj)? assignForeignObject}) {
- var localId = localKey;
- var foreignName =
- as?.isNotEmpty == true ? as! : pluralize.singular(servicePath.toString());
-
- localId ??= foreignName + 'Id';
-
- return (HookedServiceEvent e) async {
- var ref = e.getService(servicePath);
- if (ref == null) throw noService(servicePath);
-
- dynamic _getForeignKey(obj) {
- if (getForeignKey != null) {
- return getForeignKey(obj);
- } else if (obj is Map) {
- return obj[localId];
- } else if (localId == null || localId == 'userId') {
- return obj.userId;
- } else {
- return reflect(obj).getField(Symbol(localId)).reflectee;
- }
- }
-
- dynamic _assignForeignObject(foreign, obj) {
- if (assignForeignObject != null) {
- return assignForeignObject(foreign, obj);
- } else if (obj is Map) {
- obj[foreignName] = foreign;
- } else {
- reflect(obj).setField(Symbol(foreignName), foreign);
- }
- }
-
- Future _normalize(obj) async {
- if (obj != null) {
- var id = await _getForeignKey(obj);
- var indexed = await ref.index({
- 'query': {foreignKey ?? 'id': id}
- });
-
- if (indexed is! List || indexed.isNotEmpty != true) {
- await _assignForeignObject(null, obj);
- } else {
- var child = indexed.first;
- await _assignForeignObject(child, obj);
- }
- }
- }
-
- if (e.result is Iterable) {
- //await Future.wait(e.result.map(_normalize));
- await e.result.map(_normalize);
- } else {
- await _normalize(e.result);
- }
- };
-}
diff --git a/archived_packages/relations/lib/src/belongs_to_many.dart b/archived_packages/relations/lib/src/belongs_to_many.dart
deleted file mode 100644
index 7ee4d2f9..00000000
--- a/archived_packages/relations/lib/src/belongs_to_many.dart
+++ /dev/null
@@ -1,75 +0,0 @@
-import 'dart:async';
-import 'dart:mirrors';
-import 'package:angel_framework/angel_framework.dart';
-import 'plural.dart' as pluralize;
-import 'no_service.dart';
-
-/// Represents a relationship in which the current [service] "belongs to"
-/// multiple members of the service at [servicePath]. Use [as] to set the name
-/// on the target object.
-///
-/// Defaults:
-/// * [foreignKey]: `userId`
-/// * [localKey]: `id`
-HookedServiceEventListener belongsToMany(Pattern servicePath,
- {String? as,
- String? foreignKey,
- String? localKey,
- Function(dynamic obj)? getForeignKey,
- Function(dynamic foreign, dynamic obj)? assignForeignObject}) {
- var localId = localKey;
- var foreignName =
- as?.isNotEmpty == true ? as! : pluralize.plural(servicePath.toString());
-
- localId ??= foreignName + 'Id';
-
- return (HookedServiceEvent e) async {
- var ref = e.getService(servicePath);
- if (ref == null) throw noService(servicePath);
-
- dynamic _getForeignKey(obj) {
- if (getForeignKey != null) {
- return getForeignKey(obj);
- } else if (obj is Map) {
- return obj[localId];
- } else if (localId == null || localId == 'userId') {
- return obj.userId;
- } else {
- return reflect(obj).getField(Symbol(localId)).reflectee;
- }
- }
-
- dynamic _assignForeignObject(foreign, obj) {
- if (assignForeignObject != null) {
- return assignForeignObject(foreign as List?, obj);
- } else if (obj is Map) {
- obj[foreignName] = foreign;
- } else {
- reflect(obj).setField(Symbol(foreignName), foreign);
- }
- }
-
- Future _normalize(obj) async {
- if (obj != null) {
- var id = await _getForeignKey(obj);
- var indexed = await ref.index({
- 'query': {foreignKey ?? 'id': id}
- });
-
- if (indexed is! List || indexed.isNotEmpty != true) {
- await _assignForeignObject(null, obj);
- } else {
- var child = indexed is Iterable ? indexed.toList() : [indexed];
- await _assignForeignObject(child, obj);
- }
- }
- }
-
- if (e.result is Iterable) {
- //await Future.wait(e.result.map(_normalize));
- await e.result.map(_normalize);
- } else {
- await _normalize(e.result);
- }
- };
-}
diff --git a/archived_packages/relations/lib/src/has_many.dart b/archived_packages/relations/lib/src/has_many.dart
deleted file mode 100644
index cca4e9e6..00000000
--- a/archived_packages/relations/lib/src/has_many.dart
+++ /dev/null
@@ -1,70 +0,0 @@
-import 'dart:async';
-import 'dart:mirrors';
-import 'package:angel_framework/angel_framework.dart';
-import 'plural.dart' as pluralize;
-import 'no_service.dart';
-
-/// Represents a relationship in which the current [service] "owns"
-/// members of the service at [servicePath]. Use [as] to set the name
-/// on the target object.
-///
-/// Defaults:
-/// * [foreignKey]: `userId`
-/// * [localKey]: `id`
-HookedServiceEventListener hasMany(Pattern servicePath,
- {String? as,
- String? foreignKey,
- String? localKey,
- Function(dynamic obj)? getLocalKey,
- Function(dynamic foreign, dynamic obj)? assignForeignObjects}) {
- return (HookedServiceEvent e) async {
- var ref = e.getService(servicePath);
- var foreignName =
- as?.isNotEmpty == true ? as : pluralize.plural(servicePath.toString());
- if (ref == null) throw noService(servicePath);
-
- dynamic _getLocalKey(obj) {
- if (getLocalKey != null) {
- return getLocalKey(obj);
- } else if (obj is Map) {
- return obj[localKey ?? 'id'];
- } else if (localKey == null || localKey == 'id') {
- return obj.id;
- } else {
- return reflect(obj).getField(Symbol(localKey)).reflectee;
- }
- }
-
- dynamic _assignForeignObjects(foreign, obj) {
- if (assignForeignObjects != null) {
- return assignForeignObjects(foreign, obj);
- } else if (obj is Map) {
- obj[foreignName] = foreign;
- } else {
- reflect(obj).setField(Symbol(foreignName!), foreign);
- }
- }
-
- Future _normalize(obj) async {
- if (obj != null) {
- var id = await _getLocalKey(obj);
- var indexed = await ref.index({
- 'query': {foreignKey ?? 'userId': id}
- });
-
- if (indexed is! List || indexed.isNotEmpty != true) {
- await _assignForeignObjects([], obj);
- } else {
- await _assignForeignObjects(indexed, obj);
- }
- }
- }
-
- if (e.result is Iterable) {
- //await Future.wait(e.result.map(_normalize));
- await e.result.map(_normalize);
- } else {
- await _normalize(e.result);
- }
- };
-}
diff --git a/archived_packages/relations/lib/src/has_many_through.dart b/archived_packages/relations/lib/src/has_many_through.dart
deleted file mode 100644
index 23a6ed1d..00000000
--- a/archived_packages/relations/lib/src/has_many_through.dart
+++ /dev/null
@@ -1,97 +0,0 @@
-import 'dart:async';
-import 'dart:mirrors';
-import 'package:angel_framework/angel_framework.dart';
-import 'plural.dart' as pluralize;
-import 'no_service.dart';
-
-HookedServiceEventListener hasManyThrough(String servicePath, String pivotPath,
- {String? as,
- String? localKey,
- String? pivotKey,
- String? foreignKey,
- Function(dynamic obj)? getLocalKey,
- Function(dynamic obj)? getPivotKey,
- Function(dynamic obj)? getForeignKey,
- Function(dynamic foreign, dynamic obj)? assignForeignObjects}) {
- var foreignName =
- as?.isNotEmpty == true ? as : pluralize.plural(servicePath.toString());
-
- return (HookedServiceEvent e) async {
- var pivotService = e.getService(pivotPath);
- var foreignService = e.getService(servicePath);
-
- if (pivotService == null) {
- throw noService(pivotPath);
- } else if (foreignService == null) throw noService(servicePath);
-
- dynamic _assignForeignObjects(foreign, obj) {
- if (assignForeignObjects != null) {
- return assignForeignObjects(foreign, obj);
- } else if (obj is Map) {
- obj[foreignName] = foreign;
- } else {
- reflect(obj).setField(Symbol(foreignName!), foreign);
- }
- }
-
- dynamic _getLocalKey(obj) {
- if (getLocalKey != null) {
- return getLocalKey(obj);
- } else if (obj is Map) {
- return obj[localKey ?? 'id'];
- } else if (localKey == null || localKey == 'id') {
- return obj.id;
- } else {
- return reflect(obj).getField(Symbol(localKey)).reflectee;
- }
- }
-
- dynamic _getPivotKey(obj) {
- if (getPivotKey != null) {
- return getPivotKey(obj);
- } else if (obj is Map) {
- return obj[pivotKey ?? 'id'];
- } else if (pivotKey == null || pivotKey == 'id') {
- return obj.id;
- } else {
- return reflect(obj).getField(Symbol(pivotKey)).reflectee;
- }
- }
-
- Future _normalize(obj) async {
- // First, resolve pivot
- var id = await _getLocalKey(obj);
- var indexed = await pivotService.index({
- 'query': {pivotKey ?? 'userId': id}
- });
-
- if (indexed is! List || indexed.isNotEmpty != true) {
- await _assignForeignObjects([], obj);
- } else {
- // Now, resolve from foreign service
- var mapped = await Future.wait(indexed.map((pivot) async {
- var id = await _getPivotKey(obj);
- var indexed = await foreignService.index({
- 'query': {foreignKey ?? 'postId': id}
- });
-
- if (indexed is! List || indexed.isNotEmpty != true) {
- await _assignForeignObjects([], pivot);
- } else {
- await _assignForeignObjects(indexed, pivot);
- }
-
- return pivot;
- }));
- await _assignForeignObjects(mapped, obj);
- }
- }
-
- if (e.result is Iterable) {
- //await Future.wait(e.result.map(_normalize));
- await e.result.map(_normalize);
- } else {
- await _normalize(e.result);
- }
- };
-}
diff --git a/archived_packages/relations/lib/src/has_one.dart b/archived_packages/relations/lib/src/has_one.dart
deleted file mode 100644
index d463e823..00000000
--- a/archived_packages/relations/lib/src/has_one.dart
+++ /dev/null
@@ -1,73 +0,0 @@
-import 'dart:async';
-import 'dart:mirrors';
-import 'package:angel_framework/angel_framework.dart';
-import 'plural.dart' as pluralize;
-import 'no_service.dart';
-
-/// Represents a relationship in which the current [service] "owns"
-/// a single member of the service at [servicePath]. Use [as] to set the name
-/// on the target object.
-///
-/// Defaults:
-/// * [foreignKey]: `userId`
-/// * [localKey]: `id`
-HookedServiceEventListener hasOne(Pattern servicePath,
- {String? as,
- String? foreignKey,
- String? localKey,
- Function(dynamic obj)? getLocalKey,
- Function(dynamic foreign, dynamic obj)? assignForeignObject}) {
- return (HookedServiceEvent e) async {
- var ref = e.getService(servicePath);
- var foreignName = as?.isNotEmpty == true
- ? as
- : pluralize.singular(servicePath.toString());
- if (ref == null) throw noService(servicePath);
-
- dynamic _getLocalKey(obj) {
- if (getLocalKey != null) {
- return getLocalKey(obj);
- } else if (obj is Map) {
- return obj[localKey ?? 'id'];
- } else if (localKey == null || localKey == 'id') {
- return obj.id;
- } else {
- return reflect(obj).getField(Symbol(localKey)).reflectee;
- }
- }
-
- dynamic _assignForeignObject(foreign, obj) {
- if (assignForeignObject != null) {
- return assignForeignObject(foreign, obj);
- } else if (obj is Map) {
- obj[foreignName] = foreign;
- } else {
- reflect(obj).setField(Symbol(foreignName!), foreign);
- }
- }
-
- Future _normalize(obj) async {
- if (obj != null) {
- var id = await _getLocalKey(obj);
-
- var indexed = await ref.index({
- 'query': {foreignKey ?? 'userId': id}
- });
-
- if (indexed is! List || indexed.isNotEmpty != true) {
- await _assignForeignObject(null, obj);
- } else {
- var child = indexed.first;
- await _assignForeignObject(child, obj);
- }
- }
- }
-
- if (e.result is Iterable) {
- //await Future.wait(e.result.map(_normalize));
- await e.result.map(_normalize);
- } else {
- await _normalize(e.result);
- }
- };
-}
diff --git a/archived_packages/relations/lib/src/no_service.dart b/archived_packages/relations/lib/src/no_service.dart
deleted file mode 100644
index df8eb3c4..00000000
--- a/archived_packages/relations/lib/src/no_service.dart
+++ /dev/null
@@ -1,2 +0,0 @@
-ArgumentError noService(Pattern path) =>
- ArgumentError("No service exists at path '$path'.");
diff --git a/archived_packages/relations/lib/src/plural.dart b/archived_packages/relations/lib/src/plural.dart
deleted file mode 100644
index 2c94bb89..00000000
--- a/archived_packages/relations/lib/src/plural.dart
+++ /dev/null
@@ -1,23 +0,0 @@
-String singular(String path) {
- var str = path.trim().split('/').where((str) => str.isNotEmpty).last;
-
- if (str.endsWith('ies')) {
- return str.substring(0, str.length - 3) + 'y';
- } else if (str.endsWith('s')) {
- return str.substring(0, str.length - 1);
- } else {
- return str;
- }
-}
-
-String plural(String path) {
- var str = path.trim().split('/').where((str) => str.isNotEmpty).last;
-
- if (str.endsWith('y')) {
- return str.substring(0, str.length - 1) + 'ies';
- } else if (str.endsWith('s')) {
- return str;
- } else {
- return str + 's';
- }
-}
diff --git a/archived_packages/relations/pubspec.yaml b/archived_packages/relations/pubspec.yaml
deleted file mode 100644
index 53f427c4..00000000
--- a/archived_packages/relations/pubspec.yaml
+++ /dev/null
@@ -1,21 +0,0 @@
-name: angel_relations
-version: 2.0.0
-description: Database-agnostic relations between Angel services.
-homepage: "https://github.com/angel-dart/relations.git"
-publish_to: none
-environment:
- sdk: '>=2.12.0 <3.0.0'
-dependencies:
- angel_framework:
- git:
- url: https://github.com/dukefirehawk/angel.git
- ref: sdk-2.12.x_nnbd
- path: packages/framework
-dev_dependencies:
- angel_seeder:
- git:
- url: https://github.com/dukefirehawk/angel.git
- ref: sdk-2.12.x_nnbd
- path: packages/seeder
- test: ^1.17.8
- lints: ^1.0.0
diff --git a/archived_packages/relations/test/belongs_to_test.dart b/archived_packages/relations/test/belongs_to_test.dart
deleted file mode 100644
index 06e2746a..00000000
--- a/archived_packages/relations/test/belongs_to_test.dart
+++ /dev/null
@@ -1,54 +0,0 @@
-import 'package:angel_framework/angel_framework.dart';
-import 'package:angel_seeder/angel_seeder.dart';
-import 'package:test/test.dart';
-import 'common.dart';
-
-void main() {
- late Angel app;
-
- setUp(() async {
- app = Angel()..use('/authors', MapService())..use('/books', MapService());
-
- await app.configure(seed(
- 'authors',
- SeederConfiguration