|
1 | | -import 'dart:convert'; |
2 | | -import 'dart:io'; |
3 | | -import 'package:collection/collection.dart'; |
4 | | -import 'package:pub_semver/pub_semver.dart'; |
5 | | -import 'package:pubspec_parse/pubspec_parse.dart'; |
6 | | -import 'package:args/args.dart'; |
| 1 | +// ignore: implementation_imports |
| 2 | +import 'package:powersync_core/src/setup_web.dart'; |
7 | 3 |
|
8 | | -void main(List<String> arguments) async { |
9 | | - var parser = ArgParser(); |
10 | | - // Add a flag to enable/disable the download of worker (defaults to true) |
11 | | - // Pass the --no-worker argument to disable the download of the worker |
12 | | - // dart run powersync:setup_web --no-worker |
13 | | - parser.addFlag('worker', defaultsTo: true); |
14 | | - // Add a option to specify the output directory (defaults to web) |
15 | | - // Pass the --output-dir argument to specify the output directory |
16 | | - // dart run powersync:setup_web --output-dir assets |
17 | | - parser.addOption('output-dir', abbr: 'o', defaultsTo: 'web'); |
18 | | - var results = parser.parse(arguments); |
19 | | - bool downloadWorker = results.flag('worker'); |
20 | | - String outputDir = results.option('output-dir')!; |
21 | | - |
22 | | - final root = Directory.current.uri; |
23 | | - print('Project root: ${root.toFilePath()}'); |
24 | | - |
25 | | - final wasmPath = '${root.toFilePath()}$outputDir/sqlite3.wasm'; |
26 | | - |
27 | | - final workerPath = '${root.toFilePath()}$outputDir/powersync_db.worker.js'; |
28 | | - final syncWorkerPath = |
29 | | - '${root.toFilePath()}$outputDir/powersync_sync.worker.js'; |
30 | | - |
31 | | - final packageConfigFile = File.fromUri( |
32 | | - root.resolve('.dart_tool/package_config.json'), |
33 | | - ); |
34 | | - dynamic packageConfig; |
35 | | - try { |
36 | | - packageConfig = json.decode(await packageConfigFile.readAsString()); |
37 | | - } on FileSystemException { |
38 | | - print('Missing .dart_tool/package_config.json'); |
39 | | - print('Run `flutter pub get` first.'); |
40 | | - exit(1); |
41 | | - } on FormatException { |
42 | | - print('Invalid .dart_tool/package_config.json'); |
43 | | - print('Run `flutter pub get` first.'); |
44 | | - exit(1); |
45 | | - } |
46 | | - |
47 | | - try { |
48 | | - final httpClient = HttpClient(); |
49 | | - |
50 | | - final powersyncPackageName = 'powersync'; |
51 | | - |
52 | | - if (downloadWorker) { |
53 | | - final powersyncPkg = |
54 | | - getPackageFromConfig(packageConfig, powersyncPackageName); |
55 | | - |
56 | | - final powersyncVersion = getPubspecVersion( |
57 | | - packageConfigFile, powersyncPkg, powersyncPackageName); |
58 | | - |
59 | | - final workerUrl = |
60 | | - 'https://github.com/powersync-ja/powersync.dart/releases/download/powersync-v$powersyncVersion/powersync_db.worker.js'; |
61 | | - |
62 | | - final syncWorkerUrl = |
63 | | - 'https://github.com/powersync-ja/powersync.dart/releases/download/powersync-v$powersyncVersion/powersync_sync.worker.js'; |
64 | | - |
65 | | - await downloadFile(httpClient, workerUrl, workerPath); |
66 | | - await downloadFile(httpClient, syncWorkerUrl, syncWorkerPath); |
67 | | - } |
68 | | - |
69 | | - final sqlitePackageName = 'sqlite3'; |
70 | | - |
71 | | - final sqlite3Pkg = getPackageFromConfig(packageConfig, sqlitePackageName); |
72 | | - |
73 | | - String sqlite3Version = |
74 | | - "v${getPubspecVersion(packageConfigFile, sqlite3Pkg, sqlitePackageName)}"; |
75 | | - |
76 | | - List<String> tags = await getLatestTagsFromRelease(httpClient); |
77 | | - String? matchTag = tags.firstWhereOrNull((element) => |
78 | | - element.contains(sqlite3Version) && coreVersionIsInRange(element)); |
79 | | - if (matchTag != null) { |
80 | | - sqlite3Version = matchTag; |
81 | | - } else { |
82 | | - throw Exception( |
83 | | - """No compatible powersync core version found for sqlite3 version $sqlite3Version |
84 | | - Latest supported sqlite3 versions: ${tags.take(3).map((tag) => tag.split('-')[0]).join(', ')}. |
85 | | - You can view the full list of releases at https://github.com/powersync-ja/sqlite3.dart/releases"""); |
86 | | - } |
87 | | - |
88 | | - final sqliteUrl = |
89 | | - 'https://github.com/powersync-ja/sqlite3.dart/releases/download/$sqlite3Version/sqlite3.wasm'; |
90 | | - |
91 | | - await downloadFile(httpClient, sqliteUrl, wasmPath); |
92 | | - } catch (e) { |
93 | | - print(e); |
94 | | - exit(1); |
95 | | - } |
96 | | -} |
97 | | - |
98 | | -bool coreVersionIsInRange(String tag) { |
99 | | - // Sets the range of powersync core version that is compatible with the sqlite3 version |
100 | | - // We're a little more selective in the versions chosen here than the range |
101 | | - // we're compatible with. |
102 | | - VersionConstraint constraint = VersionConstraint.parse('>=0.3.0 <0.4.0'); |
103 | | - List<String> parts = tag.split('-'); |
104 | | - String powersyncPart = parts[1]; |
105 | | - |
106 | | - List<String> versionParts = powersyncPart.split('.'); |
107 | | - String extractedVersion = |
108 | | - versionParts.sublist(versionParts.length - 3).join('.'); |
109 | | - final coreVersion = Version.parse(extractedVersion); |
110 | | - if (constraint.allows(coreVersion)) { |
111 | | - return true; |
112 | | - } |
113 | | - return false; |
114 | | -} |
115 | | - |
116 | | -dynamic getPackageFromConfig(dynamic packageConfig, String packageName) { |
117 | | - final pkg = (packageConfig['packages'] ?? []).firstWhere( |
118 | | - (e) => e['name'] == packageName, |
119 | | - orElse: () => null, |
120 | | - ); |
121 | | - if (pkg == null) { |
122 | | - throw Exception('Dependency on package:$packageName is required'); |
123 | | - } |
124 | | - return pkg; |
125 | | -} |
126 | | - |
127 | | -String getPubspecVersion( |
128 | | - File packageConfigFile, dynamic package, String packageName) { |
129 | | - final rootUri = packageConfigFile.uri.resolve(package['rootUri'] ?? ''); |
130 | | - print('Using package:$packageName from ${rootUri.toFilePath()}'); |
131 | | - |
132 | | - String pubspec = |
133 | | - File('${rootUri.toFilePath()}/pubspec.yaml').readAsStringSync(); |
134 | | - Pubspec parsed = Pubspec.parse(pubspec); |
135 | | - final version = parsed.version?.toString(); |
136 | | - if (version == null) { |
137 | | - throw Exception( |
138 | | - "${capitalize(packageName)} version not found. Run `flutter pub get` first."); |
139 | | - } |
140 | | - return version; |
141 | | -} |
142 | | - |
143 | | -String capitalize(String s) => s[0].toUpperCase() + s.substring(1); |
144 | | - |
145 | | -Future<List<String>> getLatestTagsFromRelease(HttpClient httpClient) async { |
146 | | - var request = await httpClient.getUrl(Uri.parse( |
147 | | - "https://api.github.com/repos/powersync-ja/sqlite3.dart/releases")); |
148 | | - var response = await request.close(); |
149 | | - if (response.statusCode == HttpStatus.ok) { |
150 | | - var res = await response.transform(utf8.decoder).join(); |
151 | | - List<dynamic> jsonObj = json.decode(res); |
152 | | - List<String> tags = []; |
153 | | - for (dynamic obj in jsonObj) { |
154 | | - final tagName = obj['tag_name'] as String; |
155 | | - if (!tagName.contains("-powersync")) continue; |
156 | | - tags.add(tagName); |
157 | | - } |
158 | | - return tags; |
159 | | - } else { |
160 | | - throw Exception("Failed to fetch GitHub releases and tags"); |
161 | | - } |
162 | | -} |
163 | | - |
164 | | -Future<void> downloadFile( |
165 | | - HttpClient httpClient, String url, String savePath) async { |
166 | | - print('Downloading: $url'); |
167 | | - var request = await httpClient.getUrl(Uri.parse(url)); |
168 | | - var response = await request.close(); |
169 | | - if (response.statusCode == HttpStatus.ok) { |
170 | | - var file = File(savePath); |
171 | | - await response.pipe(file.openWrite()); |
172 | | - } else { |
173 | | - throw Exception( |
174 | | - 'Failed to download file: ${response.statusCode} ${response.reasonPhrase}'); |
175 | | - } |
176 | | -} |
| 4 | +void main(List<String> args) => downloadWebAssets(args); |
0 commit comments