updateSharedHubBinding function
共有hubだけを新しいmigrationで追加し、既存データDOの履歴を維持する。
Implementation
String updateSharedHubBinding(String source,
{required String binding, required String tag}) {
if (!RegExp(r"^[A-Za-z_][A-Za-z0-9_]*$").hasMatch(binding) || tag.isEmpty) {
throw ArgumentError("共有hubのbinding/tagが不正です。");
}
final pattern = RegExp(
r'"durable_objects"\s*:\s*\{\s*"bindings"\s*:\s*(\[[\s\S]*?\])\s*\}');
final match = pattern.firstMatch(source);
if (match == null) {
throw StateError("先にDO bindingを生成してください。");
}
final bindings = jsonDecode(match.group(1)!) as List;
final existing = bindings.where((e) => e["name"] == binding);
if (existing.any((e) =>
e["class_name"] != "MasamuneSharedHub" || e["script_name"] != null)) {
throw StateError("共有hubのbindingが競合しています。");
}
if (existing.isEmpty) {
bindings.add({"name": binding, "class_name": "MasamuneSharedHub"});
}
source = source.replaceRange(match.start, match.end,
'"durable_objects":{"bindings":${jsonEncode(bindings)}}');
final found = _doArrayProperty(source, "migrations");
final migrations = found?.value ?? <dynamic>[];
final desired = {
"tag": tag,
"new_sqlite_classes": ["MasamuneSharedHub"]
};
final same = migrations.where((e) => e["tag"] == tag);
if (same.any((e) => jsonEncode(e) != jsonEncode(desired))) {
throw StateError("共有hub migration tagが競合しています。");
}
if (same.isEmpty) {
if (migrations.any((e) => (e["new_sqlite_classes"] as List? ?? [])
.contains("MasamuneSharedHub"))) {
throw StateError("共有hub classは別tagで登録済みです。");
}
migrations.add(desired);
}
final property = '"migrations":${jsonEncode(migrations)}';
return found == null
? source.replaceFirst("{", "{$property,")
: source.replaceRange(found.start, found.end, property);
}