| // Copyright (c) 2026, the Dart project authors. Please see the AUTHORS file |
| // for details. All rights reserved. Use of this source code is governed by a |
| // BSD-style license that can be found in the LICENSE file. |
| |
| import 'dart:convert'; |
| import 'dart:io'; |
| |
| import 'package:crypto/crypto.dart'; |
| |
| void main() async { |
| // 1. Extract the version from pubspec.yaml |
| final pubspec = File('pubspec.yaml').readAsStringSync(); |
| final versionMatch = RegExp(r'version: (.*)').firstMatch(pubspec); |
| final version = versionMatch?.group(1); |
| if (version == null) { |
| throw Exception('Failed to find version in pubspec.yaml'); |
| } |
| |
| // 2. Generate lib/src/version.dart |
| final versionFile = File('lib/src/version.dart'); |
| versionFile.writeAsStringSync(''' |
| // Generated code. Do not modify. |
| const packageVersion = '$version'; |
| '''); |
| |
| // 3. Compile the web client to JavaScript |
| print('Compiling client.js...'); |
| final result = await Process.run(Platform.executable, [ |
| 'compile', |
| 'js', |
| '-O1', |
| '--no-source-maps', |
| '-o', |
| 'lib/src/injected/client.js', |
| 'web/client.dart', |
| ]); |
| |
| if (result.exitCode != 0) { |
| print('Failed to compile client.js'); |
| print(result.stdout); |
| print(result.stderr); |
| exit(result.exitCode); |
| } |
| |
| print('Compilation successful'); |
| |
| // 4. Clean up the generated .deps file |
| final depsFile = File('lib/src/injected/client.js.deps'); |
| if (depsFile.existsSync()) { |
| depsFile.deleteSync(); |
| } |
| |
| // 5. Generate injected_client_js.dart |
| print('Generating injected_client_js.dart...'); |
| |
| final clientDartString = File( |
| 'web/client.dart', |
| ).readAsStringSync().replaceAll('\r\n', '\n'); |
| final clientDartHash = sha256 |
| .convert(utf8.encode(clientDartString)) |
| .toString(); |
| |
| final compiledJs = File('lib/src/injected/client.js').readAsStringSync(); |
| final lines = compiledJs.replaceAll('\r\n', '\n').split('\n'); |
| |
| // Escape JS payload line-by-line using jsonEncode for multiline readability, |
| // ensure newlines are preserved identically, and manually escape the dollar |
| // sign ($) to avoid Dart interpolation. |
| final safeDartString = [ |
| for (var i = 0; i < lines.length; i++) |
| jsonEncode( |
| i == lines.length - 1 ? lines[i] : '${lines[i]}\n', |
| ).replaceAll(r'$', r'\$'), |
| ].join('\n'); |
| |
| final injectedClientJsFile = File('lib/src/handlers/injected_client_js.dart'); |
| injectedClientJsFile.writeAsStringSync(''' |
| // Generated code. Do not modify. |
| // Emits the transpiled client.js directly into a statically embeddable string. |
| // dart format off |
| |
| const injectedClientJs = $safeDartString; |
| |
| const clientDartHash = '$clientDartHash'; |
| '''); |
| print('Successfully packed client.js into injected_client_js.dart'); |
| } |