validateLocalCloudflarePackages function
ローカル適用に必要な宣言・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)",
);
}
}
}