tangled
alpha
login
or
join now
vielle.dev
/
atcities.dev
8
fork
atom
[WIP] A (somewhat barebones) atproto app for creating custom sites without hosting!
8
fork
atom
overview
issues
pulls
pipelines
server: resolve route to record in src/user.ts
vielle.dev
5 months ago
f9e651b7
7140766b
+82
-2
1 changed file
expand all
collapse all
unified
split
src
user.ts
+82
-2
src/user.ts
···
1
1
+
/// <reference types="@atcute/atproto" />
2
2
+
import { Client, simpleFetchHandler } from "@atcute/client";
3
3
+
import { is } from "@atcute/lexicons";
1
4
import {
2
5
CompositeHandleResolver,
3
6
DohJsonHandleResolver,
···
6
9
PlcDidDocumentResolver,
7
10
WebDidDocumentResolver,
8
11
} from "@atcute/identity-resolver";
12
12
+
import { DevAtcitiesRoute } from "./lexicons/index.ts";
9
13
10
14
const handleResolver = new CompositeHandleResolver({
11
15
strategy: "race",
···
110
114
pds: string,
111
115
route: string
112
116
): Promise<Response> {
113
113
-
return new Response("404 NOT FOUND: " + route, {
114
114
-
status: 404,
117
117
+
// if the url ends in `/` (and isnt the root), perma redirect to unslashed version
118
118
+
// rationale: /dvd/ is the folder dvd, /index.html/ looks Weird
119
119
+
// atcities.dev won't do folder listings (in v0.1 at least) because that requires finding EVERY rkey
120
120
+
121
121
+
if (route !== "/" && route.endsWith("/"))
122
122
+
return new Response(undefined, {
123
123
+
status: 308,
124
124
+
statusText: "Permanent Redirect",
125
125
+
headers: {
126
126
+
Location: route.slice(0, -1),
127
127
+
},
128
128
+
});
129
129
+
130
130
+
// get client to pds
131
131
+
const client = new Client({
132
132
+
handler: simpleFetchHandler({ service: pds }),
115
133
});
134
134
+
135
135
+
try {
136
136
+
// note: / urls are reserved for special routes (404)
137
137
+
// any path should be prefixed with a /
138
138
+
// this is not enforced here so that this function can be used for special routes
139
139
+
const targetRkey = urlToRkey(route);
140
140
+
console.log("trying:", targetRkey, "for", route);
141
141
+
142
142
+
if (!targetRkey) throw "invalid url";
143
143
+
144
144
+
const { ok, data } = await client.get("com.atproto.repo.getRecord", {
145
145
+
params: {
146
146
+
collection: "dev.atcities.route",
147
147
+
repo: did,
148
148
+
rkey: targetRkey,
149
149
+
},
150
150
+
});
151
151
+
152
152
+
if (!ok) {
153
153
+
switch (data.error) {
154
154
+
case "InvalidRequest":
155
155
+
case "ExpiredToken":
156
156
+
case "InvalidToken": {
157
157
+
// tokens arent used and the request should be structured fine
158
158
+
// this is an unexpected error so its fine to 500 exit
159
159
+
throw "Internal Error";
160
160
+
}
161
161
+
case "RecordNotFound": {
162
162
+
// 404 error so try load 404 page
163
163
+
if (route !== "404") {
164
164
+
const r404 = await getRoute(did, pds, "404");
165
165
+
return new Response(r404.body, {
166
166
+
status: 404,
167
167
+
statusText: "Not Found",
168
168
+
headers: r404.headers,
169
169
+
});
170
170
+
}
171
171
+
return new Response("Could not find page.", {
172
172
+
status: 404,
173
173
+
statusText: "Not Found",
174
174
+
});
175
175
+
}
176
176
+
default:
177
177
+
throw "Unhandled exception";
178
178
+
}
179
179
+
}
180
180
+
181
181
+
if (!is(DevAtcitiesRoute.mainSchema, data.value))
182
182
+
return new Response(
183
183
+
"Malformed record for at://" + did + "/dev.atcities.route/" + targetRkey
184
184
+
);
185
185
+
186
186
+
return new Response("Loading " + targetRkey, {
187
187
+
status: 404,
188
188
+
statusText: "Not Found",
189
189
+
});
190
190
+
} catch (e) {
191
191
+
console.error(e);
192
192
+
return new Response("Something went wrong loading this route", {
193
193
+
status: 500,
194
194
+
});
195
195
+
}
116
196
}
117
197
118
198
export default async function (