fix: bad ux

This commit is contained in:
juancwu 2026-01-26 21:23:33 +00:00
commit 5a425b8c60
15 changed files with 791 additions and 463 deletions

View file

@ -65,6 +65,67 @@ func (c *Client) RetrieveDNSRecords(domain string) (*DNSRecordsResponse, error)
return &resp, nil
}
func (c *Client) CreateDNSRecord(domain string, record DNSRecord) error {
reqBody := struct {
BaseRequest
Name string `json:"name"`
Type string `json:"type"`
Content string `json:"content"`
TTL string `json:"ttl,omitempty"`
Priority string `json:"prio,omitempty"`
}{
BaseRequest: BaseRequest{
APIKey: c.APIKey,
SecretAPIKey: c.SecretAPIKey,
},
Name: record.Name,
Type: record.Type,
Content: record.Content,
TTL: fmt.Sprintf("%v", record.TTL),
Priority: fmt.Sprintf("%v", record.Priority),
}
var resp BaseResponse
return c.post("/dns/create/"+domain, reqBody, &resp)
}
func (c *Client) EditDNSRecord(domain string, id string, record DNSRecord) error {
reqBody := struct {
BaseRequest
Name string `json:"name"`
Type string `json:"type"`
Content string `json:"content"`
TTL string `json:"ttl,omitempty"`
Priority string `json:"prio,omitempty"`
}{
BaseRequest: BaseRequest{
APIKey: c.APIKey,
SecretAPIKey: c.SecretAPIKey,
},
Name: record.Name,
Type: record.Type,
Content: record.Content,
TTL: fmt.Sprintf("%v", record.TTL),
Priority: fmt.Sprintf("%v", record.Priority),
}
var resp BaseResponse
return c.post("/dns/edit/"+domain+"/"+id, reqBody, &resp)
}
func (c *Client) DeleteDNSRecord(domain, id string) error {
reqBody := struct {
BaseRequest
}{
BaseRequest: BaseRequest{
APIKey: c.APIKey,
SecretAPIKey: c.SecretAPIKey,
},
}
var resp BaseResponse
return c.post("/dns/delete/"+domain+"/"+id, reqBody, &resp)
}
func (c *Client) Ping() (*PingResponse, error) {
reqBody := PingRequest{
BaseRequest: BaseRequest{

View file

@ -1,5 +1,77 @@
package porkbun
import (
"bytes"
"encoding/json"
"fmt"
"strconv"
"strings"
)
// PorkbunBadEngineeringAPIResponseType represents the great undecisiveness
// from the api endpoint in choosing one consistent data type for certain fields.
// Ranging from null, "1" and 0. Why not just use -1, 1, and 0!? or even just null, 1 and 0...
type PorkbunBadEngineeringAPIResponseType int
func (t *PorkbunBadEngineeringAPIResponseType) UnmarshalJSON(b []byte) error {
if bytes.Equal(b, []byte("null")) || len(b) == 0 {
*t = 0
return nil
}
s := string(b)
s = strings.Trim(s, "\"")
if s == "" {
*t = 0
return nil
}
i, err := strconv.ParseInt(s, 10, 32)
if err != nil {
return fmt.Errorf("cannot parse porkbun bad engeineering api response type: %w", err)
}
*t = PorkbunBadEngineeringAPIResponseType(i)
return nil
}
type NullString struct {
Valid bool
Value string
}
func (ns *NullString) UnmarshalJSON(b []byte) error {
if bytes.Equal(b, []byte("null")) || len(b) == 0 {
ns.Valid = false
ns.Value = ""
return nil
}
var s string
if err := json.Unmarshal(b, &s); err != nil {
return err
}
ns.Valid = true
ns.Value = s
return nil
}
func (ns NullString) MarshalJSON() ([]byte, error) {
if !ns.Valid {
return []byte("null"), nil
}
return json.Marshal(ns.Value)
}
func (ns NullString) String() string {
if ns.Valid {
return ""
}
return ns.Value
}
// BaseRequest contains the authentication fields required for most Porkbun API calls.
type BaseRequest struct {
APIKey string `json:"apikey"`
@ -38,16 +110,16 @@ type DomainListAllResponse struct {
// Domain represents a single domain returned by domain endpoints.
type Domain struct {
Domain string `json:"domain"`
Status string `json:"status"`
TLD string `json:"tld"`
CreateDate string `json:"createDate"`
ExpireDate string `json:"expireDate"`
SecurityLock string `json:"securityLock"`
WhoIsPrivacy string `json:"whoisPrivacy"`
AutoRenew any `json:"autoRenew"`
NotLocal any `json:"notLocal"`
Labels []DomainLabel `json:"labels,omitempty"`
Domain string `json:"domain"`
Status string `json:"status"`
TLD string `json:"tld"`
CreateDate string `json:"createDate"`
ExpireDate string `json:"expireDate"`
SecurityLock PorkbunBadEngineeringAPIResponseType `json:"securityLock"`
WhoIsPrivacy PorkbunBadEngineeringAPIResponseType `json:"whoisPrivacy"`
AutoRenew PorkbunBadEngineeringAPIResponseType `json:"autoRenew"`
NotLocal PorkbunBadEngineeringAPIResponseType `json:"notLocal"`
Labels []DomainLabel `json:"labels,omitempty"`
}
// DomainLabel represents a label associated with a domain.
@ -64,13 +136,13 @@ type DNSRecordsRequest struct {
// DNSRecord it is what it says it is.
type DNSRecord struct {
ID string `json:"id"`
Name string `json:"name"`
Type string `json:"type"`
Content string `json:"content"`
TTL any `json:"ttl"`
Priority any `json:"prio"`
Notes string `json:"notes"`
ID string `json:"id"`
Type string `json:"type"`
Content string `json:"content"`
Name string `json:"name,omitempty"`
TTL NullString `json:"ttl,omitempty"`
Priority NullString `json:"prio,omitempty"`
Notes NullString `json:"notes,omitempty"`
}
// DNSRecordsResponse it is what it says it is.