diff --git a/packages/shorebird_code_push_protocol/lib/src/models/app.dart b/packages/shorebird_code_push_protocol/lib/src/models/app.dart index f4b7208e..f4cd792a 100644 --- a/packages/shorebird_code_push_protocol/lib/src/models/app.dart +++ b/packages/shorebird_code_push_protocol/lib/src/models/app.dart @@ -3,7 +3,7 @@ import 'package:json_annotation/json_annotation.dart'; part 'app.g.dart'; /// {@template app} -/// A single app which contains zero or more releases. +/// The application downloaded and run on various devices/platforms. /// {@endtemplate} @JsonSerializable() class App { diff --git a/packages/shorebird_code_push_protocol/lib/src/models/artifact.dart b/packages/shorebird_code_push_protocol/lib/src/models/artifact.dart new file mode 100644 index 00000000..31d9df8f --- /dev/null +++ b/packages/shorebird_code_push_protocol/lib/src/models/artifact.dart @@ -0,0 +1,45 @@ +import 'package:json_annotation/json_annotation.dart'; + +part 'artifact.g.dart'; + +/// {@template artifact} +/// An artifact contains metadata about the contents of a specific patch +/// for a specific platform and architecture. +/// {@endtemplate} +@JsonSerializable() +class Artifact { + /// {@macro artifact} + const Artifact({ + required this.id, + required this.patchId, + required this.arch, + required this.platform, + required this.hash, + required this.url, + }); + + /// Converts a Map to a [Artifact] + factory Artifact.fromJson(Map json) => + _$ArtifactFromJson(json); + + /// Converts a [Artifact] to a Map + Map toJson() => _$ArtifactToJson(this); + + /// The ID of the artifact; + final int id; + + /// The ID of the patch. + final int patchId; + + /// The arch of the artifact. + final String arch; + + /// The platform of the artifact. + final String platform; + + /// The hash of the artifact. + final String hash; + + /// The url of the artifact. + final String url; +} diff --git a/packages/shorebird_code_push_protocol/lib/src/models/artifact.g.dart b/packages/shorebird_code_push_protocol/lib/src/models/artifact.g.dart new file mode 100644 index 00000000..4e373180 --- /dev/null +++ b/packages/shorebird_code_push_protocol/lib/src/models/artifact.g.dart @@ -0,0 +1,35 @@ +// GENERATED CODE - DO NOT MODIFY BY HAND + +// ignore_for_file: implicit_dynamic_parameter, require_trailing_commas, cast_nullable_to_non_nullable, lines_longer_than_80_chars + +part of 'artifact.dart'; + +// ************************************************************************** +// JsonSerializableGenerator +// ************************************************************************** + +Artifact _$ArtifactFromJson(Map json) => $checkedCreate( + 'Artifact', + json, + ($checkedConvert) { + final val = Artifact( + id: $checkedConvert('id', (v) => v as int), + patchId: $checkedConvert('patch_id', (v) => v as int), + arch: $checkedConvert('arch', (v) => v as String), + platform: $checkedConvert('platform', (v) => v as String), + hash: $checkedConvert('hash', (v) => v as String), + url: $checkedConvert('url', (v) => v as String), + ); + return val; + }, + fieldKeyMap: const {'patchId': 'patch_id'}, + ); + +Map _$ArtifactToJson(Artifact instance) => { + 'id': instance.id, + 'patch_id': instance.patchId, + 'arch': instance.arch, + 'platform': instance.platform, + 'hash': instance.hash, + 'url': instance.url, + }; diff --git a/packages/shorebird_code_push_protocol/lib/src/models/channel.dart b/packages/shorebird_code_push_protocol/lib/src/models/channel.dart new file mode 100644 index 00000000..96cc0964 --- /dev/null +++ b/packages/shorebird_code_push_protocol/lib/src/models/channel.dart @@ -0,0 +1,30 @@ +import 'package:json_annotation/json_annotation.dart'; + +part 'channel.g.dart'; + +/// {@template channel} +/// A tag used to manage the subset of applications that receive a patch. +/// By default, a "stable" channel is created and +/// used by devices to query for available patches. +/// {@endtemplate} +@JsonSerializable() +class Channel { + /// {@macro channel} + const Channel({required this.id, required this.appId, required this.name}); + + /// Converts a Map to a [Channel] + factory Channel.fromJson(Map json) => + _$ChannelFromJson(json); + + /// Converts a [Channel] to a Map + Map toJson() => _$ChannelToJson(this); + + /// The ID of the channel; + final int id; + + /// The ID of the app. + final String appId; + + /// The channel name. + final String name; +} diff --git a/packages/shorebird_code_push_protocol/lib/src/models/channel.g.dart b/packages/shorebird_code_push_protocol/lib/src/models/channel.g.dart new file mode 100644 index 00000000..2ddcafe4 --- /dev/null +++ b/packages/shorebird_code_push_protocol/lib/src/models/channel.g.dart @@ -0,0 +1,29 @@ +// GENERATED CODE - DO NOT MODIFY BY HAND + +// ignore_for_file: implicit_dynamic_parameter, require_trailing_commas, cast_nullable_to_non_nullable, lines_longer_than_80_chars + +part of 'channel.dart'; + +// ************************************************************************** +// JsonSerializableGenerator +// ************************************************************************** + +Channel _$ChannelFromJson(Map json) => $checkedCreate( + 'Channel', + json, + ($checkedConvert) { + final val = Channel( + id: $checkedConvert('id', (v) => v as int), + appId: $checkedConvert('app_id', (v) => v as String), + name: $checkedConvert('name', (v) => v as String), + ); + return val; + }, + fieldKeyMap: const {'appId': 'app_id'}, + ); + +Map _$ChannelToJson(Channel instance) => { + 'id': instance.id, + 'app_id': instance.appId, + 'name': instance.name, + }; diff --git a/packages/shorebird_code_push_protocol/lib/src/models/models.dart b/packages/shorebird_code_push_protocol/lib/src/models/models.dart index 1fb56cb4..9528d002 100644 --- a/packages/shorebird_code_push_protocol/lib/src/models/models.dart +++ b/packages/shorebird_code_push_protocol/lib/src/models/models.dart @@ -1,5 +1,8 @@ export 'app.dart'; export 'app_metadata.dart'; +export 'artifact.dart'; +export 'channel.dart'; export 'error_response.dart'; export 'patch.dart'; +export 'release.dart'; export 'user.dart'; diff --git a/packages/shorebird_code_push_protocol/lib/src/models/patch.dart b/packages/shorebird_code_push_protocol/lib/src/models/patch.dart index 07ddb9ad..b91b09db 100644 --- a/packages/shorebird_code_push_protocol/lib/src/models/patch.dart +++ b/packages/shorebird_code_push_protocol/lib/src/models/patch.dart @@ -3,7 +3,9 @@ import 'package:json_annotation/json_annotation.dart'; part 'patch.g.dart'; /// {@template patch} -/// A single patch which contains zero or more artifacts. +/// An over the air update which is applied to a specific release. +/// All patches have a patch number (auto-incrementing integer) and +/// multiple patches can be published for a given app release version. /// {@endtemplate} @JsonSerializable() class Patch { diff --git a/packages/shorebird_code_push_protocol/lib/src/models/release.dart b/packages/shorebird_code_push_protocol/lib/src/models/release.dart new file mode 100644 index 00000000..e8afc4ed --- /dev/null +++ b/packages/shorebird_code_push_protocol/lib/src/models/release.dart @@ -0,0 +1,37 @@ +import 'package:json_annotation/json_annotation.dart'; + +part 'release.g.dart'; + +/// {@template release} +/// A release build of an application that is distributed to devices. +/// A release can have zero or more patches applied to it. +/// {@endtemplate} +@JsonSerializable() +class Release { + /// {@macro release} + const Release({ + required this.id, + required this.appId, + required this.version, + required this.displayName, + }); + + /// Converts a Map to a [Release] + factory Release.fromJson(Map json) => + _$ReleaseFromJson(json); + + /// Converts a [Release] to a Map + Map toJson() => _$ReleaseToJson(this); + + /// The ID of the release; + final int id; + + /// The ID of the app. + final String appId; + + /// The version of the release. + final String version; + + /// The display name for the release + final String? displayName; +} diff --git a/packages/shorebird_code_push_protocol/lib/src/models/release.g.dart b/packages/shorebird_code_push_protocol/lib/src/models/release.g.dart new file mode 100644 index 00000000..418a0ad1 --- /dev/null +++ b/packages/shorebird_code_push_protocol/lib/src/models/release.g.dart @@ -0,0 +1,31 @@ +// GENERATED CODE - DO NOT MODIFY BY HAND + +// ignore_for_file: implicit_dynamic_parameter, require_trailing_commas, cast_nullable_to_non_nullable, lines_longer_than_80_chars + +part of 'release.dart'; + +// ************************************************************************** +// JsonSerializableGenerator +// ************************************************************************** + +Release _$ReleaseFromJson(Map json) => $checkedCreate( + 'Release', + json, + ($checkedConvert) { + final val = Release( + id: $checkedConvert('id', (v) => v as int), + appId: $checkedConvert('app_id', (v) => v as String), + version: $checkedConvert('version', (v) => v as String), + displayName: $checkedConvert('display_name', (v) => v as String?), + ); + return val; + }, + fieldKeyMap: const {'appId': 'app_id', 'displayName': 'display_name'}, + ); + +Map _$ReleaseToJson(Release instance) => { + 'id': instance.id, + 'app_id': instance.appId, + 'version': instance.version, + 'display_name': instance.displayName, + }; diff --git a/packages/shorebird_code_push_protocol/test/src/models/artifact_test.dart b/packages/shorebird_code_push_protocol/test/src/models/artifact_test.dart new file mode 100644 index 00000000..c3c9bcbb --- /dev/null +++ b/packages/shorebird_code_push_protocol/test/src/models/artifact_test.dart @@ -0,0 +1,21 @@ +import 'package:shorebird_code_push_protocol/shorebird_code_push_protocol.dart'; +import 'package:test/test.dart'; + +void main() { + group('Artifact', () { + test('can be (de)serialized', () { + const artifact = Artifact( + id: 1, + patchId: 1, + arch: 'aarch64', + platform: 'android', + url: 'https://example.com', + hash: 'sha256:1234567890', + ); + expect( + Artifact.fromJson(artifact.toJson()).toJson(), + equals(artifact.toJson()), + ); + }); + }); +} diff --git a/packages/shorebird_code_push_protocol/test/src/models/channel_test.dart b/packages/shorebird_code_push_protocol/test/src/models/channel_test.dart new file mode 100644 index 00000000..b15d0561 --- /dev/null +++ b/packages/shorebird_code_push_protocol/test/src/models/channel_test.dart @@ -0,0 +1,18 @@ +import 'package:shorebird_code_push_protocol/shorebird_code_push_protocol.dart'; +import 'package:test/test.dart'; + +void main() { + group('Channel', () { + test('can be (de)serialized', () { + const channel = Channel( + id: 1, + appId: 'app-id', + name: 'stable', + ); + expect( + Channel.fromJson(channel.toJson()).toJson(), + equals(channel.toJson()), + ); + }); + }); +} diff --git a/packages/shorebird_code_push_protocol/test/src/models/release_test.dart b/packages/shorebird_code_push_protocol/test/src/models/release_test.dart new file mode 100644 index 00000000..3bcb6ce7 --- /dev/null +++ b/packages/shorebird_code_push_protocol/test/src/models/release_test.dart @@ -0,0 +1,19 @@ +import 'package:shorebird_code_push_protocol/shorebird_code_push_protocol.dart'; +import 'package:test/test.dart'; + +void main() { + group('Release', () { + test('can be (de)serialized', () { + const release = Release( + id: 1, + appId: 'app-id', + version: '1.0.0', + displayName: 'v1.0.0', + ); + expect( + Release.fromJson(release.toJson()).toJson(), + equals(release.toJson()), + ); + }); + }); +}