Compare commits
3 Commits
77f24bf7ce
...
7875d24d48
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
7875d24d48 | ||
|
|
4ff3ea6644 | ||
|
|
a6f1a96c4a |
28
.gitea/workflows/ci.yml
Normal file
28
.gitea/workflows/ci.yml
Normal file
@@ -0,0 +1,28 @@
|
||||
name: CI
|
||||
|
||||
on:
|
||||
push:
|
||||
branches: [main]
|
||||
pull_request:
|
||||
|
||||
jobs:
|
||||
check:
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- uses: actions/checkout@v4
|
||||
|
||||
- uses: denoland/setup-deno@v2
|
||||
with:
|
||||
deno-version: v2.x
|
||||
|
||||
- name: Format check
|
||||
run: deno fmt --check
|
||||
|
||||
- name: Lint
|
||||
run: deno lint
|
||||
|
||||
- name: Type check
|
||||
run: deno check jetstream.ts server.ts scripts/*.ts src/migrations/init.ts
|
||||
|
||||
- name: Test
|
||||
run: deno test --allow-all --permit-no-files
|
||||
@@ -1,23 +0,0 @@
|
||||
stages:
|
||||
- build
|
||||
- deploy
|
||||
|
||||
variables:
|
||||
DOCKER_DRIVER: overlay2
|
||||
DOCKER_TLS_CERTDIR: "/certs"
|
||||
IMAGE_TAG: $CI_REGISTRY/litenote:$CI_COMMIT_REF_SLUG
|
||||
IMAGE_LATEST: $CI_REGISTRY/litenote:latest
|
||||
|
||||
build:
|
||||
stage: build
|
||||
image: docker:24-dind
|
||||
services:
|
||||
- docker:24-dind
|
||||
before_script:
|
||||
- docker login -u $CI_REGISTRY_USER -p $CI_REGISTRY_PASSWORD $CI_REGISTRY
|
||||
script:
|
||||
- docker build -t $IMAGE_TAG -t $IMAGE_LATEST .
|
||||
- docker push $IMAGE_TAG
|
||||
- docker push $IMAGE_LATEST
|
||||
only:
|
||||
- main
|
||||
@@ -1,4 +1,10 @@
|
||||
{
|
||||
"fmt": {
|
||||
"exclude": ["docs/"]
|
||||
},
|
||||
"lint": {
|
||||
"exclude": ["docs/"]
|
||||
},
|
||||
"tasks": {
|
||||
"jetstream:prod": "deno run --allow-net --allow-read --allow-write --allow-env --allow-ffi --unstable-ffi jetstream.ts",
|
||||
"jetstream": "deno run --watch --allow-net --allow-read --allow-write --allow-env --allow-ffi --unstable-ffi jetstream.ts",
|
||||
@@ -12,6 +18,7 @@
|
||||
"imports": {
|
||||
"@db/sqlite": "jsr:@db/sqlite@^0.13.0",
|
||||
"@oak/oak": "jsr:@oak/oak@^17.2.0",
|
||||
"@opensearch-project/opensearch": "npm:@opensearch-project/opensearch@^3.6.0",
|
||||
"@skyware/jetstream": "npm:@skyware/jetstream@^0.2.5",
|
||||
"@std/assert": "jsr:@std/assert@1"
|
||||
}
|
||||
|
||||
36
deno.lock
generated
36
deno.lock
generated
@@ -20,6 +20,8 @@
|
||||
"jsr:@std/path@1": "1.1.4",
|
||||
"jsr:@std/path@1.0": "1.0.9",
|
||||
"jsr:@std/path@^1.1.1": "1.1.4",
|
||||
"npm:@opensearch-project/opensearch@3": "3.6.0",
|
||||
"npm:@opensearch-project/opensearch@^3.6.0": "3.6.0",
|
||||
"npm:@skyware/jetstream@~0.2.5": "0.2.5",
|
||||
"npm:path-to-regexp@^6.3.0": "6.3.0"
|
||||
},
|
||||
@@ -142,6 +144,17 @@
|
||||
"unicode-segmenter"
|
||||
]
|
||||
},
|
||||
"@opensearch-project/opensearch@3.6.0": {
|
||||
"integrity": "sha512-ow1A/Z7MBlNL/JZzTY4+M+8psiVh66g0Z7EQSl/qbT0U6zLBsVDYh6nvm8D4e4tIzQtn6ODbA2OsqYGvqZj76g==",
|
||||
"dependencies": [
|
||||
"aws4",
|
||||
"debug",
|
||||
"hpagent",
|
||||
"json11",
|
||||
"ms",
|
||||
"secure-json-parse"
|
||||
]
|
||||
},
|
||||
"@skyware/jetstream@0.2.5": {
|
||||
"integrity": "sha512-fM/zs03DLwqRyzZZJFWN20e76KrdqIp97Tlm8Cek+vxn96+tu5d/fx79V6H85L0QN6HvGiX2l9A8hWFqHvYlOA==",
|
||||
"dependencies": [
|
||||
@@ -155,12 +168,31 @@
|
||||
"@standard-schema/spec@1.1.0": {
|
||||
"integrity": "sha512-l2aFy5jALhniG5HgqrD6jXLi/rUWrKvqN/qJx6yoJsgKhblVd+iqqU4RCXavm/jPityDo5TCvKMnpjKnOriy0w=="
|
||||
},
|
||||
"aws4@1.13.2": {
|
||||
"integrity": "sha512-lHe62zvbTB5eEABUVi/AwVh0ZKY9rMMDhmm+eeyuuUQbQ3+J+fONVQOZyj+DdrvD4BY33uYniyRJ4UJIaSKAfw=="
|
||||
},
|
||||
"debug@4.4.3": {
|
||||
"integrity": "sha512-RGwwWnwQvkVfavKVt22FGLw+xYSdzARwm0ru6DhTVA3umU5hZc28V3kO4stgYryrTlLpuvgI9GiijltAjNbcqA==",
|
||||
"dependencies": [
|
||||
"ms"
|
||||
]
|
||||
},
|
||||
"esm-env@1.2.2": {
|
||||
"integrity": "sha512-Epxrv+Nr/CaL4ZcFGPJIYLWFom+YeV1DqMLHJoEd9SYRxNbaFruBwfEX/kkHUJf55j2+TUbmDcmuilbP1TmXHA=="
|
||||
},
|
||||
"event-target-polyfill@0.0.4": {
|
||||
"integrity": "sha512-Gs6RLjzlLRdT8X9ZipJdIZI/Y6/HhRLyq9RdDlCsnpxr/+Nn6bU2EFGuC94GjxqhM+Nmij2Vcq98yoHrU8uNFQ=="
|
||||
},
|
||||
"hpagent@1.2.0": {
|
||||
"integrity": "sha512-A91dYTeIB6NoXG+PxTQpCCDDnfHsW9kc06Lvpu1TEe9gnd6ZFeiBoRO9JvzEv6xK7EX97/dUE8g/vBMTqTS3CA=="
|
||||
},
|
||||
"json11@2.0.2": {
|
||||
"integrity": "sha512-HIrd50UPYmP6sqLuLbFVm75g16o0oZrVfxrsY0EEys22klz8mRoWlX9KAEDOSOR9Q34rcxsyC8oDveGrCz5uLQ==",
|
||||
"bin": true
|
||||
},
|
||||
"ms@2.1.3": {
|
||||
"integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA=="
|
||||
},
|
||||
"partysocket@1.1.12": {
|
||||
"integrity": "sha512-079YDW1QZsFwJ8syLmr9xFMbE+VwbK4SpcKSOPVApX8rpIMennkxx0MeWl4oWutP/Zjgy8TMnQZ3FOXTQvu3DA==",
|
||||
"dependencies": [
|
||||
@@ -170,6 +202,9 @@
|
||||
"path-to-regexp@6.3.0": {
|
||||
"integrity": "sha512-Yhpw4T9C6hPpgPeA28us07OJeqZ5EzQTkbfwuhsUg0c237RomFoETJgmp2sa3F/41gfLE6G5cqcYwznmeEeOlQ=="
|
||||
},
|
||||
"secure-json-parse@2.7.0": {
|
||||
"integrity": "sha512-6aU+Rwsezw7VR8/nyvKTx8QpWH9FrcYiXXlqC4z5d5XQBDRqtbfsRjnwGyqbi3gddNtWHuEk9OANUotL26qKUw=="
|
||||
},
|
||||
"tiny-emitter@2.1.0": {
|
||||
"integrity": "sha512-NB6Dk1A9xgQPMoGqC5CVXn123gWyte215ONT5Pp5a0yt4nlEoO1ZWeCwpncaekPHXO60i47ihFnZPiRPjRMq4Q=="
|
||||
},
|
||||
@@ -196,6 +231,7 @@
|
||||
"jsr:@db/sqlite@0.13",
|
||||
"jsr:@oak/oak@^17.2.0",
|
||||
"jsr:@std/assert@1",
|
||||
"npm:@opensearch-project/opensearch@^3.6.0",
|
||||
"npm:@skyware/jetstream@~0.2.5"
|
||||
]
|
||||
}
|
||||
|
||||
@@ -0,0 +1,114 @@
|
||||
meta {
|
||||
name: List every webhook subscription
|
||||
type: http
|
||||
seq: 1
|
||||
}
|
||||
|
||||
get {
|
||||
url: {{baseUrl}}/admin/webhooks
|
||||
body: none
|
||||
auth: bearer
|
||||
}
|
||||
|
||||
auth:bearer {
|
||||
token: {{token}}
|
||||
}
|
||||
|
||||
example {
|
||||
name: 200 Response
|
||||
description: All subscriptions across all DIDs.
|
||||
|
||||
request: {
|
||||
url: {{baseUrl}}/admin/webhooks
|
||||
method: GET
|
||||
mode: none
|
||||
}
|
||||
|
||||
response: {
|
||||
headers: {
|
||||
Content-Type: application/json
|
||||
}
|
||||
|
||||
status: {
|
||||
code: 200
|
||||
text: OK
|
||||
}
|
||||
|
||||
body: {
|
||||
type: json
|
||||
content: '''
|
||||
[
|
||||
{
|
||||
"id": 0,
|
||||
"did": "",
|
||||
"method": "",
|
||||
"url": "",
|
||||
"verb": ""
|
||||
}
|
||||
]
|
||||
'''
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
example {
|
||||
name: 401 Response
|
||||
description: Missing or invalid bearer token.
|
||||
|
||||
request: {
|
||||
url: {{baseUrl}}/admin/webhooks
|
||||
method: GET
|
||||
mode: none
|
||||
}
|
||||
|
||||
response: {
|
||||
headers: {
|
||||
Content-Type: application/json
|
||||
}
|
||||
|
||||
status: {
|
||||
code: 401
|
||||
text: Unauthorized
|
||||
}
|
||||
|
||||
body: {
|
||||
type: json
|
||||
content: '''
|
||||
{
|
||||
"error": ""
|
||||
}
|
||||
'''
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
example {
|
||||
name: 403 Response
|
||||
description: Token is valid but the caller is not authorized for this resource.
|
||||
|
||||
request: {
|
||||
url: {{baseUrl}}/admin/webhooks
|
||||
method: GET
|
||||
mode: none
|
||||
}
|
||||
|
||||
response: {
|
||||
headers: {
|
||||
Content-Type: application/json
|
||||
}
|
||||
|
||||
status: {
|
||||
code: 403
|
||||
text: Forbidden
|
||||
}
|
||||
|
||||
body: {
|
||||
type: json
|
||||
content: '''
|
||||
{
|
||||
"error": ""
|
||||
}
|
||||
'''
|
||||
}
|
||||
}
|
||||
}
|
||||
7
docs/Remanso Jetstream API/admin/folder.bru
Normal file
7
docs/Remanso Jetstream API/admin/folder.bru
Normal file
@@ -0,0 +1,7 @@
|
||||
meta {
|
||||
name: admin
|
||||
}
|
||||
|
||||
auth {
|
||||
mode: inherit
|
||||
}
|
||||
84
docs/Remanso Jetstream API/auth/GitHub OAuth proxy.bru
Normal file
84
docs/Remanso Jetstream API/auth/GitHub OAuth proxy.bru
Normal file
@@ -0,0 +1,84 @@
|
||||
meta {
|
||||
name: GitHub OAuth proxy
|
||||
type: http
|
||||
seq: 1
|
||||
}
|
||||
|
||||
get {
|
||||
url: {{baseUrl}}/auth/github
|
||||
body: none
|
||||
auth: inherit
|
||||
}
|
||||
|
||||
params:query {
|
||||
code:
|
||||
~type:
|
||||
}
|
||||
|
||||
example {
|
||||
name: 200 Response
|
||||
description: GitHub access-token response (shape determined by GitHub).
|
||||
|
||||
request: {
|
||||
url: {{baseUrl}}/auth/github
|
||||
method: GET
|
||||
mode: none
|
||||
params:query: {
|
||||
code:
|
||||
~type:
|
||||
}
|
||||
}
|
||||
|
||||
response: {
|
||||
headers: {
|
||||
Content-Type: application/json
|
||||
}
|
||||
|
||||
status: {
|
||||
code: 200
|
||||
text: OK
|
||||
}
|
||||
|
||||
body: {
|
||||
type: json
|
||||
content: '''
|
||||
{}
|
||||
'''
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
example {
|
||||
name: 400 Response
|
||||
description: Malformed input.
|
||||
|
||||
request: {
|
||||
url: {{baseUrl}}/auth/github
|
||||
method: GET
|
||||
mode: none
|
||||
params:query: {
|
||||
code:
|
||||
~type:
|
||||
}
|
||||
}
|
||||
|
||||
response: {
|
||||
headers: {
|
||||
Content-Type: application/json
|
||||
}
|
||||
|
||||
status: {
|
||||
code: 400
|
||||
text: Bad Request
|
||||
}
|
||||
|
||||
body: {
|
||||
type: json
|
||||
content: '''
|
||||
{
|
||||
"error": ""
|
||||
}
|
||||
'''
|
||||
}
|
||||
}
|
||||
}
|
||||
7
docs/Remanso Jetstream API/auth/folder.bru
Normal file
7
docs/Remanso Jetstream API/auth/folder.bru
Normal file
@@ -0,0 +1,7 @@
|
||||
meta {
|
||||
name: auth
|
||||
}
|
||||
|
||||
auth {
|
||||
mode: inherit
|
||||
}
|
||||
9
docs/Remanso Jetstream API/bruno.json
Normal file
9
docs/Remanso Jetstream API/bruno.json
Normal file
@@ -0,0 +1,9 @@
|
||||
{
|
||||
"version": "1",
|
||||
"name": "Remanso Jetstream API",
|
||||
"type": "collection",
|
||||
"ignore": [
|
||||
"node_modules",
|
||||
".git"
|
||||
]
|
||||
}
|
||||
7
docs/Remanso Jetstream API/collection.bru
Normal file
7
docs/Remanso Jetstream API/collection.bru
Normal file
@@ -0,0 +1,7 @@
|
||||
meta {
|
||||
name: Remanso Jetstream API
|
||||
}
|
||||
|
||||
auth {
|
||||
mode: none
|
||||
}
|
||||
@@ -0,0 +1,3 @@
|
||||
vars {
|
||||
baseUrl: http://localhost:8080
|
||||
}
|
||||
3
docs/Remanso Jetstream API/environments/Production.bru
Normal file
3
docs/Remanso Jetstream API/environments/Production.bru
Normal file
@@ -0,0 +1,3 @@
|
||||
vars {
|
||||
baseUrl: https://api.remanso.space
|
||||
}
|
||||
42
docs/Remanso Jetstream API/meta/Health probe.bru
Normal file
42
docs/Remanso Jetstream API/meta/Health probe.bru
Normal file
@@ -0,0 +1,42 @@
|
||||
meta {
|
||||
name: Health probe
|
||||
type: http
|
||||
seq: 2
|
||||
}
|
||||
|
||||
get {
|
||||
url: {{baseUrl}}/health
|
||||
body: none
|
||||
auth: inherit
|
||||
}
|
||||
|
||||
example {
|
||||
name: 200 Response
|
||||
description: Service is up
|
||||
|
||||
request: {
|
||||
url: {{baseUrl}}/health
|
||||
method: GET
|
||||
mode: none
|
||||
}
|
||||
|
||||
response: {
|
||||
headers: {
|
||||
Content-Type: application/json
|
||||
}
|
||||
|
||||
status: {
|
||||
code: 200
|
||||
text: OK
|
||||
}
|
||||
|
||||
body: {
|
||||
type: json
|
||||
content: '''
|
||||
{
|
||||
"status": ""
|
||||
}
|
||||
'''
|
||||
}
|
||||
}
|
||||
}
|
||||
40
docs/Remanso Jetstream API/meta/Hello world.bru
Normal file
40
docs/Remanso Jetstream API/meta/Hello world.bru
Normal file
@@ -0,0 +1,40 @@
|
||||
meta {
|
||||
name: Hello world
|
||||
type: http
|
||||
seq: 1
|
||||
}
|
||||
|
||||
get {
|
||||
url: {{baseUrl}}/
|
||||
body: none
|
||||
auth: inherit
|
||||
}
|
||||
|
||||
example {
|
||||
name: 200 Response
|
||||
description: Plain text greeting
|
||||
|
||||
request: {
|
||||
url: {{baseUrl}}/
|
||||
method: GET
|
||||
mode: none
|
||||
}
|
||||
|
||||
response: {
|
||||
headers: {
|
||||
Content-Type: text/plain
|
||||
}
|
||||
|
||||
status: {
|
||||
code: 200
|
||||
text: OK
|
||||
}
|
||||
|
||||
body: {
|
||||
type: text
|
||||
content: '''
|
||||
Hello world
|
||||
'''
|
||||
}
|
||||
}
|
||||
}
|
||||
7
docs/Remanso Jetstream API/meta/folder.bru
Normal file
7
docs/Remanso Jetstream API/meta/folder.bru
Normal file
@@ -0,0 +1,7 @@
|
||||
meta {
|
||||
name: meta
|
||||
}
|
||||
|
||||
auth {
|
||||
mode: inherit
|
||||
}
|
||||
@@ -0,0 +1,61 @@
|
||||
meta {
|
||||
name: List discoverable notes across all users
|
||||
type: http
|
||||
seq: 1
|
||||
}
|
||||
|
||||
get {
|
||||
url: {{baseUrl}}/notes
|
||||
body: none
|
||||
auth: inherit
|
||||
}
|
||||
|
||||
params:query {
|
||||
~cursor:
|
||||
~limit:
|
||||
}
|
||||
|
||||
example {
|
||||
name: 200 Response
|
||||
description: A page of notes ordered by rkey descending.
|
||||
|
||||
request: {
|
||||
url: {{baseUrl}}/notes
|
||||
method: GET
|
||||
mode: none
|
||||
params:query: {
|
||||
~cursor:
|
||||
~limit:
|
||||
}
|
||||
}
|
||||
|
||||
response: {
|
||||
headers: {
|
||||
Content-Type: application/json
|
||||
}
|
||||
|
||||
status: {
|
||||
code: 200
|
||||
text: OK
|
||||
}
|
||||
|
||||
body: {
|
||||
type: json
|
||||
content: '''
|
||||
{
|
||||
"notes": [
|
||||
{
|
||||
"did": "",
|
||||
"rkey": "",
|
||||
"title": "",
|
||||
"publishedAt": "",
|
||||
"createdAt": "",
|
||||
"language": ""
|
||||
}
|
||||
],
|
||||
"cursor": ""
|
||||
}
|
||||
'''
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,69 @@
|
||||
meta {
|
||||
name: List discoverable notes for a single DID
|
||||
type: http
|
||||
seq: 2
|
||||
}
|
||||
|
||||
get {
|
||||
url: {{baseUrl}}/:did/notes
|
||||
body: none
|
||||
auth: inherit
|
||||
}
|
||||
|
||||
params:query {
|
||||
~cursor:
|
||||
~limit:
|
||||
}
|
||||
|
||||
params:path {
|
||||
did:
|
||||
}
|
||||
|
||||
example {
|
||||
name: 200 Response
|
||||
description: A page of notes for the given DID.
|
||||
|
||||
request: {
|
||||
url: {{baseUrl}}/:did/notes
|
||||
method: GET
|
||||
mode: none
|
||||
params:query: {
|
||||
~cursor:
|
||||
~limit:
|
||||
}
|
||||
|
||||
params:path: {
|
||||
did:
|
||||
}
|
||||
}
|
||||
|
||||
response: {
|
||||
headers: {
|
||||
Content-Type: application/json
|
||||
}
|
||||
|
||||
status: {
|
||||
code: 200
|
||||
text: OK
|
||||
}
|
||||
|
||||
body: {
|
||||
type: json
|
||||
content: '''
|
||||
{
|
||||
"notes": [
|
||||
{
|
||||
"did": "",
|
||||
"rkey": "",
|
||||
"title": "",
|
||||
"publishedAt": "",
|
||||
"createdAt": "",
|
||||
"language": ""
|
||||
}
|
||||
],
|
||||
"cursor": ""
|
||||
}
|
||||
'''
|
||||
}
|
||||
}
|
||||
}
|
||||
105
docs/Remanso Jetstream API/notes/Multi-DID feed.bru
Normal file
105
docs/Remanso Jetstream API/notes/Multi-DID feed.bru
Normal file
@@ -0,0 +1,105 @@
|
||||
meta {
|
||||
name: Multi-DID feed
|
||||
type: http
|
||||
seq: 3
|
||||
}
|
||||
|
||||
post {
|
||||
url: {{baseUrl}}/notes/feed
|
||||
body: json
|
||||
auth: inherit
|
||||
}
|
||||
|
||||
body:json {
|
||||
{
|
||||
"dids": [],
|
||||
"cursor": "",
|
||||
"limit": 0
|
||||
}
|
||||
}
|
||||
|
||||
example {
|
||||
name: 200 Response
|
||||
description: A page of notes from the requested DIDs.
|
||||
|
||||
request: {
|
||||
url: {{baseUrl}}/notes/feed
|
||||
method: POST
|
||||
mode: json
|
||||
body:json: {
|
||||
{
|
||||
"dids": [],
|
||||
"cursor": "",
|
||||
"limit": 0
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
response: {
|
||||
headers: {
|
||||
Content-Type: application/json
|
||||
}
|
||||
|
||||
status: {
|
||||
code: 200
|
||||
text: OK
|
||||
}
|
||||
|
||||
body: {
|
||||
type: json
|
||||
content: '''
|
||||
{
|
||||
"notes": [
|
||||
{
|
||||
"did": "",
|
||||
"rkey": "",
|
||||
"title": "",
|
||||
"publishedAt": "",
|
||||
"createdAt": "",
|
||||
"language": ""
|
||||
}
|
||||
],
|
||||
"cursor": ""
|
||||
}
|
||||
'''
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
example {
|
||||
name: 400 Response
|
||||
description: Malformed input.
|
||||
|
||||
request: {
|
||||
url: {{baseUrl}}/notes/feed
|
||||
method: POST
|
||||
mode: json
|
||||
body:json: {
|
||||
{
|
||||
"dids": [],
|
||||
"cursor": "",
|
||||
"limit": 0
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
response: {
|
||||
headers: {
|
||||
Content-Type: application/json
|
||||
}
|
||||
|
||||
status: {
|
||||
code: 400
|
||||
text: Bad Request
|
||||
}
|
||||
|
||||
body: {
|
||||
type: json
|
||||
content: '''
|
||||
{
|
||||
"error": ""
|
||||
}
|
||||
'''
|
||||
}
|
||||
}
|
||||
}
|
||||
7
docs/Remanso Jetstream API/notes/folder.bru
Normal file
7
docs/Remanso Jetstream API/notes/folder.bru
Normal file
@@ -0,0 +1,7 @@
|
||||
meta {
|
||||
name: notes
|
||||
}
|
||||
|
||||
auth {
|
||||
mode: inherit
|
||||
}
|
||||
@@ -0,0 +1,195 @@
|
||||
meta {
|
||||
name: Owner-scoped full-text fuzzy search
|
||||
type: http
|
||||
seq: 2
|
||||
}
|
||||
|
||||
get {
|
||||
url: {{baseUrl}}/:did/search
|
||||
body: none
|
||||
auth: bearer
|
||||
}
|
||||
|
||||
params:query {
|
||||
q:
|
||||
~cursor:
|
||||
~limit:
|
||||
}
|
||||
|
||||
params:path {
|
||||
did: did:plc:4m3kouplb7s7xozjd3whinvl
|
||||
}
|
||||
|
||||
auth:bearer {
|
||||
token: {{token}}
|
||||
}
|
||||
|
||||
example {
|
||||
name: 200 Response
|
||||
description: A page of search hits for the caller's DID.
|
||||
|
||||
request: {
|
||||
url: {{baseUrl}}/:did/search
|
||||
method: GET
|
||||
mode: none
|
||||
params:query: {
|
||||
q:
|
||||
~cursor:
|
||||
~limit:
|
||||
}
|
||||
|
||||
params:path: {
|
||||
did:
|
||||
}
|
||||
}
|
||||
|
||||
response: {
|
||||
headers: {
|
||||
Content-Type: application/json
|
||||
}
|
||||
|
||||
status: {
|
||||
code: 200
|
||||
text: OK
|
||||
}
|
||||
|
||||
body: {
|
||||
type: json
|
||||
content: '''
|
||||
{
|
||||
"results": [
|
||||
{
|
||||
"did": "",
|
||||
"rkey": "",
|
||||
"title": "",
|
||||
"snippet": "",
|
||||
"score": 0,
|
||||
"publishedAt": ""
|
||||
}
|
||||
],
|
||||
"cursor": ""
|
||||
}
|
||||
'''
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
example {
|
||||
name: 400 Response
|
||||
description: Malformed input.
|
||||
|
||||
request: {
|
||||
url: {{baseUrl}}/:did/search
|
||||
method: GET
|
||||
mode: none
|
||||
params:query: {
|
||||
q:
|
||||
~cursor:
|
||||
~limit:
|
||||
}
|
||||
|
||||
params:path: {
|
||||
did:
|
||||
}
|
||||
}
|
||||
|
||||
response: {
|
||||
headers: {
|
||||
Content-Type: application/json
|
||||
}
|
||||
|
||||
status: {
|
||||
code: 400
|
||||
text: Bad Request
|
||||
}
|
||||
|
||||
body: {
|
||||
type: json
|
||||
content: '''
|
||||
{
|
||||
"error": ""
|
||||
}
|
||||
'''
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
example {
|
||||
name: 401 Response
|
||||
description: Missing or invalid bearer token.
|
||||
|
||||
request: {
|
||||
url: {{baseUrl}}/:did/search
|
||||
method: GET
|
||||
mode: none
|
||||
params:query: {
|
||||
q:
|
||||
~cursor:
|
||||
~limit:
|
||||
}
|
||||
|
||||
params:path: {
|
||||
did:
|
||||
}
|
||||
}
|
||||
|
||||
response: {
|
||||
headers: {
|
||||
Content-Type: application/json
|
||||
}
|
||||
|
||||
status: {
|
||||
code: 401
|
||||
text: Unauthorized
|
||||
}
|
||||
|
||||
body: {
|
||||
type: json
|
||||
content: '''
|
||||
{
|
||||
"error": ""
|
||||
}
|
||||
'''
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
example {
|
||||
name: 403 Response
|
||||
description: Token is valid but the caller is not authorized for this resource.
|
||||
|
||||
request: {
|
||||
url: {{baseUrl}}/:did/search
|
||||
method: GET
|
||||
mode: none
|
||||
params:query: {
|
||||
q:
|
||||
~cursor:
|
||||
~limit:
|
||||
}
|
||||
|
||||
params:path: {
|
||||
did:
|
||||
}
|
||||
}
|
||||
|
||||
response: {
|
||||
headers: {
|
||||
Content-Type: application/json
|
||||
}
|
||||
|
||||
status: {
|
||||
code: 403
|
||||
text: Forbidden
|
||||
}
|
||||
|
||||
body: {
|
||||
type: json
|
||||
content: '''
|
||||
{
|
||||
"error": ""
|
||||
}
|
||||
'''
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,99 @@
|
||||
meta {
|
||||
name: Public full-text fuzzy search
|
||||
type: http
|
||||
seq: 1
|
||||
}
|
||||
|
||||
get {
|
||||
url: {{baseUrl}}/search?q=
|
||||
body: none
|
||||
auth: inherit
|
||||
}
|
||||
|
||||
params:query {
|
||||
q:
|
||||
~cursor:
|
||||
~limit:
|
||||
}
|
||||
|
||||
example {
|
||||
name: 200 Response
|
||||
description: A page of search hits.
|
||||
|
||||
request: {
|
||||
url: {{baseUrl}}/search
|
||||
method: GET
|
||||
mode: none
|
||||
params:query: {
|
||||
q:
|
||||
~cursor:
|
||||
~limit:
|
||||
}
|
||||
}
|
||||
|
||||
response: {
|
||||
headers: {
|
||||
Content-Type: application/json
|
||||
}
|
||||
|
||||
status: {
|
||||
code: 200
|
||||
text: OK
|
||||
}
|
||||
|
||||
body: {
|
||||
type: json
|
||||
content: '''
|
||||
{
|
||||
"results": [
|
||||
{
|
||||
"did": "",
|
||||
"rkey": "",
|
||||
"title": "",
|
||||
"snippet": "",
|
||||
"score": 0,
|
||||
"publishedAt": ""
|
||||
}
|
||||
],
|
||||
"cursor": ""
|
||||
}
|
||||
'''
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
example {
|
||||
name: 400 Response
|
||||
description: Malformed input.
|
||||
|
||||
request: {
|
||||
url: {{baseUrl}}/search
|
||||
method: GET
|
||||
mode: none
|
||||
params:query: {
|
||||
q:
|
||||
~cursor:
|
||||
~limit:
|
||||
}
|
||||
}
|
||||
|
||||
response: {
|
||||
headers: {
|
||||
Content-Type: application/json
|
||||
}
|
||||
|
||||
status: {
|
||||
code: 400
|
||||
text: Bad Request
|
||||
}
|
||||
|
||||
body: {
|
||||
type: json
|
||||
content: '''
|
||||
{
|
||||
"error": ""
|
||||
}
|
||||
'''
|
||||
}
|
||||
}
|
||||
}
|
||||
7
docs/Remanso Jetstream API/search/folder.bru
Normal file
7
docs/Remanso Jetstream API/search/folder.bru
Normal file
@@ -0,0 +1,7 @@
|
||||
meta {
|
||||
name: search
|
||||
}
|
||||
|
||||
auth {
|
||||
mode: inherit
|
||||
}
|
||||
@@ -0,0 +1,206 @@
|
||||
meta {
|
||||
name: Add one or more webhook subscriptions
|
||||
type: http
|
||||
seq: 2
|
||||
}
|
||||
|
||||
post {
|
||||
url: {{baseUrl}}/:did/webhooks
|
||||
body: json
|
||||
auth: bearer
|
||||
}
|
||||
|
||||
params:path {
|
||||
did:
|
||||
}
|
||||
|
||||
auth:bearer {
|
||||
token: {{token}}
|
||||
}
|
||||
|
||||
body:json {
|
||||
{
|
||||
"method": "",
|
||||
"url": "",
|
||||
"token": "",
|
||||
"verb": ""
|
||||
}
|
||||
}
|
||||
|
||||
example {
|
||||
name: 201 Response
|
||||
description: One subscription per requested verb.
|
||||
|
||||
request: {
|
||||
url: {{baseUrl}}/:did/webhooks
|
||||
method: POST
|
||||
mode: json
|
||||
params:path: {
|
||||
did:
|
||||
}
|
||||
|
||||
body:json: {
|
||||
{
|
||||
"method": "",
|
||||
"url": "",
|
||||
"token": "",
|
||||
"verb": ""
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
response: {
|
||||
headers: {
|
||||
Content-Type: application/json
|
||||
}
|
||||
|
||||
status: {
|
||||
code: 201
|
||||
text: Created
|
||||
}
|
||||
|
||||
body: {
|
||||
type: json
|
||||
content: '''
|
||||
[
|
||||
{
|
||||
"id": 0,
|
||||
"did": "",
|
||||
"method": "",
|
||||
"url": "",
|
||||
"verb": ""
|
||||
}
|
||||
]
|
||||
'''
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
example {
|
||||
name: 400 Response
|
||||
description: Malformed input.
|
||||
|
||||
request: {
|
||||
url: {{baseUrl}}/:did/webhooks
|
||||
method: POST
|
||||
mode: json
|
||||
params:path: {
|
||||
did:
|
||||
}
|
||||
|
||||
body:json: {
|
||||
{
|
||||
"method": "",
|
||||
"url": "",
|
||||
"token": "",
|
||||
"verb": ""
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
response: {
|
||||
headers: {
|
||||
Content-Type: application/json
|
||||
}
|
||||
|
||||
status: {
|
||||
code: 400
|
||||
text: Bad Request
|
||||
}
|
||||
|
||||
body: {
|
||||
type: json
|
||||
content: '''
|
||||
{
|
||||
"error": ""
|
||||
}
|
||||
'''
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
example {
|
||||
name: 401 Response
|
||||
description: Missing or invalid bearer token.
|
||||
|
||||
request: {
|
||||
url: {{baseUrl}}/:did/webhooks
|
||||
method: POST
|
||||
mode: json
|
||||
params:path: {
|
||||
did:
|
||||
}
|
||||
|
||||
body:json: {
|
||||
{
|
||||
"method": "",
|
||||
"url": "",
|
||||
"token": "",
|
||||
"verb": ""
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
response: {
|
||||
headers: {
|
||||
Content-Type: application/json
|
||||
}
|
||||
|
||||
status: {
|
||||
code: 401
|
||||
text: Unauthorized
|
||||
}
|
||||
|
||||
body: {
|
||||
type: json
|
||||
content: '''
|
||||
{
|
||||
"error": ""
|
||||
}
|
||||
'''
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
example {
|
||||
name: 403 Response
|
||||
description: Token is valid but the caller is not authorized for this resource.
|
||||
|
||||
request: {
|
||||
url: {{baseUrl}}/:did/webhooks
|
||||
method: POST
|
||||
mode: json
|
||||
params:path: {
|
||||
did:
|
||||
}
|
||||
|
||||
body:json: {
|
||||
{
|
||||
"method": "",
|
||||
"url": "",
|
||||
"token": "",
|
||||
"verb": ""
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
response: {
|
||||
headers: {
|
||||
Content-Type: application/json
|
||||
}
|
||||
|
||||
status: {
|
||||
code: 403
|
||||
text: Forbidden
|
||||
}
|
||||
|
||||
body: {
|
||||
type: json
|
||||
content: '''
|
||||
{
|
||||
"error": ""
|
||||
}
|
||||
'''
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,189 @@
|
||||
meta {
|
||||
name: Delete a single webhook subscription by id
|
||||
type: http
|
||||
seq: 4
|
||||
}
|
||||
|
||||
delete {
|
||||
url: {{baseUrl}}/:did/webhooks/:id
|
||||
body: none
|
||||
auth: bearer
|
||||
}
|
||||
|
||||
params:path {
|
||||
did:
|
||||
id:
|
||||
}
|
||||
|
||||
auth:bearer {
|
||||
token: {{token}}
|
||||
}
|
||||
|
||||
example {
|
||||
name: 204 Response
|
||||
description: Subscription deleted.
|
||||
|
||||
request: {
|
||||
url: {{baseUrl}}/:did/webhooks/:id
|
||||
method: DELETE
|
||||
mode: none
|
||||
params:path: {
|
||||
did:
|
||||
id:
|
||||
}
|
||||
}
|
||||
|
||||
response: {
|
||||
status: {
|
||||
code: 204
|
||||
text: No Content
|
||||
}
|
||||
|
||||
body: {
|
||||
type: text
|
||||
content: '''
|
||||
|
||||
'''
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
example {
|
||||
name: 400 Response
|
||||
description: Malformed input.
|
||||
|
||||
request: {
|
||||
url: {{baseUrl}}/:did/webhooks/:id
|
||||
method: DELETE
|
||||
mode: none
|
||||
params:path: {
|
||||
did:
|
||||
id:
|
||||
}
|
||||
}
|
||||
|
||||
response: {
|
||||
headers: {
|
||||
Content-Type: application/json
|
||||
}
|
||||
|
||||
status: {
|
||||
code: 400
|
||||
text: Bad Request
|
||||
}
|
||||
|
||||
body: {
|
||||
type: json
|
||||
content: '''
|
||||
{
|
||||
"error": ""
|
||||
}
|
||||
'''
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
example {
|
||||
name: 401 Response
|
||||
description: Missing or invalid bearer token.
|
||||
|
||||
request: {
|
||||
url: {{baseUrl}}/:did/webhooks/:id
|
||||
method: DELETE
|
||||
mode: none
|
||||
params:path: {
|
||||
did:
|
||||
id:
|
||||
}
|
||||
}
|
||||
|
||||
response: {
|
||||
headers: {
|
||||
Content-Type: application/json
|
||||
}
|
||||
|
||||
status: {
|
||||
code: 401
|
||||
text: Unauthorized
|
||||
}
|
||||
|
||||
body: {
|
||||
type: json
|
||||
content: '''
|
||||
{
|
||||
"error": ""
|
||||
}
|
||||
'''
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
example {
|
||||
name: 403 Response
|
||||
description: Token is valid but the caller is not authorized for this resource.
|
||||
|
||||
request: {
|
||||
url: {{baseUrl}}/:did/webhooks/:id
|
||||
method: DELETE
|
||||
mode: none
|
||||
params:path: {
|
||||
did:
|
||||
id:
|
||||
}
|
||||
}
|
||||
|
||||
response: {
|
||||
headers: {
|
||||
Content-Type: application/json
|
||||
}
|
||||
|
||||
status: {
|
||||
code: 403
|
||||
text: Forbidden
|
||||
}
|
||||
|
||||
body: {
|
||||
type: json
|
||||
content: '''
|
||||
{
|
||||
"error": ""
|
||||
}
|
||||
'''
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
example {
|
||||
name: 404 Response
|
||||
description: No subscription with that id owned by this DID.
|
||||
|
||||
request: {
|
||||
url: {{baseUrl}}/:did/webhooks/:id
|
||||
method: DELETE
|
||||
mode: none
|
||||
params:path: {
|
||||
did:
|
||||
id:
|
||||
}
|
||||
}
|
||||
|
||||
response: {
|
||||
headers: {
|
||||
Content-Type: application/json
|
||||
}
|
||||
|
||||
status: {
|
||||
code: 404
|
||||
text: Not Found
|
||||
}
|
||||
|
||||
body: {
|
||||
type: json
|
||||
content: '''
|
||||
{
|
||||
"error": ""
|
||||
}
|
||||
'''
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,115 @@
|
||||
meta {
|
||||
name: Delete every webhook subscription for the caller
|
||||
type: http
|
||||
seq: 3
|
||||
}
|
||||
|
||||
delete {
|
||||
url: {{baseUrl}}/:did/webhooks
|
||||
body: none
|
||||
auth: bearer
|
||||
}
|
||||
|
||||
params:path {
|
||||
did:
|
||||
}
|
||||
|
||||
auth:bearer {
|
||||
token: {{token}}
|
||||
}
|
||||
|
||||
example {
|
||||
name: 204 Response
|
||||
description: All subscriptions deleted.
|
||||
|
||||
request: {
|
||||
url: {{baseUrl}}/:did/webhooks
|
||||
method: DELETE
|
||||
mode: none
|
||||
params:path: {
|
||||
did:
|
||||
}
|
||||
}
|
||||
|
||||
response: {
|
||||
status: {
|
||||
code: 204
|
||||
text: No Content
|
||||
}
|
||||
|
||||
body: {
|
||||
type: text
|
||||
content: '''
|
||||
|
||||
'''
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
example {
|
||||
name: 401 Response
|
||||
description: Missing or invalid bearer token.
|
||||
|
||||
request: {
|
||||
url: {{baseUrl}}/:did/webhooks
|
||||
method: DELETE
|
||||
mode: none
|
||||
params:path: {
|
||||
did:
|
||||
}
|
||||
}
|
||||
|
||||
response: {
|
||||
headers: {
|
||||
Content-Type: application/json
|
||||
}
|
||||
|
||||
status: {
|
||||
code: 401
|
||||
text: Unauthorized
|
||||
}
|
||||
|
||||
body: {
|
||||
type: json
|
||||
content: '''
|
||||
{
|
||||
"error": ""
|
||||
}
|
||||
'''
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
example {
|
||||
name: 403 Response
|
||||
description: Token is valid but the caller is not authorized for this resource.
|
||||
|
||||
request: {
|
||||
url: {{baseUrl}}/:did/webhooks
|
||||
method: DELETE
|
||||
mode: none
|
||||
params:path: {
|
||||
did:
|
||||
}
|
||||
}
|
||||
|
||||
response: {
|
||||
headers: {
|
||||
Content-Type: application/json
|
||||
}
|
||||
|
||||
status: {
|
||||
code: 403
|
||||
text: Forbidden
|
||||
}
|
||||
|
||||
body: {
|
||||
type: json
|
||||
content: '''
|
||||
{
|
||||
"error": ""
|
||||
}
|
||||
'''
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,127 @@
|
||||
meta {
|
||||
name: List a DID's webhook subscriptions
|
||||
type: http
|
||||
seq: 1
|
||||
}
|
||||
|
||||
get {
|
||||
url: {{baseUrl}}/:did/webhooks
|
||||
body: none
|
||||
auth: bearer
|
||||
}
|
||||
|
||||
params:path {
|
||||
did: did:plc:4m3kouplb7s7xozjd3whinvl
|
||||
}
|
||||
|
||||
auth:bearer {
|
||||
token: {{token}}
|
||||
}
|
||||
|
||||
example {
|
||||
name: 200 Response
|
||||
description: All subscriptions owned by the caller.
|
||||
|
||||
request: {
|
||||
url: {{baseUrl}}/:did/webhooks
|
||||
method: GET
|
||||
mode: none
|
||||
params:path: {
|
||||
did:
|
||||
}
|
||||
}
|
||||
|
||||
response: {
|
||||
headers: {
|
||||
Content-Type: application/json
|
||||
}
|
||||
|
||||
status: {
|
||||
code: 200
|
||||
text: OK
|
||||
}
|
||||
|
||||
body: {
|
||||
type: json
|
||||
content: '''
|
||||
[
|
||||
{
|
||||
"id": 0,
|
||||
"did": "",
|
||||
"method": "",
|
||||
"url": "",
|
||||
"verb": ""
|
||||
}
|
||||
]
|
||||
'''
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
example {
|
||||
name: 401 Response
|
||||
description: Missing or invalid bearer token.
|
||||
|
||||
request: {
|
||||
url: {{baseUrl}}/:did/webhooks
|
||||
method: GET
|
||||
mode: none
|
||||
params:path: {
|
||||
did:
|
||||
}
|
||||
}
|
||||
|
||||
response: {
|
||||
headers: {
|
||||
Content-Type: application/json
|
||||
}
|
||||
|
||||
status: {
|
||||
code: 401
|
||||
text: Unauthorized
|
||||
}
|
||||
|
||||
body: {
|
||||
type: json
|
||||
content: '''
|
||||
{
|
||||
"error": ""
|
||||
}
|
||||
'''
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
example {
|
||||
name: 403 Response
|
||||
description: Token is valid but the caller is not authorized for this resource.
|
||||
|
||||
request: {
|
||||
url: {{baseUrl}}/:did/webhooks
|
||||
method: GET
|
||||
mode: none
|
||||
params:path: {
|
||||
did:
|
||||
}
|
||||
}
|
||||
|
||||
response: {
|
||||
headers: {
|
||||
Content-Type: application/json
|
||||
}
|
||||
|
||||
status: {
|
||||
code: 403
|
||||
text: Forbidden
|
||||
}
|
||||
|
||||
body: {
|
||||
type: json
|
||||
content: '''
|
||||
{
|
||||
"error": ""
|
||||
}
|
||||
'''
|
||||
}
|
||||
}
|
||||
}
|
||||
7
docs/Remanso Jetstream API/webhooks/folder.bru
Normal file
7
docs/Remanso Jetstream API/webhooks/folder.bru
Normal file
@@ -0,0 +1,7 @@
|
||||
meta {
|
||||
name: webhooks
|
||||
}
|
||||
|
||||
auth {
|
||||
mode: inherit
|
||||
}
|
||||
@@ -1,3 +1,4 @@
|
||||
import type { API } from "@opensearch-project/opensearch";
|
||||
import { log } from "../log.ts";
|
||||
|
||||
const OPENSEARCH_URL = Deno.env.get("OPENSEARCH_URL");
|
||||
@@ -185,7 +186,9 @@ export const searchNotes = async (
|
||||
filters.push({ term: { did: opts.did } });
|
||||
}
|
||||
|
||||
const body: Record<string, unknown> = {
|
||||
const searchAfter = opts.cursor ? decodeCursor(opts.cursor) : undefined;
|
||||
|
||||
const body: API.Search_RequestBody = {
|
||||
size: limit,
|
||||
query: {
|
||||
bool: {
|
||||
@@ -207,20 +210,15 @@ export const searchNotes = async (
|
||||
fragment_size: 200,
|
||||
number_of_fragments: 1,
|
||||
boundary_scanner: "sentence",
|
||||
boundary_scanner_locale: "en-US",
|
||||
},
|
||||
title: { number_of_fragments: 0 },
|
||||
},
|
||||
},
|
||||
sort: [{ _score: "desc" }, { rkey: "desc" }],
|
||||
_source: ["did", "rkey", "title", "content", "publishedAt"],
|
||||
...(searchAfter ? { search_after: searchAfter } : {}),
|
||||
};
|
||||
|
||||
if (opts.cursor) {
|
||||
const decoded = decodeCursor(opts.cursor);
|
||||
if (decoded) body.search_after = decoded;
|
||||
}
|
||||
|
||||
const res = await request("POST", `/${OPENSEARCH_INDEX}/_search`, body);
|
||||
if (!res.ok) {
|
||||
const text = await res.text();
|
||||
|
||||
Reference in New Issue
Block a user