diff --git a/gleam.toml b/gleam.toml index dfca6d4..61cebf4 100644 --- a/gleam.toml +++ b/gleam.toml @@ -1,5 +1,5 @@ name = "possum" -version = "1.0.5" +version = "1.0.6" description = "🐀 ATproto library for gleam" licences = ["Apache-2.0"] diff --git a/src/possum.gleam b/src/possum.gleam index 47d3157..122cfac 100644 --- a/src/possum.gleam +++ b/src/possum.gleam @@ -713,3 +713,95 @@ pub fn delete_record( |> request.set_method(http.Post) |> request.set_path(com_atproto_repo <> ".deleteRecord") } + +/// Write a repository record, creating or updating it as needed. +/// Requires auth, implemented by PDS. +/// +/// ## Body +/// +/// - **collection**: The NSID of the record collection. +/// - **record** +/// - **repo**: The handle or DID of the repo (aka, current account). +/// - **rkey**: The Record Key. +/// - **swapCommit**: Compare and swap with the previous commit by CID. +/// - **swapRecord**: Compare and swap with the previous record by CID. +/// WARNING: nullable and optional field; +/// - **validate**: Can be set to `false` to skip Lexicon schema validation +/// of record data, 'true' to require it, or leave unset to validate only +/// for known Lexicons. +/// +/// ## Examples +/// +/// ```gleam +/// import gleam/http/request +/// import possum +/// +/// let request = +/// request.new() +/// |> request.set_host("personal.data-server.pds") +/// |> possum.authorized("access-token") +/// |> possum.put_record( +/// did, +/// collection: "target.collection.data", +/// rkey: "wibble-wobble", +/// record: [], +/// swap_commit: option.None, +/// swap_record: option.None, +/// validate: option. +/// ) +/// ``` +/// +/// ## Response +/// +/// ```json +/// { +/// "cid": "string", +/// "uri": "string", +/// "commit": { +/// "cid": "string", +/// "rev": "string" +/// }, +/// "validationStatus": "valid" +/// } +/// ``` +/// +/// Endpoint Docs: [/xrpc/com.atproto.repo.putRecord](https://endpoints.bsky.app/#bluesky-app/tag/comatprotorepo/POST/xrpc/com.atproto.repo.putRecord) +pub fn put_record( + request: request.Request(_), + did: did.Did, + collection collection: String, + rkey rkey: String, + record record: List(#(String, json.Json)), + swap_commit swap_commit: option.Option(String), + swap_record swap_record: option.Option(String), + validate validate: option.Option(Bool), +) -> request.Request(_) { + let body = [ + #("collection", json.string(collection)), + #("record", json.object(record)), + #("repo", json.string(did.to_string(did))), + #("rkey", json.string(rkey)), + ] + + let body = case swap_commit { + option.Some(value) -> [#("swapCommit", json.string(value)), ..body] + option.None -> body + } + + let body = case swap_record { + option.Some(value) -> [#("swapRecord", json.string(value)), ..body] + option.None -> body + } + + let body = case validate { + option.Some(value) -> [#("validate", json.bool(value)), ..body] + option.None -> body + } + + request + |> request.prepend_header("accept", "application/json") + |> request.prepend_header("content-type", "application/json") + |> request.set_body(json.to_string(json.object(body))) + |> request.set_method(http.Post) + |> request.set_path(com_atproto_repo <> ".putRecord") +}