···3535 IsIndex bool `json:"is_index"`
3636}
37373838+// UnmarshalJSON makes DomainMapping tolerant of the legacy KV shape where
3939+// repos was map[string]bool (keyed by rkey, value = is_index). For each
4040+// entry it tries the new {rkey, is_index} struct first; if that fails it
4141+// falls back to a bare bool, using the map key itself as the rkey.
4242+func (m *DomainMapping) UnmarshalJSON(data []byte) error {
4343+ var raw struct {
4444+ Did string `json:"did"`
4545+ Repos map[string]json.RawMessage `json:"repos"`
4646+ }
4747+ if err := json.Unmarshal(data, &raw); err != nil {
4848+ return err
4949+ }
5050+ m.Did = raw.Did
5151+ m.Repos = make(map[string]RepoEntry, len(raw.Repos))
5252+ for name, val := range raw.Repos {
5353+ var entry RepoEntry
5454+ if err := json.Unmarshal(val, &entry); err == nil {
5555+ m.Repos[name] = entry
5656+ continue
5757+ }
5858+ // legacy shape: value is a bare bool; map key is the rkey
5959+ var isIndex bool
6060+ if err := json.Unmarshal(val, &isIndex); err != nil {
6161+ return fmt.Errorf("unsupported repo entry for %q: %w", name, err)
6262+ }
6363+ m.Repos[name] = RepoEntry{Rkey: name, IsIndex: isIndex}
6464+ }
6565+ return nil
6666+}
6767+3868// getOrNewMapping fetches the existing KV entry for domain, or returns a
3969// fresh empty mapping for the given did if none exists yet.
4070func getOrNewMapping(ctx context.Context, cf *cloudflare.Client, domain, did string) (DomainMapping, error) {