From c61fd5c748c8cef21b6be06343000a28741c3ac5 Mon Sep 17 00:00:00 2001 From: syui Date: Tue, 12 Nov 2024 16:38:53 +0900 Subject: [PATCH] add scpt --- at.json | 47 ++++ at.zsh | 214 ++++++++++++++++++ .../frontpage/lib/data/atproto/record.ts | 50 ++++ 3 files changed, 311 insertions(+) create mode 100644 at.json create mode 100755 at.zsh create mode 100644 repos_extra/frontpage/packages/frontpage/lib/data/atproto/record.ts diff --git a/at.json b/at.json new file mode 100644 index 0000000..7761e07 --- /dev/null +++ b/at.json @@ -0,0 +1,47 @@ +{ + "atmosphere": { + "name": "at", + "repo": "https://github.com/bluesky-social/atproto", + "uri": "https://atproto.com/ja/guides/glossary", + "exosphere": { + "km":[{ "min": 700, "max": 10000 }], + "tag": [ "universe" ] + }, + "thermosphere": { + "km":[{ "min": 80, "max": 700 }], + "tag": [ "aurora" ] + }, + "mesosphere": { + "km":[{ "min": 50, "max": 80 }], + "tag": [ "meteor" ] + }, + "stratosphere": { + "km":[{ "min": 12, "max": 50 }], + "tag": [ "ozone", "bigsky" ], + "service":[ + { "name":"ozone", "repo":"https://github.com/bluesky-social/atproto/tree/main/services/ozone" }, + { "name":"bgs", "repo":"https://github.com/bluesky-social/indigo/tree/main/cmd/bigsky" } + ] + }, + "troposphere": { + "km":[{ "min": 0, "max": 12 }], + "tag": [ "bluesky"], + "service":[ + { "name":"bsky", "repo":"https://github.com/bluesky-social/atproto/tree/main/services/bsky", "tag":[ "api", "appview" ] }, + { "name":"bsync","repo":"https://github.com/bluesky-social/atproto/tree/main/services/bsync" }, + { "name":"pds", "repo":"https://github.com/bluesky-social/atproto/tree/main/services/pds" } + ] + }, + "other": { + "tag": [ "plc", "feed", "oauth", "social-app", "stream" ], + "service":[ + { "name":"plc", "repo":"https://github.com/did-method-plc/did-method-plc/tree/main/packages/server", "tag" : [ "did" ] }, + { "name":"social-app", "repo":"https://github.com/bluesky-social/social-app", "tag": [ "web" ] }, + { "name":"oauth", "repo":"https://github.com/bluesky-social/cookbook/tree/main/python-oauth-web-app" }, + { "name":"feed", "repo":"https://github.com/bluesky-social/feed-generator" }, + { "name":"stream", "repo":"https://github.com/bluesky-social/jetstream" } + ] + } + }, + "ref": "https://en.wikipedia.org/wiki/Atmosphere_of_Earth" +} diff --git a/at.zsh b/at.zsh new file mode 100755 index 0000000..54d0ea8 --- /dev/null +++ b/at.zsh @@ -0,0 +1,214 @@ +#!/bin/zsh + +help=( + at.zsh v + at.zsh d handle + at.zsh u at-uri + at.zsh c at-uri -r + at.zsh docs + at.zsh l handle password + at.zsh r + at.zsh s + at.zsh cid handle cid + at.zsh pro + at.zsh col ai.syui.game.user self +) +host=( + bsky.social + public.api.bsky.app + plc.directory +) +lexicon=( + # https://github.com/bluesky-social/atproto/tree/main/lexicons + com.atproto.repo.describeRepo + com.atproto.repo.getRecord + com.atproto.repo.listRecords + com.atproto.identity.resolveHandle + com.atproto.server.createSession + com.atproto.server.refreshSession + com.atproto.server.getSession + com.atproto.sync.getBlob + app.bsky.actor.getProfile +) +github=( + https://github.com/bluesky-social/atproto + https://github.com/bluesky-social/social-app + https://github.com/bluesky-social/feed-generator + https://github.com/bluesky-social/jetstream + https://github.com/bluesky-social/indigo + https://github.com/did-method-plc/did-method-plc +) +tag=( at bsky bsync pds bgs plc ozone feed jetstream social-app oauth ) + +function at-env() { + host=bsky.social + at_uri=at://did:plc:4hqjfn7m6n5hno3doamuhgef/ai.syui.game.user/syui + docs_uri=https://docs.bsky.app/docs/api + handle=yui.syui.ai + did=`echo $at_uri|cut -d / -f 3` + collection=`echo $at_uri|cut -d / -f 4` + rkey=`echo $at_uri|cut -d / -f 5` + d=${0:a:h} + f=~/.config/.at-zsh.json + if [ -f $f ];then + token=`cat $f|jq -r .accessJwt` + did=`cat $f|jq -r .did` + handle=`cat $f|jq -r .handle` + actor=$did + fi +} + +function at-unset() { + unset t password token refresh +} + +function at-version() { + curl -sL ${host}/xrpc/_health |jq . +} + +function at-uri() { + if [ -n "$1" ];then + at_uri=$1 + fi + req=/xrpc/com.atproto.repo.getRecord + url=https://${host}${req} + did=`echo $at_uri|cut -d / -f 3` + collection=`echo $at_uri|cut -d / -f 4` + rkey=`echo $at_uri|cut -d / -f 5` + curl -sL "$url?repo=$did&collection=$collection&rkey=$rkey"|jq . +} + +function at-did() { + if [ -n "$1" ];then + handle=$1 + fi + req=/xrpc/com.atproto.repo.describeRepo + url=https://${host}${req} + curl -sL "$url?repo=$handle"|jq . +} + +function at-collection() { + reverse=false + if [ -n "$1" ];then + at_uri=$1 + fi + if [ "$2" = "-r" ];then + reverse=true + fi + req=/xrpc/com.atproto.repo.listRecords + url=https://${host}${req} + did=`echo $at_uri|cut -d / -f 3` + collection=`echo $at_uri|cut -d / -f 4` + curl -sL "$url?repo=$did&collection=$collection&reverse=$reverse"|jq . +} + +function at-docs() { + for i in $lexicon; do + req=`echo $i|tr '.' '-'|sed 's/[A-Z]/-&/g'|tr '[A-Z]' '[a-z]'` + url=$docs_uri/$req + echo $url + done +} + +function at-login() { + if [ -z "$1" ] || [ -z "$2" ];then + echo handle password + exit + fi + handle=$1 + password=$2 + echo $password + json="{\"identifier\":\"$handle\",\"password\":\"$password\"}" + req=/xrpc/com.atproto.server.createSession + url=https://${host}${req} + if [ ! -d ~/.config ];then + mkdir -p ~/.config + fi + t=`curl -sL -X POST -H "Content-Type: application/json" -d $json $url` + if echo $t |jq .;then + echo $t >! $f + fi +} + +function at-refresh() { + echo $f + token=`cat $f|jq -r .refreshJwt` + req=/xrpc/com.atproto.server.refreshSession + url=https://${host}${req} + t=`curl -sL -X POST -H "Content-Type: application/json" -H "Authorization: Bearer $token" $url` + if echo $t |jq .;then + echo $t >! $f + fi +} + +function at-cid() { + did=`at-did $1|jq -r .did` + cid=$2 + req=/xrpc/com.atproto.sync.getBlob + url="https://${host}${req}?did=${did}&cid=${cid}" + curl -sL $url +} + +function at-session() { + req=/xrpc/com.atproto.server.getSession + url=https://${host}${req} + t=`curl -sL -X GET -H "Content-Type: application/json" -H "Authorization: Bearer $token" $url` + if ! echo $t |jq .;then + echo refresh + t=`at-refresh` + fi +} + +function at-profile() { + if [ ! -f $f ];then + echo login + exit + else + t=`at-session` + fi + req=/xrpc/app.bsky.actor.getProfile + url="https://${host}${req}?actor=$did" + curl -sL -X GET -H "Content-Type: application/json" -H "Authorization: Bearer $token" $url|jq . +} + +at-env +case $1 in + version|v) + at-version + ;; + uri|u) + at-uri $2 + ;; + did|d) + at-did $2 + ;; + collection|c) + at-collection $2 $3 + ;; + at-docs|docs) + at-docs + ;; + cid) + at-cid $2 $3 + ;; + login|l) + at-login $2 $3 + ;; + refresh|r) + at-refresh + ;; + session|s) + at-session + ;; + profile|pro) + at-profile + ;; + *) + echo "${help[@]}" + echo "${host[@]}" + echo "${lexicon[@]}" + echo "${github[@]}" + echo "${tag[@]}" + ;; +esac +at-unset diff --git a/repos_extra/frontpage/packages/frontpage/lib/data/atproto/record.ts b/repos_extra/frontpage/packages/frontpage/lib/data/atproto/record.ts new file mode 100644 index 0000000..8445f27 --- /dev/null +++ b/repos_extra/frontpage/packages/frontpage/lib/data/atproto/record.ts @@ -0,0 +1,50 @@ +import "server-only"; +import { z } from "zod"; +import { ensureUser } from "../user"; +import { DataLayerError } from "../error"; +import { fetchAuthenticatedAtproto } from "@/lib/auth"; +import { AtUri } from "./uri"; + +const PutRecordResponse = z.object({ + uri: AtUri, + cid: z.string(), +}); + +type PutRecordInput = { + rkey?: string; + record: unknown; + collection: string; +}; + +export async function atprotoPutRecord({ + rkey, + record, + collection, +}: PutRecordInput) { + const user = await ensureUser(); + const pdsUrl = new URL(user.pdsUrl); + pdsUrl.pathname = "/xrpc/com.atproto.repo.putRecord"; + + const response = await fetchAuthenticatedAtproto(pdsUrl.toString(), { + method: "POST", + headers: { + "Content-Type": "application/json", + }, + body: JSON.stringify({ + rkey: rkey || "self", + repo: user.did, + collection, + validate: false, + record: record, + }), + }); + + if (!response.ok) { + throw new DataLayerError(`Failed to create record ${response.status}`, { + cause: response, + }); + } + + return PutRecordResponse.parse(await response.json()); +} +