···1414//// records and HTTP APIs. Functionally it's very similar to JSON-Schema and OpenAPI.
1515//// Lexicon's sole purpose is to help developers build compatible software.
1616////
1717-//// ## DID (Decentralized ID)
1818-////
1919-//// DIDs, or Decentralized IDentifiers, are universally-unique identifiers which
2020-//// represent data repos. They are permanent and non-human-readable.
2121-//// DIDs are a W3C specification. The AT Protocol currently supports
2222-//// did:web and did:plc, two different DID methods.
2323-////
2424-//// DIDs resolve to documents which contain metadata about a repo,
2525-//// including the address of the repo's PDS, the repo's handles,
2626-//// and the public signing keys.
2727-////
2817//// ## Record Keys
2918////
3019//// A record key (sometimes shortened to "rkey") is used to name and reference an individual
···4231import gleam/int
4332import gleam/json
4433import gleam/option
3434+import possum/did
45354636/// Documentation: [/xrpc/com.atproto.repo](https://endpoints.bsky.app/#bluesky-app/tag/comatprotorepo)
4737const com_atproto_repo = "xrpc/com.atproto.repo"
···9686/// Documentation: [DID PLC Directory](https://web.plc.directory/)
9787pub fn get_plc_data(
9888 request: request.Request(_),
9999- did: String,
8989+ did: did.Did,
10090) -> request.Request(_) {
10191 request
10292 |> request.set_method(http.Get)
10393 |> request.set_host("plc.directory")
104104- |> request.set_path(did <> "/data")
9494+ |> request.set_path(did.to_string(did) <> "/data")
10595}
1069610797/// Resolves a handle to a DID using a HTTPS `/.well-known/` URL path,
···211201/// Endpoint Docs: [/xrpc/com.atproto.server.createSession](https://endpoints.bsky.app/#bluesky-app/tag/comatprotoserver/POST/xrpc/com.atproto.server.createSession)
212202pub fn create_session(
213203 request: request.Request(_),
214214- did: String,
204204+ did: did.Did,
215205 app_password app_password: String,
216206 allow_takendown allow_takendown: option.Option(Bool),
217207 auth_factor_token auth_factor_token: option.Option(String),
218208) -> request.Request(_) {
219209 let values = [
220220- #("identifier", json.string(did)),
210210+ #("identifier", json.string(did.to_string(did))),
221211 #("password", json.string(app_password)),
222212 ]
223213···376366/// Endpoint Docs: [/xrpc/com.atproto.repo.describeRepo](https://endpoints.bsky.app/#bluesky-app/tag/comatprotorepo/GET/xrpc/com.atproto.repo.describeRepo)
377367pub fn describe_repository(
378368 request: request.Request(_),
379379- did: String,
369369+ did: did.Did,
380370) -> request.Request(_) {
381371 request
382372 |> request.set_method(http.Get)
383373 |> request.set_path(com_atproto_repo <> ".describeRepo")
384384- |> request.set_query([#("repo", did)])
374374+ |> request.set_query([#("repo", did.to_string(did))])
385375}
386376387377/// Get a single record from a repository. Does not require auth.
···426416/// Documentation: [atproto.com](https://atproto.com/specs/record-key)
427417pub fn get_record(
428418 request: request.Request(_),
429429- did: String,
419419+ did: did.Did,
430420 rkey rkey: String,
431421 collection collection: String,
432422 cid cid: option.Option(String),
433423) -> request.Request(_) {
434424 let query = [
435435- #("repo", did),
425425+ #("repo", did.to_string(did)),
436426 #("rkey", rkey),
437427 #("collection", collection),
438428 ]
···486476/// Endpoint Docs: [/xrpc/com.atproto.repo.listRecords](https://endpoints.bsky.app/#bluesky-app/tag/comatprotorepo/GET/xrpc/com.atproto.repo.listRecords)
487477pub fn list_records(
488478 request: request.Request(_),
489489- did: String,
479479+ did: did.Did,
490480 collection collection: String,
491481 limit limit: option.Option(Int),
492482 cursor cursor: option.Option(String),
493483 reverse reverse: option.Option(Bool),
494484) -> request.Request(_) {
495485 let query = [
496496- #("repo", did),
486486+ #("repo", did.to_string(did)),
497487 #("collection", collection),
498488 ]
499489···541531/// Documentation: [standard.site](https://standard.site/)
542532pub fn list_standard_documents(
543533 request: request.Request(_),
544544- did: String,
534534+ did: did.Did,
545535 limit limit: option.Option(Int),
546536) -> request.Request(_) {
547537 list_records(
+15-4
src/possum/did.gleam
···11-import gleam/regexp as regex
11+//// ## DID (Decentralized ID)
22+////
33+//// DIDs, or Decentralized IDentifiers, are universally-unique identifiers which
44+//// represent data repos. They are permanent and non-human-readable.
55+//// DIDs are a W3C specification. The AT Protocol currently supports
66+//// did:web and did:plc, two different DID methods.
77+////
88+//// DIDs resolve to documents which contain metadata about a repo,
99+//// including the address of the repo's PDS, the repo's handles,
1010+//// and the public signing keys.
1111+1212+import gleam/regexp
213import gleam/result
31444-const pattern = "/^did:[a-z]+:[a-zA-Z0-9._:%-]*[a-zA-Z0-9._-]$/"
1515+const pattern = "^did:[a-z]+:[a-zA-Z0-9._:%-]*[a-zA-Z0-9._-]$"
516617pub type DidError {
718 InvalidRegexPattern(pattern: String)
···9210393104pub fn new(content: String) -> Result(Did, DidError) {
94105 use with <- result.try(
9595- regex.from_string(pattern)
106106+ regexp.from_string(pattern)
96107 |> result.replace_error(InvalidRegexPattern(pattern:)),
97108 )
981099999- use value <- result.try(case regex.check(with:, content:) {
110110+ use value <- result.try(case regexp.check(with:, content:) {
100111 True -> Ok(content)
101112 False -> Error(InvalidFormat(content))
102113 })