|
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