validateLocalCloudflarePackages function

void validateLocalCloudflarePackages(
  1. Iterable<String> packages
)

ローカル適用に必要な宣言・lock・実体を、依存を変更せず検証します。

packages accepts plain names or versioned specs such as @scope/name@^1.2.3. A versioned spec also requires the locked version to satisfy the range.

Implementation

void validateLocalCloudflarePackages(Iterable<String> packages) {
  final manifest =
      jsonDecode(File("cloudflare/package.json").readAsStringSync()) as Map;
  final lock =
      jsonDecode(File("cloudflare/package-lock.json").readAsStringSync())
          as Map;
  final declared = <String, dynamic>{
    ...Map<String, dynamic>.from(manifest["dependencies"] as Map? ?? {}),
    ...Map<String, dynamic>.from(manifest["devDependencies"] as Map? ?? {}),
  };
  final locked = lock["packages"] as Map? ?? {};
  for (final spec in packages) {
    final (:name, :range) = parseCloudflarePackageSpec(spec);
    final installed = File("cloudflare/node_modules/$name/package.json");
    final entry = locked["node_modules/$name"];
    if (!declared.containsKey(name) ||
        entry is! Map ||
        !installed.existsSync()) {
      throw StateError("ローカル適用に必要な Cloudflare npm 依存が未導入です: $name");
    }
    final actual = jsonDecode(installed.readAsStringSync()) as Map;
    if (entry["version"] == null || actual["version"] != entry["version"]) {
      throw StateError("Cloudflare npm 依存の実体とlockが一致しません: $name");
    }
    if (range != null &&
        !cloudflarePackageVersionSatisfies(
          entry["version"].toString(),
          range,
        )) {
      throw StateError(
        "Cloudflare npm 依存の版が要求範囲外です: $name ${entry["version"]}(要求: $range)",
      );
    }
  }
}