feat(data): modèle de données Drift pour la persistance locale
Définit les tables Drift et les identifiants locaux (local_id.dart, tables.dart), régénère app_database.g.dart. build_runner, flutter analyze et build APK debug validés. Versionne les fichiers générés .g.dart : projet solo sans pipeline CI qui relance build_runner, on privilégie un clone immédiatement buildable. Retire la règle **/*.g.dart (et freezed/gr.dart, non utilisés) du .gitignore en conséquence. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
5
.gitignore
vendored
5
.gitignore
vendored
@ -73,11 +73,6 @@ DerivedData/
|
|||||||
*.dSYM.zip
|
*.dSYM.zip
|
||||||
*.dSYM
|
*.dSYM
|
||||||
|
|
||||||
# Generated files
|
|
||||||
**/*.g.dart
|
|
||||||
**/*.freezed.dart
|
|
||||||
**/*.gr.dart
|
|
||||||
|
|
||||||
# Coverage
|
# Coverage
|
||||||
coverage/
|
coverage/
|
||||||
|
|
||||||
|
|||||||
@ -1,16 +1,35 @@
|
|||||||
import 'package:drift/drift.dart';
|
import 'package:drift/drift.dart';
|
||||||
import 'package:drift_flutter/drift_flutter.dart';
|
import 'package:drift_flutter/drift_flutter.dart';
|
||||||
|
|
||||||
final class AppDatabase extends GeneratedDatabase {
|
import 'tables.dart';
|
||||||
AppDatabase(DatabaseConnection connection) : super.connect(connection);
|
|
||||||
|
part 'app_database.g.dart';
|
||||||
|
|
||||||
|
@DriftDatabase(
|
||||||
|
tables: [
|
||||||
|
ActiveRestStates,
|
||||||
|
ActiveSetResults,
|
||||||
|
ActiveWorkoutSessions,
|
||||||
|
ChangeLogEntries,
|
||||||
|
Exercises,
|
||||||
|
MediaAssets,
|
||||||
|
ProgramExercises,
|
||||||
|
Programs,
|
||||||
|
WorkoutHistories,
|
||||||
|
WorkoutHistorySetResults,
|
||||||
|
WorkoutTemplateExerciseOverrides,
|
||||||
|
WorkoutTemplatePrograms,
|
||||||
|
WorkoutTemplates,
|
||||||
|
],
|
||||||
|
)
|
||||||
|
final class AppDatabase extends _$AppDatabase {
|
||||||
|
AppDatabase(super.executor);
|
||||||
|
|
||||||
factory AppDatabase.open() {
|
factory AppDatabase.open() {
|
||||||
return AppDatabase(
|
return AppDatabase(
|
||||||
driftDatabase(
|
driftDatabase(
|
||||||
name: 'gametime',
|
name: 'gametime',
|
||||||
native: const DriftNativeOptions(
|
native: const DriftNativeOptions(shareAcrossIsolates: true),
|
||||||
shareAcrossIsolates: true,
|
|
||||||
),
|
|
||||||
),
|
),
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
@ -19,5 +38,95 @@ final class AppDatabase extends GeneratedDatabase {
|
|||||||
int get schemaVersion => 1;
|
int get schemaVersion => 1;
|
||||||
|
|
||||||
@override
|
@override
|
||||||
Iterable<TableInfo<Table, dynamic>> get allTables => const [];
|
MigrationStrategy get migration {
|
||||||
|
return MigrationStrategy(
|
||||||
|
onCreate: (migrator) async {
|
||||||
|
await migrator.createAll();
|
||||||
|
await _createIndexes();
|
||||||
|
},
|
||||||
|
beforeOpen: (details) async {
|
||||||
|
await customStatement('PRAGMA foreign_keys = ON');
|
||||||
|
},
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Future<void> _createIndexes() async {
|
||||||
|
for (final tableName in _syncableTableNames) {
|
||||||
|
await customStatement(
|
||||||
|
'CREATE INDEX IF NOT EXISTS idx_${tableName}_deleted_at '
|
||||||
|
'ON $tableName (deleted_at)',
|
||||||
|
);
|
||||||
|
await customStatement(
|
||||||
|
'CREATE INDEX IF NOT EXISTS idx_${tableName}_updated_at '
|
||||||
|
'ON $tableName (updated_at)',
|
||||||
|
);
|
||||||
|
await customStatement(
|
||||||
|
'CREATE INDEX IF NOT EXISTS idx_${tableName}_sync_state '
|
||||||
|
'ON $tableName (sync_state)',
|
||||||
|
);
|
||||||
|
await customStatement(
|
||||||
|
'CREATE INDEX IF NOT EXISTS idx_${tableName}_local_revision '
|
||||||
|
'ON $tableName (local_revision)',
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
await customStatement(
|
||||||
|
'CREATE INDEX IF NOT EXISTS idx_program_exercises_program_id '
|
||||||
|
'ON program_exercises (program_id)',
|
||||||
|
);
|
||||||
|
await customStatement(
|
||||||
|
'CREATE INDEX IF NOT EXISTS idx_workout_template_programs_template_id '
|
||||||
|
'ON workout_template_programs (workout_template_id)',
|
||||||
|
);
|
||||||
|
await customStatement(
|
||||||
|
'CREATE INDEX IF NOT EXISTS idx_active_set_results_session_id '
|
||||||
|
'ON active_set_results (active_workout_session_id)',
|
||||||
|
);
|
||||||
|
await customStatement(
|
||||||
|
'CREATE INDEX IF NOT EXISTS idx_active_rest_states_session_id '
|
||||||
|
'ON active_rest_states (active_workout_session_id)',
|
||||||
|
);
|
||||||
|
await customStatement(
|
||||||
|
'CREATE UNIQUE INDEX IF NOT EXISTS '
|
||||||
|
'idx_active_workout_sessions_single_open '
|
||||||
|
'ON active_workout_sessions ((1)) '
|
||||||
|
'WHERE deleted_at IS NULL '
|
||||||
|
"AND status IN ('running', 'paused', 'savedExit')",
|
||||||
|
);
|
||||||
|
await customStatement(
|
||||||
|
'CREATE INDEX IF NOT EXISTS idx_workout_history_started_at '
|
||||||
|
'ON workout_history (started_at)',
|
||||||
|
);
|
||||||
|
await customStatement(
|
||||||
|
'CREATE INDEX IF NOT EXISTS idx_workout_history_set_results_history_id '
|
||||||
|
'ON workout_history_set_results (workout_history_id)',
|
||||||
|
);
|
||||||
|
await customStatement(
|
||||||
|
'CREATE INDEX IF NOT EXISTS idx_change_log_entity '
|
||||||
|
'ON change_log (entity_type, entity_id)',
|
||||||
|
);
|
||||||
|
await customStatement(
|
||||||
|
'CREATE INDEX IF NOT EXISTS idx_change_log_local_revision '
|
||||||
|
'ON change_log (local_revision)',
|
||||||
|
);
|
||||||
|
await customStatement(
|
||||||
|
'CREATE INDEX IF NOT EXISTS idx_change_log_synced_at '
|
||||||
|
'ON change_log (synced_at)',
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
const _syncableTableNames = [
|
||||||
|
'active_rest_states',
|
||||||
|
'active_set_results',
|
||||||
|
'active_workout_sessions',
|
||||||
|
'exercises',
|
||||||
|
'media_assets',
|
||||||
|
'program_exercises',
|
||||||
|
'programs',
|
||||||
|
'workout_history',
|
||||||
|
'workout_history_set_results',
|
||||||
|
'workout_template_exercise_overrides',
|
||||||
|
'workout_template_programs',
|
||||||
|
'workout_templates',
|
||||||
|
];
|
||||||
|
|||||||
25878
lib/infrastructure/local/app_database.g.dart
Normal file
25878
lib/infrastructure/local/app_database.g.dart
Normal file
File diff suppressed because it is too large
Load Diff
@ -1 +1,2 @@
|
|||||||
export 'app_database.dart';
|
export 'app_database.dart';
|
||||||
|
export 'local_id.dart';
|
||||||
|
|||||||
28
lib/infrastructure/local/local_id.dart
Normal file
28
lib/infrastructure/local/local_id.dart
Normal file
@ -0,0 +1,28 @@
|
|||||||
|
import 'dart:math';
|
||||||
|
|
||||||
|
const _crockfordBase32 = '0123456789ABCDEFGHJKMNPQRSTVWXYZ';
|
||||||
|
|
||||||
|
final class LocalIdGenerator {
|
||||||
|
LocalIdGenerator({Random? random}) : _random = random ?? Random.secure();
|
||||||
|
|
||||||
|
final Random _random;
|
||||||
|
|
||||||
|
String newUlid({DateTime? now}) {
|
||||||
|
final timestamp = (now ?? DateTime.now().toUtc()).millisecondsSinceEpoch;
|
||||||
|
final buffer = StringBuffer();
|
||||||
|
|
||||||
|
var remainingTimestamp = timestamp;
|
||||||
|
final timestampChars = List<String>.filled(10, '0');
|
||||||
|
for (var index = 9; index >= 0; index--) {
|
||||||
|
timestampChars[index] = _crockfordBase32[remainingTimestamp & 0x1F];
|
||||||
|
remainingTimestamp >>= 5;
|
||||||
|
}
|
||||||
|
buffer.writeAll(timestampChars);
|
||||||
|
|
||||||
|
for (var index = 0; index < 16; index++) {
|
||||||
|
buffer.write(_crockfordBase32[_random.nextInt(32)]);
|
||||||
|
}
|
||||||
|
|
||||||
|
return buffer.toString();
|
||||||
|
}
|
||||||
|
}
|
||||||
381
lib/infrastructure/local/tables.dart
Normal file
381
lib/infrastructure/local/tables.dart
Normal file
@ -0,0 +1,381 @@
|
|||||||
|
import 'package:drift/drift.dart';
|
||||||
|
|
||||||
|
abstract class SyncableTable extends Table {
|
||||||
|
TextColumn get id => text()();
|
||||||
|
DateTimeColumn get createdAt => dateTime()();
|
||||||
|
DateTimeColumn get updatedAt => dateTime()();
|
||||||
|
DateTimeColumn get deletedAt => dateTime().nullable()();
|
||||||
|
IntColumn get schemaVersion => integer().withDefault(const Constant(1))();
|
||||||
|
TextColumn get syncState => text().customConstraint(
|
||||||
|
"NOT NULL CHECK (sync_state IN ('localOnly', 'dirty', 'synced', "
|
||||||
|
"'deleted'))",
|
||||||
|
)();
|
||||||
|
IntColumn get localRevision =>
|
||||||
|
integer().customConstraint('NOT NULL CHECK (local_revision >= 0)')();
|
||||||
|
TextColumn get originDeviceId => text().withLength(min: 1)();
|
||||||
|
TextColumn get futureOwnerProfileId => text().nullable()();
|
||||||
|
DateTimeColumn get lastSyncedAt => dateTime().nullable()();
|
||||||
|
TextColumn get remoteRevision => text().nullable()();
|
||||||
|
|
||||||
|
@override
|
||||||
|
Set<Column> get primaryKey => {id};
|
||||||
|
|
||||||
|
@override
|
||||||
|
List<String> get customConstraints => const [];
|
||||||
|
}
|
||||||
|
|
||||||
|
class MediaAssets extends SyncableTable {
|
||||||
|
@override
|
||||||
|
String get tableName => 'media_assets';
|
||||||
|
|
||||||
|
TextColumn get kind => text()();
|
||||||
|
TextColumn get localUri => text().withLength(min: 1)();
|
||||||
|
TextColumn get mimeType => text().nullable()();
|
||||||
|
IntColumn get sizeBytes => integer().nullable()();
|
||||||
|
IntColumn get width => integer().nullable()();
|
||||||
|
IntColumn get height => integer().nullable()();
|
||||||
|
IntColumn get durationMs => integer().nullable()();
|
||||||
|
TextColumn get checksum => text().nullable()();
|
||||||
|
TextColumn get remoteUri => text().nullable()();
|
||||||
|
TextColumn get thumbnailLocalUri => text().nullable()();
|
||||||
|
|
||||||
|
@override
|
||||||
|
List<String> get customConstraints => [
|
||||||
|
"CHECK (kind IN ('image', 'video'))",
|
||||||
|
'CHECK (size_bytes IS NULL OR size_bytes >= 0)',
|
||||||
|
'CHECK (width IS NULL OR width > 0)',
|
||||||
|
'CHECK (height IS NULL OR height > 0)',
|
||||||
|
'CHECK (duration_ms IS NULL OR duration_ms >= 0)',
|
||||||
|
];
|
||||||
|
}
|
||||||
|
|
||||||
|
class Exercises extends SyncableTable {
|
||||||
|
@override
|
||||||
|
String get tableName => 'exercises';
|
||||||
|
|
||||||
|
TextColumn get name => text().withLength(min: 1)();
|
||||||
|
TextColumn get description => text().nullable()();
|
||||||
|
@ReferenceName('exerciseImageReferences')
|
||||||
|
TextColumn get imageMediaId =>
|
||||||
|
text().nullable().references(MediaAssets, #id)();
|
||||||
|
|
||||||
|
@ReferenceName('exerciseVideoReferences')
|
||||||
|
TextColumn get videoMediaId =>
|
||||||
|
text().nullable().references(MediaAssets, #id)();
|
||||||
|
BoolColumn get hasTimeMeasure => boolean()();
|
||||||
|
BoolColumn get hasRepsMeasure => boolean()();
|
||||||
|
BoolColumn get hasScoreMeasure => boolean()();
|
||||||
|
TextColumn get scoreLabel => text().nullable()();
|
||||||
|
TextColumn get scoreUnit => text().nullable()();
|
||||||
|
DateTimeColumn get archivedAt => dateTime().nullable()();
|
||||||
|
|
||||||
|
@override
|
||||||
|
List<String> get customConstraints => [
|
||||||
|
'CHECK (has_time_measure OR has_reps_measure OR has_score_measure)',
|
||||||
|
'CHECK (NOT has_score_measure OR (score_label IS NOT NULL '
|
||||||
|
'AND length(trim(score_label)) > 0 AND score_unit IS NOT NULL '
|
||||||
|
'AND length(trim(score_unit)) > 0))',
|
||||||
|
];
|
||||||
|
}
|
||||||
|
|
||||||
|
class Programs extends SyncableTable {
|
||||||
|
@override
|
||||||
|
String get tableName => 'programs';
|
||||||
|
|
||||||
|
TextColumn get name => text().withLength(min: 1)();
|
||||||
|
IntColumn get defaultRestSeconds => integer()();
|
||||||
|
|
||||||
|
@override
|
||||||
|
List<String> get customConstraints => ['CHECK (default_rest_seconds >= 0)'];
|
||||||
|
}
|
||||||
|
|
||||||
|
class ProgramExercises extends SyncableTable {
|
||||||
|
@override
|
||||||
|
String get tableName => 'program_exercises';
|
||||||
|
|
||||||
|
TextColumn get programId => text().references(Programs, #id)();
|
||||||
|
TextColumn get sourceExerciseId =>
|
||||||
|
text().nullable().references(Exercises, #id)();
|
||||||
|
IntColumn get position => integer()();
|
||||||
|
TextColumn get exerciseNameSnapshot => text().withLength(min: 1)();
|
||||||
|
TextColumn get exerciseDescriptionSnapshot => text().nullable()();
|
||||||
|
@ReferenceName('programExerciseImageSnapshotReferences')
|
||||||
|
TextColumn get exerciseImageMediaIdSnapshot =>
|
||||||
|
text().nullable().references(MediaAssets, #id)();
|
||||||
|
|
||||||
|
@ReferenceName('programExerciseVideoSnapshotReferences')
|
||||||
|
TextColumn get exerciseVideoMediaIdSnapshot =>
|
||||||
|
text().nullable().references(MediaAssets, #id)();
|
||||||
|
BoolColumn get exerciseArchivedSnapshot =>
|
||||||
|
boolean().withDefault(const Constant(false))();
|
||||||
|
BoolColumn get availableTimeSnapshot => boolean()();
|
||||||
|
BoolColumn get availableRepsSnapshot => boolean()();
|
||||||
|
BoolColumn get availableScoreSnapshot => boolean()();
|
||||||
|
TextColumn get scoreLabelSnapshot => text().nullable()();
|
||||||
|
TextColumn get scoreUnitSnapshot => text().nullable()();
|
||||||
|
IntColumn get setsCount => integer()();
|
||||||
|
BoolColumn get timeEnabled => boolean()();
|
||||||
|
BoolColumn get repsEnabled => boolean()();
|
||||||
|
BoolColumn get scoreEnabled => boolean()();
|
||||||
|
IntColumn get targetTimeSeconds => integer().nullable()();
|
||||||
|
IntColumn get targetReps => integer().nullable()();
|
||||||
|
RealColumn get targetScore => real().nullable()();
|
||||||
|
IntColumn get restSecondsOverride => integer().nullable()();
|
||||||
|
|
||||||
|
@override
|
||||||
|
List<String> get customConstraints => [
|
||||||
|
'UNIQUE (program_id, position)',
|
||||||
|
'CHECK (position >= 0)',
|
||||||
|
'CHECK (sets_count > 0)',
|
||||||
|
'CHECK (time_enabled OR reps_enabled OR score_enabled)',
|
||||||
|
'CHECK (NOT time_enabled OR available_time_snapshot)',
|
||||||
|
'CHECK (NOT reps_enabled OR available_reps_snapshot)',
|
||||||
|
'CHECK (NOT score_enabled OR available_score_snapshot)',
|
||||||
|
'CHECK (target_time_seconds IS NULL OR target_time_seconds > 0)',
|
||||||
|
'CHECK (target_reps IS NULL OR target_reps > 0)',
|
||||||
|
'CHECK (target_score IS NULL OR target_score >= 0)',
|
||||||
|
'CHECK (rest_seconds_override IS NULL OR rest_seconds_override >= 0)',
|
||||||
|
'CHECK (target_time_seconds IS NULL OR time_enabled)',
|
||||||
|
'CHECK (target_reps IS NULL OR reps_enabled)',
|
||||||
|
'CHECK (target_score IS NULL OR score_enabled)',
|
||||||
|
'CHECK (NOT available_score_snapshot OR (score_label_snapshot '
|
||||||
|
'IS NOT NULL AND length(trim(score_label_snapshot)) > 0 '
|
||||||
|
'AND score_unit_snapshot IS NOT NULL '
|
||||||
|
'AND length(trim(score_unit_snapshot)) > 0))',
|
||||||
|
];
|
||||||
|
}
|
||||||
|
|
||||||
|
class WorkoutTemplates extends SyncableTable {
|
||||||
|
@override
|
||||||
|
String get tableName => 'workout_templates';
|
||||||
|
|
||||||
|
TextColumn get name => text().withLength(min: 1)();
|
||||||
|
DateTimeColumn get lastStartedAt => dateTime().nullable()();
|
||||||
|
}
|
||||||
|
|
||||||
|
class WorkoutTemplatePrograms extends SyncableTable {
|
||||||
|
@override
|
||||||
|
String get tableName => 'workout_template_programs';
|
||||||
|
|
||||||
|
TextColumn get workoutTemplateId =>
|
||||||
|
text().references(WorkoutTemplates, #id)();
|
||||||
|
TextColumn get sourceProgramId =>
|
||||||
|
text().nullable().references(Programs, #id)();
|
||||||
|
IntColumn get position => integer()();
|
||||||
|
TextColumn get programNameSnapshot => text().withLength(min: 1)();
|
||||||
|
IntColumn get defaultRestSecondsSnapshot => integer()();
|
||||||
|
TextColumn get programSnapshotJson => text().withLength(min: 1)();
|
||||||
|
|
||||||
|
@override
|
||||||
|
List<String> get customConstraints => [
|
||||||
|
'UNIQUE (workout_template_id, position)',
|
||||||
|
'CHECK (position >= 0)',
|
||||||
|
'CHECK (default_rest_seconds_snapshot >= 0)',
|
||||||
|
];
|
||||||
|
}
|
||||||
|
|
||||||
|
class WorkoutTemplateExerciseOverrides extends SyncableTable {
|
||||||
|
@override
|
||||||
|
String get tableName => 'workout_template_exercise_overrides';
|
||||||
|
|
||||||
|
TextColumn get workoutTemplateProgramId =>
|
||||||
|
text().references(WorkoutTemplatePrograms, #id)();
|
||||||
|
TextColumn get snapshotProgramExerciseId => text().withLength(min: 1)();
|
||||||
|
IntColumn get setsCountOverride => integer().nullable()();
|
||||||
|
IntColumn get targetTimeSecondsOverride => integer().nullable()();
|
||||||
|
IntColumn get targetRepsOverride => integer().nullable()();
|
||||||
|
RealColumn get targetScoreOverride => real().nullable()();
|
||||||
|
|
||||||
|
@override
|
||||||
|
List<String> get customConstraints => [
|
||||||
|
'UNIQUE (workout_template_program_id, snapshot_program_exercise_id)',
|
||||||
|
'CHECK (sets_count_override IS NULL OR sets_count_override > 0)',
|
||||||
|
'CHECK (target_time_seconds_override IS NULL OR '
|
||||||
|
'target_time_seconds_override > 0)',
|
||||||
|
'CHECK (target_reps_override IS NULL OR target_reps_override > 0)',
|
||||||
|
'CHECK (target_score_override IS NULL OR target_score_override >= 0)',
|
||||||
|
];
|
||||||
|
}
|
||||||
|
|
||||||
|
class ActiveWorkoutSessions extends SyncableTable {
|
||||||
|
@override
|
||||||
|
String get tableName => 'active_workout_sessions';
|
||||||
|
|
||||||
|
TextColumn get sourceWorkoutTemplateId =>
|
||||||
|
text().nullable().references(WorkoutTemplates, #id)();
|
||||||
|
TextColumn get status => text()();
|
||||||
|
DateTimeColumn get startedAt => dateTime()();
|
||||||
|
DateTimeColumn get pausedAt => dateTime().nullable()();
|
||||||
|
DateTimeColumn get endedAt => dateTime().nullable()();
|
||||||
|
DateTimeColumn get lastPersistedAt => dateTime()();
|
||||||
|
IntColumn get elapsedActiveMs => integer()();
|
||||||
|
IntColumn get currentProgramIndex => integer()();
|
||||||
|
IntColumn get currentExerciseIndex => integer()();
|
||||||
|
IntColumn get currentSetIndex => integer()();
|
||||||
|
TextColumn get resolvedTemplateSnapshotJson => text().withLength(min: 1)();
|
||||||
|
|
||||||
|
@override
|
||||||
|
List<String> get customConstraints => [
|
||||||
|
"CHECK (status IN ('running', 'paused', 'savedExit', 'completed', "
|
||||||
|
"'abandoned'))",
|
||||||
|
'CHECK (elapsed_active_ms >= 0)',
|
||||||
|
'CHECK (current_program_index >= 0)',
|
||||||
|
'CHECK (current_exercise_index >= 0)',
|
||||||
|
'CHECK (current_set_index >= 0)',
|
||||||
|
];
|
||||||
|
}
|
||||||
|
|
||||||
|
class ActiveSetResults extends SyncableTable {
|
||||||
|
@override
|
||||||
|
String get tableName => 'active_set_results';
|
||||||
|
|
||||||
|
TextColumn get activeWorkoutSessionId =>
|
||||||
|
text().references(ActiveWorkoutSessions, #id)();
|
||||||
|
TextColumn get programSnapshotId => text().withLength(min: 1)();
|
||||||
|
TextColumn get exerciseSnapshotId => text().withLength(min: 1)();
|
||||||
|
IntColumn get programIndex => integer()();
|
||||||
|
IntColumn get exerciseIndex => integer()();
|
||||||
|
IntColumn get setIndex => integer()();
|
||||||
|
DateTimeColumn get startedAt => dateTime().nullable()();
|
||||||
|
DateTimeColumn get completedAt => dateTime().nullable()();
|
||||||
|
IntColumn get actualTimeMs => integer().nullable()();
|
||||||
|
IntColumn get actualReps => integer().nullable()();
|
||||||
|
RealColumn get actualScore => real().nullable()();
|
||||||
|
TextColumn get scoreLabelSnapshot => text().nullable()();
|
||||||
|
TextColumn get scoreUnitSnapshot => text().nullable()();
|
||||||
|
TextColumn get note => text().nullable()();
|
||||||
|
|
||||||
|
@override
|
||||||
|
List<String> get customConstraints => [
|
||||||
|
'UNIQUE (active_workout_session_id, program_index, exercise_index, '
|
||||||
|
'set_index)',
|
||||||
|
'CHECK (program_index >= 0)',
|
||||||
|
'CHECK (exercise_index >= 0)',
|
||||||
|
'CHECK (set_index >= 0)',
|
||||||
|
'CHECK (actual_time_ms IS NULL OR actual_time_ms >= 0)',
|
||||||
|
'CHECK (actual_reps IS NULL OR actual_reps >= 0)',
|
||||||
|
'CHECK (actual_score IS NULL OR actual_score >= 0)',
|
||||||
|
'CHECK (actual_score IS NULL OR (score_label_snapshot IS NOT NULL '
|
||||||
|
'AND length(trim(score_label_snapshot)) > 0 '
|
||||||
|
'AND score_unit_snapshot IS NOT NULL '
|
||||||
|
'AND length(trim(score_unit_snapshot)) > 0))',
|
||||||
|
];
|
||||||
|
}
|
||||||
|
|
||||||
|
class ActiveRestStates extends SyncableTable {
|
||||||
|
@override
|
||||||
|
String get tableName => 'active_rest_states';
|
||||||
|
|
||||||
|
TextColumn get activeWorkoutSessionId =>
|
||||||
|
text().references(ActiveWorkoutSessions, #id)();
|
||||||
|
IntColumn get afterProgramIndex => integer()();
|
||||||
|
IntColumn get afterExerciseIndex => integer()();
|
||||||
|
IntColumn get afterSetIndex => integer()();
|
||||||
|
IntColumn get plannedRestSeconds => integer()();
|
||||||
|
IntColumn get adjustedRestSeconds => integer()();
|
||||||
|
DateTimeColumn get startedAt => dateTime()();
|
||||||
|
DateTimeColumn get endedAt => dateTime().nullable()();
|
||||||
|
DateTimeColumn get skippedAt => dateTime().nullable()();
|
||||||
|
|
||||||
|
@override
|
||||||
|
List<String> get customConstraints => [
|
||||||
|
'CHECK (after_program_index >= 0)',
|
||||||
|
'CHECK (after_exercise_index >= 0)',
|
||||||
|
'CHECK (after_set_index >= 0)',
|
||||||
|
'CHECK (planned_rest_seconds >= 0)',
|
||||||
|
'CHECK (adjusted_rest_seconds >= 0)',
|
||||||
|
'CHECK (ended_at IS NULL OR skipped_at IS NULL)',
|
||||||
|
];
|
||||||
|
}
|
||||||
|
|
||||||
|
class WorkoutHistories extends SyncableTable {
|
||||||
|
@override
|
||||||
|
String get tableName => 'workout_history';
|
||||||
|
|
||||||
|
TextColumn get sourceWorkoutTemplateId =>
|
||||||
|
text().nullable().references(WorkoutTemplates, #id)();
|
||||||
|
TextColumn get sourceActiveWorkoutSessionId =>
|
||||||
|
text().nullable().references(ActiveWorkoutSessions, #id)();
|
||||||
|
TextColumn get nameSnapshot => text().withLength(min: 1)();
|
||||||
|
DateTimeColumn get startedAt => dateTime()();
|
||||||
|
DateTimeColumn get endedAt => dateTime()();
|
||||||
|
IntColumn get totalActiveMs => integer()();
|
||||||
|
BoolColumn get completed => boolean()();
|
||||||
|
TextColumn get historySnapshotJson => text().withLength(min: 1)();
|
||||||
|
|
||||||
|
@override
|
||||||
|
List<String> get customConstraints => ['CHECK (total_active_ms >= 0)'];
|
||||||
|
}
|
||||||
|
|
||||||
|
class WorkoutHistorySetResults extends SyncableTable {
|
||||||
|
@override
|
||||||
|
String get tableName => 'workout_history_set_results';
|
||||||
|
|
||||||
|
TextColumn get workoutHistoryId => text().references(WorkoutHistories, #id)();
|
||||||
|
TextColumn get programSnapshotId => text().withLength(min: 1)();
|
||||||
|
TextColumn get exerciseSnapshotId => text().withLength(min: 1)();
|
||||||
|
IntColumn get programIndex => integer()();
|
||||||
|
IntColumn get exerciseIndex => integer()();
|
||||||
|
IntColumn get setIndex => integer()();
|
||||||
|
TextColumn get programNameSnapshot => text().withLength(min: 1)();
|
||||||
|
TextColumn get exerciseNameSnapshot => text().withLength(min: 1)();
|
||||||
|
BoolColumn get timeEnabledSnapshot => boolean()();
|
||||||
|
BoolColumn get repsEnabledSnapshot => boolean()();
|
||||||
|
BoolColumn get scoreEnabledSnapshot => boolean()();
|
||||||
|
IntColumn get targetTimeSecondsSnapshot => integer().nullable()();
|
||||||
|
IntColumn get targetRepsSnapshot => integer().nullable()();
|
||||||
|
RealColumn get targetScoreSnapshot => real().nullable()();
|
||||||
|
IntColumn get actualTimeMs => integer().nullable()();
|
||||||
|
IntColumn get actualReps => integer().nullable()();
|
||||||
|
RealColumn get actualScore => real().nullable()();
|
||||||
|
TextColumn get scoreLabelSnapshot => text().nullable()();
|
||||||
|
TextColumn get scoreUnitSnapshot => text().nullable()();
|
||||||
|
DateTimeColumn get startedAt => dateTime().nullable()();
|
||||||
|
DateTimeColumn get completedAt => dateTime().nullable()();
|
||||||
|
|
||||||
|
@override
|
||||||
|
List<String> get customConstraints => [
|
||||||
|
'UNIQUE (workout_history_id, program_index, exercise_index, '
|
||||||
|
'set_index)',
|
||||||
|
'CHECK (program_index >= 0)',
|
||||||
|
'CHECK (exercise_index >= 0)',
|
||||||
|
'CHECK (set_index >= 0)',
|
||||||
|
'CHECK (time_enabled_snapshot OR reps_enabled_snapshot OR '
|
||||||
|
'score_enabled_snapshot)',
|
||||||
|
'CHECK (target_time_seconds_snapshot IS NULL OR '
|
||||||
|
'target_time_seconds_snapshot > 0)',
|
||||||
|
'CHECK (target_reps_snapshot IS NULL OR target_reps_snapshot > 0)',
|
||||||
|
'CHECK (target_score_snapshot IS NULL OR target_score_snapshot >= 0)',
|
||||||
|
'CHECK (actual_time_ms IS NULL OR actual_time_ms >= 0)',
|
||||||
|
'CHECK (actual_reps IS NULL OR actual_reps >= 0)',
|
||||||
|
'CHECK (actual_score IS NULL OR actual_score >= 0)',
|
||||||
|
'CHECK (actual_score IS NULL OR (score_label_snapshot IS NOT NULL '
|
||||||
|
'AND length(trim(score_label_snapshot)) > 0 '
|
||||||
|
'AND score_unit_snapshot IS NOT NULL '
|
||||||
|
'AND length(trim(score_unit_snapshot)) > 0))',
|
||||||
|
];
|
||||||
|
}
|
||||||
|
|
||||||
|
class ChangeLogEntries extends Table {
|
||||||
|
@override
|
||||||
|
String get tableName => 'change_log';
|
||||||
|
|
||||||
|
TextColumn get id => text()();
|
||||||
|
TextColumn get entityType => text().withLength(min: 1)();
|
||||||
|
TextColumn get entityId => text().withLength(min: 1)();
|
||||||
|
TextColumn get operation => text()();
|
||||||
|
TextColumn get payloadHash => text().nullable()();
|
||||||
|
IntColumn get localRevision => integer()();
|
||||||
|
TextColumn get originDeviceId => text().withLength(min: 1)();
|
||||||
|
DateTimeColumn get createdAt => dateTime()();
|
||||||
|
DateTimeColumn get syncedAt => dateTime().nullable()();
|
||||||
|
|
||||||
|
@override
|
||||||
|
Set<Column> get primaryKey => {id};
|
||||||
|
|
||||||
|
@override
|
||||||
|
List<String> get customConstraints => const [
|
||||||
|
"CHECK (operation IN ('insert', 'update', 'softDelete', 'restore'))",
|
||||||
|
'CHECK (local_revision >= 0)',
|
||||||
|
];
|
||||||
|
}
|
||||||
250
pubspec.lock
250
pubspec.lock
@ -1,6 +1,22 @@
|
|||||||
# Generated by pub
|
# Generated by pub
|
||||||
# See https://dart.dev/tools/pub/glossary#lockfile
|
# See https://dart.dev/tools/pub/glossary#lockfile
|
||||||
packages:
|
packages:
|
||||||
|
_fe_analyzer_shared:
|
||||||
|
dependency: transitive
|
||||||
|
description:
|
||||||
|
name: _fe_analyzer_shared
|
||||||
|
sha256: cd6add6f846f35fb79f3c315296703c1a24f3cfd7f4739d91a74961c1c7e9f1b
|
||||||
|
url: "https://pub.dev"
|
||||||
|
source: hosted
|
||||||
|
version: "100.0.0"
|
||||||
|
analyzer:
|
||||||
|
dependency: transitive
|
||||||
|
description:
|
||||||
|
name: analyzer
|
||||||
|
sha256: "6ba98576948803398b69e3a444df24eacdbe12ed699c7014e120ea38552debbf"
|
||||||
|
url: "https://pub.dev"
|
||||||
|
source: hosted
|
||||||
|
version: "13.0.0"
|
||||||
args:
|
args:
|
||||||
dependency: transitive
|
dependency: transitive
|
||||||
description:
|
description:
|
||||||
@ -25,6 +41,54 @@ packages:
|
|||||||
url: "https://pub.dev"
|
url: "https://pub.dev"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "2.1.2"
|
version: "2.1.2"
|
||||||
|
build:
|
||||||
|
dependency: transitive
|
||||||
|
description:
|
||||||
|
name: build
|
||||||
|
sha256: "45d14a0fb23e018d8287c32fc98d726ce466b231928ed9b9200f29bd3ccd39ae"
|
||||||
|
url: "https://pub.dev"
|
||||||
|
source: hosted
|
||||||
|
version: "4.0.7"
|
||||||
|
build_config:
|
||||||
|
dependency: transitive
|
||||||
|
description:
|
||||||
|
name: build_config
|
||||||
|
sha256: f2c223156a26eea323e6244b85141d76413a80aeee9fe0b380773789fabaf8ae
|
||||||
|
url: "https://pub.dev"
|
||||||
|
source: hosted
|
||||||
|
version: "1.3.1"
|
||||||
|
build_daemon:
|
||||||
|
dependency: transitive
|
||||||
|
description:
|
||||||
|
name: build_daemon
|
||||||
|
sha256: fd754058c342243718d5171a95f352cfc9fcf0cba8cfa26df67cb13a5836db78
|
||||||
|
url: "https://pub.dev"
|
||||||
|
source: hosted
|
||||||
|
version: "4.1.2"
|
||||||
|
build_runner:
|
||||||
|
dependency: "direct dev"
|
||||||
|
description:
|
||||||
|
name: build_runner
|
||||||
|
sha256: "5367e521935b102bdf1e735d2aab461e36b2edca6517662d088dd04cc39f8d16"
|
||||||
|
url: "https://pub.dev"
|
||||||
|
source: hosted
|
||||||
|
version: "2.15.1"
|
||||||
|
built_collection:
|
||||||
|
dependency: transitive
|
||||||
|
description:
|
||||||
|
name: built_collection
|
||||||
|
sha256: "376e3dd27b51ea877c28d525560790aee2e6fbb5f20e2f85d5081027d94e2100"
|
||||||
|
url: "https://pub.dev"
|
||||||
|
source: hosted
|
||||||
|
version: "5.1.1"
|
||||||
|
built_value:
|
||||||
|
dependency: transitive
|
||||||
|
description:
|
||||||
|
name: built_value
|
||||||
|
sha256: "34e4067d30ce212937df995f03b69992eea683539ceeac7f679a1f1eba055b56"
|
||||||
|
url: "https://pub.dev"
|
||||||
|
source: hosted
|
||||||
|
version: "8.12.6"
|
||||||
characters:
|
characters:
|
||||||
dependency: transitive
|
dependency: transitive
|
||||||
description:
|
description:
|
||||||
@ -33,6 +97,30 @@ packages:
|
|||||||
url: "https://pub.dev"
|
url: "https://pub.dev"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "1.4.1"
|
version: "1.4.1"
|
||||||
|
charcode:
|
||||||
|
dependency: transitive
|
||||||
|
description:
|
||||||
|
name: charcode
|
||||||
|
sha256: fb0f1107cac15a5ea6ef0a6ef71a807b9e4267c713bb93e00e92d737cc8dbd8a
|
||||||
|
url: "https://pub.dev"
|
||||||
|
source: hosted
|
||||||
|
version: "1.4.0"
|
||||||
|
checked_yaml:
|
||||||
|
dependency: transitive
|
||||||
|
description:
|
||||||
|
name: checked_yaml
|
||||||
|
sha256: "959525d3162f249993882720d52b7e0c833978df229be20702b33d48d91de70f"
|
||||||
|
url: "https://pub.dev"
|
||||||
|
source: hosted
|
||||||
|
version: "2.0.4"
|
||||||
|
cli_util:
|
||||||
|
dependency: transitive
|
||||||
|
description:
|
||||||
|
name: cli_util
|
||||||
|
sha256: "5909d2c6b66817222779e1eedc19e0e28b76d1df7bd9856a4792ccb9881df358"
|
||||||
|
url: "https://pub.dev"
|
||||||
|
source: hosted
|
||||||
|
version: "0.5.1"
|
||||||
clock:
|
clock:
|
||||||
dependency: transitive
|
dependency: transitive
|
||||||
description:
|
description:
|
||||||
@ -81,6 +169,14 @@ packages:
|
|||||||
url: "https://pub.dev"
|
url: "https://pub.dev"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "1.0.9"
|
version: "1.0.9"
|
||||||
|
dart_style:
|
||||||
|
dependency: transitive
|
||||||
|
description:
|
||||||
|
name: dart_style
|
||||||
|
sha256: "59d53ef8eaed9d288ed9767618e2b31c4fa0383a127db59d5eb2e737a7638a60"
|
||||||
|
url: "https://pub.dev"
|
||||||
|
source: hosted
|
||||||
|
version: "3.1.9"
|
||||||
drift:
|
drift:
|
||||||
dependency: "direct main"
|
dependency: "direct main"
|
||||||
description:
|
description:
|
||||||
@ -89,6 +185,14 @@ packages:
|
|||||||
url: "https://pub.dev"
|
url: "https://pub.dev"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "2.34.2"
|
version: "2.34.2"
|
||||||
|
drift_dev:
|
||||||
|
dependency: "direct dev"
|
||||||
|
description:
|
||||||
|
name: drift_dev
|
||||||
|
sha256: "5c0e6ae3c2afcfc2e3f66ea51e7268622906a1e29fd0ee82e6a9b17bfd73a9b0"
|
||||||
|
url: "https://pub.dev"
|
||||||
|
source: hosted
|
||||||
|
version: "2.34.4"
|
||||||
drift_flutter:
|
drift_flutter:
|
||||||
dependency: "direct main"
|
dependency: "direct main"
|
||||||
description:
|
description:
|
||||||
@ -121,6 +225,14 @@ packages:
|
|||||||
url: "https://pub.dev"
|
url: "https://pub.dev"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "7.0.1"
|
version: "7.0.1"
|
||||||
|
fixnum:
|
||||||
|
dependency: transitive
|
||||||
|
description:
|
||||||
|
name: fixnum
|
||||||
|
sha256: b6dc7065e46c974bc7c5f143080a6764ec7a4be6da1285ececdc37be96de53be
|
||||||
|
url: "https://pub.dev"
|
||||||
|
source: hosted
|
||||||
|
version: "1.1.1"
|
||||||
flutter:
|
flutter:
|
||||||
dependency: "direct main"
|
dependency: "direct main"
|
||||||
description: flutter
|
description: flutter
|
||||||
@ -147,6 +259,14 @@ packages:
|
|||||||
url: "https://pub.dev"
|
url: "https://pub.dev"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "2.1.3"
|
version: "2.1.3"
|
||||||
|
graphs:
|
||||||
|
dependency: transitive
|
||||||
|
description:
|
||||||
|
name: graphs
|
||||||
|
sha256: "741bbf84165310a68ff28fe9e727332eef1407342fca52759cb21ad8177bb8d0"
|
||||||
|
url: "https://pub.dev"
|
||||||
|
source: hosted
|
||||||
|
version: "2.3.2"
|
||||||
hooks:
|
hooks:
|
||||||
dependency: transitive
|
dependency: transitive
|
||||||
description:
|
description:
|
||||||
@ -155,6 +275,30 @@ packages:
|
|||||||
url: "https://pub.dev"
|
url: "https://pub.dev"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "2.0.2"
|
version: "2.0.2"
|
||||||
|
http_multi_server:
|
||||||
|
dependency: transitive
|
||||||
|
description:
|
||||||
|
name: http_multi_server
|
||||||
|
sha256: aa6199f908078bb1c5efb8d8638d4ae191aac11b311132c3ef48ce352fb52ef8
|
||||||
|
url: "https://pub.dev"
|
||||||
|
source: hosted
|
||||||
|
version: "3.2.2"
|
||||||
|
http_parser:
|
||||||
|
dependency: transitive
|
||||||
|
description:
|
||||||
|
name: http_parser
|
||||||
|
sha256: "178d74305e7866013777bab2c3d8726205dc5a4dd935297175b19a23a2e66571"
|
||||||
|
url: "https://pub.dev"
|
||||||
|
source: hosted
|
||||||
|
version: "4.1.2"
|
||||||
|
io:
|
||||||
|
dependency: transitive
|
||||||
|
description:
|
||||||
|
name: io
|
||||||
|
sha256: dfd5a80599cf0165756e3181807ed3e77daf6dd4137caaad72d0b7931597650b
|
||||||
|
url: "https://pub.dev"
|
||||||
|
source: hosted
|
||||||
|
version: "1.0.5"
|
||||||
jni:
|
jni:
|
||||||
dependency: transitive
|
dependency: transitive
|
||||||
description:
|
description:
|
||||||
@ -171,6 +315,14 @@ packages:
|
|||||||
url: "https://pub.dev"
|
url: "https://pub.dev"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "1.0.1"
|
version: "1.0.1"
|
||||||
|
json_annotation:
|
||||||
|
dependency: transitive
|
||||||
|
description:
|
||||||
|
name: json_annotation
|
||||||
|
sha256: "2a743920d81b7910627f68ee2c9ac1fc0bfee32b9fc3403587d7c6791ca12f80"
|
||||||
|
url: "https://pub.dev"
|
||||||
|
source: hosted
|
||||||
|
version: "4.12.0"
|
||||||
leak_tracker:
|
leak_tracker:
|
||||||
dependency: transitive
|
dependency: transitive
|
||||||
description:
|
description:
|
||||||
@ -235,6 +387,14 @@ packages:
|
|||||||
url: "https://pub.dev"
|
url: "https://pub.dev"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "1.18.0"
|
version: "1.18.0"
|
||||||
|
mime:
|
||||||
|
dependency: transitive
|
||||||
|
description:
|
||||||
|
name: mime
|
||||||
|
sha256: "41a20518f0cb1256669420fdba0cd90d21561e560ac240f26ef8322e45bb7ed6"
|
||||||
|
url: "https://pub.dev"
|
||||||
|
source: hosted
|
||||||
|
version: "2.0.0"
|
||||||
native_toolchain_c:
|
native_toolchain_c:
|
||||||
dependency: transitive
|
dependency: transitive
|
||||||
description:
|
description:
|
||||||
@ -331,6 +491,14 @@ packages:
|
|||||||
url: "https://pub.dev"
|
url: "https://pub.dev"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "2.1.8"
|
version: "2.1.8"
|
||||||
|
pool:
|
||||||
|
dependency: transitive
|
||||||
|
description:
|
||||||
|
name: pool
|
||||||
|
sha256: "978783255c543aa3586a1b3c21f6e9d720eb315376a915872c61ef8b5c20177d"
|
||||||
|
url: "https://pub.dev"
|
||||||
|
source: hosted
|
||||||
|
version: "1.5.2"
|
||||||
pub_semver:
|
pub_semver:
|
||||||
dependency: transitive
|
dependency: transitive
|
||||||
description:
|
description:
|
||||||
@ -339,6 +507,22 @@ packages:
|
|||||||
url: "https://pub.dev"
|
url: "https://pub.dev"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "2.2.0"
|
version: "2.2.0"
|
||||||
|
pubspec_parse:
|
||||||
|
dependency: transitive
|
||||||
|
description:
|
||||||
|
name: pubspec_parse
|
||||||
|
sha256: "0560ba233314abbed0a48a2956f7f022cce7c3e1e73df540277da7544cad4082"
|
||||||
|
url: "https://pub.dev"
|
||||||
|
source: hosted
|
||||||
|
version: "1.5.0"
|
||||||
|
recase:
|
||||||
|
dependency: transitive
|
||||||
|
description:
|
||||||
|
name: recase
|
||||||
|
sha256: e4eb4ec2dcdee52dcf99cb4ceabaffc631d7424ee55e56f280bc039737f89213
|
||||||
|
url: "https://pub.dev"
|
||||||
|
source: hosted
|
||||||
|
version: "4.1.0"
|
||||||
record_use:
|
record_use:
|
||||||
dependency: transitive
|
dependency: transitive
|
||||||
description:
|
description:
|
||||||
@ -347,11 +531,35 @@ packages:
|
|||||||
url: "https://pub.dev"
|
url: "https://pub.dev"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "0.6.0"
|
version: "0.6.0"
|
||||||
|
shelf:
|
||||||
|
dependency: transitive
|
||||||
|
description:
|
||||||
|
name: shelf
|
||||||
|
sha256: e7dd780a7ffb623c57850b33f43309312fc863fb6aa3d276a754bb299839ef12
|
||||||
|
url: "https://pub.dev"
|
||||||
|
source: hosted
|
||||||
|
version: "1.4.2"
|
||||||
|
shelf_web_socket:
|
||||||
|
dependency: transitive
|
||||||
|
description:
|
||||||
|
name: shelf_web_socket
|
||||||
|
sha256: "3632775c8e90d6c9712f883e633716432a27758216dfb61bd86a8321c0580925"
|
||||||
|
url: "https://pub.dev"
|
||||||
|
source: hosted
|
||||||
|
version: "3.0.0"
|
||||||
sky_engine:
|
sky_engine:
|
||||||
dependency: transitive
|
dependency: transitive
|
||||||
description: flutter
|
description: flutter
|
||||||
source: sdk
|
source: sdk
|
||||||
version: "0.0.0"
|
version: "0.0.0"
|
||||||
|
source_gen:
|
||||||
|
dependency: transitive
|
||||||
|
description:
|
||||||
|
name: source_gen
|
||||||
|
sha256: ec37cc0e6694374cbef59ed79685572c870a54ede6fa30a3e420feb3adffea02
|
||||||
|
url: "https://pub.dev"
|
||||||
|
source: hosted
|
||||||
|
version: "4.2.3"
|
||||||
source_span:
|
source_span:
|
||||||
dependency: transitive
|
dependency: transitive
|
||||||
description:
|
description:
|
||||||
@ -384,6 +592,14 @@ packages:
|
|||||||
url: "https://pub.dev"
|
url: "https://pub.dev"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "0.6.0+eol"
|
version: "0.6.0+eol"
|
||||||
|
sqlparser:
|
||||||
|
dependency: transitive
|
||||||
|
description:
|
||||||
|
name: sqlparser
|
||||||
|
sha256: "772bb2f6f5bce0631a60f26b57d6e8882e1105c22345b05c163ee6ee5d7ba32d"
|
||||||
|
url: "https://pub.dev"
|
||||||
|
source: hosted
|
||||||
|
version: "0.45.0"
|
||||||
stack_trace:
|
stack_trace:
|
||||||
dependency: transitive
|
dependency: transitive
|
||||||
description:
|
description:
|
||||||
@ -400,6 +616,14 @@ packages:
|
|||||||
url: "https://pub.dev"
|
url: "https://pub.dev"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "2.1.4"
|
version: "2.1.4"
|
||||||
|
stream_transform:
|
||||||
|
dependency: transitive
|
||||||
|
description:
|
||||||
|
name: stream_transform
|
||||||
|
sha256: ad47125e588cfd37a9a7f86c7d6356dde8dfe89d071d293f80ca9e9273a33871
|
||||||
|
url: "https://pub.dev"
|
||||||
|
source: hosted
|
||||||
|
version: "2.1.1"
|
||||||
string_scanner:
|
string_scanner:
|
||||||
dependency: transitive
|
dependency: transitive
|
||||||
description:
|
description:
|
||||||
@ -448,6 +672,14 @@ packages:
|
|||||||
url: "https://pub.dev"
|
url: "https://pub.dev"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "15.2.0"
|
version: "15.2.0"
|
||||||
|
watcher:
|
||||||
|
dependency: transitive
|
||||||
|
description:
|
||||||
|
name: watcher
|
||||||
|
sha256: "1398c9f081a753f9226febe8900fce8f7d0a67163334e1c94a2438339d79d635"
|
||||||
|
url: "https://pub.dev"
|
||||||
|
source: hosted
|
||||||
|
version: "1.2.1"
|
||||||
web:
|
web:
|
||||||
dependency: transitive
|
dependency: transitive
|
||||||
description:
|
description:
|
||||||
@ -456,6 +688,22 @@ packages:
|
|||||||
url: "https://pub.dev"
|
url: "https://pub.dev"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "1.1.1"
|
version: "1.1.1"
|
||||||
|
web_socket:
|
||||||
|
dependency: transitive
|
||||||
|
description:
|
||||||
|
name: web_socket
|
||||||
|
sha256: "34d64019aa8e36bf9842ac014bb5d2f5586ca73df5e4d9bf5c936975cae6982c"
|
||||||
|
url: "https://pub.dev"
|
||||||
|
source: hosted
|
||||||
|
version: "1.0.1"
|
||||||
|
web_socket_channel:
|
||||||
|
dependency: transitive
|
||||||
|
description:
|
||||||
|
name: web_socket_channel
|
||||||
|
sha256: d645757fb0f4773d602444000a8131ff5d48c9e47adfe9772652dd1a4f2d45c8
|
||||||
|
url: "https://pub.dev"
|
||||||
|
source: hosted
|
||||||
|
version: "3.0.3"
|
||||||
xdg_directories:
|
xdg_directories:
|
||||||
dependency: transitive
|
dependency: transitive
|
||||||
description:
|
description:
|
||||||
@ -473,5 +721,5 @@ packages:
|
|||||||
source: hosted
|
source: hosted
|
||||||
version: "3.1.3"
|
version: "3.1.3"
|
||||||
sdks:
|
sdks:
|
||||||
dart: ">=3.10.3 <4.0.0"
|
dart: ">=3.11.0 <4.0.0"
|
||||||
flutter: ">=3.38.4"
|
flutter: ">=3.38.4"
|
||||||
|
|||||||
@ -21,6 +21,8 @@ dev_dependencies:
|
|||||||
flutter_test:
|
flutter_test:
|
||||||
sdk: flutter
|
sdk: flutter
|
||||||
flutter_lints: ^6.0.0
|
flutter_lints: ^6.0.0
|
||||||
|
build_runner: ^2.7.0
|
||||||
|
drift_dev: ^2.34.2
|
||||||
|
|
||||||
flutter:
|
flutter:
|
||||||
uses-material-design: true
|
uses-material-design: true
|
||||||
|
|||||||
Reference in New Issue
Block a user