linkWeb function

int linkWeb(
  1. String pluginName,
  2. List<ModuleInfo> moduleInfos, {
  3. String? baseDir,
})

Writes/refreshes web/build_web.sh for the web-targeting modules and ensures the assets/web/ asset directory exists. No-op (removes nothing) when no module targets web.

Returns the number of web-targeting modules wired.

Implementation

int linkWeb(String pluginName, List<ModuleInfo> moduleInfos, {String? baseDir}) {
  final base = baseDir ?? pluginName;
  final webLibs = moduleInfos.where((m) => m.webIsWasm).map((m) => m.lib).toList();
  if (webLibs.isEmpty) return 0;

  final webDir = Directory(p.join(base, 'web'))..createSync(recursive: true);

  // Same shape as linux/src: an inert starter sits beside the shared impl as
  // an option. Both `web:` spellings mean "shared" (every existing plugin
  // writes the specific one), so — unlike desktop — no annotation form ever
  // triggers migration; only real code in the file opts web out of sharing.
  for (final lib in webLibs) {
    _writeOrMigratePlatformImplStub(
      baseDir: base,
      platform: 'web',
      lib: lib,
      requestsSeparateImpl: false,
      genericStubContent: webImplStarterContent(base, lib),
    );
  }

  final script = File(p.join(webDir.path, 'build_web.sh'));
  script.writeAsStringSync(webBuildScriptTemplate(
    webLibs,
    bridgeChecksums: {
      for (final lib in webLibs) lib: ?readBridgeChecksum(base, lib),
    },
    webSpecificImpls: {for (final lib in webLibs) if (webUsesSpecificImpl(base, lib)) lib},
  ));
  if (!Platform.isWindows) {
    Process.runSync('chmod', ['+x', script.path]);
  }

  final assetsDir = Directory(p.join(base, 'assets', 'web'))..createSync(recursive: true);
  final gitkeep = File(p.join(assetsDir.path, '.gitkeep'));
  if (!gitkeep.existsSync()) {
    gitkeep.writeAsStringSync('# WASM build outputs land here (web/build_web.sh)\n');
  }

  // The .wasm only reaches the browser if Flutter bundles it. `nitrogen init`
  // declares this for projects created WITH web, but a plugin that adds web
  // later would otherwise build the module and never ship it — the failure
  // surfaces at runtime as a 404 from ensure<Class>Ready(), long after the
  // build looked successful. Declaring it here covers both paths.
  final pubspecFile = File(p.join(base, 'pubspec.yaml'));
  _ensureWebAssetsDeclared(pubspecFile);
  _scaffoldWebTests(base, moduleInfos.where((m) => m.webIsWasm).toList(), pubspecFile);
  return webLibs.length;
}