+51
README.md
+51
README.md
···
1
+
# atcities.dev
2
+
3
+
A (somewhat barebones) atproto app for creating custom sites without hosting!
4
+
5
+
> [!CAUTION]
6
+
> This software is super duper alpha and not tested thoroughly! Use at your own risk!
7
+
8
+
- Lexicons are located at [`./lexicons`](./lexicons/)
9
+
- Server backend is located at [`./server`](./server/)
10
+
- Upload CLI is located at [`./upload`](./upload/)
11
+
- Web GUI **will be** located at [`./web-gui`](./web-gui/)
12
+
- Fuse tool **will be** located at [`./fuse`](./fuse/)
13
+
14
+
## How to:
15
+
16
+
**View someones site?**
17
+
> Head to `https://<handle>.atcities.dev/` or `https://<did>.did-<method>.atcities.dev/`.
18
+
19
+
**Upload your own site?**
20
+
> Use the upload cli. Installation guide below.
21
+
22
+
**Self host atcities.dev?**
23
+
> Clone this repo and setup the `.env` file for `/server`, then run `deno run run`
24
+
25
+
### CLI installation guide.
26
+
27
+
1. Build from source:
28
+
Prerequisites: `git` `cargo` `rust`
29
+
```sh
30
+
git clone https://tangled.org/@vielle.dev/atcities.dev
31
+
cd atcities.dev/upload
32
+
cargo build
33
+
sudo cp ./target/debug/atcities-upload /bin
34
+
# Reload your shell environment
35
+
atcities-upload --version
36
+
```
37
+
38
+
## Todo:
39
+
40
+
- [x] Resolve `handle.host` and `did.did-method.host` domains to records/blobs
41
+
- [x] Backfill network
42
+
- [x] Store did+route -> blob & mime type in database
43
+
- [x] Store blobs for CDN (max ~0.25gb per user)
44
+
- [x] Moderate illegal content or hope that people are niceys
45
+
(Hope that people are niceys)
46
+
- [x] Finish CLI tool
47
+
- [x] Sign in via app password
48
+
- [x] Clear old site
49
+
- [x] Upload new site
50
+
- [ ] Fuse uploader
51
+
- [ ] Web GUI uploader
+33
lexicons/dev.atcities.route.json
+33
lexicons/dev.atcities.route.json
···
1
+
{
2
+
"lexicon": 1,
3
+
"id": "dev.atcities.route",
4
+
"description": "Define the route for a given page. Page content is a blob",
5
+
"defs": {
6
+
"main": {
7
+
"type": "record",
8
+
"description": "Page URL maps directly to a record key",
9
+
"key": "any",
10
+
"record": {
11
+
"type": "object",
12
+
"properties": {
13
+
"page": {
14
+
"type": "union",
15
+
"refs": ["#blob"]
16
+
}
17
+
},
18
+
"required": ["page"]
19
+
}
20
+
},
21
+
22
+
"blob": {
23
+
"type": "object",
24
+
"properties": {
25
+
"blob": {
26
+
"type": "blob",
27
+
"accept": ["*/*"]
28
+
}
29
+
},
30
+
"required": ["blob"]
31
+
}
32
+
}
33
+
}
+4
-1
server/.env.template
+4
-1
server/.env.template
+9
-3
server/deno.json
+9
-3
server/deno.json
···
1
1
{
2
2
"tasks": {
3
-
"dev": "PORT=8000 deno run --watch --allow-net --allow-env=HOSTNAME,PORT,NODE_ENV --env-file src/index.ts",
4
-
"lexgen": "deno run --allow-env --allow-sys --allow-read=. --allow-write=./src/lexicons --no-prompt @atcute/lex-cli generate -c ./lex.config.js && cat ./src/lexicons/index.ts | sed \"s/.js/.ts/\" > ./src/lexicons/index.ts"
3
+
"dev": "deno run --watch --allow-net --allow-env --allow-sys --allow-read=/usr/bin/ldd,./blobs,./src --allow-write=./blobs --allow-ffi --env-file src/index.ts",
4
+
"run": "deno run --allow-net --allow-env --allow-sys --allow-read=/usr/bin/ldd,./blobs,./src --allow-write=./blobs --allow-ffi --env-file src/index.ts",
5
+
"lexgen": "deno run --allow-env --allow-sys --allow-read=.. --allow-write=./src/lexicons --no-prompt @atcute/lex-cli generate -c ./lex.config.js && cat ./src/lexicons/index.ts | sed \"s/.js/.ts/\" > ./src/lexicons/index.ts",
6
+
"dk": "deno run -A --node-modules-dir npm:drizzle-kit"
5
7
},
6
8
"imports": {
9
+
"@atcute/cbor": "npm:@atcute/cbor@^2.2.6",
7
10
"@atcute/identity-resolver": "npm:@atcute/identity-resolver@^1.1.3",
8
11
"@atcute/atproto": "npm:@atcute/atproto@^3.1.4",
9
12
"@atcute/client": "npm:@atcute/client@^4.0.3",
10
13
"@atcute/lex-cli": "npm:@atcute/lex-cli@^2.2.0",
11
14
"@atcute/lexicons": "npm:@atcute/lexicons@^1.1.1",
12
-
"@libsql/client": "npm:@libsql/client@^0.15.15"
15
+
"@atproto-labs/fetch-node": "npm:@atproto-labs/fetch-node@^0.1.10",
16
+
"@libsql/client": "npm:@libsql/client@^0.15.15",
17
+
"drizzle-kit": "npm:drizzle-kit@^0.31.5",
18
+
"drizzle-orm": "npm:drizzle-orm@^0.44.6"
13
19
},
14
20
"unstable": ["raw-imports"]
15
21
}
+437
-2
server/deno.lock
+437
-2
server/deno.lock
···
2
2
"version": "5",
3
3
"specifiers": {
4
4
"npm:@atcute/atproto@^3.1.4": "3.1.4",
5
+
"npm:@atcute/cbor@^2.2.6": "2.2.6",
5
6
"npm:@atcute/client@^4.0.3": "4.0.3",
6
7
"npm:@atcute/identity-resolver@^1.1.3": "1.1.3_@atcute+identity@1.1.0",
7
8
"npm:@atcute/lex-cli@^2.2.0": "2.2.0_@badrap+valita@0.4.6",
8
9
"npm:@atcute/lexicons@^1.1.1": "1.1.1",
9
-
"npm:@libsql/client@~0.15.15": "0.15.15"
10
+
"npm:@atproto-labs/fetch-node@~0.1.10": "0.1.10",
11
+
"npm:@libsql/client@~0.15.15": "0.15.15",
12
+
"npm:drizzle-kit@*": "0.31.5_esbuild@0.25.10",
13
+
"npm:drizzle-kit@~0.31.5": "0.31.5_esbuild@0.25.10",
14
+
"npm:drizzle-orm@~0.44.6": "0.44.6_@libsql+client@0.15.15"
10
15
},
11
16
"npm": {
12
17
"@atcute/atproto@3.1.4": {
13
18
"integrity": "sha512-v0/ue7mZYtjYw4vWbtda51bLwW88mqsUQB8F/UZNO18ANAQWmKq1HDceVqjvruaLe2QPqE43XM3WkEyZ2FhOrA==",
14
19
"dependencies": [
15
20
"@atcute/lexicons"
21
+
]
22
+
},
23
+
"@atcute/cbor@2.2.6": {
24
+
"integrity": "sha512-pDfsn/vPTmgeXZiZdyc5vCGCPSxWlfTUIGFMCd5SroAgoLk1v9xxF7R/8+gt1lj1OKAwCwhS0doVmtLjqqzdbA==",
25
+
"dependencies": [
26
+
"@atcute/cid",
27
+
"@atcute/multibase",
28
+
"@atcute/uint8array"
29
+
]
30
+
},
31
+
"@atcute/cid@2.2.4": {
32
+
"integrity": "sha512-6RUMyt7rp6KOSb4TWwifOZURnFrGgKqYyjVkYjiAcscZWgJpJxwoCUCdonxCfxhQtB0yJ+WlfqNXicGB+Pe94A==",
33
+
"dependencies": [
34
+
"@atcute/multibase",
35
+
"@atcute/uint8array"
16
36
]
17
37
},
18
38
"@atcute/client@4.0.3": {
···
61
81
"esm-env"
62
82
]
63
83
},
84
+
"@atcute/multibase@1.1.6": {
85
+
"integrity": "sha512-HBxuCgYLKPPxETV0Rot4VP9e24vKl8JdzGCZOVsDaOXJgbRZoRIF67Lp0H/OgnJeH/Xpva8Z5ReoTNJE5dn3kg==",
86
+
"dependencies": [
87
+
"@atcute/uint8array"
88
+
]
89
+
},
90
+
"@atcute/uint8array@1.0.5": {
91
+
"integrity": "sha512-XLWWxoR2HNl2qU+FCr0rp1APwJXci7HnzbOQLxK55OaMNBXZ19+xNC5ii4QCsThsDxa4JS/JTzuiQLziITWf2Q=="
92
+
},
64
93
"@atcute/util-fetch@1.0.1": {
65
94
"integrity": "sha512-Clc0E/5ufyGBVfYBUwWNlHONlZCoblSr4Ho50l1LhmRPGB1Wu/AQ9Sz+rsBg7fdaW/auve8ulmwhRhnX2cGRow==",
66
95
"dependencies": [
67
96
"@badrap/valita"
68
97
]
69
98
},
99
+
"@atproto-labs/fetch-node@0.1.10": {
100
+
"integrity": "sha512-o7hGaonA71A6p7O107VhM6UBUN/g9tTyYohMp1q0Kf6xQ4npnuZYRSHSf2g6reSfGQJ1GoFNjBObETTT1ge/jQ==",
101
+
"dependencies": [
102
+
"@atproto-labs/fetch",
103
+
"@atproto-labs/pipe",
104
+
"ipaddr.js",
105
+
"undici"
106
+
]
107
+
},
108
+
"@atproto-labs/fetch@0.2.3": {
109
+
"integrity": "sha512-NZtbJOCbxKUFRFKMpamT38PUQMY0hX0p7TG5AEYOPhZKZEP7dHZ1K2s1aB8MdVH0qxmqX7nQleNrrvLf09Zfdw==",
110
+
"dependencies": [
111
+
"@atproto-labs/pipe"
112
+
]
113
+
},
114
+
"@atproto-labs/pipe@0.1.1": {
115
+
"integrity": "sha512-hdNw2oUs2B6BN1lp+32pF7cp8EMKuIN5Qok2Vvv/aOpG/3tNSJ9YkvfI0k6Zd188LeDDYRUpYpxcoFIcGH/FNg=="
116
+
},
70
117
"@badrap/valita@0.4.6": {
71
118
"integrity": "sha512-4kdqcjyxo/8RQ8ayjms47HCWZIF5981oE5nIenbfThKDxWXtEHKipAOWlflpPJzZx9y/JWYQkp18Awr7VuepFg=="
72
119
},
120
+
"@drizzle-team/brocli@0.10.2": {
121
+
"integrity": "sha512-z33Il7l5dKjUgGULTqBsQBQwckHh5AbIuxhdsIxDDiZAzBOrZO6q9ogcWC65kU382AfynTfgNumVcNIjuIua6w=="
122
+
},
123
+
"@esbuild-kit/core-utils@3.3.2": {
124
+
"integrity": "sha512-sPRAnw9CdSsRmEtnsl2WXWdyquogVpB3yZ3dgwJfe8zrOzTsV7cJvmwrKVa+0ma5BoiGJ+BoqkMvawbayKUsqQ==",
125
+
"dependencies": [
126
+
"esbuild@0.18.20",
127
+
"source-map-support"
128
+
],
129
+
"deprecated": true
130
+
},
131
+
"@esbuild-kit/esm-loader@2.6.5": {
132
+
"integrity": "sha512-FxEMIkJKnodyA1OaCUoEvbYRkoZlLZ4d/eXFu9Fh8CbBBgP5EmZxrfTRyN0qpXZ4vOvqnE5YdRdcrmUUXuU+dA==",
133
+
"dependencies": [
134
+
"@esbuild-kit/core-utils",
135
+
"get-tsconfig"
136
+
],
137
+
"deprecated": true
138
+
},
139
+
"@esbuild/aix-ppc64@0.25.10": {
140
+
"integrity": "sha512-0NFWnA+7l41irNuaSVlLfgNT12caWJVLzp5eAVhZ0z1qpxbockccEt3s+149rE64VUI3Ml2zt8Nv5JVc4QXTsw==",
141
+
"os": ["aix"],
142
+
"cpu": ["ppc64"]
143
+
},
144
+
"@esbuild/android-arm64@0.18.20": {
145
+
"integrity": "sha512-Nz4rJcchGDtENV0eMKUNa6L12zz2zBDXuhj/Vjh18zGqB44Bi7MBMSXjgunJgjRhCmKOjnPuZp4Mb6OKqtMHLQ==",
146
+
"os": ["android"],
147
+
"cpu": ["arm64"]
148
+
},
149
+
"@esbuild/android-arm64@0.25.10": {
150
+
"integrity": "sha512-LSQa7eDahypv/VO6WKohZGPSJDq5OVOo3UoFR1E4t4Gj1W7zEQMUhI+lo81H+DtB+kP+tDgBp+M4oNCwp6kffg==",
151
+
"os": ["android"],
152
+
"cpu": ["arm64"]
153
+
},
154
+
"@esbuild/android-arm@0.18.20": {
155
+
"integrity": "sha512-fyi7TDI/ijKKNZTUJAQqiG5T7YjJXgnzkURqmGj13C6dCqckZBLdl4h7bkhHt/t0WP+zO9/zwroDvANaOqO5Sw==",
156
+
"os": ["android"],
157
+
"cpu": ["arm"]
158
+
},
159
+
"@esbuild/android-arm@0.25.10": {
160
+
"integrity": "sha512-dQAxF1dW1C3zpeCDc5KqIYuZ1tgAdRXNoZP7vkBIRtKZPYe2xVr/d3SkirklCHudW1B45tGiUlz2pUWDfbDD4w==",
161
+
"os": ["android"],
162
+
"cpu": ["arm"]
163
+
},
164
+
"@esbuild/android-x64@0.18.20": {
165
+
"integrity": "sha512-8GDdlePJA8D6zlZYJV/jnrRAi6rOiNaCC/JclcXpB+KIuvfBN4owLtgzY2bsxnx666XjJx2kDPUmnTtR8qKQUg==",
166
+
"os": ["android"],
167
+
"cpu": ["x64"]
168
+
},
169
+
"@esbuild/android-x64@0.25.10": {
170
+
"integrity": "sha512-MiC9CWdPrfhibcXwr39p9ha1x0lZJ9KaVfvzA0Wxwz9ETX4v5CHfF09bx935nHlhi+MxhA63dKRRQLiVgSUtEg==",
171
+
"os": ["android"],
172
+
"cpu": ["x64"]
173
+
},
174
+
"@esbuild/darwin-arm64@0.18.20": {
175
+
"integrity": "sha512-bxRHW5kHU38zS2lPTPOyuyTm+S+eobPUnTNkdJEfAddYgEcll4xkT8DB9d2008DtTbl7uJag2HuE5NZAZgnNEA==",
176
+
"os": ["darwin"],
177
+
"cpu": ["arm64"]
178
+
},
179
+
"@esbuild/darwin-arm64@0.25.10": {
180
+
"integrity": "sha512-JC74bdXcQEpW9KkV326WpZZjLguSZ3DfS8wrrvPMHgQOIEIG/sPXEN/V8IssoJhbefLRcRqw6RQH2NnpdprtMA==",
181
+
"os": ["darwin"],
182
+
"cpu": ["arm64"]
183
+
},
184
+
"@esbuild/darwin-x64@0.18.20": {
185
+
"integrity": "sha512-pc5gxlMDxzm513qPGbCbDukOdsGtKhfxD1zJKXjCCcU7ju50O7MeAZ8c4krSJcOIJGFR+qx21yMMVYwiQvyTyQ==",
186
+
"os": ["darwin"],
187
+
"cpu": ["x64"]
188
+
},
189
+
"@esbuild/darwin-x64@0.25.10": {
190
+
"integrity": "sha512-tguWg1olF6DGqzws97pKZ8G2L7Ig1vjDmGTwcTuYHbuU6TTjJe5FXbgs5C1BBzHbJ2bo1m3WkQDbWO2PvamRcg==",
191
+
"os": ["darwin"],
192
+
"cpu": ["x64"]
193
+
},
194
+
"@esbuild/freebsd-arm64@0.18.20": {
195
+
"integrity": "sha512-yqDQHy4QHevpMAaxhhIwYPMv1NECwOvIpGCZkECn8w2WFHXjEwrBn3CeNIYsibZ/iZEUemj++M26W3cNR5h+Tw==",
196
+
"os": ["freebsd"],
197
+
"cpu": ["arm64"]
198
+
},
199
+
"@esbuild/freebsd-arm64@0.25.10": {
200
+
"integrity": "sha512-3ZioSQSg1HT2N05YxeJWYR+Libe3bREVSdWhEEgExWaDtyFbbXWb49QgPvFH8u03vUPX10JhJPcz7s9t9+boWg==",
201
+
"os": ["freebsd"],
202
+
"cpu": ["arm64"]
203
+
},
204
+
"@esbuild/freebsd-x64@0.18.20": {
205
+
"integrity": "sha512-tgWRPPuQsd3RmBZwarGVHZQvtzfEBOreNuxEMKFcd5DaDn2PbBxfwLcj4+aenoh7ctXcbXmOQIn8HI6mCSw5MQ==",
206
+
"os": ["freebsd"],
207
+
"cpu": ["x64"]
208
+
},
209
+
"@esbuild/freebsd-x64@0.25.10": {
210
+
"integrity": "sha512-LLgJfHJk014Aa4anGDbh8bmI5Lk+QidDmGzuC2D+vP7mv/GeSN+H39zOf7pN5N8p059FcOfs2bVlrRr4SK9WxA==",
211
+
"os": ["freebsd"],
212
+
"cpu": ["x64"]
213
+
},
214
+
"@esbuild/linux-arm64@0.18.20": {
215
+
"integrity": "sha512-2YbscF+UL7SQAVIpnWvYwM+3LskyDmPhe31pE7/aoTMFKKzIc9lLbyGUpmmb8a8AixOL61sQ/mFh3jEjHYFvdA==",
216
+
"os": ["linux"],
217
+
"cpu": ["arm64"]
218
+
},
219
+
"@esbuild/linux-arm64@0.25.10": {
220
+
"integrity": "sha512-5luJWN6YKBsawd5f9i4+c+geYiVEw20FVW5x0v1kEMWNq8UctFjDiMATBxLvmmHA4bf7F6hTRaJgtghFr9iziQ==",
221
+
"os": ["linux"],
222
+
"cpu": ["arm64"]
223
+
},
224
+
"@esbuild/linux-arm@0.18.20": {
225
+
"integrity": "sha512-/5bHkMWnq1EgKr1V+Ybz3s1hWXok7mDFUMQ4cG10AfW3wL02PSZi5kFpYKrptDsgb2WAJIvRcDm+qIvXf/apvg==",
226
+
"os": ["linux"],
227
+
"cpu": ["arm"]
228
+
},
229
+
"@esbuild/linux-arm@0.25.10": {
230
+
"integrity": "sha512-oR31GtBTFYCqEBALI9r6WxoU/ZofZl962pouZRTEYECvNF/dtXKku8YXcJkhgK/beU+zedXfIzHijSRapJY3vg==",
231
+
"os": ["linux"],
232
+
"cpu": ["arm"]
233
+
},
234
+
"@esbuild/linux-ia32@0.18.20": {
235
+
"integrity": "sha512-P4etWwq6IsReT0E1KHU40bOnzMHoH73aXp96Fs8TIT6z9Hu8G6+0SHSw9i2isWrD2nbx2qo5yUqACgdfVGx7TA==",
236
+
"os": ["linux"],
237
+
"cpu": ["ia32"]
238
+
},
239
+
"@esbuild/linux-ia32@0.25.10": {
240
+
"integrity": "sha512-NrSCx2Kim3EnnWgS4Txn0QGt0Xipoumb6z6sUtl5bOEZIVKhzfyp/Lyw4C1DIYvzeW/5mWYPBFJU3a/8Yr75DQ==",
241
+
"os": ["linux"],
242
+
"cpu": ["ia32"]
243
+
},
244
+
"@esbuild/linux-loong64@0.18.20": {
245
+
"integrity": "sha512-nXW8nqBTrOpDLPgPY9uV+/1DjxoQ7DoB2N8eocyq8I9XuqJ7BiAMDMf9n1xZM9TgW0J8zrquIb/A7s3BJv7rjg==",
246
+
"os": ["linux"],
247
+
"cpu": ["loong64"]
248
+
},
249
+
"@esbuild/linux-loong64@0.25.10": {
250
+
"integrity": "sha512-xoSphrd4AZda8+rUDDfD9J6FUMjrkTz8itpTITM4/xgerAZZcFW7Dv+sun7333IfKxGG8gAq+3NbfEMJfiY+Eg==",
251
+
"os": ["linux"],
252
+
"cpu": ["loong64"]
253
+
},
254
+
"@esbuild/linux-mips64el@0.18.20": {
255
+
"integrity": "sha512-d5NeaXZcHp8PzYy5VnXV3VSd2D328Zb+9dEq5HE6bw6+N86JVPExrA6O68OPwobntbNJ0pzCpUFZTo3w0GyetQ==",
256
+
"os": ["linux"],
257
+
"cpu": ["mips64el"]
258
+
},
259
+
"@esbuild/linux-mips64el@0.25.10": {
260
+
"integrity": "sha512-ab6eiuCwoMmYDyTnyptoKkVS3k8fy/1Uvq7Dj5czXI6DF2GqD2ToInBI0SHOp5/X1BdZ26RKc5+qjQNGRBelRA==",
261
+
"os": ["linux"],
262
+
"cpu": ["mips64el"]
263
+
},
264
+
"@esbuild/linux-ppc64@0.18.20": {
265
+
"integrity": "sha512-WHPyeScRNcmANnLQkq6AfyXRFr5D6N2sKgkFo2FqguP44Nw2eyDlbTdZwd9GYk98DZG9QItIiTlFLHJHjxP3FA==",
266
+
"os": ["linux"],
267
+
"cpu": ["ppc64"]
268
+
},
269
+
"@esbuild/linux-ppc64@0.25.10": {
270
+
"integrity": "sha512-NLinzzOgZQsGpsTkEbdJTCanwA5/wozN9dSgEl12haXJBzMTpssebuXR42bthOF3z7zXFWH1AmvWunUCkBE4EA==",
271
+
"os": ["linux"],
272
+
"cpu": ["ppc64"]
273
+
},
274
+
"@esbuild/linux-riscv64@0.18.20": {
275
+
"integrity": "sha512-WSxo6h5ecI5XH34KC7w5veNnKkju3zBRLEQNY7mv5mtBmrP/MjNBCAlsM2u5hDBlS3NGcTQpoBvRzqBcRtpq1A==",
276
+
"os": ["linux"],
277
+
"cpu": ["riscv64"]
278
+
},
279
+
"@esbuild/linux-riscv64@0.25.10": {
280
+
"integrity": "sha512-FE557XdZDrtX8NMIeA8LBJX3dC2M8VGXwfrQWU7LB5SLOajfJIxmSdyL/gU1m64Zs9CBKvm4UAuBp5aJ8OgnrA==",
281
+
"os": ["linux"],
282
+
"cpu": ["riscv64"]
283
+
},
284
+
"@esbuild/linux-s390x@0.18.20": {
285
+
"integrity": "sha512-+8231GMs3mAEth6Ja1iK0a1sQ3ohfcpzpRLH8uuc5/KVDFneH6jtAJLFGafpzpMRO6DzJ6AvXKze9LfFMrIHVQ==",
286
+
"os": ["linux"],
287
+
"cpu": ["s390x"]
288
+
},
289
+
"@esbuild/linux-s390x@0.25.10": {
290
+
"integrity": "sha512-3BBSbgzuB9ajLoVZk0mGu+EHlBwkusRmeNYdqmznmMc9zGASFjSsxgkNsqmXugpPk00gJ0JNKh/97nxmjctdew==",
291
+
"os": ["linux"],
292
+
"cpu": ["s390x"]
293
+
},
294
+
"@esbuild/linux-x64@0.18.20": {
295
+
"integrity": "sha512-UYqiqemphJcNsFEskc73jQ7B9jgwjWrSayxawS6UVFZGWrAAtkzjxSqnoclCXxWtfwLdzU+vTpcNYhpn43uP1w==",
296
+
"os": ["linux"],
297
+
"cpu": ["x64"]
298
+
},
299
+
"@esbuild/linux-x64@0.25.10": {
300
+
"integrity": "sha512-QSX81KhFoZGwenVyPoberggdW1nrQZSvfVDAIUXr3WqLRZGZqWk/P4T8p2SP+de2Sr5HPcvjhcJzEiulKgnxtA==",
301
+
"os": ["linux"],
302
+
"cpu": ["x64"]
303
+
},
304
+
"@esbuild/netbsd-arm64@0.25.10": {
305
+
"integrity": "sha512-AKQM3gfYfSW8XRk8DdMCzaLUFB15dTrZfnX8WXQoOUpUBQ+NaAFCP1kPS/ykbbGYz7rxn0WS48/81l9hFl3u4A==",
306
+
"os": ["netbsd"],
307
+
"cpu": ["arm64"]
308
+
},
309
+
"@esbuild/netbsd-x64@0.18.20": {
310
+
"integrity": "sha512-iO1c++VP6xUBUmltHZoMtCUdPlnPGdBom6IrO4gyKPFFVBKioIImVooR5I83nTew5UOYrk3gIJhbZh8X44y06A==",
311
+
"os": ["netbsd"],
312
+
"cpu": ["x64"]
313
+
},
314
+
"@esbuild/netbsd-x64@0.25.10": {
315
+
"integrity": "sha512-7RTytDPGU6fek/hWuN9qQpeGPBZFfB4zZgcz2VK2Z5VpdUxEI8JKYsg3JfO0n/Z1E/6l05n0unDCNc4HnhQGig==",
316
+
"os": ["netbsd"],
317
+
"cpu": ["x64"]
318
+
},
319
+
"@esbuild/openbsd-arm64@0.25.10": {
320
+
"integrity": "sha512-5Se0VM9Wtq797YFn+dLimf2Zx6McttsH2olUBsDml+lm0GOCRVebRWUvDtkY4BWYv/3NgzS8b/UM3jQNh5hYyw==",
321
+
"os": ["openbsd"],
322
+
"cpu": ["arm64"]
323
+
},
324
+
"@esbuild/openbsd-x64@0.18.20": {
325
+
"integrity": "sha512-e5e4YSsuQfX4cxcygw/UCPIEP6wbIL+se3sxPdCiMbFLBWu0eiZOJ7WoD+ptCLrmjZBK1Wk7I6D/I3NglUGOxg==",
326
+
"os": ["openbsd"],
327
+
"cpu": ["x64"]
328
+
},
329
+
"@esbuild/openbsd-x64@0.25.10": {
330
+
"integrity": "sha512-XkA4frq1TLj4bEMB+2HnI0+4RnjbuGZfet2gs/LNs5Hc7D89ZQBHQ0gL2ND6Lzu1+QVkjp3x1gIcPKzRNP8bXw==",
331
+
"os": ["openbsd"],
332
+
"cpu": ["x64"]
333
+
},
334
+
"@esbuild/openharmony-arm64@0.25.10": {
335
+
"integrity": "sha512-AVTSBhTX8Y/Fz6OmIVBip9tJzZEUcY8WLh7I59+upa5/GPhh2/aM6bvOMQySspnCCHvFi79kMtdJS1w0DXAeag==",
336
+
"os": ["openharmony"],
337
+
"cpu": ["arm64"]
338
+
},
339
+
"@esbuild/sunos-x64@0.18.20": {
340
+
"integrity": "sha512-kDbFRFp0YpTQVVrqUd5FTYmWo45zGaXe0X8E1G/LKFC0v8x0vWrhOWSLITcCn63lmZIxfOMXtCfti/RxN/0wnQ==",
341
+
"os": ["sunos"],
342
+
"cpu": ["x64"]
343
+
},
344
+
"@esbuild/sunos-x64@0.25.10": {
345
+
"integrity": "sha512-fswk3XT0Uf2pGJmOpDB7yknqhVkJQkAQOcW/ccVOtfx05LkbWOaRAtn5SaqXypeKQra1QaEa841PgrSL9ubSPQ==",
346
+
"os": ["sunos"],
347
+
"cpu": ["x64"]
348
+
},
349
+
"@esbuild/win32-arm64@0.18.20": {
350
+
"integrity": "sha512-ddYFR6ItYgoaq4v4JmQQaAI5s7npztfV4Ag6NrhiaW0RrnOXqBkgwZLofVTlq1daVTQNhtI5oieTvkRPfZrePg==",
351
+
"os": ["win32"],
352
+
"cpu": ["arm64"]
353
+
},
354
+
"@esbuild/win32-arm64@0.25.10": {
355
+
"integrity": "sha512-ah+9b59KDTSfpaCg6VdJoOQvKjI33nTaQr4UluQwW7aEwZQsbMCfTmfEO4VyewOxx4RaDT/xCy9ra2GPWmO7Kw==",
356
+
"os": ["win32"],
357
+
"cpu": ["arm64"]
358
+
},
359
+
"@esbuild/win32-ia32@0.18.20": {
360
+
"integrity": "sha512-Wv7QBi3ID/rROT08SABTS7eV4hX26sVduqDOTe1MvGMjNd3EjOz4b7zeexIR62GTIEKrfJXKL9LFxTYgkyeu7g==",
361
+
"os": ["win32"],
362
+
"cpu": ["ia32"]
363
+
},
364
+
"@esbuild/win32-ia32@0.25.10": {
365
+
"integrity": "sha512-QHPDbKkrGO8/cz9LKVnJU22HOi4pxZnZhhA2HYHez5Pz4JeffhDjf85E57Oyco163GnzNCVkZK0b/n4Y0UHcSw==",
366
+
"os": ["win32"],
367
+
"cpu": ["ia32"]
368
+
},
369
+
"@esbuild/win32-x64@0.18.20": {
370
+
"integrity": "sha512-kTdfRcSiDfQca/y9QIkng02avJ+NCaQvrMejlsB3RRv5sE9rRoeBPISaZpKxHELzRxZyLvNts1P27W3wV+8geQ==",
371
+
"os": ["win32"],
372
+
"cpu": ["x64"]
373
+
},
374
+
"@esbuild/win32-x64@0.25.10": {
375
+
"integrity": "sha512-9KpxSVFCu0iK1owoez6aC/s/EdUQLDN3adTxGCqxMVhrPDj6bt5dbrHDXUuq+Bs2vATFBBrQS5vdQ/Ed2P+nbw==",
376
+
"os": ["win32"],
377
+
"cpu": ["x64"]
378
+
},
73
379
"@externdefs/collider@0.3.0_@badrap+valita@0.4.6": {
74
380
"integrity": "sha512-x5CpeZ4c8n+1wMFthUMWSQKqCGcQo52/Qbda5ES+JFRRg/D8Ep6/JOvUUq5HExFuv/wW+6UYG2U/mXzw0IAd8Q==",
75
381
"dependencies": [
···
171
477
"@types/node"
172
478
]
173
479
},
480
+
"buffer-from@1.1.2": {
481
+
"integrity": "sha512-E+XQCRwSbaaiChtv6k6Dwgc+bx+Bs6vuKJHHl5kox/BaKbhiXzqQOwK4cO22yElGp2OCmjwVhT3HmxgyPGnJfQ=="
482
+
},
174
483
"data-uri-to-buffer@4.0.1": {
175
484
"integrity": "sha512-0R9ikRb668HB7QDxT1vkpuUBtqc53YyAwMwGeUFKRojY/NWKvdZ+9UYtRfGmhqNbRkTSVpMbmyhXipFFv2cb/A=="
176
485
},
486
+
"debug@4.4.3": {
487
+
"integrity": "sha512-RGwwWnwQvkVfavKVt22FGLw+xYSdzARwm0ru6DhTVA3umU5hZc28V3kO4stgYryrTlLpuvgI9GiijltAjNbcqA==",
488
+
"dependencies": [
489
+
"ms"
490
+
]
491
+
},
177
492
"detect-libc@2.0.2": {
178
493
"integrity": "sha512-UX6sGumvvqSaXgdKGUsgZWqcUyIXZ/vZTrlRT/iobiKhGL0zL4d3osHj3uqllWJK+i+sixDS/3COVEOFbupFyw=="
179
494
},
495
+
"drizzle-kit@0.31.5_esbuild@0.25.10": {
496
+
"integrity": "sha512-+CHgPFzuoTQTt7cOYCV6MOw2w8vqEn/ap1yv4bpZOWL03u7rlVRQhUY0WYT3rHsgVTXwYQDZaSUJSQrMBUKuWg==",
497
+
"dependencies": [
498
+
"@drizzle-team/brocli",
499
+
"@esbuild-kit/esm-loader",
500
+
"esbuild@0.25.10",
501
+
"esbuild-register"
502
+
],
503
+
"bin": true
504
+
},
505
+
"drizzle-orm@0.44.6_@libsql+client@0.15.15": {
506
+
"integrity": "sha512-uy6uarrrEOc9K1u5/uhBFJbdF5VJ5xQ/Yzbecw3eAYOunv5FDeYkR2m8iitocdHBOHbvorviKOW5GVw0U1j4LQ==",
507
+
"dependencies": [
508
+
"@libsql/client"
509
+
],
510
+
"optionalPeers": [
511
+
"@libsql/client"
512
+
]
513
+
},
514
+
"esbuild-register@3.6.0_esbuild@0.25.10": {
515
+
"integrity": "sha512-H2/S7Pm8a9CL1uhp9OvjwrBh5Pvx0H8qVOxNu8Wed9Y7qv56MPtq+GGM8RJpq6glYJn9Wspr8uw7l55uyinNeg==",
516
+
"dependencies": [
517
+
"debug",
518
+
"esbuild@0.25.10"
519
+
]
520
+
},
521
+
"esbuild@0.18.20": {
522
+
"integrity": "sha512-ceqxoedUrcayh7Y7ZX6NdbbDzGROiyVBgC4PriJThBKSVPWnnFHZAkfI1lJT8QFkOwH4qOS2SJkS4wvpGl8BpA==",
523
+
"optionalDependencies": [
524
+
"@esbuild/android-arm@0.18.20",
525
+
"@esbuild/android-arm64@0.18.20",
526
+
"@esbuild/android-x64@0.18.20",
527
+
"@esbuild/darwin-arm64@0.18.20",
528
+
"@esbuild/darwin-x64@0.18.20",
529
+
"@esbuild/freebsd-arm64@0.18.20",
530
+
"@esbuild/freebsd-x64@0.18.20",
531
+
"@esbuild/linux-arm@0.18.20",
532
+
"@esbuild/linux-arm64@0.18.20",
533
+
"@esbuild/linux-ia32@0.18.20",
534
+
"@esbuild/linux-loong64@0.18.20",
535
+
"@esbuild/linux-mips64el@0.18.20",
536
+
"@esbuild/linux-ppc64@0.18.20",
537
+
"@esbuild/linux-riscv64@0.18.20",
538
+
"@esbuild/linux-s390x@0.18.20",
539
+
"@esbuild/linux-x64@0.18.20",
540
+
"@esbuild/netbsd-x64@0.18.20",
541
+
"@esbuild/openbsd-x64@0.18.20",
542
+
"@esbuild/sunos-x64@0.18.20",
543
+
"@esbuild/win32-arm64@0.18.20",
544
+
"@esbuild/win32-ia32@0.18.20",
545
+
"@esbuild/win32-x64@0.18.20"
546
+
],
547
+
"scripts": true,
548
+
"bin": true
549
+
},
550
+
"esbuild@0.25.10": {
551
+
"integrity": "sha512-9RiGKvCwaqxO2owP61uQ4BgNborAQskMR6QusfWzQqv7AZOg5oGehdY2pRJMTKuwxd1IDBP4rSbI5lHzU7SMsQ==",
552
+
"optionalDependencies": [
553
+
"@esbuild/aix-ppc64",
554
+
"@esbuild/android-arm@0.25.10",
555
+
"@esbuild/android-arm64@0.25.10",
556
+
"@esbuild/android-x64@0.25.10",
557
+
"@esbuild/darwin-arm64@0.25.10",
558
+
"@esbuild/darwin-x64@0.25.10",
559
+
"@esbuild/freebsd-arm64@0.25.10",
560
+
"@esbuild/freebsd-x64@0.25.10",
561
+
"@esbuild/linux-arm@0.25.10",
562
+
"@esbuild/linux-arm64@0.25.10",
563
+
"@esbuild/linux-ia32@0.25.10",
564
+
"@esbuild/linux-loong64@0.25.10",
565
+
"@esbuild/linux-mips64el@0.25.10",
566
+
"@esbuild/linux-ppc64@0.25.10",
567
+
"@esbuild/linux-riscv64@0.25.10",
568
+
"@esbuild/linux-s390x@0.25.10",
569
+
"@esbuild/linux-x64@0.25.10",
570
+
"@esbuild/netbsd-arm64",
571
+
"@esbuild/netbsd-x64@0.25.10",
572
+
"@esbuild/openbsd-arm64",
573
+
"@esbuild/openbsd-x64@0.25.10",
574
+
"@esbuild/openharmony-arm64",
575
+
"@esbuild/sunos-x64@0.25.10",
576
+
"@esbuild/win32-arm64@0.25.10",
577
+
"@esbuild/win32-ia32@0.25.10",
578
+
"@esbuild/win32-x64@0.25.10"
579
+
],
580
+
"scripts": true,
581
+
"bin": true
582
+
},
180
583
"esm-env@1.2.2": {
181
584
"integrity": "sha512-Epxrv+Nr/CaL4ZcFGPJIYLWFom+YeV1DqMLHJoEd9SYRxNbaFruBwfEX/kkHUJf55j2+TUbmDcmuilbP1TmXHA=="
182
585
},
···
193
596
"fetch-blob"
194
597
]
195
598
},
599
+
"get-tsconfig@4.10.1": {
600
+
"integrity": "sha512-auHyJ4AgMz7vgS8Hp3N6HXSmlMdUyhSUrfBF16w153rxtLIEOE+HGqaBppczZvnHLqQJfiHotCYpNhl0lUROFQ==",
601
+
"dependencies": [
602
+
"resolve-pkg-maps"
603
+
]
604
+
},
605
+
"ipaddr.js@2.2.0": {
606
+
"integrity": "sha512-Ag3wB2o37wslZS19hZqorUnrnzSkpOVy+IiiDEiTqNubEYpYuHWIf6K4psgN2ZWKExS4xhVCrRVfb/wfW8fWJA=="
607
+
},
196
608
"js-base64@3.7.8": {
197
609
"integrity": "sha512-hNngCeKxIUQiEUN3GPJOkz4wF/YvdUdbNL9hsBcMQTkKzboD7T/q3OYOuuPZLUE6dBxSGpwhk5mwuDud7JVAow=="
198
610
},
···
216
628
"os": ["darwin", "linux", "win32"],
217
629
"cpu": ["x64", "arm64", "wasm32", "arm"]
218
630
},
631
+
"ms@2.1.3": {
632
+
"integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA=="
633
+
},
219
634
"node-domexception@1.0.0": {
220
635
"integrity": "sha512-/jKZoMpw0F8GRwl4/eLROPA3cfcXtLApP0QzLmUT/HuPCZWyB7IY9ZrMeKw2O/nFIqPQB3PVM9aYm0F312AXDQ==",
221
636
"deprecated": true
···
238
653
"promise-limit@2.7.0": {
239
654
"integrity": "sha512-7nJ6v5lnJsXwGprnGXga4wx6d1POjvi5Qmf1ivTRxTjH4Z/9Czja/UCMLVmB9N93GeWOU93XaFaEt6jbuoagNw=="
240
655
},
656
+
"resolve-pkg-maps@1.0.0": {
657
+
"integrity": "sha512-seS2Tj26TBVOC2NIc2rOe2y2ZO7efxITtLZcGSOnHHNOQ7CkiUBfw0Iw2ck6xkIhPwLhKNLS8BO+hEpngQlqzw=="
658
+
},
659
+
"source-map-support@0.5.21": {
660
+
"integrity": "sha512-uBHU3L3czsIyYXKX88fdrGovxdSCoTGDRZ6SYXtSRxLZUzHg5P/66Ht6uoUlHu9EZod+inXhKo3qQgwXUT/y1w==",
661
+
"dependencies": [
662
+
"buffer-from",
663
+
"source-map"
664
+
]
665
+
},
666
+
"source-map@0.6.1": {
667
+
"integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g=="
668
+
},
241
669
"undici-types@7.10.0": {
242
670
"integrity": "sha512-t5Fy/nfn+14LuOc2KNYg75vZqClpAiqscVvMygNnlsHBFpSXdJaYtXMcdNLpl/Qvc3P2cB3s6lOV51nqsFq4ag=="
671
+
},
672
+
"undici@6.22.0": {
673
+
"integrity": "sha512-hU/10obOIu62MGYjdskASR3CUAiYaFTtC9Pa6vHyf//mAipSvSQg6od2CnJswq7fvzNS3zJhxoRkgNVaHurWKw=="
243
674
},
244
675
"web-streams-polyfill@3.3.3": {
245
676
"integrity": "sha512-d2JWLCivmZYTSIoge9MsgFCZrt571BikcWGYkjC1khllbTeDlGqZ2D8vD8E/lJa8WGWbb7Plm8/XJYV7IJHZZw=="
···
251
682
"workspace": {
252
683
"dependencies": [
253
684
"npm:@atcute/atproto@^3.1.4",
685
+
"npm:@atcute/cbor@^2.2.6",
254
686
"npm:@atcute/client@^4.0.3",
255
687
"npm:@atcute/identity-resolver@^1.1.3",
256
688
"npm:@atcute/lex-cli@^2.2.0",
257
689
"npm:@atcute/lexicons@^1.1.1",
258
-
"npm:@libsql/client@~0.15.15"
690
+
"npm:@atproto-labs/fetch-node@~0.1.10",
691
+
"npm:@libsql/client@~0.15.15",
692
+
"npm:drizzle-kit@~0.31.5",
693
+
"npm:drizzle-orm@~0.44.6"
259
694
]
260
695
}
261
696
}
+10
server/drizzle.config.ts
+10
server/drizzle.config.ts
-22
server/lex/dev.atcities.route.json
-22
server/lex/dev.atcities.route.json
···
1
-
{
2
-
"lexicon": 1,
3
-
"id": "dev.atcities.route",
4
-
"description": "Define the route for a given page. Page content is a blob",
5
-
"defs": {
6
-
"main": {
7
-
"type": "record",
8
-
"description": "Page URL maps directly to a record key",
9
-
"key": "any",
10
-
"record": {
11
-
"type": "object",
12
-
"properties": {
13
-
"page": {
14
-
"type": "blob",
15
-
"accept": ["*/*"]
16
-
}
17
-
},
18
-
"required": ["page"]
19
-
}
20
-
}
21
-
}
22
-
}
+1
-1
server/lex.config.js
+1
-1
server/lex.config.js
+44
server/src/backfill/blob.ts
+44
server/src/backfill/blob.ts
···
1
+
import { Client } from "@atcute/client";
2
+
import { fetchHandler, getPds, MAX_SITE_SIZE } from "../utils.ts";
3
+
4
+
export default async function (
5
+
did: `did:${"plc" | "web"}:${string}`,
6
+
cid: string
7
+
): Promise<Blob> {
8
+
// if the user has been manually taken down (cache dir deleted and replaced with empty file)
9
+
// this errors out for quick exit
10
+
// saving the round trip to resolve the pds and blob.
11
+
await Deno.mkdir(`./blobs/${did}`, { recursive: true });
12
+
13
+
const pds = await getPds(did);
14
+
if (!pds) throw "PDS not found";
15
+
16
+
const { data, ok } = await new Client({
17
+
handler: fetchHandler({ service: pds }),
18
+
}).get("com.atproto.sync.getBlob", {
19
+
params: {
20
+
did,
21
+
cid,
22
+
},
23
+
as: "blob",
24
+
});
25
+
26
+
if (!ok) throw `${data.error}`;
27
+
28
+
// if the file size cant be calculated or the file cant be written, still return the blob
29
+
try {
30
+
let size = 0;
31
+
for await (const file of Deno.readDir(`./blobs/${did}`)) {
32
+
size += (await Deno.stat(`./blobs/${did}/${file.name}`)).size;
33
+
}
34
+
// only write if total stays below max site size
35
+
if (size + data.size <= MAX_SITE_SIZE)
36
+
await Deno.writeFile(`./blobs/${did}/${cid}`, await data.bytes(), {
37
+
createNew: true,
38
+
});
39
+
} catch (e) {
40
+
console.warn(e);
41
+
}
42
+
43
+
return data;
44
+
}
+25
server/src/backfill/index.ts
+25
server/src/backfill/index.ts
···
1
+
import { drizzle } from "drizzle-orm/libsql";
2
+
import { routes } from "../db/schema.ts";
3
+
import * as schema from "../db/schema.ts";
4
+
import { db as db_type } from "../utils.ts";
5
+
import oldRecords from "./old-records.ts";
6
+
import newRecords from "./new-records.ts";
7
+
8
+
const db: db_type = drizzle<typeof schema>(
9
+
Deno.env.get("DB_FILE_NAME")! ||
10
+
(() => {
11
+
throw "DB_FILE_NAME not set";
12
+
})()
13
+
);
14
+
15
+
// clear old records & blobs
16
+
// accounts could have deleted their sites or anything
17
+
// so we should just nuke them
18
+
// blobs could be kept but would be a nightmare
19
+
await db.delete(routes);
20
+
await Deno.remove("./blobs", { recursive: true });
21
+
22
+
oldRecords(db);
23
+
newRecords(db);
24
+
25
+
export default db;
+188
server/src/backfill/new-records.ts
+188
server/src/backfill/new-records.ts
···
1
+
import { db, getPds, isDid, rkeyToUrl, fetchHandler } from "../utils.ts";
2
+
import { decodeFirst } from "@atcute/cbor";
3
+
import { DevAtcitiesRoute } from "../lexicons/index.ts";
4
+
import { is } from "@atcute/lexicons";
5
+
import { ComAtprotoSyncSubscribeRepos } from "@atcute/atproto";
6
+
import { Client } from "@atcute/client";
7
+
import { routes } from "../db/schema.ts";
8
+
import { and, eq } from "drizzle-orm";
9
+
10
+
const ErrorEvent = Symbol("error event");
11
+
export default function newRecords(db: db) {
12
+
// https://pdsls.dev/at://did:plc:6msi3pj7krzih5qxqtryxlzw/com.atproto.lexicon.schema/com.atproto.sync.subscribeRepos
13
+
const ws = new WebSocket(
14
+
`${
15
+
Deno.env.get("ATPROTO_RELAY") ||
16
+
(() => {
17
+
throw "ATPROTO_RELAY not set";
18
+
})()
19
+
}/xrpc/com.atproto.sync.subscribeRepos`
20
+
);
21
+
22
+
ws.addEventListener("close", (ev) => {
23
+
throw ev;
24
+
});
25
+
ws.addEventListener("error", (ev) => {
26
+
throw ev;
27
+
});
28
+
ws.addEventListener("open", () => console.log("Listening for new events."));
29
+
30
+
try {
31
+
ws.addEventListener("message", async (ev) => {
32
+
if (ev.data instanceof Blob) {
33
+
try {
34
+
const [header, remainder] = decodeFirst(await ev.data.bytes());
35
+
const [payload] = decodeFirst(remainder);
36
+
// https://atproto.com/specs/event-stream#framing
37
+
if (typeof header !== "object" || !header) return;
38
+
if (!("op" in header) || typeof header.op !== "number") return;
39
+
if (header.op === -1) {
40
+
console.error(header);
41
+
ws.close();
42
+
throw ErrorEvent;
43
+
}
44
+
45
+
// we only care about commits
46
+
// identity events and similar are irrelevant
47
+
if (!is(ComAtprotoSyncSubscribeRepos.commitSchema, payload)) {
48
+
return;
49
+
}
50
+
if (!isDid(payload.repo)) {
51
+
console.warn("Invalid did:", payload.repo);
52
+
return;
53
+
}
54
+
const pds = await getPds(payload.repo);
55
+
if (!pds) {
56
+
return;
57
+
}
58
+
59
+
const client = new Client({
60
+
handler: fetchHandler({
61
+
service: pds,
62
+
}),
63
+
});
64
+
65
+
for (const op of payload.ops) {
66
+
const [collection, rkey] = op.path.split("/");
67
+
if (!collection || !rkey) {
68
+
console.warn("Invalid path", op.path);
69
+
continue;
70
+
}
71
+
const path = rkeyToUrl(rkey);
72
+
if (!path) continue;
73
+
if (collection !== "dev.atcities.route") continue;
74
+
75
+
switch (op.action) {
76
+
case "create":
77
+
case "update": {
78
+
// hydrate data
79
+
const { data, ok } = await client.get(
80
+
"com.atproto.repo.getRecord",
81
+
{
82
+
params: {
83
+
repo: payload.repo,
84
+
collection: "dev.atcities.route",
85
+
rkey,
86
+
},
87
+
}
88
+
);
89
+
90
+
if (!ok) {
91
+
console.warn(data);
92
+
continue;
93
+
}
94
+
95
+
if (!is(DevAtcitiesRoute.mainSchema, data.value)) {
96
+
console.warn(
97
+
"Invalid record:",
98
+
`at://${payload.repo}/dev.atcities.route.${rkey}`
99
+
);
100
+
continue;
101
+
}
102
+
103
+
if (data.value.page.$type !== "dev.atcities.route#blob") {
104
+
continue;
105
+
}
106
+
107
+
// if this page exists in db, get the id so it can be replaced
108
+
const id = (
109
+
await db
110
+
.select({
111
+
id: routes.id,
112
+
})
113
+
.from(routes)
114
+
.where(
115
+
and(
116
+
eq(routes.did, payload.repo),
117
+
eq(routes.url_route, path)
118
+
)
119
+
)
120
+
).at(0);
121
+
122
+
await db.insert(routes).values({
123
+
did: payload.repo,
124
+
url_route: path,
125
+
id: id ? id.id : undefined,
126
+
blob_cid:
127
+
"ref" in data.value.page.blob
128
+
? data.value.page.blob.ref.$link
129
+
: data.value.page.blob.cid,
130
+
mime: data.value.page.blob.mimeType,
131
+
});
132
+
133
+
continue;
134
+
}
135
+
case "delete": {
136
+
const deleted = (
137
+
await db
138
+
.select({
139
+
id: routes.id,
140
+
cid: routes.blob_cid,
141
+
})
142
+
.from(routes)
143
+
.where(
144
+
and(
145
+
eq(routes.did, payload.repo),
146
+
eq(routes.url_route, path)
147
+
)
148
+
)
149
+
).at(0);
150
+
if (!deleted) continue;
151
+
152
+
await db.delete(routes).where(eq(routes.id, deleted.id));
153
+
154
+
const cidInUse =
155
+
(
156
+
await db
157
+
.select({})
158
+
.from(routes)
159
+
.where(eq(routes.blob_cid, deleted.cid))
160
+
).length > 0;
161
+
162
+
// purge cid if not in use
163
+
if (!cidInUse)
164
+
Deno.remove(`./blobs/${payload.repo}/${deleted.cid}`);
165
+
166
+
continue;
167
+
}
168
+
}
169
+
}
170
+
} catch (e) {
171
+
if (Error.isError(e)) {
172
+
console.warn(
173
+
"Invalid DAG-CBOR data:",
174
+
e.name,
175
+
e.message,
176
+
e.cause,
177
+
e.stack
178
+
);
179
+
} else throw e;
180
+
}
181
+
}
182
+
});
183
+
} catch (e) {
184
+
// if and only if an error message was recived, reopen the connection
185
+
if (e === ErrorEvent) newRecords(db);
186
+
else throw e;
187
+
}
188
+
}
+96
server/src/backfill/old-records.ts
+96
server/src/backfill/old-records.ts
···
1
+
import { Client } from "@atcute/client";
2
+
import { db, fetchHandler, getPds, isDid, rkeyToUrl } from "../utils.ts";
3
+
import { is } from "@atcute/lexicons";
4
+
import { DevAtcitiesRoute } from "../lexicons/index.ts";
5
+
import { routes } from "../db/schema.ts";
6
+
7
+
async function indexUser(did: `did:${"web" | "plc"}:${string}`, db: db) {
8
+
const pds = await getPds(did);
9
+
if (!pds) return console.error(did, "could not be resolved to a pds.");
10
+
const pdsClient = new Client({
11
+
handler: fetchHandler({ service: pds }),
12
+
});
13
+
14
+
let cursor: string | undefined;
15
+
while (true) {
16
+
const { data, ok } = await pdsClient.get("com.atproto.repo.listRecords", {
17
+
params: {
18
+
repo: did,
19
+
collection: "dev.atcities.route",
20
+
cursor,
21
+
},
22
+
});
23
+
24
+
if (!ok) {
25
+
console.error("Got error:", data.error, data.message);
26
+
break;
27
+
}
28
+
29
+
for (const record of data.records) {
30
+
if (is(DevAtcitiesRoute.mainSchema, record.value)) {
31
+
// ignore non blob page values
32
+
// this will be expanded in future
33
+
if (record.value.page.$type === "dev.atcities.route#blob") {
34
+
const url = rkeyToUrl(record.uri.split("/")[4]);
35
+
if (!url) continue;
36
+
const data: typeof routes.$inferInsert = {
37
+
did: did,
38
+
url_route: url,
39
+
blob_cid:
40
+
"ref" in record.value.page.blob
41
+
? record.value.page.blob.ref.$link
42
+
: record.value.page.blob.cid,
43
+
mime: record.value.page.blob.mimeType,
44
+
};
45
+
await db.insert(routes).values(data);
46
+
}
47
+
} else console.warn("Invalid record:", record.uri);
48
+
}
49
+
50
+
cursor = data.cursor;
51
+
if (!cursor) break;
52
+
}
53
+
}
54
+
55
+
export default async function (db: db) {
56
+
const relay = new Client({
57
+
handler: fetchHandler({
58
+
service:
59
+
Deno.env.get("ATPROTO_RELAY") ||
60
+
(() => {
61
+
throw "ATPROTO_RELAY not set";
62
+
})(),
63
+
}),
64
+
});
65
+
66
+
let repos: `did:${string}:${string}`[] = [];
67
+
let cursor: string | undefined;
68
+
while (true) {
69
+
const { data, ok } = await relay.get(
70
+
"com.atproto.sync.listReposByCollection",
71
+
{
72
+
params: {
73
+
collection: "dev.atcities.route",
74
+
cursor,
75
+
},
76
+
}
77
+
);
78
+
79
+
if (!ok) {
80
+
throw data.error + "\n" + data.message;
81
+
}
82
+
83
+
repos = [...repos, ...data.repos.map((x) => x.did)];
84
+
cursor = data.cursor;
85
+
if (!cursor) break;
86
+
}
87
+
88
+
const pending: Promise<unknown>[] = [];
89
+
for (const i in repos) {
90
+
const did = repos[i];
91
+
console.log(`indexing ${Number(i) + 1}/${repos.length} ${did}`);
92
+
if (isDid(did)) pending.push(indexUser(did, db));
93
+
}
94
+
await Promise.all(pending);
95
+
console.log("Finished backfilling.");
96
+
}
+9
server/src/db/schema.ts
+9
server/src/db/schema.ts
···
1
+
import { int, sqliteTable, text } from "drizzle-orm/sqlite-core";
2
+
3
+
export const routes = sqliteTable("routes", {
4
+
id: int("id").primaryKey({ autoIncrement: true }),
5
+
did: text("did").notNull(),
6
+
url_route: text("url_route").notNull(),
7
+
blob_cid: text("blob_cid").notNull(),
8
+
mime: text("mime").notNull(),
9
+
});
+23
-44
server/src/index.ts
+23
-44
server/src/index.ts
···
1
-
import root from "./root.ts";
2
-
import user from "./user.ts";
3
-
4
-
const ROOT_DOMAIN = Deno.env.get("HOSTNAME") || "localhost";
5
-
const PORT = Number(Deno.env.get("PORT")) || 80;
1
+
import root from "./routes/root.ts";
2
+
import user from "./routes/user.ts";
3
+
import backfill from "./backfill/index.ts";
4
+
import { clearCookies, PORT, ROOT_DOMAIN, SUBDOMAIN_REGEX } from "./utils.ts";
6
5
7
-
const SUBDOMAIN_REGEX = new RegExp(`.+(?=\\.${ROOT_DOMAIN}$)`, "gm");
8
-
9
-
function clearCookies(req: Request): Headers {
10
-
const cookie_header = req.headers.get("Cookie");
11
-
// cookies are unset so return empty headers
12
-
if (!cookie_header) return new Headers();
13
-
// get each kv pair and extract the key
14
-
const cookies = cookie_header.split("; ").map((x) => x.split("=")[0]);
15
-
const head = new Headers();
16
-
for (const key of cookies) {
17
-
// max-age <= 0 means instant expiry .: deleted instantly
18
-
head.append("Set-Cookie", `${key}=; Max-Age=-1`);
19
-
}
20
-
return head;
21
-
}
6
+
const db = await backfill;
22
7
23
8
Deno.serve({ port: PORT, hostname: ROOT_DOMAIN }, async (req) => {
24
9
const reqUrl = new URL(req.url);
···
41
26
// did:plc example: `sjkdgfjk.did-plc.ROOT_DOMAIN`
42
27
// did:web example: `vielle.dev.did-web.ROOT_DOMAIN
43
28
// last segment must be did-plc or did-web
44
-
if (subdomain.at(-1)?.match(/^did-(web|plc)+$/gm)) {
45
-
const res = await user(req, {
46
-
did: `did:${subdomain.at(-1) === "did-plc" ? "plc" : "web"}:${subdomain.slice(0, -1).join(".")}`,
47
-
});
48
-
return new Response(res.body, {
49
-
...res,
50
-
headers: {
51
-
...Array.from(res.headers.entries()).reduce(
52
-
(acc, [k, v]) => ({ ...acc, [k]: v }),
53
-
{}
54
-
),
55
-
...clearCookies(req),
56
-
},
57
-
});
58
-
}
59
-
29
+
const isDidSubdomain = !!subdomain.at(-1)?.match(/^did-(web|plc)+$/gm);
60
30
// ex: vielle.dev.ROOT_DOMAIN
61
31
// cannot contain hyphen in top level domain
62
-
if (!subdomain.at(-1)?.startsWith("did-") && subdomain.length > 1) {
63
-
const res = await user(req, {
64
-
handle: subdomain.join(".") as `${string}.${string}`,
65
-
});
32
+
const isHandleSubdomain = !isDidSubdomain && subdomain.length > 1;
33
+
34
+
if (isDidSubdomain || isHandleSubdomain) {
35
+
const res: Response = await user(
36
+
db,
37
+
req,
38
+
isDidSubdomain
39
+
? {
40
+
did: `did:${subdomain.at(-1) === "did-plc" ? "plc" : "web"}:${subdomain
41
+
.slice(0, -1)
42
+
.join(".")}`,
43
+
}
44
+
: {
45
+
handle: subdomain.join(".") as `${string}.${string}`,
46
+
}
47
+
);
66
48
return new Response(res.body, {
67
49
...res,
68
50
headers: {
69
-
...Array.from(res.headers.entries()).reduce(
70
-
(acc, [k, v]) => ({ ...acc, [k]: v }),
71
-
{}
72
-
),
51
+
...res.headers,
73
52
...clearCookies(req),
74
53
},
75
54
});
+13
-1
server/src/lexicons/types/dev/atcities/route.ts
+13
-1
server/src/lexicons/types/dev/atcities/route.ts
···
2
2
import * as v from "@atcute/lexicons/validations";
3
3
import type {} from "@atcute/lexicons/ambient";
4
4
5
+
const _blobSchema = /*#__PURE__*/ v.object({
6
+
$type: /*#__PURE__*/ v.optional(
7
+
/*#__PURE__*/ v.literal("dev.atcities.route#blob"),
8
+
),
9
+
blob: /*#__PURE__*/ v.blob(),
10
+
});
5
11
const _mainSchema = /*#__PURE__*/ v.record(
6
12
/*#__PURE__*/ v.string(),
7
13
/*#__PURE__*/ v.object({
8
14
$type: /*#__PURE__*/ v.literal("dev.atcities.route"),
9
-
page: /*#__PURE__*/ v.blob(),
15
+
get page() {
16
+
return /*#__PURE__*/ v.variant([blobSchema]);
17
+
},
10
18
}),
11
19
);
12
20
21
+
type blob$schematype = typeof _blobSchema;
13
22
type main$schematype = typeof _mainSchema;
14
23
24
+
export interface blobSchema extends blob$schematype {}
15
25
export interface mainSchema extends main$schematype {}
16
26
27
+
export const blobSchema = _blobSchema as blobSchema;
17
28
export const mainSchema = _mainSchema as mainSchema;
18
29
30
+
export interface Blob extends v.InferInput<typeof blobSchema> {}
19
31
export interface Main extends v.InferInput<typeof mainSchema> {}
20
32
21
33
declare module "@atcute/lexicons/ambient" {
-13
server/src/root.ts
-13
server/src/root.ts
···
1
-
import index from "./www/index.html" with { type: "text" };
2
-
3
-
export default function (req: Request) {
4
-
if (new URL(req.url).pathname === "/")
5
-
return new Response(index, {
6
-
headers: {
7
-
"Content-Type": "text/html; charset=utf8",
8
-
},
9
-
});
10
-
return new Response("404", {
11
-
status: 404,
12
-
});
13
-
}
+38
server/src/routes/root.ts
+38
server/src/routes/root.ts
···
1
+
import { ROOT_DOMAIN } from "../utils.ts";
2
+
import index from "../www/index.html" with { type: "text" };
3
+
import ascii from "./ascii.txt" with { type: "text" };
4
+
5
+
function route(
6
+
path: string,
7
+
callback: (req: Request) => Response
8
+
): {
9
+
test: (path: string) => boolean;
10
+
fn: (req: Request) => Response;
11
+
} {
12
+
const pattern = new URLPattern(path, `https://www.${ROOT_DOMAIN}`);
13
+
return {
14
+
test: (path) => pattern.test(path, `https://www.${ROOT_DOMAIN}`),
15
+
fn: callback,
16
+
};
17
+
}
18
+
19
+
const routes = [
20
+
route(
21
+
"/",
22
+
() =>
23
+
new Response(index, {
24
+
headers: {
25
+
"Content-Type": "text/html; charset=utf8",
26
+
},
27
+
})
28
+
),
29
+
route("/ascii.txt", () => new Response(ascii)),
30
+
];
31
+
32
+
export default function (req: Request) {
33
+
const path = new URL(req.url).pathname;
34
+
for (const r of routes) if (r.test(path)) return r.fn(req);
35
+
return new Response("404", {
36
+
status: 404,
37
+
});
38
+
}
+116
server/src/routes/user.ts
+116
server/src/routes/user.ts
···
1
+
/// <reference types="@atcute/atproto" />
2
+
import {
3
+
CompositeHandleResolver,
4
+
DohJsonHandleResolver,
5
+
WellKnownHandleResolver,
6
+
} from "@atcute/identity-resolver";
7
+
import { and, eq } from "drizzle-orm";
8
+
import { routes } from "../db/schema.ts";
9
+
import { type db, isDid, ROOT_DOMAIN } from "../utils.ts";
10
+
import ascii from "./ascii.txt" with { type: "text" };
11
+
import storeBlob from "../backfill/blob.ts";
12
+
13
+
const handleResolver = new CompositeHandleResolver({
14
+
strategy: "race",
15
+
methods: {
16
+
dns: new DohJsonHandleResolver({
17
+
dohUrl: "https://mozilla.cloudflare-dns.com/dns-query",
18
+
}),
19
+
http: new WellKnownHandleResolver(),
20
+
},
21
+
});
22
+
23
+
export default async function (
24
+
db: db,
25
+
req: Request,
26
+
user:
27
+
| { handle: `${string}.${string}` }
28
+
| { did: `did:plc:${string}` | `did:web:${string}` }
29
+
): Promise<Response> {
30
+
// if handle: resolve did
31
+
let did: `did:${"plc" | "web"}:${string}`;
32
+
if ("handle" in user) {
33
+
try {
34
+
// cast bc i know it will be `string.string`
35
+
did = await handleResolver.resolve(user.handle);
36
+
} catch {
37
+
return new Response(
38
+
`${ascii}
39
+
40
+
This handle could not be resolved.
41
+
`,
42
+
{
43
+
status: 500,
44
+
statusText: "Internal Server Error",
45
+
}
46
+
);
47
+
}
48
+
} else did = user.did;
49
+
50
+
// look up in db
51
+
const db_res =
52
+
(
53
+
await db
54
+
.select()
55
+
.from(routes)
56
+
.where(
57
+
and(
58
+
eq(routes.did, did),
59
+
eq(routes.url_route, new URL(req.url).pathname)
60
+
)
61
+
)
62
+
).at(0) ??
63
+
(
64
+
await db
65
+
.select()
66
+
.from(routes)
67
+
.where(and(eq(routes.did, did), eq(routes.url_route, "404")))
68
+
).at(0);
69
+
70
+
if (!db_res) {
71
+
return new Response(`${ascii}
72
+
73
+
404: The user has no atcities site or is missing a 404 page.
74
+
75
+
If you're the owner of this account, head to https://atcities.dev/ for more information.
76
+
The index of this account is at https://${
77
+
"handle" in user
78
+
? user.handle
79
+
: user.did.split(":").at(-1) + ".did-" + user.did.split(":").at(1)
80
+
}.${ROOT_DOMAIN}/
81
+
`);
82
+
}
83
+
try {
84
+
const file = await Deno.readFile(
85
+
`./blobs/${db_res.did}/${db_res.blob_cid}`
86
+
);
87
+
return new Response(file, {
88
+
headers: {
89
+
"Content-Type": db_res.mime,
90
+
},
91
+
});
92
+
} catch {
93
+
if (!isDid(db_res.did))
94
+
return new Response(`${ascii}
95
+
96
+
${db_res.did} is not a valid DID. This account could not be resolved
97
+
`);
98
+
try {
99
+
const blob = await storeBlob(db_res.did, db_res.blob_cid);
100
+
return new Response(blob, {
101
+
headers: {
102
+
"Content-Type": db_res.mime,
103
+
},
104
+
});
105
+
} catch (e) {
106
+
console.error(e);
107
+
return new Response(`${ascii}
108
+
109
+
This page could not be resolved. Either:
110
+
- The user has no PDS
111
+
- The blob does not exist
112
+
- The user has been manually hidden for uploading illegal content.
113
+
`);
114
+
}
115
+
}
116
+
}
-294
server/src/user.ts
-294
server/src/user.ts
···
1
-
/// <reference types="@atcute/atproto" />
2
-
import { Client, simpleFetchHandler } from "@atcute/client";
3
-
import { is } from "@atcute/lexicons";
4
-
import {
5
-
CompositeHandleResolver,
6
-
DohJsonHandleResolver,
7
-
WellKnownHandleResolver,
8
-
CompositeDidDocumentResolver,
9
-
PlcDidDocumentResolver,
10
-
WebDidDocumentResolver,
11
-
} from "@atcute/identity-resolver";
12
-
import { DevAtcitiesRoute } from "./lexicons/index.ts";
13
-
14
-
const handleResolver = new CompositeHandleResolver({
15
-
strategy: "race",
16
-
methods: {
17
-
dns: new DohJsonHandleResolver({
18
-
dohUrl: "https://mozilla.cloudflare-dns.com/dns-query",
19
-
}),
20
-
http: new WellKnownHandleResolver(),
21
-
},
22
-
});
23
-
24
-
const docResolver = new CompositeDidDocumentResolver({
25
-
methods: {
26
-
plc: new PlcDidDocumentResolver(),
27
-
web: new WebDidDocumentResolver(),
28
-
},
29
-
});
30
-
31
-
/**
32
-
* given a valid url path string containing
33
-
* - `/` for seperating characters
34
-
* - a-zA-Z0-9 `-._~` as unreserved
35
-
* - `!$&'()*+,;=` as reserved but valid in paths
36
-
* - `:@` as neither reserved or unreserved but valid in paths
37
-
* - %XX where X are hex digits for percent encoding
38
-
*
39
-
* we need to consistently and bidirectionally convert it into a string containing the characters A-Z, a-z, 0-9, `.-_:~` for an atproto rkey
40
-
* A-Z a-z 0-9 are covered easily
41
-
* we can also take -._~ as they are also unreserved
42
-
* leaving : as a valid rkey character which looks nice for encoding
43
-
* the uppercase versions MUST be used to prevent ambiguity
44
-
* a colon which isnt followed by a valid character is an invalid rkey and should be ignored
45
-
* - `/` `::`
46
-
* - `%` `:~`
47
-
* - `!` `:21`
48
-
* - `$` `:24`
49
-
* - `&` `:26`
50
-
* - `'` `:27`
51
-
* - `(` `:28`
52
-
* - `)` `:29`
53
-
* - `*` `:2A`
54
-
* - `+` `:2B`
55
-
* - `,` `:2C`
56
-
* - `:` `:3A`
57
-
* - `;` `:3B`
58
-
* - `=` `:3D`
59
-
* - `@` `:40`
60
-
* @returns {string | undefined} undefined when input is invalid
61
-
*/
62
-
function urlToRkey(url: string): string | undefined {
63
-
// contains 0-9A-Za-z + special valid chars and / seperator. also can contain %XX with XX being hex
64
-
if (!url.match(/^([a-zA-Z0-9/\-._~!$&'()*+,;=:@]|(%[0-9a-fA-F]{2}))*$/gm))
65
-
return;
66
-
return (
67
-
url
68
-
// : replace is hoisted so it doesnt replace colons from elsewhere
69
-
.replaceAll(":", ":3A")
70
-
.replaceAll("/", "::")
71
-
.replaceAll("%", ":~")
72
-
.replaceAll("!", ":21")
73
-
.replaceAll("$", ":24")
74
-
.replaceAll("&", ":26")
75
-
.replaceAll("'", ":27")
76
-
.replaceAll("(", ":28")
77
-
.replaceAll(")", ":29")
78
-
.replaceAll("*", ":2A")
79
-
.replaceAll("+", ":2B")
80
-
.replaceAll(",", ":2C")
81
-
.replaceAll(";", ":3B")
82
-
.replaceAll("=", ":3D")
83
-
.replaceAll("@", ":40")
84
-
);
85
-
}
86
-
87
-
/**
88
-
* @see {@link urlToRkey} for rkey <=> url conversion syntax
89
-
* @returns {string | undefined} undefined when input is invalid
90
-
*/
91
-
function rkeyToUrl(rkey: string): string | undefined {
92
-
// contains 0-9A-Za-z .-_:~
93
-
if (!rkey.match(/^[A-Za-z0-9.\-_:~]*$/gm)) return;
94
-
return rkey
95
-
.replaceAll("::", "/")
96
-
.replaceAll(":~", "%")
97
-
.replaceAll(":21", "!")
98
-
.replaceAll(":24", "$")
99
-
.replaceAll(":26", "&")
100
-
.replaceAll(":27", "'")
101
-
.replaceAll(":28", "(")
102
-
.replaceAll(":29", ")")
103
-
.replaceAll(":2A", "*")
104
-
.replaceAll(":2B", "+")
105
-
.replaceAll(":2C", ",")
106
-
.replaceAll(":3A", ":")
107
-
.replaceAll(":3B", ";")
108
-
.replaceAll(":3D", "=")
109
-
.replaceAll(":40", "@");
110
-
}
111
-
112
-
async function getRoute(
113
-
did: `did:${"plc" | "web"}:${string}`,
114
-
pds: string,
115
-
route: string
116
-
): Promise<Response> {
117
-
// get client to pds
118
-
const client = new Client({
119
-
handler: simpleFetchHandler({ service: pds }),
120
-
});
121
-
122
-
try {
123
-
// note: / urls are reserved for special routes (404)
124
-
// any path should be prefixed with a /
125
-
// this is not enforced here so that this function can be used for special routes
126
-
const targetRkey = urlToRkey(route);
127
-
console.log("trying:", targetRkey, "for", route);
128
-
129
-
if (!targetRkey) throw "invalid url";
130
-
131
-
const { ok: record_ok, data: record_data } = await client.get(
132
-
"com.atproto.repo.getRecord",
133
-
{
134
-
params: {
135
-
collection: "dev.atcities.route",
136
-
repo: did,
137
-
rkey: targetRkey,
138
-
},
139
-
}
140
-
);
141
-
142
-
if (!record_ok) {
143
-
switch (record_data.error) {
144
-
case "RecordNotFound": {
145
-
// 404 error so try load 404 page
146
-
if (route !== "404") {
147
-
// try remove trailing / to see if that works
148
-
// if that fails it'll get a 404 anyway
149
-
if (route !== "/" && route.endsWith("/"))
150
-
return new Response(undefined, {
151
-
status: 308,
152
-
statusText: "Permanent Redirect",
153
-
headers: {
154
-
Location: route.slice(0, -1),
155
-
},
156
-
});
157
-
158
-
const r404 = await getRoute(did, pds, "404");
159
-
return new Response(r404.body, {
160
-
status: 404,
161
-
statusText: "Not Found",
162
-
headers: r404.headers,
163
-
});
164
-
}
165
-
return new Response("Could not find page.", {
166
-
status: 404,
167
-
statusText: "Not Found",
168
-
});
169
-
}
170
-
// unless its a 404, internal error
171
-
default:
172
-
throw "Internal Error";
173
-
}
174
-
}
175
-
176
-
if (is(DevAtcitiesRoute.mainSchema, record_data.value)) {
177
-
const { ok: blob_ok, data: blob_data } = await client.get(
178
-
"com.atproto.sync.getBlob",
179
-
{
180
-
params: {
181
-
did,
182
-
cid:
183
-
"ref" in record_data.value.page
184
-
? record_data.value.page.ref.$link
185
-
: record_data.value.page.cid,
186
-
},
187
-
as: "stream",
188
-
}
189
-
);
190
-
191
-
// possible errors include:
192
-
// - request issue
193
-
// - 404 not found
194
-
// - account takedown
195
-
// in all cases thats not recoverable
196
-
// so throw out and take the happy path
197
-
if (!blob_ok) {
198
-
if (blob_data.error === "BlobNotFound") {
199
-
// 404 error so try load 404 page
200
-
if (route !== "404") {
201
-
const r404 = await getRoute(did, pds, "404");
202
-
return new Response(r404.body, {
203
-
status: 404,
204
-
statusText: "Not Found",
205
-
headers: r404.headers,
206
-
});
207
-
}
208
-
return new Response("Could not load page.", {
209
-
status: 404,
210
-
statusText: "Not Found",
211
-
});
212
-
} else throw "Internal Error";
213
-
}
214
-
215
-
return new Response(blob_data, {
216
-
headers: {
217
-
"Content-Type": record_data.value.page.mimeType,
218
-
},
219
-
});
220
-
221
-
// isnt valid data so throw exception
222
-
} else
223
-
return new Response(
224
-
"Malformed record for at://" + did + "/dev.atcities.route/" + targetRkey
225
-
);
226
-
} catch (e) {
227
-
console.error(e);
228
-
return new Response("Something went wrong loading this route", {
229
-
status: 500,
230
-
statusText: "Internal Server Error",
231
-
});
232
-
}
233
-
}
234
-
235
-
export default async function (
236
-
req: Request,
237
-
user:
238
-
| { handle: `${string}.${string}` }
239
-
| { did: `did:plc:${string}` | `did:web:${string}` }
240
-
): Promise<Response> {
241
-
// if handle: resolve did
242
-
let did: `did:${"plc" | "web"}:${string}`;
243
-
if ("handle" in user) {
244
-
try {
245
-
// cast bc i know it will be `string.string`
246
-
did = await handleResolver.resolve(user.handle);
247
-
} catch {
248
-
return new Response("Failed to resolve handle", {
249
-
status: 500,
250
-
statusText: "Internal Server Error",
251
-
});
252
-
}
253
-
} else did = user.did;
254
-
255
-
// resolve did doc
256
-
let doc;
257
-
try {
258
-
doc = await docResolver.resolve(did);
259
-
} catch {
260
-
return new Response("Could not resolve " + did + ".\n", {
261
-
status: 500,
262
-
statusText: "Internal Server Error",
263
-
});
264
-
}
265
-
266
-
// handle must be in did document
267
-
if ("handle" in user && !doc.alsoKnownAs?.includes(`at://${user.handle}`)) {
268
-
return new Response(
269
-
`Provided handle (at://${user.handle}) was not found in the did document for ${did}. Found handles:\n${doc.alsoKnownAs?.map((x) => "- " + x).join("\n") ?? "None"}`,
270
-
{
271
-
status: 500,
272
-
statusText: "Internal Server Error",
273
-
}
274
-
);
275
-
}
276
-
277
-
const pds = doc.service?.filter(
278
-
(x) =>
279
-
x.id.endsWith("#atproto_pds") &&
280
-
x.type === "AtprotoPersonalDataServer" &&
281
-
typeof x.serviceEndpoint === "string"
282
-
// cast as we type checked it above but it didnt acc apply?
283
-
)[0].serviceEndpoint as string | undefined;
284
-
if (!pds)
285
-
return new Response(
286
-
`Could not find a valid pds for ${"handle" in user ? user.handle : user.did}`,
287
-
{
288
-
status: 500,
289
-
statusText: "Internal Server Error",
290
-
}
291
-
);
292
-
293
-
return await getRoute(did, pds, new URL(req.url).pathname);
294
-
}
+165
server/src/utils.ts
+165
server/src/utils.ts
···
1
+
import { LibSQLDatabase } from "drizzle-orm/libsql";
2
+
import { Client } from "@libsql/client";
3
+
import * as schema from "./db/schema.ts";
4
+
import {
5
+
CompositeDidDocumentResolver,
6
+
PlcDidDocumentResolver,
7
+
WebDidDocumentResolver,
8
+
} from "@atcute/identity-resolver";
9
+
import { FetchHandler, SimpleFetchHandlerOptions } from "@atcute/client";
10
+
import { safeFetchWrap } from "@atproto-labs/fetch-node";
11
+
12
+
export type db = LibSQLDatabase<typeof schema> & {
13
+
$client: Client;
14
+
};
15
+
16
+
export const ROOT_DOMAIN = Deno.env.get("HOSTNAME") || "localhost";
17
+
export const PORT = Number(Deno.env.get("PORT")) || 80;
18
+
export const MAX_SITE_SIZE = Number(Deno.env.get("MAX_SITE_SIZE")) || 250000000;
19
+
20
+
export const SUBDOMAIN_REGEX = new RegExp(`.+(?=\\.${ROOT_DOMAIN}$)`, "gm");
21
+
22
+
export function clearCookies(req: Request): Headers {
23
+
const cookie_header = req.headers.get("Cookie");
24
+
// cookies are unset so return empty headers
25
+
if (!cookie_header) return new Headers();
26
+
// get each kv pair and extract the key
27
+
const cookies = cookie_header.split("; ").map((x) => x.split("=")[0]);
28
+
const head = new Headers();
29
+
for (const key of cookies) {
30
+
// max-age <= 0 means instant expiry .: deleted instantly
31
+
head.append("Set-Cookie", `${key}=; Max-Age=-1`);
32
+
}
33
+
return head;
34
+
}
35
+
36
+
const docResolver = new CompositeDidDocumentResolver({
37
+
methods: {
38
+
plc: new PlcDidDocumentResolver(),
39
+
web: new WebDidDocumentResolver(),
40
+
},
41
+
});
42
+
43
+
export const fetchHandler: ({
44
+
service,
45
+
}: SimpleFetchHandlerOptions) => FetchHandler = ({
46
+
service,
47
+
}: SimpleFetchHandlerOptions): FetchHandler => {
48
+
const safeFetch = safeFetchWrap();
49
+
return async (pathname, init) => {
50
+
const url = new URL(pathname, service);
51
+
return await safeFetch(url, init);
52
+
};
53
+
};
54
+
55
+
export async function getPds(
56
+
did: `did:${"plc" | "web"}:${string}`
57
+
): Promise<string | undefined> {
58
+
try {
59
+
const doc = await docResolver.resolve(did);
60
+
const pds = doc.service?.filter(
61
+
(x) =>
62
+
x.id.endsWith("#atproto_pds") && x.type === "AtprotoPersonalDataServer"
63
+
)[0].serviceEndpoint;
64
+
return typeof pds === "string" ? pds : undefined;
65
+
} catch {
66
+
return undefined;
67
+
}
68
+
}
69
+
70
+
export function isDid(did: unknown): did is `did:${"plc" | "web"}:${string}` {
71
+
return (
72
+
typeof did === "string" &&
73
+
(did.startsWith("did:web:") || did.startsWith("did:plc:"))
74
+
);
75
+
}
76
+
77
+
/**
78
+
* given a valid url path string containing
79
+
* - `/` for seperating characters
80
+
* - a-zA-Z0-9 `-._~` as unreserved
81
+
* - `!$&'()*+,;=` as reserved but valid in paths
82
+
* - `:@` as neither reserved or unreserved but valid in paths
83
+
* - %XX where X are hex digits for percent encoding
84
+
*
85
+
* we need to consistently and bidirectionally convert it into a string containing the characters A-Z, a-z, 0-9, `.-_:~` for an atproto rkey
86
+
* A-Z a-z 0-9 are covered easily
87
+
* we can also take -._~ as they are also unreserved
88
+
* leaving : as a valid rkey character which looks nice for encoding
89
+
* the uppercase versions MUST be used to prevent ambiguity
90
+
* a colon which isnt followed by a valid character is an invalid rkey and should be ignored
91
+
* - `/` `::`
92
+
* - `%` `:~`
93
+
* - `!` `:21`
94
+
* - `$` `:24`
95
+
* - `&` `:26`
96
+
* - `'` `:27`
97
+
* - `(` `:28`
98
+
* - `)` `:29`
99
+
* - `*` `:2A`
100
+
* - `+` `:2B`
101
+
* - `,` `:2C`
102
+
* - `:` `:3A`
103
+
* - `;` `:3B`
104
+
* - `=` `:3D`
105
+
* - `@` `:40`
106
+
* @returns {string | undefined} undefined when input is invalid
107
+
*/
108
+
export function urlToRkey(url: string): string | undefined {
109
+
// contains 0-9A-Za-z + special valid chars and / seperator. also can contain %XX with XX being hex
110
+
if (
111
+
!url.match(/^(?:[a-zA-Z0-9/\-._~!$&'()*+,;=:@]|(?:%[0-9a-fA-F]{2}))*$/gm)
112
+
) {
113
+
return;
114
+
}
115
+
return (
116
+
url
117
+
// : replace is hoisted so it doesnt replace colons from elsewhere
118
+
.replaceAll(":", ":3A")
119
+
.replaceAll("/", "::")
120
+
.replaceAll("%", ":~")
121
+
.replaceAll("!", ":21")
122
+
.replaceAll("$", ":24")
123
+
.replaceAll("&", ":26")
124
+
.replaceAll("'", ":27")
125
+
.replaceAll("(", ":28")
126
+
.replaceAll(")", ":29")
127
+
.replaceAll("*", ":2A")
128
+
.replaceAll("+", ":2B")
129
+
.replaceAll(",", ":2C")
130
+
.replaceAll(";", ":3B")
131
+
.replaceAll("=", ":3D")
132
+
.replaceAll("@", ":40")
133
+
);
134
+
}
135
+
136
+
/**
137
+
* @see {@link urlToRkey} for rkey <=> url conversion syntax
138
+
* @returns {string | undefined} undefined when input is invalid
139
+
*/
140
+
export function rkeyToUrl(rkey: string): string | undefined {
141
+
// contains 0-9A-Za-z .-_~
142
+
// or any valid colon escape sequence
143
+
if (
144
+
!rkey.match(
145
+
/^(?:[A-Za-z0-9.\-_~]|(?:::)|(?::~)|(?::21)|(?::24)|(?::26)|(?::27)|(?::28)|(?::29)|(?::2A)|(?::2B)|(?::2C)|(?::3A)|(?::3B)|(?::3D)|(?::40))*$/gm
146
+
)
147
+
)
148
+
return;
149
+
return rkey
150
+
.replaceAll("::", "/")
151
+
.replaceAll(":~", "%")
152
+
.replaceAll(":21", "!")
153
+
.replaceAll(":24", "$")
154
+
.replaceAll(":26", "&")
155
+
.replaceAll(":27", "'")
156
+
.replaceAll(":28", "(")
157
+
.replaceAll(":29", ")")
158
+
.replaceAll(":2A", "*")
159
+
.replaceAll(":2B", "+")
160
+
.replaceAll(":2C", ",")
161
+
.replaceAll(":3A", ":")
162
+
.replaceAll(":3B", ";")
163
+
.replaceAll(":3D", "=")
164
+
.replaceAll(":40", "@");
165
+
}
+1
-1
server/src/www/index.html
+1
-1
server/src/www/index.html
+4435
upload/Cargo.lock
+4435
upload/Cargo.lock
···
3
3
version = 4
4
4
5
5
[[package]]
6
+
name = "abnf"
7
+
version = "0.13.0"
8
+
source = "registry+https://github.com/rust-lang/crates.io-index"
9
+
checksum = "087113bd50d9adce24850eed5d0476c7d199d532fce8fab5173650331e09033a"
10
+
dependencies = [
11
+
"abnf-core",
12
+
"nom",
13
+
]
14
+
15
+
[[package]]
16
+
name = "abnf-core"
17
+
version = "0.5.0"
18
+
source = "registry+https://github.com/rust-lang/crates.io-index"
19
+
checksum = "c44e09c43ae1c368fb91a03a566472d0087c26cf7e1b9e8e289c14ede681dd7d"
20
+
dependencies = [
21
+
"nom",
22
+
]
23
+
24
+
[[package]]
25
+
name = "addr2line"
26
+
version = "0.25.1"
27
+
source = "registry+https://github.com/rust-lang/crates.io-index"
28
+
checksum = "1b5d307320b3181d6d7954e663bd7c774a838b8220fe0593c86d9fb09f498b4b"
29
+
dependencies = [
30
+
"gimli",
31
+
]
32
+
33
+
[[package]]
34
+
name = "adler2"
35
+
version = "2.0.1"
36
+
source = "registry+https://github.com/rust-lang/crates.io-index"
37
+
checksum = "320119579fcad9c21884f5c4861d16174d0e06250625266f50fe6898340abefa"
38
+
39
+
[[package]]
40
+
name = "adler32"
41
+
version = "1.2.0"
42
+
source = "registry+https://github.com/rust-lang/crates.io-index"
43
+
checksum = "aae1277d39aeec15cb388266ecc24b11c80469deae6067e17a1a7aa9e5c1f234"
44
+
45
+
[[package]]
46
+
name = "aho-corasick"
47
+
version = "1.1.3"
48
+
source = "registry+https://github.com/rust-lang/crates.io-index"
49
+
checksum = "8e60d3430d3a69478ad0993f19238d2df97c507009a52b3c10addcd7f6bcb916"
50
+
dependencies = [
51
+
"memchr",
52
+
]
53
+
54
+
[[package]]
55
+
name = "aliasable"
56
+
version = "0.1.3"
57
+
source = "registry+https://github.com/rust-lang/crates.io-index"
58
+
checksum = "250f629c0161ad8107cf89319e990051fae62832fd343083bea452d93e2205fd"
59
+
60
+
[[package]]
61
+
name = "alloc-no-stdlib"
62
+
version = "2.0.4"
63
+
source = "registry+https://github.com/rust-lang/crates.io-index"
64
+
checksum = "cc7bb162ec39d46ab1ca8c77bf72e890535becd1751bb45f64c597edb4c8c6b3"
65
+
66
+
[[package]]
67
+
name = "alloc-stdlib"
68
+
version = "0.2.2"
69
+
source = "registry+https://github.com/rust-lang/crates.io-index"
70
+
checksum = "94fb8275041c72129eb51b7d0322c29b8387a0386127718b096429201a5d6ece"
71
+
dependencies = [
72
+
"alloc-no-stdlib",
73
+
]
74
+
75
+
[[package]]
76
+
name = "android_system_properties"
77
+
version = "0.1.5"
78
+
source = "registry+https://github.com/rust-lang/crates.io-index"
79
+
checksum = "819e7219dbd41043ac279b19830f2efc897156490d7fd6ea916720117ee66311"
80
+
dependencies = [
81
+
"libc",
82
+
]
83
+
84
+
[[package]]
85
+
name = "anstream"
86
+
version = "0.6.21"
87
+
source = "registry+https://github.com/rust-lang/crates.io-index"
88
+
checksum = "43d5b281e737544384e969a5ccad3f1cdd24b48086a0fc1b2a5262a26b8f4f4a"
89
+
dependencies = [
90
+
"anstyle",
91
+
"anstyle-parse",
92
+
"anstyle-query",
93
+
"anstyle-wincon",
94
+
"colorchoice",
95
+
"is_terminal_polyfill",
96
+
"utf8parse",
97
+
]
98
+
99
+
[[package]]
100
+
name = "anstyle"
101
+
version = "1.0.13"
102
+
source = "registry+https://github.com/rust-lang/crates.io-index"
103
+
checksum = "5192cca8006f1fd4f7237516f40fa183bb07f8fbdfedaa0036de5ea9b0b45e78"
104
+
105
+
[[package]]
106
+
name = "anstyle-parse"
107
+
version = "0.2.7"
108
+
source = "registry+https://github.com/rust-lang/crates.io-index"
109
+
checksum = "4e7644824f0aa2c7b9384579234ef10eb7efb6a0deb83f9630a49594dd9c15c2"
110
+
dependencies = [
111
+
"utf8parse",
112
+
]
113
+
114
+
[[package]]
115
+
name = "anstyle-query"
116
+
version = "1.1.4"
117
+
source = "registry+https://github.com/rust-lang/crates.io-index"
118
+
checksum = "9e231f6134f61b71076a3eab506c379d4f36122f2af15a9ff04415ea4c3339e2"
119
+
dependencies = [
120
+
"windows-sys 0.60.2",
121
+
]
122
+
123
+
[[package]]
124
+
name = "anstyle-wincon"
125
+
version = "3.0.10"
126
+
source = "registry+https://github.com/rust-lang/crates.io-index"
127
+
checksum = "3e0633414522a32ffaac8ac6cc8f748e090c5717661fddeea04219e2344f5f2a"
128
+
dependencies = [
129
+
"anstyle",
130
+
"once_cell_polyfill",
131
+
"windows-sys 0.60.2",
132
+
]
133
+
134
+
[[package]]
135
+
name = "ascii"
136
+
version = "1.1.0"
137
+
source = "registry+https://github.com/rust-lang/crates.io-index"
138
+
checksum = "d92bec98840b8f03a5ff5413de5293bfcd8bf96467cf5452609f939ec6f5de16"
139
+
140
+
[[package]]
141
+
name = "async-compression"
142
+
version = "0.4.32"
143
+
source = "registry+https://github.com/rust-lang/crates.io-index"
144
+
checksum = "5a89bce6054c720275ac2432fbba080a66a2106a44a1b804553930ca6909f4e0"
145
+
dependencies = [
146
+
"compression-codecs",
147
+
"compression-core",
148
+
"futures-core",
149
+
"pin-project-lite",
150
+
"tokio",
151
+
]
152
+
153
+
[[package]]
154
+
name = "async-trait"
155
+
version = "0.1.89"
156
+
source = "registry+https://github.com/rust-lang/crates.io-index"
157
+
checksum = "9035ad2d096bed7955a320ee7e2230574d28fd3c3a0f186cbea1ff3c7eed5dbb"
158
+
dependencies = [
159
+
"proc-macro2",
160
+
"quote",
161
+
"syn 2.0.107",
162
+
]
163
+
164
+
[[package]]
6
165
name = "atcities-upload"
166
+
version = "1.0.1"
167
+
dependencies = [
168
+
"clap",
169
+
"env_logger",
170
+
"ignore",
171
+
"jacquard",
172
+
"lexicons",
173
+
"miette",
174
+
"mime_guess",
175
+
"regex",
176
+
"reqwest",
177
+
"thiserror 2.0.17",
178
+
"tokio",
179
+
]
180
+
181
+
[[package]]
182
+
name = "atomic-waker"
183
+
version = "1.1.2"
184
+
source = "registry+https://github.com/rust-lang/crates.io-index"
185
+
checksum = "1505bd5d3d116872e7271a6d4e16d81d0c8570876c8de68093a09ac269d8aac0"
186
+
187
+
[[package]]
188
+
name = "autocfg"
189
+
version = "1.5.0"
190
+
source = "registry+https://github.com/rust-lang/crates.io-index"
191
+
checksum = "c08606f8c3cbf4ce6ec8e28fb0014a2c086708fe954eaa885384a6165172e7e8"
192
+
193
+
[[package]]
194
+
name = "backtrace"
195
+
version = "0.3.76"
196
+
source = "registry+https://github.com/rust-lang/crates.io-index"
197
+
checksum = "bb531853791a215d7c62a30daf0dde835f381ab5de4589cfe7c649d2cbe92bd6"
198
+
dependencies = [
199
+
"addr2line",
200
+
"cfg-if",
201
+
"libc",
202
+
"miniz_oxide",
203
+
"object",
204
+
"rustc-demangle",
205
+
"windows-link 0.2.1",
206
+
]
207
+
208
+
[[package]]
209
+
name = "backtrace-ext"
210
+
version = "0.2.1"
211
+
source = "registry+https://github.com/rust-lang/crates.io-index"
212
+
checksum = "537beee3be4a18fb023b570f80e3ae28003db9167a751266b259926e25539d50"
213
+
dependencies = [
214
+
"backtrace",
215
+
]
216
+
217
+
[[package]]
218
+
name = "base-x"
219
+
version = "0.2.11"
220
+
source = "registry+https://github.com/rust-lang/crates.io-index"
221
+
checksum = "4cbbc9d0964165b47557570cce6c952866c2678457aca742aafc9fb771d30270"
222
+
223
+
[[package]]
224
+
name = "base16ct"
225
+
version = "0.2.0"
226
+
source = "registry+https://github.com/rust-lang/crates.io-index"
227
+
checksum = "4c7f02d4ea65f2c1853089ffd8d2787bdbc63de2f0d29dedbcf8ccdfa0ccd4cf"
228
+
229
+
[[package]]
230
+
name = "base256emoji"
231
+
version = "1.0.2"
232
+
source = "registry+https://github.com/rust-lang/crates.io-index"
233
+
checksum = "b5e9430d9a245a77c92176e649af6e275f20839a48389859d1661e9a128d077c"
234
+
dependencies = [
235
+
"const-str",
236
+
"match-lookup",
237
+
]
238
+
239
+
[[package]]
240
+
name = "base64"
241
+
version = "0.13.1"
242
+
source = "registry+https://github.com/rust-lang/crates.io-index"
243
+
checksum = "9e1b586273c5702936fe7b7d6896644d8be71e6314cfe09d3167c95f712589e8"
244
+
245
+
[[package]]
246
+
name = "base64"
247
+
version = "0.22.1"
248
+
source = "registry+https://github.com/rust-lang/crates.io-index"
249
+
checksum = "72b3254f16251a8381aa12e40e3c4d2f0199f8c6508fbecb9d91f575e0fbb8c6"
250
+
251
+
[[package]]
252
+
name = "base64ct"
253
+
version = "1.8.0"
254
+
source = "registry+https://github.com/rust-lang/crates.io-index"
255
+
checksum = "55248b47b0caf0546f7988906588779981c43bb1bc9d0c44087278f80cdb44ba"
256
+
257
+
[[package]]
258
+
name = "bitflags"
259
+
version = "2.9.4"
260
+
source = "registry+https://github.com/rust-lang/crates.io-index"
261
+
checksum = "2261d10cca569e4643e526d8dc2e62e433cc8aba21ab764233731f8d369bf394"
262
+
263
+
[[package]]
264
+
name = "block-buffer"
265
+
version = "0.10.4"
266
+
source = "registry+https://github.com/rust-lang/crates.io-index"
267
+
checksum = "3078c7629b62d3f0439517fa394996acacc5cbc91c5a20d8c658e77abd503a71"
268
+
dependencies = [
269
+
"generic-array",
270
+
]
271
+
272
+
[[package]]
273
+
name = "bon"
274
+
version = "3.8.1"
275
+
source = "registry+https://github.com/rust-lang/crates.io-index"
276
+
checksum = "ebeb9aaf9329dff6ceb65c689ca3db33dbf15f324909c60e4e5eef5701ce31b1"
277
+
dependencies = [
278
+
"bon-macros",
279
+
"rustversion",
280
+
]
281
+
282
+
[[package]]
283
+
name = "bon-macros"
284
+
version = "3.8.1"
285
+
source = "registry+https://github.com/rust-lang/crates.io-index"
286
+
checksum = "77e9d642a7e3a318e37c2c9427b5a6a48aa1ad55dcd986f3034ab2239045a645"
287
+
dependencies = [
288
+
"darling",
289
+
"ident_case",
290
+
"prettyplease",
291
+
"proc-macro2",
292
+
"quote",
293
+
"rustversion",
294
+
"syn 2.0.107",
295
+
]
296
+
297
+
[[package]]
298
+
name = "borsh"
299
+
version = "1.5.7"
300
+
source = "registry+https://github.com/rust-lang/crates.io-index"
301
+
checksum = "ad8646f98db542e39fc66e68a20b2144f6a732636df7c2354e74645faaa433ce"
302
+
dependencies = [
303
+
"cfg_aliases",
304
+
]
305
+
306
+
[[package]]
307
+
name = "brotli"
308
+
version = "3.5.0"
309
+
source = "registry+https://github.com/rust-lang/crates.io-index"
310
+
checksum = "d640d25bc63c50fb1f0b545ffd80207d2e10a4c965530809b40ba3386825c391"
311
+
dependencies = [
312
+
"alloc-no-stdlib",
313
+
"alloc-stdlib",
314
+
"brotli-decompressor",
315
+
]
316
+
317
+
[[package]]
318
+
name = "brotli-decompressor"
319
+
version = "2.5.1"
320
+
source = "registry+https://github.com/rust-lang/crates.io-index"
321
+
checksum = "4e2e4afe60d7dd600fdd3de8d0f08c2b7ec039712e3b6137ff98b7004e82de4f"
322
+
dependencies = [
323
+
"alloc-no-stdlib",
324
+
"alloc-stdlib",
325
+
]
326
+
327
+
[[package]]
328
+
name = "bstr"
329
+
version = "1.12.0"
330
+
source = "registry+https://github.com/rust-lang/crates.io-index"
331
+
checksum = "234113d19d0d7d613b40e86fb654acf958910802bcceab913a4f9e7cda03b1a4"
332
+
dependencies = [
333
+
"memchr",
334
+
"serde",
335
+
]
336
+
337
+
[[package]]
338
+
name = "btree-range-map"
339
+
version = "0.7.2"
340
+
source = "registry+https://github.com/rust-lang/crates.io-index"
341
+
checksum = "1be5c9672446d3800bcbcaabaeba121fe22f1fb25700c4562b22faf76d377c33"
342
+
dependencies = [
343
+
"btree-slab",
344
+
"cc-traits",
345
+
"range-traits",
346
+
"serde",
347
+
"slab",
348
+
]
349
+
350
+
[[package]]
351
+
name = "btree-slab"
352
+
version = "0.6.1"
353
+
source = "registry+https://github.com/rust-lang/crates.io-index"
354
+
checksum = "7a2b56d3029f075c4fa892428a098425b86cef5c89ae54073137ece416aef13c"
355
+
dependencies = [
356
+
"cc-traits",
357
+
"slab",
358
+
"smallvec",
359
+
]
360
+
361
+
[[package]]
362
+
name = "buf_redux"
363
+
version = "0.8.4"
364
+
source = "registry+https://github.com/rust-lang/crates.io-index"
365
+
checksum = "b953a6887648bb07a535631f2bc00fbdb2a2216f135552cb3f534ed136b9c07f"
366
+
dependencies = [
367
+
"memchr",
368
+
"safemem",
369
+
]
370
+
371
+
[[package]]
372
+
name = "bumpalo"
373
+
version = "3.19.0"
374
+
source = "registry+https://github.com/rust-lang/crates.io-index"
375
+
checksum = "46c5e41b57b8bba42a04676d81cb89e9ee8e859a1a66f80a5a72e1cb76b34d43"
376
+
377
+
[[package]]
378
+
name = "byteorder"
379
+
version = "1.5.0"
380
+
source = "registry+https://github.com/rust-lang/crates.io-index"
381
+
checksum = "1fd0f2584146f6f2ef48085050886acf353beff7305ebd1ae69500e27c67f64b"
382
+
383
+
[[package]]
384
+
name = "bytes"
385
+
version = "1.10.1"
386
+
source = "registry+https://github.com/rust-lang/crates.io-index"
387
+
checksum = "d71b6127be86fdcfddb610f7182ac57211d4b18a3e9c82eb2d17662f2227ad6a"
388
+
dependencies = [
389
+
"serde",
390
+
]
391
+
392
+
[[package]]
393
+
name = "cbor4ii"
394
+
version = "0.2.14"
395
+
source = "registry+https://github.com/rust-lang/crates.io-index"
396
+
checksum = "b544cf8c89359205f4f990d0e6f3828db42df85b5dac95d09157a250eb0749c4"
397
+
dependencies = [
398
+
"serde",
399
+
]
400
+
401
+
[[package]]
402
+
name = "cc"
403
+
version = "1.2.41"
404
+
source = "registry+https://github.com/rust-lang/crates.io-index"
405
+
checksum = "ac9fe6cdbb24b6ade63616c0a0688e45bb56732262c158df3c0c4bea4ca47cb7"
406
+
dependencies = [
407
+
"find-msvc-tools",
408
+
"shlex",
409
+
]
410
+
411
+
[[package]]
412
+
name = "cc-traits"
413
+
version = "2.0.0"
414
+
source = "registry+https://github.com/rust-lang/crates.io-index"
415
+
checksum = "060303ef31ef4a522737e1b1ab68c67916f2a787bb2f4f54f383279adba962b5"
416
+
dependencies = [
417
+
"slab",
418
+
]
419
+
420
+
[[package]]
421
+
name = "cesu8"
422
+
version = "1.1.0"
423
+
source = "registry+https://github.com/rust-lang/crates.io-index"
424
+
checksum = "6d43a04d8753f35258c91f8ec639f792891f748a1edbd759cf1dcea3382ad83c"
425
+
426
+
[[package]]
427
+
name = "cfg-if"
428
+
version = "1.0.4"
429
+
source = "registry+https://github.com/rust-lang/crates.io-index"
430
+
checksum = "9330f8b2ff13f34540b44e946ef35111825727b38d33286ef986142615121801"
431
+
432
+
[[package]]
433
+
name = "cfg_aliases"
434
+
version = "0.2.1"
435
+
source = "registry+https://github.com/rust-lang/crates.io-index"
436
+
checksum = "613afe47fcd5fac7ccf1db93babcb082c5994d996f20b8b159f2ad1658eb5724"
437
+
438
+
[[package]]
439
+
name = "chrono"
440
+
version = "0.4.42"
441
+
source = "registry+https://github.com/rust-lang/crates.io-index"
442
+
checksum = "145052bdd345b87320e369255277e3fb5152762ad123a901ef5c262dd38fe8d2"
443
+
dependencies = [
444
+
"iana-time-zone",
445
+
"js-sys",
446
+
"num-traits",
447
+
"wasm-bindgen",
448
+
"windows-link 0.2.1",
449
+
]
450
+
451
+
[[package]]
452
+
name = "chunked_transfer"
453
+
version = "1.5.0"
454
+
source = "registry+https://github.com/rust-lang/crates.io-index"
455
+
checksum = "6e4de3bc4ea267985becf712dc6d9eed8b04c953b3fcfb339ebc87acd9804901"
456
+
457
+
[[package]]
458
+
name = "ciborium"
459
+
version = "0.2.2"
460
+
source = "registry+https://github.com/rust-lang/crates.io-index"
461
+
checksum = "42e69ffd6f0917f5c029256a24d0161db17cea3997d185db0d35926308770f0e"
462
+
dependencies = [
463
+
"ciborium-io",
464
+
"ciborium-ll",
465
+
"serde",
466
+
]
467
+
468
+
[[package]]
469
+
name = "ciborium-io"
470
+
version = "0.2.2"
471
+
source = "registry+https://github.com/rust-lang/crates.io-index"
472
+
checksum = "05afea1e0a06c9be33d539b876f1ce3692f4afea2cb41f740e7743225ed1c757"
473
+
474
+
[[package]]
475
+
name = "ciborium-ll"
476
+
version = "0.2.2"
477
+
source = "registry+https://github.com/rust-lang/crates.io-index"
478
+
checksum = "57663b653d948a338bfb3eeba9bb2fd5fcfaecb9e199e87e1eda4d9e8b240fd9"
479
+
dependencies = [
480
+
"ciborium-io",
481
+
"half",
482
+
]
483
+
484
+
[[package]]
485
+
name = "cid"
486
+
version = "0.11.1"
487
+
source = "registry+https://github.com/rust-lang/crates.io-index"
488
+
checksum = "3147d8272e8fa0ccd29ce51194dd98f79ddfb8191ba9e3409884e751798acf3a"
489
+
dependencies = [
490
+
"core2",
491
+
"multibase",
492
+
"multihash",
493
+
"serde",
494
+
"serde_bytes",
495
+
"unsigned-varint",
496
+
]
497
+
498
+
[[package]]
499
+
name = "clap"
500
+
version = "4.5.49"
501
+
source = "registry+https://github.com/rust-lang/crates.io-index"
502
+
checksum = "f4512b90fa68d3a9932cea5184017c5d200f5921df706d45e853537dea51508f"
503
+
dependencies = [
504
+
"clap_builder",
505
+
"clap_derive",
506
+
]
507
+
508
+
[[package]]
509
+
name = "clap_builder"
510
+
version = "4.5.49"
511
+
source = "registry+https://github.com/rust-lang/crates.io-index"
512
+
checksum = "0025e98baa12e766c67ba13ff4695a887a1eba19569aad00a472546795bd6730"
513
+
dependencies = [
514
+
"anstream",
515
+
"anstyle",
516
+
"clap_lex",
517
+
"strsim",
518
+
]
519
+
520
+
[[package]]
521
+
name = "clap_derive"
522
+
version = "4.5.49"
523
+
source = "registry+https://github.com/rust-lang/crates.io-index"
524
+
checksum = "2a0b5487afeab2deb2ff4e03a807ad1a03ac532ff5a2cee5d86884440c7f7671"
525
+
dependencies = [
526
+
"heck 0.5.0",
527
+
"proc-macro2",
528
+
"quote",
529
+
"syn 2.0.107",
530
+
]
531
+
532
+
[[package]]
533
+
name = "clap_lex"
534
+
version = "0.7.6"
535
+
source = "registry+https://github.com/rust-lang/crates.io-index"
536
+
checksum = "a1d728cc89cf3aee9ff92b05e62b19ee65a02b5702cff7d5a377e32c6ae29d8d"
537
+
538
+
[[package]]
539
+
name = "colorchoice"
540
+
version = "1.0.4"
541
+
source = "registry+https://github.com/rust-lang/crates.io-index"
542
+
checksum = "b05b61dc5112cbb17e4b6cd61790d9845d13888356391624cbe7e41efeac1e75"
543
+
544
+
[[package]]
545
+
name = "combine"
546
+
version = "4.6.7"
547
+
source = "registry+https://github.com/rust-lang/crates.io-index"
548
+
checksum = "ba5a308b75df32fe02788e748662718f03fde005016435c444eea572398219fd"
549
+
dependencies = [
550
+
"bytes",
551
+
"memchr",
552
+
]
553
+
554
+
[[package]]
555
+
name = "compression-codecs"
556
+
version = "0.4.31"
557
+
source = "registry+https://github.com/rust-lang/crates.io-index"
558
+
checksum = "ef8a506ec4b81c460798f572caead636d57d3d7e940f998160f52bd254bf2d23"
559
+
dependencies = [
560
+
"compression-core",
561
+
"flate2",
562
+
"memchr",
563
+
]
564
+
565
+
[[package]]
566
+
name = "compression-core"
567
+
version = "0.4.29"
568
+
source = "registry+https://github.com/rust-lang/crates.io-index"
569
+
checksum = "e47641d3deaf41fb1538ac1f54735925e275eaf3bf4d55c81b137fba797e5cbb"
570
+
571
+
[[package]]
572
+
name = "const-oid"
573
+
version = "0.9.6"
574
+
source = "registry+https://github.com/rust-lang/crates.io-index"
575
+
checksum = "c2459377285ad874054d797f3ccebf984978aa39129f6eafde5cdc8315b612f8"
576
+
577
+
[[package]]
578
+
name = "const-str"
579
+
version = "0.4.3"
580
+
source = "registry+https://github.com/rust-lang/crates.io-index"
581
+
checksum = "2f421161cb492475f1661ddc9815a745a1c894592070661180fdec3d4872e9c3"
582
+
583
+
[[package]]
584
+
name = "core-foundation"
585
+
version = "0.9.4"
586
+
source = "registry+https://github.com/rust-lang/crates.io-index"
587
+
checksum = "91e195e091a93c46f7102ec7818a2aa394e1e1771c3ab4825963fa03e45afb8f"
588
+
dependencies = [
589
+
"core-foundation-sys",
590
+
"libc",
591
+
]
592
+
593
+
[[package]]
594
+
name = "core-foundation-sys"
595
+
version = "0.8.7"
596
+
source = "registry+https://github.com/rust-lang/crates.io-index"
597
+
checksum = "773648b94d0e5d620f64f280777445740e61fe701025087ec8b57f45c791888b"
598
+
599
+
[[package]]
600
+
name = "core2"
601
+
version = "0.4.0"
602
+
source = "registry+https://github.com/rust-lang/crates.io-index"
603
+
checksum = "b49ba7ef1ad6107f8824dbe97de947cbaac53c44e7f9756a1fba0d37c1eec505"
604
+
dependencies = [
605
+
"memchr",
606
+
]
607
+
608
+
[[package]]
609
+
name = "cpufeatures"
610
+
version = "0.2.17"
611
+
source = "registry+https://github.com/rust-lang/crates.io-index"
612
+
checksum = "59ed5838eebb26a2bb2e58f6d5b5316989ae9d08bab10e0e6d103e656d1b0280"
613
+
dependencies = [
614
+
"libc",
615
+
]
616
+
617
+
[[package]]
618
+
name = "crc32fast"
619
+
version = "1.5.0"
620
+
source = "registry+https://github.com/rust-lang/crates.io-index"
621
+
checksum = "9481c1c90cbf2ac953f07c8d4a58aa3945c425b7185c9154d67a65e4230da511"
622
+
dependencies = [
623
+
"cfg-if",
624
+
]
625
+
626
+
[[package]]
627
+
name = "crossbeam-deque"
628
+
version = "0.8.6"
629
+
source = "registry+https://github.com/rust-lang/crates.io-index"
630
+
checksum = "9dd111b7b7f7d55b72c0a6ae361660ee5853c9af73f70c3c2ef6858b950e2e51"
631
+
dependencies = [
632
+
"crossbeam-epoch",
633
+
"crossbeam-utils",
634
+
]
635
+
636
+
[[package]]
637
+
name = "crossbeam-epoch"
638
+
version = "0.9.18"
639
+
source = "registry+https://github.com/rust-lang/crates.io-index"
640
+
checksum = "5b82ac4a3c2ca9c3460964f020e1402edd5753411d7737aa39c3714ad1b5420e"
641
+
dependencies = [
642
+
"crossbeam-utils",
643
+
]
644
+
645
+
[[package]]
646
+
name = "crossbeam-utils"
647
+
version = "0.8.21"
648
+
source = "registry+https://github.com/rust-lang/crates.io-index"
649
+
checksum = "d0a5c400df2834b80a4c3327b3aad3a4c4cd4de0629063962b03235697506a28"
650
+
651
+
[[package]]
652
+
name = "crunchy"
653
+
version = "0.2.4"
654
+
source = "registry+https://github.com/rust-lang/crates.io-index"
655
+
checksum = "460fbee9c2c2f33933d720630a6a0bac33ba7053db5344fac858d4b8952d77d5"
656
+
657
+
[[package]]
658
+
name = "crypto-bigint"
659
+
version = "0.5.5"
660
+
source = "registry+https://github.com/rust-lang/crates.io-index"
661
+
checksum = "0dc92fb57ca44df6db8059111ab3af99a63d5d0f8375d9972e319a379c6bab76"
662
+
dependencies = [
663
+
"generic-array",
664
+
"rand_core 0.6.4",
665
+
"subtle",
666
+
"zeroize",
667
+
]
668
+
669
+
[[package]]
670
+
name = "crypto-common"
671
+
version = "0.1.6"
672
+
source = "registry+https://github.com/rust-lang/crates.io-index"
673
+
checksum = "1bfb12502f3fc46cca1bb51ac28df9d618d813cdc3d2f25b9fe775a34af26bb3"
674
+
dependencies = [
675
+
"generic-array",
676
+
"typenum",
677
+
]
678
+
679
+
[[package]]
680
+
name = "darling"
681
+
version = "0.21.3"
682
+
source = "registry+https://github.com/rust-lang/crates.io-index"
683
+
checksum = "9cdf337090841a411e2a7f3deb9187445851f91b309c0c0a29e05f74a00a48c0"
684
+
dependencies = [
685
+
"darling_core",
686
+
"darling_macro",
687
+
]
688
+
689
+
[[package]]
690
+
name = "darling_core"
691
+
version = "0.21.3"
692
+
source = "registry+https://github.com/rust-lang/crates.io-index"
693
+
checksum = "1247195ecd7e3c85f83c8d2a366e4210d588e802133e1e355180a9870b517ea4"
694
+
dependencies = [
695
+
"fnv",
696
+
"ident_case",
697
+
"proc-macro2",
698
+
"quote",
699
+
"strsim",
700
+
"syn 2.0.107",
701
+
]
702
+
703
+
[[package]]
704
+
name = "darling_macro"
705
+
version = "0.21.3"
706
+
source = "registry+https://github.com/rust-lang/crates.io-index"
707
+
checksum = "d38308df82d1080de0afee5d069fa14b0326a88c14f15c5ccda35b4a6c414c81"
708
+
dependencies = [
709
+
"darling_core",
710
+
"quote",
711
+
"syn 2.0.107",
712
+
]
713
+
714
+
[[package]]
715
+
name = "dashmap"
716
+
version = "6.1.0"
717
+
source = "registry+https://github.com/rust-lang/crates.io-index"
718
+
checksum = "5041cc499144891f3790297212f32a74fb938e5136a14943f338ef9e0ae276cf"
719
+
dependencies = [
720
+
"cfg-if",
721
+
"crossbeam-utils",
722
+
"hashbrown 0.14.5",
723
+
"lock_api",
724
+
"once_cell",
725
+
"parking_lot_core",
726
+
]
727
+
728
+
[[package]]
729
+
name = "data-encoding"
730
+
version = "2.9.0"
731
+
source = "registry+https://github.com/rust-lang/crates.io-index"
732
+
checksum = "2a2330da5de22e8a3cb63252ce2abb30116bf5265e89c0e01bc17015ce30a476"
733
+
734
+
[[package]]
735
+
name = "data-encoding-macro"
736
+
version = "0.1.18"
737
+
source = "registry+https://github.com/rust-lang/crates.io-index"
738
+
checksum = "47ce6c96ea0102f01122a185683611bd5ac8d99e62bc59dd12e6bda344ee673d"
739
+
dependencies = [
740
+
"data-encoding",
741
+
"data-encoding-macro-internal",
742
+
]
743
+
744
+
[[package]]
745
+
name = "data-encoding-macro-internal"
746
+
version = "0.1.16"
747
+
source = "registry+https://github.com/rust-lang/crates.io-index"
748
+
checksum = "8d162beedaa69905488a8da94f5ac3edb4dd4788b732fadb7bd120b2625c1976"
749
+
dependencies = [
750
+
"data-encoding",
751
+
"syn 2.0.107",
752
+
]
753
+
754
+
[[package]]
755
+
name = "deflate"
756
+
version = "1.0.0"
757
+
source = "registry+https://github.com/rust-lang/crates.io-index"
758
+
checksum = "c86f7e25f518f4b81808a2cf1c50996a61f5c2eb394b2393bd87f2a4780a432f"
759
+
dependencies = [
760
+
"adler32",
761
+
"gzip-header",
762
+
]
763
+
764
+
[[package]]
765
+
name = "der"
766
+
version = "0.7.10"
767
+
source = "registry+https://github.com/rust-lang/crates.io-index"
768
+
checksum = "e7c1832837b905bbfb5101e07cc24c8deddf52f93225eee6ead5f4d63d53ddcb"
769
+
dependencies = [
770
+
"const-oid",
771
+
"pem-rfc7468",
772
+
"zeroize",
773
+
]
774
+
775
+
[[package]]
776
+
name = "deranged"
777
+
version = "0.5.4"
778
+
source = "registry+https://github.com/rust-lang/crates.io-index"
779
+
checksum = "a41953f86f8a05768a6cda24def994fd2f424b04ec5c719cf89989779f199071"
780
+
dependencies = [
781
+
"powerfmt",
782
+
]
783
+
784
+
[[package]]
785
+
name = "digest"
786
+
version = "0.10.7"
787
+
source = "registry+https://github.com/rust-lang/crates.io-index"
788
+
checksum = "9ed9a281f7bc9b7576e61468ba615a66a5c8cfdff42420a70aa82701a3b1e292"
789
+
dependencies = [
790
+
"block-buffer",
791
+
"const-oid",
792
+
"crypto-common",
793
+
"subtle",
794
+
]
795
+
796
+
[[package]]
797
+
name = "displaydoc"
798
+
version = "0.2.5"
799
+
source = "registry+https://github.com/rust-lang/crates.io-index"
800
+
checksum = "97369cbbc041bc366949bc74d34658d6cda5621039731c6310521892a3a20ae0"
801
+
dependencies = [
802
+
"proc-macro2",
803
+
"quote",
804
+
"syn 2.0.107",
805
+
]
806
+
807
+
[[package]]
808
+
name = "ecdsa"
809
+
version = "0.16.9"
810
+
source = "registry+https://github.com/rust-lang/crates.io-index"
811
+
checksum = "ee27f32b5c5292967d2d4a9d7f1e0b0aed2c15daded5a60300e4abb9d8020bca"
812
+
dependencies = [
813
+
"der",
814
+
"digest",
815
+
"elliptic-curve",
816
+
"rfc6979",
817
+
"signature",
818
+
"spki",
819
+
]
820
+
821
+
[[package]]
822
+
name = "elliptic-curve"
823
+
version = "0.13.8"
824
+
source = "registry+https://github.com/rust-lang/crates.io-index"
825
+
checksum = "b5e6043086bf7973472e0c7dff2142ea0b680d30e18d9cc40f267efbf222bd47"
826
+
dependencies = [
827
+
"base16ct",
828
+
"crypto-bigint",
829
+
"digest",
830
+
"ff",
831
+
"generic-array",
832
+
"group",
833
+
"pem-rfc7468",
834
+
"pkcs8",
835
+
"rand_core 0.6.4",
836
+
"sec1",
837
+
"subtle",
838
+
"zeroize",
839
+
]
840
+
841
+
[[package]]
842
+
name = "encoding_rs"
843
+
version = "0.8.35"
844
+
source = "registry+https://github.com/rust-lang/crates.io-index"
845
+
checksum = "75030f3c4f45dafd7586dd6780965a8c7e8e285a5ecb86713e63a79c5b2766f3"
846
+
dependencies = [
847
+
"cfg-if",
848
+
]
849
+
850
+
[[package]]
851
+
name = "enum-as-inner"
852
+
version = "0.6.1"
853
+
source = "registry+https://github.com/rust-lang/crates.io-index"
854
+
checksum = "a1e6a265c649f3f5979b601d26f1d05ada116434c87741c9493cb56218f76cbc"
855
+
dependencies = [
856
+
"heck 0.5.0",
857
+
"proc-macro2",
858
+
"quote",
859
+
"syn 2.0.107",
860
+
]
861
+
862
+
[[package]]
863
+
name = "env_filter"
864
+
version = "0.1.4"
865
+
source = "registry+https://github.com/rust-lang/crates.io-index"
866
+
checksum = "1bf3c259d255ca70051b30e2e95b5446cdb8949ac4cd22c0d7fd634d89f568e2"
867
+
dependencies = [
868
+
"log",
869
+
"regex",
870
+
]
871
+
872
+
[[package]]
873
+
name = "env_logger"
874
+
version = "0.11.8"
875
+
source = "registry+https://github.com/rust-lang/crates.io-index"
876
+
checksum = "13c863f0904021b108aa8b2f55046443e6b1ebde8fd4a15c399893aae4fa069f"
877
+
dependencies = [
878
+
"anstream",
879
+
"anstyle",
880
+
"env_filter",
881
+
"jiff",
882
+
"log",
883
+
]
884
+
885
+
[[package]]
886
+
name = "equivalent"
887
+
version = "1.0.2"
888
+
source = "registry+https://github.com/rust-lang/crates.io-index"
889
+
checksum = "877a4ace8713b0bcf2a4e7eec82529c029f1d0619886d18145fea96c3ffe5c0f"
890
+
891
+
[[package]]
892
+
name = "errno"
893
+
version = "0.3.14"
894
+
source = "registry+https://github.com/rust-lang/crates.io-index"
895
+
checksum = "39cab71617ae0d63f51a36d69f866391735b51691dbda63cf6f96d042b63efeb"
896
+
dependencies = [
897
+
"libc",
898
+
"windows-sys 0.61.2",
899
+
]
900
+
901
+
[[package]]
902
+
name = "fastrand"
903
+
version = "2.3.0"
904
+
source = "registry+https://github.com/rust-lang/crates.io-index"
905
+
checksum = "37909eebbb50d72f9059c3b6d82c0463f2ff062c9e95845c43a6c9c0355411be"
906
+
907
+
[[package]]
908
+
name = "ff"
909
+
version = "0.13.1"
910
+
source = "registry+https://github.com/rust-lang/crates.io-index"
911
+
checksum = "c0b50bfb653653f9ca9095b427bed08ab8d75a137839d9ad64eb11810d5b6393"
912
+
dependencies = [
913
+
"rand_core 0.6.4",
914
+
"subtle",
915
+
]
916
+
917
+
[[package]]
918
+
name = "filetime"
919
+
version = "0.2.26"
920
+
source = "registry+https://github.com/rust-lang/crates.io-index"
921
+
checksum = "bc0505cd1b6fa6580283f6bdf70a73fcf4aba1184038c90902b92b3dd0df63ed"
922
+
dependencies = [
923
+
"cfg-if",
924
+
"libc",
925
+
"libredox",
926
+
"windows-sys 0.60.2",
927
+
]
928
+
929
+
[[package]]
930
+
name = "find-msvc-tools"
931
+
version = "0.1.4"
932
+
source = "registry+https://github.com/rust-lang/crates.io-index"
933
+
checksum = "52051878f80a721bb68ebfbc930e07b65ba72f2da88968ea5c06fd6ca3d3a127"
934
+
935
+
[[package]]
936
+
name = "flate2"
937
+
version = "1.1.4"
938
+
source = "registry+https://github.com/rust-lang/crates.io-index"
939
+
checksum = "dc5a4e564e38c699f2880d3fda590bedc2e69f3f84cd48b457bd892ce61d0aa9"
940
+
dependencies = [
941
+
"crc32fast",
942
+
"miniz_oxide",
943
+
]
944
+
945
+
[[package]]
946
+
name = "fnv"
947
+
version = "1.0.7"
948
+
source = "registry+https://github.com/rust-lang/crates.io-index"
949
+
checksum = "3f9eec918d3f24069decb9af1554cad7c880e2da24a9afd88aca000531ab82c1"
950
+
951
+
[[package]]
952
+
name = "foreign-types"
953
+
version = "0.3.2"
954
+
source = "registry+https://github.com/rust-lang/crates.io-index"
955
+
checksum = "f6f339eb8adc052cd2ca78910fda869aefa38d22d5cb648e6485e4d3fc06f3b1"
956
+
dependencies = [
957
+
"foreign-types-shared",
958
+
]
959
+
960
+
[[package]]
961
+
name = "foreign-types-shared"
962
+
version = "0.1.1"
963
+
source = "registry+https://github.com/rust-lang/crates.io-index"
964
+
checksum = "00b0228411908ca8685dba7fc2cdd70ec9990a6e753e89b6ac91a84c40fbaf4b"
965
+
966
+
[[package]]
967
+
name = "form_urlencoded"
968
+
version = "1.2.2"
969
+
source = "registry+https://github.com/rust-lang/crates.io-index"
970
+
checksum = "cb4cb245038516f5f85277875cdaa4f7d2c9a0fa0468de06ed190163b1581fcf"
971
+
dependencies = [
972
+
"percent-encoding",
973
+
]
974
+
975
+
[[package]]
976
+
name = "futures-channel"
977
+
version = "0.3.31"
978
+
source = "registry+https://github.com/rust-lang/crates.io-index"
979
+
checksum = "2dff15bf788c671c1934e366d07e30c1814a8ef514e1af724a602e8a2fbe1b10"
980
+
dependencies = [
981
+
"futures-core",
982
+
]
983
+
984
+
[[package]]
985
+
name = "futures-core"
986
+
version = "0.3.31"
987
+
source = "registry+https://github.com/rust-lang/crates.io-index"
988
+
checksum = "05f29059c0c2090612e8d742178b0580d2dc940c837851ad723096f87af6663e"
989
+
990
+
[[package]]
991
+
name = "futures-io"
992
+
version = "0.3.31"
993
+
source = "registry+https://github.com/rust-lang/crates.io-index"
994
+
checksum = "9e5c1b78ca4aae1ac06c48a526a655760685149f0d465d21f37abfe57ce075c6"
995
+
996
+
[[package]]
997
+
name = "futures-macro"
998
+
version = "0.3.31"
999
+
source = "registry+https://github.com/rust-lang/crates.io-index"
1000
+
checksum = "162ee34ebcb7c64a8abebc059ce0fee27c2262618d7b60ed8faf72fef13c3650"
1001
+
dependencies = [
1002
+
"proc-macro2",
1003
+
"quote",
1004
+
"syn 2.0.107",
1005
+
]
1006
+
1007
+
[[package]]
1008
+
name = "futures-sink"
1009
+
version = "0.3.31"
1010
+
source = "registry+https://github.com/rust-lang/crates.io-index"
1011
+
checksum = "e575fab7d1e0dcb8d0c7bcf9a63ee213816ab51902e6d244a95819acacf1d4f7"
1012
+
1013
+
[[package]]
1014
+
name = "futures-task"
1015
+
version = "0.3.31"
1016
+
source = "registry+https://github.com/rust-lang/crates.io-index"
1017
+
checksum = "f90f7dce0722e95104fcb095585910c0977252f286e354b5e3bd38902cd99988"
1018
+
1019
+
[[package]]
1020
+
name = "futures-util"
1021
+
version = "0.3.31"
1022
+
source = "registry+https://github.com/rust-lang/crates.io-index"
1023
+
checksum = "9fa08315bb612088cc391249efdc3bc77536f16c91f6cf495e6fbe85b20a4a81"
1024
+
dependencies = [
1025
+
"futures-core",
1026
+
"futures-io",
1027
+
"futures-macro",
1028
+
"futures-sink",
1029
+
"futures-task",
1030
+
"memchr",
1031
+
"pin-project-lite",
1032
+
"pin-utils",
1033
+
"slab",
1034
+
]
1035
+
1036
+
[[package]]
1037
+
name = "genawaiter"
1038
+
version = "0.99.1"
1039
+
source = "registry+https://github.com/rust-lang/crates.io-index"
1040
+
checksum = "c86bd0361bcbde39b13475e6e36cb24c329964aa2611be285289d1e4b751c1a0"
1041
+
dependencies = [
1042
+
"futures-core",
1043
+
"genawaiter-macro",
1044
+
"genawaiter-proc-macro",
1045
+
"proc-macro-hack",
1046
+
]
1047
+
1048
+
[[package]]
1049
+
name = "genawaiter-macro"
1050
+
version = "0.99.1"
1051
+
source = "registry+https://github.com/rust-lang/crates.io-index"
1052
+
checksum = "0b32dfe1fdfc0bbde1f22a5da25355514b5e450c33a6af6770884c8750aedfbc"
1053
+
1054
+
[[package]]
1055
+
name = "genawaiter-proc-macro"
1056
+
version = "0.99.1"
1057
+
source = "registry+https://github.com/rust-lang/crates.io-index"
1058
+
checksum = "784f84eebc366e15251c4a8c3acee82a6a6f427949776ecb88377362a9621738"
1059
+
dependencies = [
1060
+
"proc-macro-error 0.4.12",
1061
+
"proc-macro-hack",
1062
+
"proc-macro2",
1063
+
"quote",
1064
+
"syn 1.0.109",
1065
+
]
1066
+
1067
+
[[package]]
1068
+
name = "generic-array"
1069
+
version = "0.14.9"
1070
+
source = "registry+https://github.com/rust-lang/crates.io-index"
1071
+
checksum = "4bb6743198531e02858aeaea5398fcc883e71851fcbcb5a2f773e2fb6cb1edf2"
1072
+
dependencies = [
1073
+
"typenum",
1074
+
"version_check",
1075
+
"zeroize",
1076
+
]
1077
+
1078
+
[[package]]
1079
+
name = "getrandom"
1080
+
version = "0.2.16"
1081
+
source = "registry+https://github.com/rust-lang/crates.io-index"
1082
+
checksum = "335ff9f135e4384c8150d6f27c6daed433577f86b4750418338c01a1a2528592"
1083
+
dependencies = [
1084
+
"cfg-if",
1085
+
"js-sys",
1086
+
"libc",
1087
+
"wasi",
1088
+
"wasm-bindgen",
1089
+
]
1090
+
1091
+
[[package]]
1092
+
name = "getrandom"
1093
+
version = "0.3.4"
1094
+
source = "registry+https://github.com/rust-lang/crates.io-index"
1095
+
checksum = "899def5c37c4fd7b2664648c28120ecec138e4d395b459e5ca34f9cce2dd77fd"
1096
+
dependencies = [
1097
+
"cfg-if",
1098
+
"js-sys",
1099
+
"libc",
1100
+
"r-efi",
1101
+
"wasip2",
1102
+
"wasm-bindgen",
1103
+
]
1104
+
1105
+
[[package]]
1106
+
name = "gimli"
1107
+
version = "0.32.3"
1108
+
source = "registry+https://github.com/rust-lang/crates.io-index"
1109
+
checksum = "e629b9b98ef3dd8afe6ca2bd0f89306cec16d43d907889945bc5d6687f2f13c7"
1110
+
1111
+
[[package]]
1112
+
name = "globset"
1113
+
version = "0.4.17"
1114
+
source = "registry+https://github.com/rust-lang/crates.io-index"
1115
+
checksum = "eab69130804d941f8075cfd713bf8848a2c3b3f201a9457a11e6f87e1ab62305"
1116
+
dependencies = [
1117
+
"aho-corasick",
1118
+
"bstr",
1119
+
"log",
1120
+
"regex-automata",
1121
+
"regex-syntax",
1122
+
]
1123
+
1124
+
[[package]]
1125
+
name = "group"
1126
+
version = "0.13.0"
1127
+
source = "registry+https://github.com/rust-lang/crates.io-index"
1128
+
checksum = "f0f9ef7462f7c099f518d754361858f86d8a07af53ba9af0fe635bbccb151a63"
1129
+
dependencies = [
1130
+
"ff",
1131
+
"rand_core 0.6.4",
1132
+
"subtle",
1133
+
]
1134
+
1135
+
[[package]]
1136
+
name = "gzip-header"
1137
+
version = "1.0.0"
1138
+
source = "registry+https://github.com/rust-lang/crates.io-index"
1139
+
checksum = "95cc527b92e6029a62960ad99aa8a6660faa4555fe5f731aab13aa6a921795a2"
1140
+
dependencies = [
1141
+
"crc32fast",
1142
+
]
1143
+
1144
+
[[package]]
1145
+
name = "h2"
1146
+
version = "0.4.12"
1147
+
source = "registry+https://github.com/rust-lang/crates.io-index"
1148
+
checksum = "f3c0b69cfcb4e1b9f1bf2f53f95f766e4661169728ec61cd3fe5a0166f2d1386"
1149
+
dependencies = [
1150
+
"atomic-waker",
1151
+
"bytes",
1152
+
"fnv",
1153
+
"futures-core",
1154
+
"futures-sink",
1155
+
"http",
1156
+
"indexmap",
1157
+
"slab",
1158
+
"tokio",
1159
+
"tokio-util",
1160
+
"tracing",
1161
+
]
1162
+
1163
+
[[package]]
1164
+
name = "half"
1165
+
version = "2.7.1"
1166
+
source = "registry+https://github.com/rust-lang/crates.io-index"
1167
+
checksum = "6ea2d84b969582b4b1864a92dc5d27cd2b77b622a8d79306834f1be5ba20d84b"
1168
+
dependencies = [
1169
+
"cfg-if",
1170
+
"crunchy",
1171
+
"zerocopy",
1172
+
]
1173
+
1174
+
[[package]]
1175
+
name = "hashbrown"
1176
+
version = "0.14.5"
1177
+
source = "registry+https://github.com/rust-lang/crates.io-index"
1178
+
checksum = "e5274423e17b7c9fc20b6e7e208532f9b19825d82dfd615708b70edd83df41f1"
1179
+
1180
+
[[package]]
1181
+
name = "hashbrown"
1182
+
version = "0.16.0"
1183
+
source = "registry+https://github.com/rust-lang/crates.io-index"
1184
+
checksum = "5419bdc4f6a9207fbeba6d11b604d481addf78ecd10c11ad51e76c2f6482748d"
1185
+
1186
+
[[package]]
1187
+
name = "heck"
1188
+
version = "0.4.1"
1189
+
source = "registry+https://github.com/rust-lang/crates.io-index"
1190
+
checksum = "95505c38b4572b2d910cecb0281560f54b440a19336cbbcb27bf6ce6adc6f5a8"
1191
+
1192
+
[[package]]
1193
+
name = "heck"
1194
+
version = "0.5.0"
1195
+
source = "registry+https://github.com/rust-lang/crates.io-index"
1196
+
checksum = "2304e00983f87ffb38b55b444b5e3b60a884b5d30c0fca7d82fe33449bbe55ea"
1197
+
1198
+
[[package]]
1199
+
name = "hermit-abi"
1200
+
version = "0.5.2"
1201
+
source = "registry+https://github.com/rust-lang/crates.io-index"
1202
+
checksum = "fc0fef456e4baa96da950455cd02c081ca953b141298e41db3fc7e36b1da849c"
1203
+
1204
+
[[package]]
1205
+
name = "hex_fmt"
1206
+
version = "0.3.0"
1207
+
source = "registry+https://github.com/rust-lang/crates.io-index"
1208
+
checksum = "b07f60793ff0a4d9cef0f18e63b5357e06209987153a64648c972c1e5aff336f"
1209
+
1210
+
[[package]]
1211
+
name = "hickory-proto"
1212
+
version = "0.24.4"
1213
+
source = "registry+https://github.com/rust-lang/crates.io-index"
1214
+
checksum = "92652067c9ce6f66ce53cc38d1169daa36e6e7eb7dd3b63b5103bd9d97117248"
1215
+
dependencies = [
1216
+
"async-trait",
1217
+
"cfg-if",
1218
+
"data-encoding",
1219
+
"enum-as-inner",
1220
+
"futures-channel",
1221
+
"futures-io",
1222
+
"futures-util",
1223
+
"idna",
1224
+
"ipnet",
1225
+
"once_cell",
1226
+
"rand 0.8.5",
1227
+
"thiserror 1.0.69",
1228
+
"tinyvec",
1229
+
"tokio",
1230
+
"tracing",
1231
+
"url",
1232
+
]
1233
+
1234
+
[[package]]
1235
+
name = "hickory-resolver"
1236
+
version = "0.24.4"
1237
+
source = "registry+https://github.com/rust-lang/crates.io-index"
1238
+
checksum = "cbb117a1ca520e111743ab2f6688eddee69db4e0ea242545a604dce8a66fd22e"
1239
+
dependencies = [
1240
+
"cfg-if",
1241
+
"futures-util",
1242
+
"hickory-proto",
1243
+
"ipconfig",
1244
+
"lru-cache",
1245
+
"once_cell",
1246
+
"parking_lot",
1247
+
"rand 0.8.5",
1248
+
"resolv-conf",
1249
+
"smallvec",
1250
+
"thiserror 1.0.69",
1251
+
"tokio",
1252
+
"tracing",
1253
+
]
1254
+
1255
+
[[package]]
1256
+
name = "hmac"
1257
+
version = "0.12.1"
1258
+
source = "registry+https://github.com/rust-lang/crates.io-index"
1259
+
checksum = "6c49c37c09c17a53d937dfbb742eb3a961d65a994e6bcdcf37e7399d0cc8ab5e"
1260
+
dependencies = [
1261
+
"digest",
1262
+
]
1263
+
1264
+
[[package]]
1265
+
name = "home"
1266
+
version = "0.5.11"
1267
+
source = "registry+https://github.com/rust-lang/crates.io-index"
1268
+
checksum = "589533453244b0995c858700322199b2becb13b627df2851f64a2775d024abcf"
1269
+
dependencies = [
1270
+
"windows-sys 0.59.0",
1271
+
]
1272
+
1273
+
[[package]]
1274
+
name = "http"
1275
+
version = "1.3.1"
1276
+
source = "registry+https://github.com/rust-lang/crates.io-index"
1277
+
checksum = "f4a85d31aea989eead29a3aaf9e1115a180df8282431156e533de47660892565"
1278
+
dependencies = [
1279
+
"bytes",
1280
+
"fnv",
1281
+
"itoa",
1282
+
]
1283
+
1284
+
[[package]]
1285
+
name = "http-body"
1286
+
version = "1.0.1"
1287
+
source = "registry+https://github.com/rust-lang/crates.io-index"
1288
+
checksum = "1efedce1fb8e6913f23e0c92de8e62cd5b772a67e7b3946df930a62566c93184"
1289
+
dependencies = [
1290
+
"bytes",
1291
+
"http",
1292
+
]
1293
+
1294
+
[[package]]
1295
+
name = "http-body-util"
1296
+
version = "0.1.3"
1297
+
source = "registry+https://github.com/rust-lang/crates.io-index"
1298
+
checksum = "b021d93e26becf5dc7e1b75b1bed1fd93124b374ceb73f43d4d4eafec896a64a"
1299
+
dependencies = [
1300
+
"bytes",
1301
+
"futures-core",
1302
+
"http",
1303
+
"http-body",
1304
+
"pin-project-lite",
1305
+
]
1306
+
1307
+
[[package]]
1308
+
name = "httparse"
1309
+
version = "1.10.1"
1310
+
source = "registry+https://github.com/rust-lang/crates.io-index"
1311
+
checksum = "6dbf3de79e51f3d586ab4cb9d5c3e2c14aa28ed23d180cf89b4df0454a69cc87"
1312
+
1313
+
[[package]]
1314
+
name = "httpdate"
1315
+
version = "1.0.3"
1316
+
source = "registry+https://github.com/rust-lang/crates.io-index"
1317
+
checksum = "df3b46402a9d5adb4c86a0cf463f42e19994e3ee891101b1841f30a545cb49a9"
1318
+
1319
+
[[package]]
1320
+
name = "hyper"
1321
+
version = "1.7.0"
1322
+
source = "registry+https://github.com/rust-lang/crates.io-index"
1323
+
checksum = "eb3aa54a13a0dfe7fbe3a59e0c76093041720fdc77b110cc0fc260fafb4dc51e"
1324
+
dependencies = [
1325
+
"atomic-waker",
1326
+
"bytes",
1327
+
"futures-channel",
1328
+
"futures-core",
1329
+
"h2",
1330
+
"http",
1331
+
"http-body",
1332
+
"httparse",
1333
+
"itoa",
1334
+
"pin-project-lite",
1335
+
"pin-utils",
1336
+
"smallvec",
1337
+
"tokio",
1338
+
"want",
1339
+
]
1340
+
1341
+
[[package]]
1342
+
name = "hyper-rustls"
1343
+
version = "0.27.7"
1344
+
source = "registry+https://github.com/rust-lang/crates.io-index"
1345
+
checksum = "e3c93eb611681b207e1fe55d5a71ecf91572ec8a6705cdb6857f7d8d5242cf58"
1346
+
dependencies = [
1347
+
"http",
1348
+
"hyper",
1349
+
"hyper-util",
1350
+
"rustls",
1351
+
"rustls-pki-types",
1352
+
"tokio",
1353
+
"tokio-rustls",
1354
+
"tower-service",
1355
+
"webpki-roots",
1356
+
]
1357
+
1358
+
[[package]]
1359
+
name = "hyper-tls"
1360
+
version = "0.6.0"
1361
+
source = "registry+https://github.com/rust-lang/crates.io-index"
1362
+
checksum = "70206fc6890eaca9fde8a0bf71caa2ddfc9fe045ac9e5c70df101a7dbde866e0"
1363
+
dependencies = [
1364
+
"bytes",
1365
+
"http-body-util",
1366
+
"hyper",
1367
+
"hyper-util",
1368
+
"native-tls",
1369
+
"tokio",
1370
+
"tokio-native-tls",
1371
+
"tower-service",
1372
+
]
1373
+
1374
+
[[package]]
1375
+
name = "hyper-util"
1376
+
version = "0.1.17"
1377
+
source = "registry+https://github.com/rust-lang/crates.io-index"
1378
+
checksum = "3c6995591a8f1380fcb4ba966a252a4b29188d51d2b89e3a252f5305be65aea8"
1379
+
dependencies = [
1380
+
"base64 0.22.1",
1381
+
"bytes",
1382
+
"futures-channel",
1383
+
"futures-core",
1384
+
"futures-util",
1385
+
"http",
1386
+
"http-body",
1387
+
"hyper",
1388
+
"ipnet",
1389
+
"libc",
1390
+
"percent-encoding",
1391
+
"pin-project-lite",
1392
+
"socket2 0.6.1",
1393
+
"system-configuration",
1394
+
"tokio",
1395
+
"tower-service",
1396
+
"tracing",
1397
+
"windows-registry",
1398
+
]
1399
+
1400
+
[[package]]
1401
+
name = "iana-time-zone"
1402
+
version = "0.1.64"
1403
+
source = "registry+https://github.com/rust-lang/crates.io-index"
1404
+
checksum = "33e57f83510bb73707521ebaffa789ec8caf86f9657cad665b092b581d40e9fb"
1405
+
dependencies = [
1406
+
"android_system_properties",
1407
+
"core-foundation-sys",
1408
+
"iana-time-zone-haiku",
1409
+
"js-sys",
1410
+
"log",
1411
+
"wasm-bindgen",
1412
+
"windows-core",
1413
+
]
1414
+
1415
+
[[package]]
1416
+
name = "iana-time-zone-haiku"
1417
+
version = "0.1.2"
1418
+
source = "registry+https://github.com/rust-lang/crates.io-index"
1419
+
checksum = "f31827a206f56af32e590ba56d5d2d085f558508192593743f16b2306495269f"
1420
+
dependencies = [
1421
+
"cc",
1422
+
]
1423
+
1424
+
[[package]]
1425
+
name = "icu_collections"
1426
+
version = "2.0.0"
1427
+
source = "registry+https://github.com/rust-lang/crates.io-index"
1428
+
checksum = "200072f5d0e3614556f94a9930d5dc3e0662a652823904c3a75dc3b0af7fee47"
1429
+
dependencies = [
1430
+
"displaydoc",
1431
+
"potential_utf",
1432
+
"yoke",
1433
+
"zerofrom",
1434
+
"zerovec",
1435
+
]
1436
+
1437
+
[[package]]
1438
+
name = "icu_locale_core"
1439
+
version = "2.0.0"
1440
+
source = "registry+https://github.com/rust-lang/crates.io-index"
1441
+
checksum = "0cde2700ccaed3872079a65fb1a78f6c0a36c91570f28755dda67bc8f7d9f00a"
1442
+
dependencies = [
1443
+
"displaydoc",
1444
+
"litemap",
1445
+
"tinystr",
1446
+
"writeable",
1447
+
"zerovec",
1448
+
]
1449
+
1450
+
[[package]]
1451
+
name = "icu_normalizer"
1452
+
version = "2.0.0"
1453
+
source = "registry+https://github.com/rust-lang/crates.io-index"
1454
+
checksum = "436880e8e18df4d7bbc06d58432329d6458cc84531f7ac5f024e93deadb37979"
1455
+
dependencies = [
1456
+
"displaydoc",
1457
+
"icu_collections",
1458
+
"icu_normalizer_data",
1459
+
"icu_properties",
1460
+
"icu_provider",
1461
+
"smallvec",
1462
+
"zerovec",
1463
+
]
1464
+
1465
+
[[package]]
1466
+
name = "icu_normalizer_data"
1467
+
version = "2.0.0"
1468
+
source = "registry+https://github.com/rust-lang/crates.io-index"
1469
+
checksum = "00210d6893afc98edb752b664b8890f0ef174c8adbb8d0be9710fa66fbbf72d3"
1470
+
1471
+
[[package]]
1472
+
name = "icu_properties"
1473
+
version = "2.0.1"
1474
+
source = "registry+https://github.com/rust-lang/crates.io-index"
1475
+
checksum = "016c619c1eeb94efb86809b015c58f479963de65bdb6253345c1a1276f22e32b"
1476
+
dependencies = [
1477
+
"displaydoc",
1478
+
"icu_collections",
1479
+
"icu_locale_core",
1480
+
"icu_properties_data",
1481
+
"icu_provider",
1482
+
"potential_utf",
1483
+
"zerotrie",
1484
+
"zerovec",
1485
+
]
1486
+
1487
+
[[package]]
1488
+
name = "icu_properties_data"
1489
+
version = "2.0.1"
1490
+
source = "registry+https://github.com/rust-lang/crates.io-index"
1491
+
checksum = "298459143998310acd25ffe6810ed544932242d3f07083eee1084d83a71bd632"
1492
+
1493
+
[[package]]
1494
+
name = "icu_provider"
1495
+
version = "2.0.0"
1496
+
source = "registry+https://github.com/rust-lang/crates.io-index"
1497
+
checksum = "03c80da27b5f4187909049ee2d72f276f0d9f99a42c306bd0131ecfe04d8e5af"
1498
+
dependencies = [
1499
+
"displaydoc",
1500
+
"icu_locale_core",
1501
+
"stable_deref_trait",
1502
+
"tinystr",
1503
+
"writeable",
1504
+
"yoke",
1505
+
"zerofrom",
1506
+
"zerotrie",
1507
+
"zerovec",
1508
+
]
1509
+
1510
+
[[package]]
1511
+
name = "ident_case"
1512
+
version = "1.0.1"
1513
+
source = "registry+https://github.com/rust-lang/crates.io-index"
1514
+
checksum = "b9e0384b61958566e926dc50660321d12159025e767c18e043daf26b70104c39"
1515
+
1516
+
[[package]]
1517
+
name = "idna"
1518
+
version = "1.1.0"
1519
+
source = "registry+https://github.com/rust-lang/crates.io-index"
1520
+
checksum = "3b0875f23caa03898994f6ddc501886a45c7d3d62d04d2d90788d47be1b1e4de"
1521
+
dependencies = [
1522
+
"idna_adapter",
1523
+
"smallvec",
1524
+
"utf8_iter",
1525
+
]
1526
+
1527
+
[[package]]
1528
+
name = "idna_adapter"
1529
+
version = "1.2.1"
1530
+
source = "registry+https://github.com/rust-lang/crates.io-index"
1531
+
checksum = "3acae9609540aa318d1bc588455225fb2085b9ed0c4f6bd0d9d5bcd86f1a0344"
1532
+
dependencies = [
1533
+
"icu_normalizer",
1534
+
"icu_properties",
1535
+
]
1536
+
1537
+
[[package]]
1538
+
name = "ignore"
1539
+
version = "0.4.24"
1540
+
source = "registry+https://github.com/rust-lang/crates.io-index"
1541
+
checksum = "81776e6f9464432afcc28d03e52eb101c93b6f0566f52aef2427663e700f0403"
1542
+
dependencies = [
1543
+
"crossbeam-deque",
1544
+
"globset",
1545
+
"log",
1546
+
"memchr",
1547
+
"regex-automata",
1548
+
"same-file",
1549
+
"walkdir",
1550
+
"winapi-util",
1551
+
]
1552
+
1553
+
[[package]]
1554
+
name = "indexmap"
1555
+
version = "2.12.0"
1556
+
source = "registry+https://github.com/rust-lang/crates.io-index"
1557
+
checksum = "6717a8d2a5a929a1a2eb43a12812498ed141a0bcfb7e8f7844fbdbe4303bba9f"
1558
+
dependencies = [
1559
+
"equivalent",
1560
+
"hashbrown 0.16.0",
1561
+
]
1562
+
1563
+
[[package]]
1564
+
name = "indoc"
1565
+
version = "2.0.6"
1566
+
source = "registry+https://github.com/rust-lang/crates.io-index"
1567
+
checksum = "f4c7245a08504955605670dbf141fceab975f15ca21570696aebe9d2e71576bd"
1568
+
1569
+
[[package]]
1570
+
name = "ipconfig"
1571
+
version = "0.3.2"
1572
+
source = "registry+https://github.com/rust-lang/crates.io-index"
1573
+
checksum = "b58db92f96b720de98181bbbe63c831e87005ab460c1bf306eb2622b4707997f"
1574
+
dependencies = [
1575
+
"socket2 0.5.10",
1576
+
"widestring",
1577
+
"windows-sys 0.48.0",
1578
+
"winreg",
1579
+
]
1580
+
1581
+
[[package]]
1582
+
name = "ipld-core"
1583
+
version = "0.4.2"
1584
+
source = "registry+https://github.com/rust-lang/crates.io-index"
1585
+
checksum = "104718b1cc124d92a6d01ca9c9258a7df311405debb3408c445a36452f9bf8db"
1586
+
dependencies = [
1587
+
"cid",
1588
+
"serde",
1589
+
"serde_bytes",
1590
+
]
1591
+
1592
+
[[package]]
1593
+
name = "ipnet"
1594
+
version = "2.11.0"
1595
+
source = "registry+https://github.com/rust-lang/crates.io-index"
1596
+
checksum = "469fb0b9cefa57e3ef31275ee7cacb78f2fdca44e4765491884a2b119d4eb130"
1597
+
1598
+
[[package]]
1599
+
name = "iri-string"
1600
+
version = "0.7.8"
1601
+
source = "registry+https://github.com/rust-lang/crates.io-index"
1602
+
checksum = "dbc5ebe9c3a1a7a5127f920a418f7585e9e758e911d0466ed004f393b0e380b2"
1603
+
dependencies = [
1604
+
"memchr",
1605
+
"serde",
1606
+
]
1607
+
1608
+
[[package]]
1609
+
name = "is_ci"
1610
+
version = "1.2.0"
1611
+
source = "registry+https://github.com/rust-lang/crates.io-index"
1612
+
checksum = "7655c9839580ee829dfacba1d1278c2b7883e50a277ff7541299489d6bdfdc45"
1613
+
1614
+
[[package]]
1615
+
name = "is_terminal_polyfill"
1616
+
version = "1.70.1"
1617
+
source = "registry+https://github.com/rust-lang/crates.io-index"
1618
+
checksum = "7943c866cc5cd64cbc25b2e01621d07fa8eb2a1a23160ee81ce38704e97b8ecf"
1619
+
1620
+
[[package]]
1621
+
name = "itoa"
1622
+
version = "1.0.15"
1623
+
source = "registry+https://github.com/rust-lang/crates.io-index"
1624
+
checksum = "4a5f13b858c8d314ee3e8f639011f7ccefe71f97f96e50151fb991f267928e2c"
1625
+
1626
+
[[package]]
1627
+
name = "jacquard"
1628
+
version = "0.6.0"
1629
+
source = "registry+https://github.com/rust-lang/crates.io-index"
1630
+
checksum = "5857f000e67605995ba7c24c9833f840adf5c063a731a6f72f69e0e3c986791c"
1631
+
dependencies = [
1632
+
"bon",
1633
+
"bytes",
1634
+
"getrandom 0.2.16",
1635
+
"http",
1636
+
"jacquard-api",
1637
+
"jacquard-common",
1638
+
"jacquard-derive",
1639
+
"jacquard-identity",
1640
+
"jacquard-oauth",
1641
+
"jose-jwk",
1642
+
"miette",
1643
+
"p256",
1644
+
"percent-encoding",
1645
+
"rand_core 0.6.4",
1646
+
"reqwest",
1647
+
"serde",
1648
+
"serde_html_form",
1649
+
"serde_ipld_dagcbor",
1650
+
"serde_json",
1651
+
"smol_str",
1652
+
"thiserror 2.0.17",
1653
+
"tokio",
1654
+
"trait-variant",
1655
+
"url",
1656
+
]
1657
+
1658
+
[[package]]
1659
+
name = "jacquard-api"
1660
+
version = "0.6.0"
1661
+
source = "registry+https://github.com/rust-lang/crates.io-index"
1662
+
checksum = "58132b60473124a34c64c267a1c3390c2e4a4dfd62c801639903c4aefd05f52d"
1663
+
dependencies = [
1664
+
"bon",
1665
+
"bytes",
1666
+
"jacquard-common",
1667
+
"jacquard-derive",
1668
+
"miette",
1669
+
"serde",
1670
+
"serde_ipld_dagcbor",
1671
+
"thiserror 2.0.17",
1672
+
]
1673
+
1674
+
[[package]]
1675
+
name = "jacquard-common"
1676
+
version = "0.6.0"
1677
+
source = "registry+https://github.com/rust-lang/crates.io-index"
1678
+
checksum = "f7f1bab0279ae2e29c3383f132a05b9c708585fab62e94292affdf352ce13242"
1679
+
dependencies = [
1680
+
"base64 0.22.1",
1681
+
"bon",
1682
+
"bytes",
1683
+
"chrono",
1684
+
"cid",
1685
+
"genawaiter",
1686
+
"getrandom 0.3.4",
1687
+
"http",
1688
+
"ipld-core",
1689
+
"k256",
1690
+
"langtag",
1691
+
"miette",
1692
+
"multibase",
1693
+
"multihash",
1694
+
"ouroboros",
1695
+
"p256",
1696
+
"rand 0.9.2",
1697
+
"regex",
1698
+
"reqwest",
1699
+
"serde",
1700
+
"serde_html_form",
1701
+
"serde_ipld_dagcbor",
1702
+
"serde_json",
1703
+
"signature",
1704
+
"smol_str",
1705
+
"thiserror 2.0.17",
1706
+
"tokio",
1707
+
"tokio-util",
1708
+
"trait-variant",
1709
+
"url",
1710
+
]
1711
+
1712
+
[[package]]
1713
+
name = "jacquard-derive"
1714
+
version = "0.6.0"
1715
+
source = "registry+https://github.com/rust-lang/crates.io-index"
1716
+
checksum = "a4741844c0638498156338e6230a81ecb54d0a061ffc6f4f54e97b94972a01fb"
1717
+
dependencies = [
1718
+
"proc-macro2",
1719
+
"quote",
1720
+
"syn 2.0.107",
1721
+
]
1722
+
1723
+
[[package]]
1724
+
name = "jacquard-identity"
1725
+
version = "0.6.0"
1726
+
source = "registry+https://github.com/rust-lang/crates.io-index"
1727
+
checksum = "65ae022725ddc09ce03c1a02a97b895279e1d46957c0574a032fa78b81273263"
1728
+
dependencies = [
1729
+
"bon",
1730
+
"bytes",
1731
+
"hickory-resolver",
1732
+
"http",
1733
+
"jacquard-api",
1734
+
"jacquard-common",
1735
+
"miette",
1736
+
"percent-encoding",
1737
+
"reqwest",
1738
+
"serde",
1739
+
"serde_html_form",
1740
+
"serde_json",
1741
+
"thiserror 2.0.17",
1742
+
"tokio",
1743
+
"trait-variant",
1744
+
"url",
1745
+
"urlencoding",
1746
+
]
1747
+
1748
+
[[package]]
1749
+
name = "jacquard-oauth"
1750
+
version = "0.6.0"
1751
+
source = "registry+https://github.com/rust-lang/crates.io-index"
1752
+
checksum = "8c37269e2ea0c6c3418bf61fb3d342aab87b1bda706ebae49e454f8e50580cab"
1753
+
dependencies = [
1754
+
"base64 0.22.1",
1755
+
"bytes",
1756
+
"chrono",
1757
+
"dashmap",
1758
+
"elliptic-curve",
1759
+
"http",
1760
+
"jacquard-common",
1761
+
"jacquard-identity",
1762
+
"jose-jwa",
1763
+
"jose-jwk",
1764
+
"miette",
1765
+
"p256",
1766
+
"rand 0.8.5",
1767
+
"rand_core 0.6.4",
1768
+
"reqwest",
1769
+
"rouille",
1770
+
"serde",
1771
+
"serde_html_form",
1772
+
"serde_json",
1773
+
"sha2",
1774
+
"signature",
1775
+
"smol_str",
1776
+
"thiserror 2.0.17",
1777
+
"tokio",
1778
+
"trait-variant",
1779
+
"url",
1780
+
"webbrowser",
1781
+
]
1782
+
1783
+
[[package]]
1784
+
name = "jiff"
1785
+
version = "0.2.15"
1786
+
source = "registry+https://github.com/rust-lang/crates.io-index"
1787
+
checksum = "be1f93b8b1eb69c77f24bbb0afdf66f54b632ee39af40ca21c4365a1d7347e49"
1788
+
dependencies = [
1789
+
"jiff-static",
1790
+
"log",
1791
+
"portable-atomic",
1792
+
"portable-atomic-util",
1793
+
"serde",
1794
+
]
1795
+
1796
+
[[package]]
1797
+
name = "jiff-static"
1798
+
version = "0.2.15"
1799
+
source = "registry+https://github.com/rust-lang/crates.io-index"
1800
+
checksum = "03343451ff899767262ec32146f6d559dd759fdadf42ff0e227c7c48f72594b4"
1801
+
dependencies = [
1802
+
"proc-macro2",
1803
+
"quote",
1804
+
"syn 2.0.107",
1805
+
]
1806
+
1807
+
[[package]]
1808
+
name = "jni"
1809
+
version = "0.21.1"
1810
+
source = "registry+https://github.com/rust-lang/crates.io-index"
1811
+
checksum = "1a87aa2bb7d2af34197c04845522473242e1aa17c12f4935d5856491a7fb8c97"
1812
+
dependencies = [
1813
+
"cesu8",
1814
+
"cfg-if",
1815
+
"combine",
1816
+
"jni-sys",
1817
+
"log",
1818
+
"thiserror 1.0.69",
1819
+
"walkdir",
1820
+
"windows-sys 0.45.0",
1821
+
]
1822
+
1823
+
[[package]]
1824
+
name = "jni-sys"
1825
+
version = "0.3.0"
1826
+
source = "registry+https://github.com/rust-lang/crates.io-index"
1827
+
checksum = "8eaf4bc02d17cbdd7ff4c7438cafcdf7fb9a4613313ad11b4f8fefe7d3fa0130"
1828
+
1829
+
[[package]]
1830
+
name = "jose-b64"
1831
+
version = "0.1.2"
1832
+
source = "registry+https://github.com/rust-lang/crates.io-index"
1833
+
checksum = "bec69375368709666b21c76965ce67549f2d2db7605f1f8707d17c9656801b56"
1834
+
dependencies = [
1835
+
"base64ct",
1836
+
"serde",
1837
+
"subtle",
1838
+
"zeroize",
1839
+
]
1840
+
1841
+
[[package]]
1842
+
name = "jose-jwa"
1843
+
version = "0.1.2"
1844
+
source = "registry+https://github.com/rust-lang/crates.io-index"
1845
+
checksum = "9ab78e053fe886a351d67cf0d194c000f9d0dcb92906eb34d853d7e758a4b3a7"
1846
+
dependencies = [
1847
+
"serde",
1848
+
]
1849
+
1850
+
[[package]]
1851
+
name = "jose-jwk"
1852
+
version = "0.1.2"
1853
+
source = "registry+https://github.com/rust-lang/crates.io-index"
1854
+
checksum = "280fa263807fe0782ecb6f2baadc28dffc04e00558a58e33bfdb801d11fd58e7"
1855
+
dependencies = [
1856
+
"jose-b64",
1857
+
"jose-jwa",
1858
+
"p256",
1859
+
"p384",
1860
+
"rsa",
1861
+
"serde",
1862
+
"zeroize",
1863
+
]
1864
+
1865
+
[[package]]
1866
+
name = "js-sys"
1867
+
version = "0.3.81"
1868
+
source = "registry+https://github.com/rust-lang/crates.io-index"
1869
+
checksum = "ec48937a97411dcb524a265206ccd4c90bb711fca92b2792c407f268825b9305"
1870
+
dependencies = [
1871
+
"once_cell",
1872
+
"wasm-bindgen",
1873
+
]
1874
+
1875
+
[[package]]
1876
+
name = "k256"
1877
+
version = "0.13.4"
1878
+
source = "registry+https://github.com/rust-lang/crates.io-index"
1879
+
checksum = "f6e3919bbaa2945715f0bb6d3934a173d1e9a59ac23767fbaaef277265a7411b"
1880
+
dependencies = [
1881
+
"cfg-if",
1882
+
"ecdsa",
1883
+
"elliptic-curve",
1884
+
"sha2",
1885
+
]
1886
+
1887
+
[[package]]
1888
+
name = "langtag"
1889
+
version = "0.4.0"
1890
+
source = "registry+https://github.com/rust-lang/crates.io-index"
1891
+
checksum = "9ecb4c689a30e48ebeaa14237f34037e300dd072e6ad21a9ec72e810ff3c6600"
1892
+
dependencies = [
1893
+
"serde",
1894
+
"static-regular-grammar",
1895
+
"thiserror 1.0.69",
1896
+
]
1897
+
1898
+
[[package]]
1899
+
name = "lazy_static"
1900
+
version = "1.5.0"
1901
+
source = "registry+https://github.com/rust-lang/crates.io-index"
1902
+
checksum = "bbd2bcb4c963f2ddae06a2efc7e9f3591312473c50c6685e1f298068316e66fe"
1903
+
dependencies = [
1904
+
"spin",
1905
+
]
1906
+
1907
+
[[package]]
1908
+
name = "lexicons"
1909
+
version = "1.0.0"
1910
+
dependencies = [
1911
+
"bon",
1912
+
"bytes",
1913
+
"jacquard-common",
1914
+
"jacquard-derive",
1915
+
"miette",
1916
+
"serde",
1917
+
"thiserror 2.0.17",
1918
+
]
1919
+
1920
+
[[package]]
1921
+
name = "libc"
1922
+
version = "0.2.177"
1923
+
source = "registry+https://github.com/rust-lang/crates.io-index"
1924
+
checksum = "2874a2af47a2325c2001a6e6fad9b16a53b802102b528163885171cf92b15976"
1925
+
1926
+
[[package]]
1927
+
name = "libm"
1928
+
version = "0.2.15"
1929
+
source = "registry+https://github.com/rust-lang/crates.io-index"
1930
+
checksum = "f9fbbcab51052fe104eb5e5d351cf728d30a5be1fe14d9be8a3b097481fb97de"
1931
+
1932
+
[[package]]
1933
+
name = "libredox"
1934
+
version = "0.1.10"
1935
+
source = "registry+https://github.com/rust-lang/crates.io-index"
1936
+
checksum = "416f7e718bdb06000964960ffa43b4335ad4012ae8b99060261aa4a8088d5ccb"
1937
+
dependencies = [
1938
+
"bitflags",
1939
+
"libc",
1940
+
"redox_syscall",
1941
+
]
1942
+
1943
+
[[package]]
1944
+
name = "linked-hash-map"
1945
+
version = "0.5.6"
1946
+
source = "registry+https://github.com/rust-lang/crates.io-index"
1947
+
checksum = "0717cef1bc8b636c6e1c1bbdefc09e6322da8a9321966e8928ef80d20f7f770f"
1948
+
1949
+
[[package]]
1950
+
name = "linux-raw-sys"
1951
+
version = "0.11.0"
1952
+
source = "registry+https://github.com/rust-lang/crates.io-index"
1953
+
checksum = "df1d3c3b53da64cf5760482273a98e575c651a67eec7f77df96b5b642de8f039"
1954
+
1955
+
[[package]]
1956
+
name = "litemap"
1957
+
version = "0.8.0"
1958
+
source = "registry+https://github.com/rust-lang/crates.io-index"
1959
+
checksum = "241eaef5fd12c88705a01fc1066c48c4b36e0dd4377dcdc7ec3942cea7a69956"
1960
+
1961
+
[[package]]
1962
+
name = "lock_api"
1963
+
version = "0.4.14"
1964
+
source = "registry+https://github.com/rust-lang/crates.io-index"
1965
+
checksum = "224399e74b87b5f3557511d98dff8b14089b3dadafcab6bb93eab67d3aace965"
1966
+
dependencies = [
1967
+
"scopeguard",
1968
+
]
1969
+
1970
+
[[package]]
1971
+
name = "log"
1972
+
version = "0.4.28"
1973
+
source = "registry+https://github.com/rust-lang/crates.io-index"
1974
+
checksum = "34080505efa8e45a4b816c349525ebe327ceaa8559756f0356cba97ef3bf7432"
1975
+
1976
+
[[package]]
1977
+
name = "lru-cache"
1978
+
version = "0.1.2"
1979
+
source = "registry+https://github.com/rust-lang/crates.io-index"
1980
+
checksum = "31e24f1ad8321ca0e8a1e0ac13f23cb668e6f5466c2c57319f6a5cf1cc8e3b1c"
1981
+
dependencies = [
1982
+
"linked-hash-map",
1983
+
]
1984
+
1985
+
[[package]]
1986
+
name = "lru-slab"
1987
+
version = "0.1.2"
1988
+
source = "registry+https://github.com/rust-lang/crates.io-index"
1989
+
checksum = "112b39cec0b298b6c1999fee3e31427f74f676e4cb9879ed1a121b43661a4154"
1990
+
1991
+
[[package]]
1992
+
name = "malloc_buf"
1993
+
version = "0.0.6"
1994
+
source = "registry+https://github.com/rust-lang/crates.io-index"
1995
+
checksum = "62bb907fe88d54d8d9ce32a3cceab4218ed2f6b7d35617cafe9adf84e43919cb"
1996
+
dependencies = [
1997
+
"libc",
1998
+
]
1999
+
2000
+
[[package]]
2001
+
name = "match-lookup"
2002
+
version = "0.1.1"
2003
+
source = "registry+https://github.com/rust-lang/crates.io-index"
2004
+
checksum = "1265724d8cb29dbbc2b0f06fffb8bf1a8c0cf73a78eede9ba73a4a66c52a981e"
2005
+
dependencies = [
2006
+
"proc-macro2",
2007
+
"quote",
2008
+
"syn 1.0.109",
2009
+
]
2010
+
2011
+
[[package]]
2012
+
name = "memchr"
2013
+
version = "2.7.6"
2014
+
source = "registry+https://github.com/rust-lang/crates.io-index"
2015
+
checksum = "f52b00d39961fc5b2736ea853c9cc86238e165017a493d1d5c8eac6bdc4cc273"
2016
+
2017
+
[[package]]
2018
+
name = "miette"
2019
+
version = "7.6.0"
2020
+
source = "registry+https://github.com/rust-lang/crates.io-index"
2021
+
checksum = "5f98efec8807c63c752b5bd61f862c165c115b0a35685bdcfd9238c7aeb592b7"
2022
+
dependencies = [
2023
+
"backtrace",
2024
+
"backtrace-ext",
2025
+
"cfg-if",
2026
+
"miette-derive",
2027
+
"owo-colors",
2028
+
"supports-color",
2029
+
"supports-hyperlinks",
2030
+
"supports-unicode",
2031
+
"terminal_size",
2032
+
"textwrap",
2033
+
"unicode-width 0.1.14",
2034
+
]
2035
+
2036
+
[[package]]
2037
+
name = "miette-derive"
2038
+
version = "7.6.0"
2039
+
source = "registry+https://github.com/rust-lang/crates.io-index"
2040
+
checksum = "db5b29714e950dbb20d5e6f74f9dcec4edbcc1067bb7f8ed198c097b8c1a818b"
2041
+
dependencies = [
2042
+
"proc-macro2",
2043
+
"quote",
2044
+
"syn 2.0.107",
2045
+
]
2046
+
2047
+
[[package]]
2048
+
name = "mime"
2049
+
version = "0.3.17"
2050
+
source = "registry+https://github.com/rust-lang/crates.io-index"
2051
+
checksum = "6877bb514081ee2a7ff5ef9de3281f14a4dd4bceac4c09388074a6b5df8a139a"
2052
+
2053
+
[[package]]
2054
+
name = "mime_guess"
2055
+
version = "2.0.5"
2056
+
source = "registry+https://github.com/rust-lang/crates.io-index"
2057
+
checksum = "f7c44f8e672c00fe5308fa235f821cb4198414e1c77935c1ab6948d3fd78550e"
2058
+
dependencies = [
2059
+
"mime",
2060
+
"unicase",
2061
+
]
2062
+
2063
+
[[package]]
2064
+
name = "minimal-lexical"
2065
+
version = "0.2.1"
2066
+
source = "registry+https://github.com/rust-lang/crates.io-index"
2067
+
checksum = "68354c5c6bd36d73ff3feceb05efa59b6acb7626617f4962be322a825e61f79a"
2068
+
2069
+
[[package]]
2070
+
name = "miniz_oxide"
2071
+
version = "0.8.9"
2072
+
source = "registry+https://github.com/rust-lang/crates.io-index"
2073
+
checksum = "1fa76a2c86f704bdb222d66965fb3d63269ce38518b83cb0575fca855ebb6316"
2074
+
dependencies = [
2075
+
"adler2",
2076
+
"simd-adler32",
2077
+
]
2078
+
2079
+
[[package]]
2080
+
name = "mio"
2081
+
version = "1.1.0"
2082
+
source = "registry+https://github.com/rust-lang/crates.io-index"
2083
+
checksum = "69d83b0086dc8ecf3ce9ae2874b2d1290252e2a30720bea58a5c6639b0092873"
2084
+
dependencies = [
2085
+
"libc",
2086
+
"wasi",
2087
+
"windows-sys 0.61.2",
2088
+
]
2089
+
2090
+
[[package]]
2091
+
name = "multibase"
2092
+
version = "0.9.2"
2093
+
source = "registry+https://github.com/rust-lang/crates.io-index"
2094
+
checksum = "8694bb4835f452b0e3bb06dbebb1d6fc5385b6ca1caf2e55fd165c042390ec77"
2095
+
dependencies = [
2096
+
"base-x",
2097
+
"base256emoji",
2098
+
"data-encoding",
2099
+
"data-encoding-macro",
2100
+
]
2101
+
2102
+
[[package]]
2103
+
name = "multihash"
2104
+
version = "0.19.3"
2105
+
source = "registry+https://github.com/rust-lang/crates.io-index"
2106
+
checksum = "6b430e7953c29dd6a09afc29ff0bb69c6e306329ee6794700aee27b76a1aea8d"
2107
+
dependencies = [
2108
+
"core2",
2109
+
"serde",
2110
+
"unsigned-varint",
2111
+
]
2112
+
2113
+
[[package]]
2114
+
name = "multipart"
2115
+
version = "0.18.0"
2116
+
source = "registry+https://github.com/rust-lang/crates.io-index"
2117
+
checksum = "00dec633863867f29cb39df64a397cdf4a6354708ddd7759f70c7fb51c5f9182"
2118
+
dependencies = [
2119
+
"buf_redux",
2120
+
"httparse",
2121
+
"log",
2122
+
"mime",
2123
+
"mime_guess",
2124
+
"quick-error",
2125
+
"rand 0.8.5",
2126
+
"safemem",
2127
+
"tempfile",
2128
+
"twoway",
2129
+
]
2130
+
2131
+
[[package]]
2132
+
name = "native-tls"
2133
+
version = "0.2.14"
2134
+
source = "registry+https://github.com/rust-lang/crates.io-index"
2135
+
checksum = "87de3442987e9dbec73158d5c715e7ad9072fda936bb03d19d7fa10e00520f0e"
2136
+
dependencies = [
2137
+
"libc",
2138
+
"log",
2139
+
"openssl",
2140
+
"openssl-probe",
2141
+
"openssl-sys",
2142
+
"schannel",
2143
+
"security-framework",
2144
+
"security-framework-sys",
2145
+
"tempfile",
2146
+
]
2147
+
2148
+
[[package]]
2149
+
name = "ndk-context"
2150
+
version = "0.1.1"
2151
+
source = "registry+https://github.com/rust-lang/crates.io-index"
2152
+
checksum = "27b02d87554356db9e9a873add8782d4ea6e3e58ea071a9adb9a2e8ddb884a8b"
2153
+
2154
+
[[package]]
2155
+
name = "nom"
2156
+
version = "7.1.3"
2157
+
source = "registry+https://github.com/rust-lang/crates.io-index"
2158
+
checksum = "d273983c5a657a70a3e8f2a01329822f3b8c8172b73826411a55751e404a0a4a"
2159
+
dependencies = [
2160
+
"memchr",
2161
+
"minimal-lexical",
2162
+
]
2163
+
2164
+
[[package]]
2165
+
name = "num-bigint-dig"
2166
+
version = "0.8.4"
2167
+
source = "registry+https://github.com/rust-lang/crates.io-index"
2168
+
checksum = "dc84195820f291c7697304f3cbdadd1cb7199c0efc917ff5eafd71225c136151"
2169
+
dependencies = [
2170
+
"byteorder",
2171
+
"lazy_static",
2172
+
"libm",
2173
+
"num-integer",
2174
+
"num-iter",
2175
+
"num-traits",
2176
+
"rand 0.8.5",
2177
+
"smallvec",
2178
+
"zeroize",
2179
+
]
2180
+
2181
+
[[package]]
2182
+
name = "num-conv"
7
2183
version = "0.1.0"
2184
+
source = "registry+https://github.com/rust-lang/crates.io-index"
2185
+
checksum = "51d515d32fb182ee37cda2ccdcb92950d6a3c2893aa280e540671c2cd0f3b1d9"
2186
+
2187
+
[[package]]
2188
+
name = "num-integer"
2189
+
version = "0.1.46"
2190
+
source = "registry+https://github.com/rust-lang/crates.io-index"
2191
+
checksum = "7969661fd2958a5cb096e56c8e1ad0444ac2bbcd0061bd28660485a44879858f"
2192
+
dependencies = [
2193
+
"num-traits",
2194
+
]
2195
+
2196
+
[[package]]
2197
+
name = "num-iter"
2198
+
version = "0.1.45"
2199
+
source = "registry+https://github.com/rust-lang/crates.io-index"
2200
+
checksum = "1429034a0490724d0075ebb2bc9e875d6503c3cf69e235a8941aa757d83ef5bf"
2201
+
dependencies = [
2202
+
"autocfg",
2203
+
"num-integer",
2204
+
"num-traits",
2205
+
]
2206
+
2207
+
[[package]]
2208
+
name = "num-traits"
2209
+
version = "0.2.19"
2210
+
source = "registry+https://github.com/rust-lang/crates.io-index"
2211
+
checksum = "071dfc062690e90b734c0b2273ce72ad0ffa95f0c74596bc250dcfd960262841"
2212
+
dependencies = [
2213
+
"autocfg",
2214
+
"libm",
2215
+
]
2216
+
2217
+
[[package]]
2218
+
name = "num_cpus"
2219
+
version = "1.17.0"
2220
+
source = "registry+https://github.com/rust-lang/crates.io-index"
2221
+
checksum = "91df4bbde75afed763b708b7eee1e8e7651e02d97f6d5dd763e89367e957b23b"
2222
+
dependencies = [
2223
+
"hermit-abi",
2224
+
"libc",
2225
+
]
2226
+
2227
+
[[package]]
2228
+
name = "num_threads"
2229
+
version = "0.1.7"
2230
+
source = "registry+https://github.com/rust-lang/crates.io-index"
2231
+
checksum = "5c7398b9c8b70908f6371f47ed36737907c87c52af34c268fed0bf0ceb92ead9"
2232
+
dependencies = [
2233
+
"libc",
2234
+
]
2235
+
2236
+
[[package]]
2237
+
name = "objc"
2238
+
version = "0.2.7"
2239
+
source = "registry+https://github.com/rust-lang/crates.io-index"
2240
+
checksum = "915b1b472bc21c53464d6c8461c9d3af805ba1ef837e1cac254428f4a77177b1"
2241
+
dependencies = [
2242
+
"malloc_buf",
2243
+
]
2244
+
2245
+
[[package]]
2246
+
name = "object"
2247
+
version = "0.37.3"
2248
+
source = "registry+https://github.com/rust-lang/crates.io-index"
2249
+
checksum = "ff76201f031d8863c38aa7f905eca4f53abbfa15f609db4277d44cd8938f33fe"
2250
+
dependencies = [
2251
+
"memchr",
2252
+
]
2253
+
2254
+
[[package]]
2255
+
name = "once_cell"
2256
+
version = "1.21.3"
2257
+
source = "registry+https://github.com/rust-lang/crates.io-index"
2258
+
checksum = "42f5e15c9953c5e4ccceeb2e7382a716482c34515315f7b03532b8b4e8393d2d"
2259
+
2260
+
[[package]]
2261
+
name = "once_cell_polyfill"
2262
+
version = "1.70.1"
2263
+
source = "registry+https://github.com/rust-lang/crates.io-index"
2264
+
checksum = "a4895175b425cb1f87721b59f0f286c2092bd4af812243672510e1ac53e2e0ad"
2265
+
2266
+
[[package]]
2267
+
name = "openssl"
2268
+
version = "0.10.74"
2269
+
source = "registry+https://github.com/rust-lang/crates.io-index"
2270
+
checksum = "24ad14dd45412269e1a30f52ad8f0664f0f4f4a89ee8fe28c3b3527021ebb654"
2271
+
dependencies = [
2272
+
"bitflags",
2273
+
"cfg-if",
2274
+
"foreign-types",
2275
+
"libc",
2276
+
"once_cell",
2277
+
"openssl-macros",
2278
+
"openssl-sys",
2279
+
]
2280
+
2281
+
[[package]]
2282
+
name = "openssl-macros"
2283
+
version = "0.1.1"
2284
+
source = "registry+https://github.com/rust-lang/crates.io-index"
2285
+
checksum = "a948666b637a0f465e8564c73e89d4dde00d72d4d473cc972f390fc3dcee7d9c"
2286
+
dependencies = [
2287
+
"proc-macro2",
2288
+
"quote",
2289
+
"syn 2.0.107",
2290
+
]
2291
+
2292
+
[[package]]
2293
+
name = "openssl-probe"
2294
+
version = "0.1.6"
2295
+
source = "registry+https://github.com/rust-lang/crates.io-index"
2296
+
checksum = "d05e27ee213611ffe7d6348b942e8f942b37114c00cc03cec254295a4a17852e"
2297
+
2298
+
[[package]]
2299
+
name = "openssl-sys"
2300
+
version = "0.9.110"
2301
+
source = "registry+https://github.com/rust-lang/crates.io-index"
2302
+
checksum = "0a9f0075ba3c21b09f8e8b2026584b1d18d49388648f2fbbf3c97ea8deced8e2"
2303
+
dependencies = [
2304
+
"cc",
2305
+
"libc",
2306
+
"pkg-config",
2307
+
"vcpkg",
2308
+
]
2309
+
2310
+
[[package]]
2311
+
name = "ouroboros"
2312
+
version = "0.18.5"
2313
+
source = "registry+https://github.com/rust-lang/crates.io-index"
2314
+
checksum = "1e0f050db9c44b97a94723127e6be766ac5c340c48f2c4bb3ffa11713744be59"
2315
+
dependencies = [
2316
+
"aliasable",
2317
+
"ouroboros_macro",
2318
+
"static_assertions",
2319
+
]
2320
+
2321
+
[[package]]
2322
+
name = "ouroboros_macro"
2323
+
version = "0.18.5"
2324
+
source = "registry+https://github.com/rust-lang/crates.io-index"
2325
+
checksum = "3c7028bdd3d43083f6d8d4d5187680d0d3560d54df4cc9d752005268b41e64d0"
2326
+
dependencies = [
2327
+
"heck 0.4.1",
2328
+
"proc-macro2",
2329
+
"proc-macro2-diagnostics",
2330
+
"quote",
2331
+
"syn 2.0.107",
2332
+
]
2333
+
2334
+
[[package]]
2335
+
name = "owo-colors"
2336
+
version = "4.2.3"
2337
+
source = "registry+https://github.com/rust-lang/crates.io-index"
2338
+
checksum = "9c6901729fa79e91a0913333229e9ca5dc725089d1c363b2f4b4760709dc4a52"
2339
+
2340
+
[[package]]
2341
+
name = "p256"
2342
+
version = "0.13.2"
2343
+
source = "registry+https://github.com/rust-lang/crates.io-index"
2344
+
checksum = "c9863ad85fa8f4460f9c48cb909d38a0d689dba1f6f6988a5e3e0d31071bcd4b"
2345
+
dependencies = [
2346
+
"ecdsa",
2347
+
"elliptic-curve",
2348
+
"primeorder",
2349
+
"sha2",
2350
+
]
2351
+
2352
+
[[package]]
2353
+
name = "p384"
2354
+
version = "0.13.1"
2355
+
source = "registry+https://github.com/rust-lang/crates.io-index"
2356
+
checksum = "fe42f1670a52a47d448f14b6a5c61dd78fce51856e68edaa38f7ae3a46b8d6b6"
2357
+
dependencies = [
2358
+
"elliptic-curve",
2359
+
"primeorder",
2360
+
]
2361
+
2362
+
[[package]]
2363
+
name = "parking_lot"
2364
+
version = "0.12.5"
2365
+
source = "registry+https://github.com/rust-lang/crates.io-index"
2366
+
checksum = "93857453250e3077bd71ff98b6a65ea6621a19bb0f559a85248955ac12c45a1a"
2367
+
dependencies = [
2368
+
"lock_api",
2369
+
"parking_lot_core",
2370
+
]
2371
+
2372
+
[[package]]
2373
+
name = "parking_lot_core"
2374
+
version = "0.9.12"
2375
+
source = "registry+https://github.com/rust-lang/crates.io-index"
2376
+
checksum = "2621685985a2ebf1c516881c026032ac7deafcda1a2c9b7850dc81e3dfcb64c1"
2377
+
dependencies = [
2378
+
"cfg-if",
2379
+
"libc",
2380
+
"redox_syscall",
2381
+
"smallvec",
2382
+
"windows-link 0.2.1",
2383
+
]
2384
+
2385
+
[[package]]
2386
+
name = "pem-rfc7468"
2387
+
version = "0.7.0"
2388
+
source = "registry+https://github.com/rust-lang/crates.io-index"
2389
+
checksum = "88b39c9bfcfc231068454382784bb460aae594343fb030d46e9f50a645418412"
2390
+
dependencies = [
2391
+
"base64ct",
2392
+
]
2393
+
2394
+
[[package]]
2395
+
name = "percent-encoding"
2396
+
version = "2.3.2"
2397
+
source = "registry+https://github.com/rust-lang/crates.io-index"
2398
+
checksum = "9b4f627cb1b25917193a259e49bdad08f671f8d9708acfd5fe0a8c1455d87220"
2399
+
2400
+
[[package]]
2401
+
name = "pin-project-lite"
2402
+
version = "0.2.16"
2403
+
source = "registry+https://github.com/rust-lang/crates.io-index"
2404
+
checksum = "3b3cff922bd51709b605d9ead9aa71031d81447142d828eb4a6eba76fe619f9b"
2405
+
2406
+
[[package]]
2407
+
name = "pin-utils"
2408
+
version = "0.1.0"
2409
+
source = "registry+https://github.com/rust-lang/crates.io-index"
2410
+
checksum = "8b870d8c151b6f2fb93e84a13146138f05d02ed11c7e7c54f8826aaaf7c9f184"
2411
+
2412
+
[[package]]
2413
+
name = "pkcs1"
2414
+
version = "0.7.5"
2415
+
source = "registry+https://github.com/rust-lang/crates.io-index"
2416
+
checksum = "c8ffb9f10fa047879315e6625af03c164b16962a5368d724ed16323b68ace47f"
2417
+
dependencies = [
2418
+
"der",
2419
+
"pkcs8",
2420
+
"spki",
2421
+
]
2422
+
2423
+
[[package]]
2424
+
name = "pkcs8"
2425
+
version = "0.10.2"
2426
+
source = "registry+https://github.com/rust-lang/crates.io-index"
2427
+
checksum = "f950b2377845cebe5cf8b5165cb3cc1a5e0fa5cfa3e1f7f55707d8fd82e0a7b7"
2428
+
dependencies = [
2429
+
"der",
2430
+
"spki",
2431
+
]
2432
+
2433
+
[[package]]
2434
+
name = "pkg-config"
2435
+
version = "0.3.32"
2436
+
source = "registry+https://github.com/rust-lang/crates.io-index"
2437
+
checksum = "7edddbd0b52d732b21ad9a5fab5c704c14cd949e5e9a1ec5929a24fded1b904c"
2438
+
2439
+
[[package]]
2440
+
name = "portable-atomic"
2441
+
version = "1.11.1"
2442
+
source = "registry+https://github.com/rust-lang/crates.io-index"
2443
+
checksum = "f84267b20a16ea918e43c6a88433c2d54fa145c92a811b5b047ccbe153674483"
2444
+
2445
+
[[package]]
2446
+
name = "portable-atomic-util"
2447
+
version = "0.2.4"
2448
+
source = "registry+https://github.com/rust-lang/crates.io-index"
2449
+
checksum = "d8a2f0d8d040d7848a709caf78912debcc3f33ee4b3cac47d73d1e1069e83507"
2450
+
dependencies = [
2451
+
"portable-atomic",
2452
+
]
2453
+
2454
+
[[package]]
2455
+
name = "potential_utf"
2456
+
version = "0.1.3"
2457
+
source = "registry+https://github.com/rust-lang/crates.io-index"
2458
+
checksum = "84df19adbe5b5a0782edcab45899906947ab039ccf4573713735ee7de1e6b08a"
2459
+
dependencies = [
2460
+
"zerovec",
2461
+
]
2462
+
2463
+
[[package]]
2464
+
name = "powerfmt"
2465
+
version = "0.2.0"
2466
+
source = "registry+https://github.com/rust-lang/crates.io-index"
2467
+
checksum = "439ee305def115ba05938db6eb1644ff94165c5ab5e9420d1c1bcedbba909391"
2468
+
2469
+
[[package]]
2470
+
name = "ppv-lite86"
2471
+
version = "0.2.21"
2472
+
source = "registry+https://github.com/rust-lang/crates.io-index"
2473
+
checksum = "85eae3c4ed2f50dcfe72643da4befc30deadb458a9b590d720cde2f2b1e97da9"
2474
+
dependencies = [
2475
+
"zerocopy",
2476
+
]
2477
+
2478
+
[[package]]
2479
+
name = "prettyplease"
2480
+
version = "0.2.37"
2481
+
source = "registry+https://github.com/rust-lang/crates.io-index"
2482
+
checksum = "479ca8adacdd7ce8f1fb39ce9ecccbfe93a3f1344b3d0d97f20bc0196208f62b"
2483
+
dependencies = [
2484
+
"proc-macro2",
2485
+
"syn 2.0.107",
2486
+
]
2487
+
2488
+
[[package]]
2489
+
name = "primeorder"
2490
+
version = "0.13.6"
2491
+
source = "registry+https://github.com/rust-lang/crates.io-index"
2492
+
checksum = "353e1ca18966c16d9deb1c69278edbc5f194139612772bd9537af60ac231e1e6"
2493
+
dependencies = [
2494
+
"elliptic-curve",
2495
+
]
2496
+
2497
+
[[package]]
2498
+
name = "proc-macro-error"
2499
+
version = "0.4.12"
2500
+
source = "registry+https://github.com/rust-lang/crates.io-index"
2501
+
checksum = "18f33027081eba0a6d8aba6d1b1c3a3be58cbb12106341c2d5759fcd9b5277e7"
2502
+
dependencies = [
2503
+
"proc-macro-error-attr 0.4.12",
2504
+
"proc-macro2",
2505
+
"quote",
2506
+
"syn 1.0.109",
2507
+
"version_check",
2508
+
]
2509
+
2510
+
[[package]]
2511
+
name = "proc-macro-error"
2512
+
version = "1.0.4"
2513
+
source = "registry+https://github.com/rust-lang/crates.io-index"
2514
+
checksum = "da25490ff9892aab3fcf7c36f08cfb902dd3e71ca0f9f9517bea02a73a5ce38c"
2515
+
dependencies = [
2516
+
"proc-macro-error-attr 1.0.4",
2517
+
"proc-macro2",
2518
+
"quote",
2519
+
"syn 1.0.109",
2520
+
"version_check",
2521
+
]
2522
+
2523
+
[[package]]
2524
+
name = "proc-macro-error-attr"
2525
+
version = "0.4.12"
2526
+
source = "registry+https://github.com/rust-lang/crates.io-index"
2527
+
checksum = "8a5b4b77fdb63c1eca72173d68d24501c54ab1269409f6b672c85deb18af69de"
2528
+
dependencies = [
2529
+
"proc-macro2",
2530
+
"quote",
2531
+
"syn 1.0.109",
2532
+
"syn-mid",
2533
+
"version_check",
2534
+
]
2535
+
2536
+
[[package]]
2537
+
name = "proc-macro-error-attr"
2538
+
version = "1.0.4"
2539
+
source = "registry+https://github.com/rust-lang/crates.io-index"
2540
+
checksum = "a1be40180e52ecc98ad80b184934baf3d0d29f979574e439af5a55274b35f869"
2541
+
dependencies = [
2542
+
"proc-macro2",
2543
+
"quote",
2544
+
"version_check",
2545
+
]
2546
+
2547
+
[[package]]
2548
+
name = "proc-macro-hack"
2549
+
version = "0.5.20+deprecated"
2550
+
source = "registry+https://github.com/rust-lang/crates.io-index"
2551
+
checksum = "dc375e1527247fe1a97d8b7156678dfe7c1af2fc075c9a4db3690ecd2a148068"
2552
+
2553
+
[[package]]
2554
+
name = "proc-macro2"
2555
+
version = "1.0.101"
2556
+
source = "registry+https://github.com/rust-lang/crates.io-index"
2557
+
checksum = "89ae43fd86e4158d6db51ad8e2b80f313af9cc74f5c0e03ccb87de09998732de"
2558
+
dependencies = [
2559
+
"unicode-ident",
2560
+
]
2561
+
2562
+
[[package]]
2563
+
name = "proc-macro2-diagnostics"
2564
+
version = "0.10.1"
2565
+
source = "registry+https://github.com/rust-lang/crates.io-index"
2566
+
checksum = "af066a9c399a26e020ada66a034357a868728e72cd426f3adcd35f80d88d88c8"
2567
+
dependencies = [
2568
+
"proc-macro2",
2569
+
"quote",
2570
+
"syn 2.0.107",
2571
+
"version_check",
2572
+
"yansi",
2573
+
]
2574
+
2575
+
[[package]]
2576
+
name = "quick-error"
2577
+
version = "1.2.3"
2578
+
source = "registry+https://github.com/rust-lang/crates.io-index"
2579
+
checksum = "a1d01941d82fa2ab50be1e79e6714289dd7cde78eba4c074bc5a4374f650dfe0"
2580
+
2581
+
[[package]]
2582
+
name = "quinn"
2583
+
version = "0.11.9"
2584
+
source = "registry+https://github.com/rust-lang/crates.io-index"
2585
+
checksum = "b9e20a958963c291dc322d98411f541009df2ced7b5a4f2bd52337638cfccf20"
2586
+
dependencies = [
2587
+
"bytes",
2588
+
"cfg_aliases",
2589
+
"pin-project-lite",
2590
+
"quinn-proto",
2591
+
"quinn-udp",
2592
+
"rustc-hash",
2593
+
"rustls",
2594
+
"socket2 0.6.1",
2595
+
"thiserror 2.0.17",
2596
+
"tokio",
2597
+
"tracing",
2598
+
"web-time",
2599
+
]
2600
+
2601
+
[[package]]
2602
+
name = "quinn-proto"
2603
+
version = "0.11.13"
2604
+
source = "registry+https://github.com/rust-lang/crates.io-index"
2605
+
checksum = "f1906b49b0c3bc04b5fe5d86a77925ae6524a19b816ae38ce1e426255f1d8a31"
2606
+
dependencies = [
2607
+
"bytes",
2608
+
"getrandom 0.3.4",
2609
+
"lru-slab",
2610
+
"rand 0.9.2",
2611
+
"ring",
2612
+
"rustc-hash",
2613
+
"rustls",
2614
+
"rustls-pki-types",
2615
+
"slab",
2616
+
"thiserror 2.0.17",
2617
+
"tinyvec",
2618
+
"tracing",
2619
+
"web-time",
2620
+
]
2621
+
2622
+
[[package]]
2623
+
name = "quinn-udp"
2624
+
version = "0.5.14"
2625
+
source = "registry+https://github.com/rust-lang/crates.io-index"
2626
+
checksum = "addec6a0dcad8a8d96a771f815f0eaf55f9d1805756410b39f5fa81332574cbd"
2627
+
dependencies = [
2628
+
"cfg_aliases",
2629
+
"libc",
2630
+
"once_cell",
2631
+
"socket2 0.6.1",
2632
+
"tracing",
2633
+
"windows-sys 0.60.2",
2634
+
]
2635
+
2636
+
[[package]]
2637
+
name = "quote"
2638
+
version = "1.0.41"
2639
+
source = "registry+https://github.com/rust-lang/crates.io-index"
2640
+
checksum = "ce25767e7b499d1b604768e7cde645d14cc8584231ea6b295e9c9eb22c02e1d1"
2641
+
dependencies = [
2642
+
"proc-macro2",
2643
+
]
2644
+
2645
+
[[package]]
2646
+
name = "r-efi"
2647
+
version = "5.3.0"
2648
+
source = "registry+https://github.com/rust-lang/crates.io-index"
2649
+
checksum = "69cdb34c158ceb288df11e18b4bd39de994f6657d83847bdffdbd7f346754b0f"
2650
+
2651
+
[[package]]
2652
+
name = "rand"
2653
+
version = "0.8.5"
2654
+
source = "registry+https://github.com/rust-lang/crates.io-index"
2655
+
checksum = "34af8d1a0e25924bc5b7c43c079c942339d8f0a8b57c39049bef581b46327404"
2656
+
dependencies = [
2657
+
"libc",
2658
+
"rand_chacha 0.3.1",
2659
+
"rand_core 0.6.4",
2660
+
]
2661
+
2662
+
[[package]]
2663
+
name = "rand"
2664
+
version = "0.9.2"
2665
+
source = "registry+https://github.com/rust-lang/crates.io-index"
2666
+
checksum = "6db2770f06117d490610c7488547d543617b21bfa07796d7a12f6f1bd53850d1"
2667
+
dependencies = [
2668
+
"rand_chacha 0.9.0",
2669
+
"rand_core 0.9.3",
2670
+
]
2671
+
2672
+
[[package]]
2673
+
name = "rand_chacha"
2674
+
version = "0.3.1"
2675
+
source = "registry+https://github.com/rust-lang/crates.io-index"
2676
+
checksum = "e6c10a63a0fa32252be49d21e7709d4d4baf8d231c2dbce1eaa8141b9b127d88"
2677
+
dependencies = [
2678
+
"ppv-lite86",
2679
+
"rand_core 0.6.4",
2680
+
]
2681
+
2682
+
[[package]]
2683
+
name = "rand_chacha"
2684
+
version = "0.9.0"
2685
+
source = "registry+https://github.com/rust-lang/crates.io-index"
2686
+
checksum = "d3022b5f1df60f26e1ffddd6c66e8aa15de382ae63b3a0c1bfc0e4d3e3f325cb"
2687
+
dependencies = [
2688
+
"ppv-lite86",
2689
+
"rand_core 0.9.3",
2690
+
]
2691
+
2692
+
[[package]]
2693
+
name = "rand_core"
2694
+
version = "0.6.4"
2695
+
source = "registry+https://github.com/rust-lang/crates.io-index"
2696
+
checksum = "ec0be4795e2f6a28069bec0b5ff3e2ac9bafc99e6a9a7dc3547996c5c816922c"
2697
+
dependencies = [
2698
+
"getrandom 0.2.16",
2699
+
]
2700
+
2701
+
[[package]]
2702
+
name = "rand_core"
2703
+
version = "0.9.3"
2704
+
source = "registry+https://github.com/rust-lang/crates.io-index"
2705
+
checksum = "99d9a13982dcf210057a8a78572b2217b667c3beacbf3a0d8b454f6f82837d38"
2706
+
dependencies = [
2707
+
"getrandom 0.3.4",
2708
+
]
2709
+
2710
+
[[package]]
2711
+
name = "range-traits"
2712
+
version = "0.3.2"
2713
+
source = "registry+https://github.com/rust-lang/crates.io-index"
2714
+
checksum = "d20581732dd76fa913c7dff1a2412b714afe3573e94d41c34719de73337cc8ab"
2715
+
2716
+
[[package]]
2717
+
name = "raw-window-handle"
2718
+
version = "0.5.2"
2719
+
source = "registry+https://github.com/rust-lang/crates.io-index"
2720
+
checksum = "f2ff9a1f06a88b01621b7ae906ef0211290d1c8a168a15542486a8f61c0833b9"
2721
+
2722
+
[[package]]
2723
+
name = "redox_syscall"
2724
+
version = "0.5.18"
2725
+
source = "registry+https://github.com/rust-lang/crates.io-index"
2726
+
checksum = "ed2bf2547551a7053d6fdfafda3f938979645c44812fbfcda098faae3f1a362d"
2727
+
dependencies = [
2728
+
"bitflags",
2729
+
]
2730
+
2731
+
[[package]]
2732
+
name = "regex"
2733
+
version = "1.12.2"
2734
+
source = "registry+https://github.com/rust-lang/crates.io-index"
2735
+
checksum = "843bc0191f75f3e22651ae5f1e72939ab2f72a4bc30fa80a066bd66edefc24d4"
2736
+
dependencies = [
2737
+
"aho-corasick",
2738
+
"memchr",
2739
+
"regex-automata",
2740
+
"regex-syntax",
2741
+
]
2742
+
2743
+
[[package]]
2744
+
name = "regex-automata"
2745
+
version = "0.4.13"
2746
+
source = "registry+https://github.com/rust-lang/crates.io-index"
2747
+
checksum = "5276caf25ac86c8d810222b3dbb938e512c55c6831a10f3e6ed1c93b84041f1c"
2748
+
dependencies = [
2749
+
"aho-corasick",
2750
+
"memchr",
2751
+
"regex-syntax",
2752
+
]
2753
+
2754
+
[[package]]
2755
+
name = "regex-syntax"
2756
+
version = "0.8.8"
2757
+
source = "registry+https://github.com/rust-lang/crates.io-index"
2758
+
checksum = "7a2d987857b319362043e95f5353c0535c1f58eec5336fdfcf626430af7def58"
2759
+
2760
+
[[package]]
2761
+
name = "reqwest"
2762
+
version = "0.12.24"
2763
+
source = "registry+https://github.com/rust-lang/crates.io-index"
2764
+
checksum = "9d0946410b9f7b082a427e4ef5c8ff541a88b357bc6c637c40db3a68ac70a36f"
2765
+
dependencies = [
2766
+
"async-compression",
2767
+
"base64 0.22.1",
2768
+
"bytes",
2769
+
"encoding_rs",
2770
+
"futures-core",
2771
+
"futures-util",
2772
+
"h2",
2773
+
"http",
2774
+
"http-body",
2775
+
"http-body-util",
2776
+
"hyper",
2777
+
"hyper-rustls",
2778
+
"hyper-tls",
2779
+
"hyper-util",
2780
+
"js-sys",
2781
+
"log",
2782
+
"mime",
2783
+
"native-tls",
2784
+
"percent-encoding",
2785
+
"pin-project-lite",
2786
+
"quinn",
2787
+
"rustls",
2788
+
"rustls-pki-types",
2789
+
"serde",
2790
+
"serde_json",
2791
+
"serde_urlencoded",
2792
+
"sync_wrapper",
2793
+
"tokio",
2794
+
"tokio-native-tls",
2795
+
"tokio-rustls",
2796
+
"tokio-util",
2797
+
"tower",
2798
+
"tower-http",
2799
+
"tower-service",
2800
+
"url",
2801
+
"wasm-bindgen",
2802
+
"wasm-bindgen-futures",
2803
+
"wasm-streams",
2804
+
"web-sys",
2805
+
"webpki-roots",
2806
+
]
2807
+
2808
+
[[package]]
2809
+
name = "resolv-conf"
2810
+
version = "0.7.5"
2811
+
source = "registry+https://github.com/rust-lang/crates.io-index"
2812
+
checksum = "6b3789b30bd25ba102de4beabd95d21ac45b69b1be7d14522bab988c526d6799"
2813
+
2814
+
[[package]]
2815
+
name = "rfc6979"
2816
+
version = "0.4.0"
2817
+
source = "registry+https://github.com/rust-lang/crates.io-index"
2818
+
checksum = "f8dd2a808d456c4a54e300a23e9f5a67e122c3024119acbfd73e3bf664491cb2"
2819
+
dependencies = [
2820
+
"hmac",
2821
+
"subtle",
2822
+
]
2823
+
2824
+
[[package]]
2825
+
name = "ring"
2826
+
version = "0.17.14"
2827
+
source = "registry+https://github.com/rust-lang/crates.io-index"
2828
+
checksum = "a4689e6c2294d81e88dc6261c768b63bc4fcdb852be6d1352498b114f61383b7"
2829
+
dependencies = [
2830
+
"cc",
2831
+
"cfg-if",
2832
+
"getrandom 0.2.16",
2833
+
"libc",
2834
+
"untrusted",
2835
+
"windows-sys 0.52.0",
2836
+
]
2837
+
2838
+
[[package]]
2839
+
name = "rouille"
2840
+
version = "3.6.2"
2841
+
source = "registry+https://github.com/rust-lang/crates.io-index"
2842
+
checksum = "3716fbf57fc1084d7a706adf4e445298d123e4a44294c4e8213caf1b85fcc921"
2843
+
dependencies = [
2844
+
"base64 0.13.1",
2845
+
"brotli",
2846
+
"chrono",
2847
+
"deflate",
2848
+
"filetime",
2849
+
"multipart",
2850
+
"percent-encoding",
2851
+
"rand 0.8.5",
2852
+
"serde",
2853
+
"serde_derive",
2854
+
"serde_json",
2855
+
"sha1_smol",
2856
+
"threadpool",
2857
+
"time",
2858
+
"tiny_http",
2859
+
"url",
2860
+
]
2861
+
2862
+
[[package]]
2863
+
name = "rsa"
2864
+
version = "0.9.8"
2865
+
source = "registry+https://github.com/rust-lang/crates.io-index"
2866
+
checksum = "78928ac1ed176a5ca1d17e578a1825f3d81ca54cf41053a592584b020cfd691b"
2867
+
dependencies = [
2868
+
"const-oid",
2869
+
"digest",
2870
+
"num-bigint-dig",
2871
+
"num-integer",
2872
+
"num-traits",
2873
+
"pkcs1",
2874
+
"pkcs8",
2875
+
"rand_core 0.6.4",
2876
+
"signature",
2877
+
"spki",
2878
+
"subtle",
2879
+
"zeroize",
2880
+
]
2881
+
2882
+
[[package]]
2883
+
name = "rustc-demangle"
2884
+
version = "0.1.26"
2885
+
source = "registry+https://github.com/rust-lang/crates.io-index"
2886
+
checksum = "56f7d92ca342cea22a06f2121d944b4fd82af56988c270852495420f961d4ace"
2887
+
2888
+
[[package]]
2889
+
name = "rustc-hash"
2890
+
version = "2.1.1"
2891
+
source = "registry+https://github.com/rust-lang/crates.io-index"
2892
+
checksum = "357703d41365b4b27c590e3ed91eabb1b663f07c4c084095e60cbed4362dff0d"
2893
+
2894
+
[[package]]
2895
+
name = "rustix"
2896
+
version = "1.1.2"
2897
+
source = "registry+https://github.com/rust-lang/crates.io-index"
2898
+
checksum = "cd15f8a2c5551a84d56efdc1cd049089e409ac19a3072d5037a17fd70719ff3e"
2899
+
dependencies = [
2900
+
"bitflags",
2901
+
"errno",
2902
+
"libc",
2903
+
"linux-raw-sys",
2904
+
"windows-sys 0.61.2",
2905
+
]
2906
+
2907
+
[[package]]
2908
+
name = "rustls"
2909
+
version = "0.23.33"
2910
+
source = "registry+https://github.com/rust-lang/crates.io-index"
2911
+
checksum = "751e04a496ca00bb97a5e043158d23d66b5aabf2e1d5aa2a0aaebb1aafe6f82c"
2912
+
dependencies = [
2913
+
"once_cell",
2914
+
"ring",
2915
+
"rustls-pki-types",
2916
+
"rustls-webpki",
2917
+
"subtle",
2918
+
"zeroize",
2919
+
]
2920
+
2921
+
[[package]]
2922
+
name = "rustls-pki-types"
2923
+
version = "1.12.0"
2924
+
source = "registry+https://github.com/rust-lang/crates.io-index"
2925
+
checksum = "229a4a4c221013e7e1f1a043678c5cc39fe5171437c88fb47151a21e6f5b5c79"
2926
+
dependencies = [
2927
+
"web-time",
2928
+
"zeroize",
2929
+
]
2930
+
2931
+
[[package]]
2932
+
name = "rustls-webpki"
2933
+
version = "0.103.7"
2934
+
source = "registry+https://github.com/rust-lang/crates.io-index"
2935
+
checksum = "e10b3f4191e8a80e6b43eebabfac91e5dcecebb27a71f04e820c47ec41d314bf"
2936
+
dependencies = [
2937
+
"ring",
2938
+
"rustls-pki-types",
2939
+
"untrusted",
2940
+
]
2941
+
2942
+
[[package]]
2943
+
name = "rustversion"
2944
+
version = "1.0.22"
2945
+
source = "registry+https://github.com/rust-lang/crates.io-index"
2946
+
checksum = "b39cdef0fa800fc44525c84ccb54a029961a8215f9619753635a9c0d2538d46d"
2947
+
2948
+
[[package]]
2949
+
name = "ryu"
2950
+
version = "1.0.20"
2951
+
source = "registry+https://github.com/rust-lang/crates.io-index"
2952
+
checksum = "28d3b2b1366ec20994f1fd18c3c594f05c5dd4bc44d8bb0c1c632c8d6829481f"
2953
+
2954
+
[[package]]
2955
+
name = "safemem"
2956
+
version = "0.3.3"
2957
+
source = "registry+https://github.com/rust-lang/crates.io-index"
2958
+
checksum = "ef703b7cb59335eae2eb93ceb664c0eb7ea6bf567079d843e09420219668e072"
2959
+
2960
+
[[package]]
2961
+
name = "same-file"
2962
+
version = "1.0.6"
2963
+
source = "registry+https://github.com/rust-lang/crates.io-index"
2964
+
checksum = "93fc1dc3aaa9bfed95e02e6eadabb4baf7e3078b0bd1b4d7b6b0b68378900502"
2965
+
dependencies = [
2966
+
"winapi-util",
2967
+
]
2968
+
2969
+
[[package]]
2970
+
name = "schannel"
2971
+
version = "0.1.28"
2972
+
source = "registry+https://github.com/rust-lang/crates.io-index"
2973
+
checksum = "891d81b926048e76efe18581bf793546b4c0eaf8448d72be8de2bbee5fd166e1"
2974
+
dependencies = [
2975
+
"windows-sys 0.61.2",
2976
+
]
2977
+
2978
+
[[package]]
2979
+
name = "scopeguard"
2980
+
version = "1.2.0"
2981
+
source = "registry+https://github.com/rust-lang/crates.io-index"
2982
+
checksum = "94143f37725109f92c262ed2cf5e59bce7498c01bcc1502d7b9afe439a4e9f49"
2983
+
2984
+
[[package]]
2985
+
name = "sec1"
2986
+
version = "0.7.3"
2987
+
source = "registry+https://github.com/rust-lang/crates.io-index"
2988
+
checksum = "d3e97a565f76233a6003f9f5c54be1d9c5bdfa3eccfb189469f11ec4901c47dc"
2989
+
dependencies = [
2990
+
"base16ct",
2991
+
"der",
2992
+
"generic-array",
2993
+
"pkcs8",
2994
+
"subtle",
2995
+
"zeroize",
2996
+
]
2997
+
2998
+
[[package]]
2999
+
name = "security-framework"
3000
+
version = "2.11.1"
3001
+
source = "registry+https://github.com/rust-lang/crates.io-index"
3002
+
checksum = "897b2245f0b511c87893af39b033e5ca9cce68824c4d7e7630b5a1d339658d02"
3003
+
dependencies = [
3004
+
"bitflags",
3005
+
"core-foundation",
3006
+
"core-foundation-sys",
3007
+
"libc",
3008
+
"security-framework-sys",
3009
+
]
3010
+
3011
+
[[package]]
3012
+
name = "security-framework-sys"
3013
+
version = "2.15.0"
3014
+
source = "registry+https://github.com/rust-lang/crates.io-index"
3015
+
checksum = "cc1f0cbffaac4852523ce30d8bd3c5cdc873501d96ff467ca09b6767bb8cd5c0"
3016
+
dependencies = [
3017
+
"core-foundation-sys",
3018
+
"libc",
3019
+
]
3020
+
3021
+
[[package]]
3022
+
name = "serde"
3023
+
version = "1.0.228"
3024
+
source = "registry+https://github.com/rust-lang/crates.io-index"
3025
+
checksum = "9a8e94ea7f378bd32cbbd37198a4a91436180c5bb472411e48b5ec2e2124ae9e"
3026
+
dependencies = [
3027
+
"serde_core",
3028
+
"serde_derive",
3029
+
]
3030
+
3031
+
[[package]]
3032
+
name = "serde_bytes"
3033
+
version = "0.11.19"
3034
+
source = "registry+https://github.com/rust-lang/crates.io-index"
3035
+
checksum = "a5d440709e79d88e51ac01c4b72fc6cb7314017bb7da9eeff678aa94c10e3ea8"
3036
+
dependencies = [
3037
+
"serde",
3038
+
"serde_core",
3039
+
]
3040
+
3041
+
[[package]]
3042
+
name = "serde_core"
3043
+
version = "1.0.228"
3044
+
source = "registry+https://github.com/rust-lang/crates.io-index"
3045
+
checksum = "41d385c7d4ca58e59fc732af25c3983b67ac852c1a25000afe1175de458b67ad"
3046
+
dependencies = [
3047
+
"serde_derive",
3048
+
]
3049
+
3050
+
[[package]]
3051
+
name = "serde_derive"
3052
+
version = "1.0.228"
3053
+
source = "registry+https://github.com/rust-lang/crates.io-index"
3054
+
checksum = "d540f220d3187173da220f885ab66608367b6574e925011a9353e4badda91d79"
3055
+
dependencies = [
3056
+
"proc-macro2",
3057
+
"quote",
3058
+
"syn 2.0.107",
3059
+
]
3060
+
3061
+
[[package]]
3062
+
name = "serde_html_form"
3063
+
version = "0.2.8"
3064
+
source = "registry+https://github.com/rust-lang/crates.io-index"
3065
+
checksum = "b2f2d7ff8a2140333718bb329f5c40fc5f0865b84c426183ce14c97d2ab8154f"
3066
+
dependencies = [
3067
+
"form_urlencoded",
3068
+
"indexmap",
3069
+
"itoa",
3070
+
"ryu",
3071
+
"serde_core",
3072
+
]
3073
+
3074
+
[[package]]
3075
+
name = "serde_ipld_dagcbor"
3076
+
version = "0.6.4"
3077
+
source = "registry+https://github.com/rust-lang/crates.io-index"
3078
+
checksum = "46182f4f08349a02b45c998ba3215d3f9de826246ba02bb9dddfe9a2a2100778"
3079
+
dependencies = [
3080
+
"cbor4ii",
3081
+
"ipld-core",
3082
+
"scopeguard",
3083
+
"serde",
3084
+
]
3085
+
3086
+
[[package]]
3087
+
name = "serde_json"
3088
+
version = "1.0.145"
3089
+
source = "registry+https://github.com/rust-lang/crates.io-index"
3090
+
checksum = "402a6f66d8c709116cf22f558eab210f5a50187f702eb4d7e5ef38d9a7f1c79c"
3091
+
dependencies = [
3092
+
"itoa",
3093
+
"memchr",
3094
+
"ryu",
3095
+
"serde",
3096
+
"serde_core",
3097
+
]
3098
+
3099
+
[[package]]
3100
+
name = "serde_urlencoded"
3101
+
version = "0.7.1"
3102
+
source = "registry+https://github.com/rust-lang/crates.io-index"
3103
+
checksum = "d3491c14715ca2294c4d6a88f15e84739788c1d030eed8c110436aafdaa2f3fd"
3104
+
dependencies = [
3105
+
"form_urlencoded",
3106
+
"itoa",
3107
+
"ryu",
3108
+
"serde",
3109
+
]
3110
+
3111
+
[[package]]
3112
+
name = "sha1_smol"
3113
+
version = "1.0.1"
3114
+
source = "registry+https://github.com/rust-lang/crates.io-index"
3115
+
checksum = "bbfa15b3dddfee50a0fff136974b3e1bde555604ba463834a7eb7deb6417705d"
3116
+
3117
+
[[package]]
3118
+
name = "sha2"
3119
+
version = "0.10.9"
3120
+
source = "registry+https://github.com/rust-lang/crates.io-index"
3121
+
checksum = "a7507d819769d01a365ab707794a4084392c824f54a7a6a7862f8c3d0892b283"
3122
+
dependencies = [
3123
+
"cfg-if",
3124
+
"cpufeatures",
3125
+
"digest",
3126
+
]
3127
+
3128
+
[[package]]
3129
+
name = "shlex"
3130
+
version = "1.3.0"
3131
+
source = "registry+https://github.com/rust-lang/crates.io-index"
3132
+
checksum = "0fda2ff0d084019ba4d7c6f371c95d8fd75ce3524c3cb8fb653a3023f6323e64"
3133
+
3134
+
[[package]]
3135
+
name = "signature"
3136
+
version = "2.2.0"
3137
+
source = "registry+https://github.com/rust-lang/crates.io-index"
3138
+
checksum = "77549399552de45a898a580c1b41d445bf730df867cc44e6c0233bbc4b8329de"
3139
+
dependencies = [
3140
+
"digest",
3141
+
"rand_core 0.6.4",
3142
+
]
3143
+
3144
+
[[package]]
3145
+
name = "simd-adler32"
3146
+
version = "0.3.7"
3147
+
source = "registry+https://github.com/rust-lang/crates.io-index"
3148
+
checksum = "d66dc143e6b11c1eddc06d5c423cfc97062865baf299914ab64caa38182078fe"
3149
+
3150
+
[[package]]
3151
+
name = "slab"
3152
+
version = "0.4.11"
3153
+
source = "registry+https://github.com/rust-lang/crates.io-index"
3154
+
checksum = "7a2ae44ef20feb57a68b23d846850f861394c2e02dc425a50098ae8c90267589"
3155
+
3156
+
[[package]]
3157
+
name = "smallvec"
3158
+
version = "1.15.1"
3159
+
source = "registry+https://github.com/rust-lang/crates.io-index"
3160
+
checksum = "67b1b7a3b5fe4f1376887184045fcf45c69e92af734b7aaddc05fb777b6fbd03"
3161
+
3162
+
[[package]]
3163
+
name = "smol_str"
3164
+
version = "0.3.2"
3165
+
source = "registry+https://github.com/rust-lang/crates.io-index"
3166
+
checksum = "9676b89cd56310a87b93dec47b11af744f34d5fc9f367b829474eec0a891350d"
3167
+
dependencies = [
3168
+
"borsh",
3169
+
"serde",
3170
+
]
3171
+
3172
+
[[package]]
3173
+
name = "socket2"
3174
+
version = "0.5.10"
3175
+
source = "registry+https://github.com/rust-lang/crates.io-index"
3176
+
checksum = "e22376abed350d73dd1cd119b57ffccad95b4e585a7cda43e286245ce23c0678"
3177
+
dependencies = [
3178
+
"libc",
3179
+
"windows-sys 0.52.0",
3180
+
]
3181
+
3182
+
[[package]]
3183
+
name = "socket2"
3184
+
version = "0.6.1"
3185
+
source = "registry+https://github.com/rust-lang/crates.io-index"
3186
+
checksum = "17129e116933cf371d018bb80ae557e889637989d8638274fb25622827b03881"
3187
+
dependencies = [
3188
+
"libc",
3189
+
"windows-sys 0.60.2",
3190
+
]
3191
+
3192
+
[[package]]
3193
+
name = "spin"
3194
+
version = "0.9.8"
3195
+
source = "registry+https://github.com/rust-lang/crates.io-index"
3196
+
checksum = "6980e8d7511241f8acf4aebddbb1ff938df5eebe98691418c4468d0b72a96a67"
3197
+
3198
+
[[package]]
3199
+
name = "spki"
3200
+
version = "0.7.3"
3201
+
source = "registry+https://github.com/rust-lang/crates.io-index"
3202
+
checksum = "d91ed6c858b01f942cd56b37a94b3e0a1798290327d1236e4d9cf4eaca44d29d"
3203
+
dependencies = [
3204
+
"base64ct",
3205
+
"der",
3206
+
]
3207
+
3208
+
[[package]]
3209
+
name = "stable_deref_trait"
3210
+
version = "1.2.1"
3211
+
source = "registry+https://github.com/rust-lang/crates.io-index"
3212
+
checksum = "6ce2be8dc25455e1f91df71bfa12ad37d7af1092ae736f3a6cd0e37bc7810596"
3213
+
3214
+
[[package]]
3215
+
name = "static-regular-grammar"
3216
+
version = "2.0.2"
3217
+
source = "registry+https://github.com/rust-lang/crates.io-index"
3218
+
checksum = "4f4a6c40247579acfbb138c3cd7de3dab113ab4ac6227f1b7de7d626ee667957"
3219
+
dependencies = [
3220
+
"abnf",
3221
+
"btree-range-map",
3222
+
"ciborium",
3223
+
"hex_fmt",
3224
+
"indoc",
3225
+
"proc-macro-error 1.0.4",
3226
+
"proc-macro2",
3227
+
"quote",
3228
+
"serde",
3229
+
"sha2",
3230
+
"syn 2.0.107",
3231
+
"thiserror 1.0.69",
3232
+
]
3233
+
3234
+
[[package]]
3235
+
name = "static_assertions"
3236
+
version = "1.1.0"
3237
+
source = "registry+https://github.com/rust-lang/crates.io-index"
3238
+
checksum = "a2eb9349b6444b326872e140eb1cf5e7c522154d69e7a0ffb0fb81c06b37543f"
3239
+
3240
+
[[package]]
3241
+
name = "strsim"
3242
+
version = "0.11.1"
3243
+
source = "registry+https://github.com/rust-lang/crates.io-index"
3244
+
checksum = "7da8b5736845d9f2fcb837ea5d9e2628564b3b043a70948a3f0b778838c5fb4f"
3245
+
3246
+
[[package]]
3247
+
name = "subtle"
3248
+
version = "2.6.1"
3249
+
source = "registry+https://github.com/rust-lang/crates.io-index"
3250
+
checksum = "13c2bddecc57b384dee18652358fb23172facb8a2c51ccc10d74c157bdea3292"
3251
+
3252
+
[[package]]
3253
+
name = "supports-color"
3254
+
version = "3.0.2"
3255
+
source = "registry+https://github.com/rust-lang/crates.io-index"
3256
+
checksum = "c64fc7232dd8d2e4ac5ce4ef302b1d81e0b80d055b9d77c7c4f51f6aa4c867d6"
3257
+
dependencies = [
3258
+
"is_ci",
3259
+
]
3260
+
3261
+
[[package]]
3262
+
name = "supports-hyperlinks"
3263
+
version = "3.1.0"
3264
+
source = "registry+https://github.com/rust-lang/crates.io-index"
3265
+
checksum = "804f44ed3c63152de6a9f90acbea1a110441de43006ea51bcce8f436196a288b"
3266
+
3267
+
[[package]]
3268
+
name = "supports-unicode"
3269
+
version = "3.0.0"
3270
+
source = "registry+https://github.com/rust-lang/crates.io-index"
3271
+
checksum = "b7401a30af6cb5818bb64852270bb722533397edcfc7344954a38f420819ece2"
3272
+
3273
+
[[package]]
3274
+
name = "syn"
3275
+
version = "1.0.109"
3276
+
source = "registry+https://github.com/rust-lang/crates.io-index"
3277
+
checksum = "72b64191b275b66ffe2469e8af2c1cfe3bafa67b529ead792a6d0160888b4237"
3278
+
dependencies = [
3279
+
"proc-macro2",
3280
+
"quote",
3281
+
"unicode-ident",
3282
+
]
3283
+
3284
+
[[package]]
3285
+
name = "syn"
3286
+
version = "2.0.107"
3287
+
source = "registry+https://github.com/rust-lang/crates.io-index"
3288
+
checksum = "2a26dbd934e5451d21ef060c018dae56fc073894c5a7896f882928a76e6d081b"
3289
+
dependencies = [
3290
+
"proc-macro2",
3291
+
"quote",
3292
+
"unicode-ident",
3293
+
]
3294
+
3295
+
[[package]]
3296
+
name = "syn-mid"
3297
+
version = "0.5.4"
3298
+
source = "registry+https://github.com/rust-lang/crates.io-index"
3299
+
checksum = "fea305d57546cc8cd04feb14b62ec84bf17f50e3f7b12560d7bfa9265f39d9ed"
3300
+
dependencies = [
3301
+
"proc-macro2",
3302
+
"quote",
3303
+
"syn 1.0.109",
3304
+
]
3305
+
3306
+
[[package]]
3307
+
name = "sync_wrapper"
3308
+
version = "1.0.2"
3309
+
source = "registry+https://github.com/rust-lang/crates.io-index"
3310
+
checksum = "0bf256ce5efdfa370213c1dabab5935a12e49f2c58d15e9eac2870d3b4f27263"
3311
+
dependencies = [
3312
+
"futures-core",
3313
+
]
3314
+
3315
+
[[package]]
3316
+
name = "synstructure"
3317
+
version = "0.13.2"
3318
+
source = "registry+https://github.com/rust-lang/crates.io-index"
3319
+
checksum = "728a70f3dbaf5bab7f0c4b1ac8d7ae5ea60a4b5549c8a5914361c99147a709d2"
3320
+
dependencies = [
3321
+
"proc-macro2",
3322
+
"quote",
3323
+
"syn 2.0.107",
3324
+
]
3325
+
3326
+
[[package]]
3327
+
name = "system-configuration"
3328
+
version = "0.6.1"
3329
+
source = "registry+https://github.com/rust-lang/crates.io-index"
3330
+
checksum = "3c879d448e9d986b661742763247d3693ed13609438cf3d006f51f5368a5ba6b"
3331
+
dependencies = [
3332
+
"bitflags",
3333
+
"core-foundation",
3334
+
"system-configuration-sys",
3335
+
]
3336
+
3337
+
[[package]]
3338
+
name = "system-configuration-sys"
3339
+
version = "0.6.0"
3340
+
source = "registry+https://github.com/rust-lang/crates.io-index"
3341
+
checksum = "8e1d1b10ced5ca923a1fcb8d03e96b8d3268065d724548c0211415ff6ac6bac4"
3342
+
dependencies = [
3343
+
"core-foundation-sys",
3344
+
"libc",
3345
+
]
3346
+
3347
+
[[package]]
3348
+
name = "tempfile"
3349
+
version = "3.23.0"
3350
+
source = "registry+https://github.com/rust-lang/crates.io-index"
3351
+
checksum = "2d31c77bdf42a745371d260a26ca7163f1e0924b64afa0b688e61b5a9fa02f16"
3352
+
dependencies = [
3353
+
"fastrand",
3354
+
"getrandom 0.3.4",
3355
+
"once_cell",
3356
+
"rustix",
3357
+
"windows-sys 0.61.2",
3358
+
]
3359
+
3360
+
[[package]]
3361
+
name = "terminal_size"
3362
+
version = "0.4.3"
3363
+
source = "registry+https://github.com/rust-lang/crates.io-index"
3364
+
checksum = "60b8cb979cb11c32ce1603f8137b22262a9d131aaa5c37b5678025f22b8becd0"
3365
+
dependencies = [
3366
+
"rustix",
3367
+
"windows-sys 0.60.2",
3368
+
]
3369
+
3370
+
[[package]]
3371
+
name = "textwrap"
3372
+
version = "0.16.2"
3373
+
source = "registry+https://github.com/rust-lang/crates.io-index"
3374
+
checksum = "c13547615a44dc9c452a8a534638acdf07120d4b6847c8178705da06306a3057"
3375
+
dependencies = [
3376
+
"unicode-linebreak",
3377
+
"unicode-width 0.2.2",
3378
+
]
3379
+
3380
+
[[package]]
3381
+
name = "thiserror"
3382
+
version = "1.0.69"
3383
+
source = "registry+https://github.com/rust-lang/crates.io-index"
3384
+
checksum = "b6aaf5339b578ea85b50e080feb250a3e8ae8cfcdff9a461c9ec2904bc923f52"
3385
+
dependencies = [
3386
+
"thiserror-impl 1.0.69",
3387
+
]
3388
+
3389
+
[[package]]
3390
+
name = "thiserror"
3391
+
version = "2.0.17"
3392
+
source = "registry+https://github.com/rust-lang/crates.io-index"
3393
+
checksum = "f63587ca0f12b72a0600bcba1d40081f830876000bb46dd2337a3051618f4fc8"
3394
+
dependencies = [
3395
+
"thiserror-impl 2.0.17",
3396
+
]
3397
+
3398
+
[[package]]
3399
+
name = "thiserror-impl"
3400
+
version = "1.0.69"
3401
+
source = "registry+https://github.com/rust-lang/crates.io-index"
3402
+
checksum = "4fee6c4efc90059e10f81e6d42c60a18f76588c3d74cb83a0b242a2b6c7504c1"
3403
+
dependencies = [
3404
+
"proc-macro2",
3405
+
"quote",
3406
+
"syn 2.0.107",
3407
+
]
3408
+
3409
+
[[package]]
3410
+
name = "thiserror-impl"
3411
+
version = "2.0.17"
3412
+
source = "registry+https://github.com/rust-lang/crates.io-index"
3413
+
checksum = "3ff15c8ecd7de3849db632e14d18d2571fa09dfc5ed93479bc4485c7a517c913"
3414
+
dependencies = [
3415
+
"proc-macro2",
3416
+
"quote",
3417
+
"syn 2.0.107",
3418
+
]
3419
+
3420
+
[[package]]
3421
+
name = "threadpool"
3422
+
version = "1.8.1"
3423
+
source = "registry+https://github.com/rust-lang/crates.io-index"
3424
+
checksum = "d050e60b33d41c19108b32cea32164033a9013fe3b46cbd4457559bfbf77afaa"
3425
+
dependencies = [
3426
+
"num_cpus",
3427
+
]
3428
+
3429
+
[[package]]
3430
+
name = "time"
3431
+
version = "0.3.44"
3432
+
source = "registry+https://github.com/rust-lang/crates.io-index"
3433
+
checksum = "91e7d9e3bb61134e77bde20dd4825b97c010155709965fedf0f49bb138e52a9d"
3434
+
dependencies = [
3435
+
"deranged",
3436
+
"libc",
3437
+
"num-conv",
3438
+
"num_threads",
3439
+
"powerfmt",
3440
+
"serde",
3441
+
"time-core",
3442
+
]
3443
+
3444
+
[[package]]
3445
+
name = "time-core"
3446
+
version = "0.1.6"
3447
+
source = "registry+https://github.com/rust-lang/crates.io-index"
3448
+
checksum = "40868e7c1d2f0b8d73e4a8c7f0ff63af4f6d19be117e90bd73eb1d62cf831c6b"
3449
+
3450
+
[[package]]
3451
+
name = "tiny_http"
3452
+
version = "0.12.0"
3453
+
source = "registry+https://github.com/rust-lang/crates.io-index"
3454
+
checksum = "389915df6413a2e74fb181895f933386023c71110878cd0825588928e64cdc82"
3455
+
dependencies = [
3456
+
"ascii",
3457
+
"chunked_transfer",
3458
+
"httpdate",
3459
+
"log",
3460
+
]
3461
+
3462
+
[[package]]
3463
+
name = "tinystr"
3464
+
version = "0.8.1"
3465
+
source = "registry+https://github.com/rust-lang/crates.io-index"
3466
+
checksum = "5d4f6d1145dcb577acf783d4e601bc1d76a13337bb54e6233add580b07344c8b"
3467
+
dependencies = [
3468
+
"displaydoc",
3469
+
"zerovec",
3470
+
]
3471
+
3472
+
[[package]]
3473
+
name = "tinyvec"
3474
+
version = "1.10.0"
3475
+
source = "registry+https://github.com/rust-lang/crates.io-index"
3476
+
checksum = "bfa5fdc3bce6191a1dbc8c02d5c8bffcf557bafa17c124c5264a458f1b0613fa"
3477
+
dependencies = [
3478
+
"tinyvec_macros",
3479
+
]
3480
+
3481
+
[[package]]
3482
+
name = "tinyvec_macros"
3483
+
version = "0.1.1"
3484
+
source = "registry+https://github.com/rust-lang/crates.io-index"
3485
+
checksum = "1f3ccbac311fea05f86f61904b462b55fb3df8837a366dfc601a0161d0532f20"
3486
+
3487
+
[[package]]
3488
+
name = "tokio"
3489
+
version = "1.48.0"
3490
+
source = "registry+https://github.com/rust-lang/crates.io-index"
3491
+
checksum = "ff360e02eab121e0bc37a2d3b4d4dc622e6eda3a8e5253d5435ecf5bd4c68408"
3492
+
dependencies = [
3493
+
"bytes",
3494
+
"libc",
3495
+
"mio",
3496
+
"pin-project-lite",
3497
+
"socket2 0.6.1",
3498
+
"tokio-macros",
3499
+
"windows-sys 0.61.2",
3500
+
]
3501
+
3502
+
[[package]]
3503
+
name = "tokio-macros"
3504
+
version = "2.6.0"
3505
+
source = "registry+https://github.com/rust-lang/crates.io-index"
3506
+
checksum = "af407857209536a95c8e56f8231ef2c2e2aff839b22e07a1ffcbc617e9db9fa5"
3507
+
dependencies = [
3508
+
"proc-macro2",
3509
+
"quote",
3510
+
"syn 2.0.107",
3511
+
]
3512
+
3513
+
[[package]]
3514
+
name = "tokio-native-tls"
3515
+
version = "0.3.1"
3516
+
source = "registry+https://github.com/rust-lang/crates.io-index"
3517
+
checksum = "bbae76ab933c85776efabc971569dd6119c580d8f5d448769dec1764bf796ef2"
3518
+
dependencies = [
3519
+
"native-tls",
3520
+
"tokio",
3521
+
]
3522
+
3523
+
[[package]]
3524
+
name = "tokio-rustls"
3525
+
version = "0.26.4"
3526
+
source = "registry+https://github.com/rust-lang/crates.io-index"
3527
+
checksum = "1729aa945f29d91ba541258c8df89027d5792d85a8841fb65e8bf0f4ede4ef61"
3528
+
dependencies = [
3529
+
"rustls",
3530
+
"tokio",
3531
+
]
3532
+
3533
+
[[package]]
3534
+
name = "tokio-util"
3535
+
version = "0.7.16"
3536
+
source = "registry+https://github.com/rust-lang/crates.io-index"
3537
+
checksum = "14307c986784f72ef81c89db7d9e28d6ac26d16213b109ea501696195e6e3ce5"
3538
+
dependencies = [
3539
+
"bytes",
3540
+
"futures-core",
3541
+
"futures-sink",
3542
+
"pin-project-lite",
3543
+
"tokio",
3544
+
]
3545
+
3546
+
[[package]]
3547
+
name = "tower"
3548
+
version = "0.5.2"
3549
+
source = "registry+https://github.com/rust-lang/crates.io-index"
3550
+
checksum = "d039ad9159c98b70ecfd540b2573b97f7f52c3e8d9f8ad57a24b916a536975f9"
3551
+
dependencies = [
3552
+
"futures-core",
3553
+
"futures-util",
3554
+
"pin-project-lite",
3555
+
"sync_wrapper",
3556
+
"tokio",
3557
+
"tower-layer",
3558
+
"tower-service",
3559
+
]
3560
+
3561
+
[[package]]
3562
+
name = "tower-http"
3563
+
version = "0.6.6"
3564
+
source = "registry+https://github.com/rust-lang/crates.io-index"
3565
+
checksum = "adc82fd73de2a9722ac5da747f12383d2bfdb93591ee6c58486e0097890f05f2"
3566
+
dependencies = [
3567
+
"bitflags",
3568
+
"bytes",
3569
+
"futures-util",
3570
+
"http",
3571
+
"http-body",
3572
+
"iri-string",
3573
+
"pin-project-lite",
3574
+
"tower",
3575
+
"tower-layer",
3576
+
"tower-service",
3577
+
]
3578
+
3579
+
[[package]]
3580
+
name = "tower-layer"
3581
+
version = "0.3.3"
3582
+
source = "registry+https://github.com/rust-lang/crates.io-index"
3583
+
checksum = "121c2a6cda46980bb0fcd1647ffaf6cd3fc79a013de288782836f6df9c48780e"
3584
+
3585
+
[[package]]
3586
+
name = "tower-service"
3587
+
version = "0.3.3"
3588
+
source = "registry+https://github.com/rust-lang/crates.io-index"
3589
+
checksum = "8df9b6e13f2d32c91b9bd719c00d1958837bc7dec474d94952798cc8e69eeec3"
3590
+
3591
+
[[package]]
3592
+
name = "tracing"
3593
+
version = "0.1.41"
3594
+
source = "registry+https://github.com/rust-lang/crates.io-index"
3595
+
checksum = "784e0ac535deb450455cbfa28a6f0df145ea1bb7ae51b821cf5e7927fdcfbdd0"
3596
+
dependencies = [
3597
+
"pin-project-lite",
3598
+
"tracing-attributes",
3599
+
"tracing-core",
3600
+
]
3601
+
3602
+
[[package]]
3603
+
name = "tracing-attributes"
3604
+
version = "0.1.30"
3605
+
source = "registry+https://github.com/rust-lang/crates.io-index"
3606
+
checksum = "81383ab64e72a7a8b8e13130c49e3dab29def6d0c7d76a03087b3cf71c5c6903"
3607
+
dependencies = [
3608
+
"proc-macro2",
3609
+
"quote",
3610
+
"syn 2.0.107",
3611
+
]
3612
+
3613
+
[[package]]
3614
+
name = "tracing-core"
3615
+
version = "0.1.34"
3616
+
source = "registry+https://github.com/rust-lang/crates.io-index"
3617
+
checksum = "b9d12581f227e93f094d3af2ae690a574abb8a2b9b7a96e7cfe9647b2b617678"
3618
+
dependencies = [
3619
+
"once_cell",
3620
+
]
3621
+
3622
+
[[package]]
3623
+
name = "trait-variant"
3624
+
version = "0.1.2"
3625
+
source = "registry+https://github.com/rust-lang/crates.io-index"
3626
+
checksum = "70977707304198400eb4835a78f6a9f928bf41bba420deb8fdb175cd965d77a7"
3627
+
dependencies = [
3628
+
"proc-macro2",
3629
+
"quote",
3630
+
"syn 2.0.107",
3631
+
]
3632
+
3633
+
[[package]]
3634
+
name = "try-lock"
3635
+
version = "0.2.5"
3636
+
source = "registry+https://github.com/rust-lang/crates.io-index"
3637
+
checksum = "e421abadd41a4225275504ea4d6566923418b7f05506fbc9c0fe86ba7396114b"
3638
+
3639
+
[[package]]
3640
+
name = "twoway"
3641
+
version = "0.1.8"
3642
+
source = "registry+https://github.com/rust-lang/crates.io-index"
3643
+
checksum = "59b11b2b5241ba34be09c3cc85a36e56e48f9888862e19cedf23336d35316ed1"
3644
+
dependencies = [
3645
+
"memchr",
3646
+
]
3647
+
3648
+
[[package]]
3649
+
name = "typenum"
3650
+
version = "1.19.0"
3651
+
source = "registry+https://github.com/rust-lang/crates.io-index"
3652
+
checksum = "562d481066bde0658276a35467c4af00bdc6ee726305698a55b86e61d7ad82bb"
3653
+
3654
+
[[package]]
3655
+
name = "unicase"
3656
+
version = "2.8.1"
3657
+
source = "registry+https://github.com/rust-lang/crates.io-index"
3658
+
checksum = "75b844d17643ee918803943289730bec8aac480150456169e647ed0b576ba539"
3659
+
3660
+
[[package]]
3661
+
name = "unicode-ident"
3662
+
version = "1.0.19"
3663
+
source = "registry+https://github.com/rust-lang/crates.io-index"
3664
+
checksum = "f63a545481291138910575129486daeaf8ac54aee4387fe7906919f7830c7d9d"
3665
+
3666
+
[[package]]
3667
+
name = "unicode-linebreak"
3668
+
version = "0.1.5"
3669
+
source = "registry+https://github.com/rust-lang/crates.io-index"
3670
+
checksum = "3b09c83c3c29d37506a3e260c08c03743a6bb66a9cd432c6934ab501a190571f"
3671
+
3672
+
[[package]]
3673
+
name = "unicode-width"
3674
+
version = "0.1.14"
3675
+
source = "registry+https://github.com/rust-lang/crates.io-index"
3676
+
checksum = "7dd6e30e90baa6f72411720665d41d89b9a3d039dc45b8faea1ddd07f617f6af"
3677
+
3678
+
[[package]]
3679
+
name = "unicode-width"
3680
+
version = "0.2.2"
3681
+
source = "registry+https://github.com/rust-lang/crates.io-index"
3682
+
checksum = "b4ac048d71ede7ee76d585517add45da530660ef4390e49b098733c6e897f254"
3683
+
3684
+
[[package]]
3685
+
name = "unsigned-varint"
3686
+
version = "0.8.0"
3687
+
source = "registry+https://github.com/rust-lang/crates.io-index"
3688
+
checksum = "eb066959b24b5196ae73cb057f45598450d2c5f71460e98c49b738086eff9c06"
3689
+
3690
+
[[package]]
3691
+
name = "untrusted"
3692
+
version = "0.9.0"
3693
+
source = "registry+https://github.com/rust-lang/crates.io-index"
3694
+
checksum = "8ecb6da28b8a351d773b68d5825ac39017e680750f980f3a1a85cd8dd28a47c1"
3695
+
3696
+
[[package]]
3697
+
name = "url"
3698
+
version = "2.5.7"
3699
+
source = "registry+https://github.com/rust-lang/crates.io-index"
3700
+
checksum = "08bc136a29a3d1758e07a9cca267be308aeebf5cfd5a10f3f67ab2097683ef5b"
3701
+
dependencies = [
3702
+
"form_urlencoded",
3703
+
"idna",
3704
+
"percent-encoding",
3705
+
"serde",
3706
+
]
3707
+
3708
+
[[package]]
3709
+
name = "urlencoding"
3710
+
version = "2.1.3"
3711
+
source = "registry+https://github.com/rust-lang/crates.io-index"
3712
+
checksum = "daf8dba3b7eb870caf1ddeed7bc9d2a049f3cfdfae7cb521b087cc33ae4c49da"
3713
+
3714
+
[[package]]
3715
+
name = "utf8_iter"
3716
+
version = "1.0.4"
3717
+
source = "registry+https://github.com/rust-lang/crates.io-index"
3718
+
checksum = "b6c140620e7ffbb22c2dee59cafe6084a59b5ffc27a8859a5f0d494b5d52b6be"
3719
+
3720
+
[[package]]
3721
+
name = "utf8parse"
3722
+
version = "0.2.2"
3723
+
source = "registry+https://github.com/rust-lang/crates.io-index"
3724
+
checksum = "06abde3611657adf66d383f00b093d7faecc7fa57071cce2578660c9f1010821"
3725
+
3726
+
[[package]]
3727
+
name = "vcpkg"
3728
+
version = "0.2.15"
3729
+
source = "registry+https://github.com/rust-lang/crates.io-index"
3730
+
checksum = "accd4ea62f7bb7a82fe23066fb0957d48ef677f6eeb8215f372f52e48bb32426"
3731
+
3732
+
[[package]]
3733
+
name = "version_check"
3734
+
version = "0.9.5"
3735
+
source = "registry+https://github.com/rust-lang/crates.io-index"
3736
+
checksum = "0b928f33d975fc6ad9f86c8f283853ad26bdd5b10b7f1542aa2fa15e2289105a"
3737
+
3738
+
[[package]]
3739
+
name = "walkdir"
3740
+
version = "2.5.0"
3741
+
source = "registry+https://github.com/rust-lang/crates.io-index"
3742
+
checksum = "29790946404f91d9c5d06f9874efddea1dc06c5efe94541a7d6863108e3a5e4b"
3743
+
dependencies = [
3744
+
"same-file",
3745
+
"winapi-util",
3746
+
]
3747
+
3748
+
[[package]]
3749
+
name = "want"
3750
+
version = "0.3.1"
3751
+
source = "registry+https://github.com/rust-lang/crates.io-index"
3752
+
checksum = "bfa7760aed19e106de2c7c0b581b509f2f25d3dacaf737cb82ac61bc6d760b0e"
3753
+
dependencies = [
3754
+
"try-lock",
3755
+
]
3756
+
3757
+
[[package]]
3758
+
name = "wasi"
3759
+
version = "0.11.1+wasi-snapshot-preview1"
3760
+
source = "registry+https://github.com/rust-lang/crates.io-index"
3761
+
checksum = "ccf3ec651a847eb01de73ccad15eb7d99f80485de043efb2f370cd654f4ea44b"
3762
+
3763
+
[[package]]
3764
+
name = "wasip2"
3765
+
version = "1.0.1+wasi-0.2.4"
3766
+
source = "registry+https://github.com/rust-lang/crates.io-index"
3767
+
checksum = "0562428422c63773dad2c345a1882263bbf4d65cf3f42e90921f787ef5ad58e7"
3768
+
dependencies = [
3769
+
"wit-bindgen",
3770
+
]
3771
+
3772
+
[[package]]
3773
+
name = "wasm-bindgen"
3774
+
version = "0.2.104"
3775
+
source = "registry+https://github.com/rust-lang/crates.io-index"
3776
+
checksum = "c1da10c01ae9f1ae40cbfac0bac3b1e724b320abfcf52229f80b547c0d250e2d"
3777
+
dependencies = [
3778
+
"cfg-if",
3779
+
"once_cell",
3780
+
"rustversion",
3781
+
"wasm-bindgen-macro",
3782
+
"wasm-bindgen-shared",
3783
+
]
3784
+
3785
+
[[package]]
3786
+
name = "wasm-bindgen-backend"
3787
+
version = "0.2.104"
3788
+
source = "registry+https://github.com/rust-lang/crates.io-index"
3789
+
checksum = "671c9a5a66f49d8a47345ab942e2cb93c7d1d0339065d4f8139c486121b43b19"
3790
+
dependencies = [
3791
+
"bumpalo",
3792
+
"log",
3793
+
"proc-macro2",
3794
+
"quote",
3795
+
"syn 2.0.107",
3796
+
"wasm-bindgen-shared",
3797
+
]
3798
+
3799
+
[[package]]
3800
+
name = "wasm-bindgen-futures"
3801
+
version = "0.4.54"
3802
+
source = "registry+https://github.com/rust-lang/crates.io-index"
3803
+
checksum = "7e038d41e478cc73bae0ff9b36c60cff1c98b8f38f8d7e8061e79ee63608ac5c"
3804
+
dependencies = [
3805
+
"cfg-if",
3806
+
"js-sys",
3807
+
"once_cell",
3808
+
"wasm-bindgen",
3809
+
"web-sys",
3810
+
]
3811
+
3812
+
[[package]]
3813
+
name = "wasm-bindgen-macro"
3814
+
version = "0.2.104"
3815
+
source = "registry+https://github.com/rust-lang/crates.io-index"
3816
+
checksum = "7ca60477e4c59f5f2986c50191cd972e3a50d8a95603bc9434501cf156a9a119"
3817
+
dependencies = [
3818
+
"quote",
3819
+
"wasm-bindgen-macro-support",
3820
+
]
3821
+
3822
+
[[package]]
3823
+
name = "wasm-bindgen-macro-support"
3824
+
version = "0.2.104"
3825
+
source = "registry+https://github.com/rust-lang/crates.io-index"
3826
+
checksum = "9f07d2f20d4da7b26400c9f4a0511e6e0345b040694e8a75bd41d578fa4421d7"
3827
+
dependencies = [
3828
+
"proc-macro2",
3829
+
"quote",
3830
+
"syn 2.0.107",
3831
+
"wasm-bindgen-backend",
3832
+
"wasm-bindgen-shared",
3833
+
]
3834
+
3835
+
[[package]]
3836
+
name = "wasm-bindgen-shared"
3837
+
version = "0.2.104"
3838
+
source = "registry+https://github.com/rust-lang/crates.io-index"
3839
+
checksum = "bad67dc8b2a1a6e5448428adec4c3e84c43e561d8c9ee8a9e5aabeb193ec41d1"
3840
+
dependencies = [
3841
+
"unicode-ident",
3842
+
]
3843
+
3844
+
[[package]]
3845
+
name = "wasm-streams"
3846
+
version = "0.4.2"
3847
+
source = "registry+https://github.com/rust-lang/crates.io-index"
3848
+
checksum = "15053d8d85c7eccdbefef60f06769760a563c7f0a9d6902a13d35c7800b0ad65"
3849
+
dependencies = [
3850
+
"futures-util",
3851
+
"js-sys",
3852
+
"wasm-bindgen",
3853
+
"wasm-bindgen-futures",
3854
+
"web-sys",
3855
+
]
3856
+
3857
+
[[package]]
3858
+
name = "web-sys"
3859
+
version = "0.3.81"
3860
+
source = "registry+https://github.com/rust-lang/crates.io-index"
3861
+
checksum = "9367c417a924a74cae129e6a2ae3b47fabb1f8995595ab474029da749a8be120"
3862
+
dependencies = [
3863
+
"js-sys",
3864
+
"wasm-bindgen",
3865
+
]
3866
+
3867
+
[[package]]
3868
+
name = "web-time"
3869
+
version = "1.1.0"
3870
+
source = "registry+https://github.com/rust-lang/crates.io-index"
3871
+
checksum = "5a6580f308b1fad9207618087a65c04e7a10bc77e02c8e84e9b00dd4b12fa0bb"
3872
+
dependencies = [
3873
+
"js-sys",
3874
+
"wasm-bindgen",
3875
+
]
3876
+
3877
+
[[package]]
3878
+
name = "webbrowser"
3879
+
version = "0.8.15"
3880
+
source = "registry+https://github.com/rust-lang/crates.io-index"
3881
+
checksum = "db67ae75a9405634f5882791678772c94ff5f16a66535aae186e26aa0841fc8b"
3882
+
dependencies = [
3883
+
"core-foundation",
3884
+
"home",
3885
+
"jni",
3886
+
"log",
3887
+
"ndk-context",
3888
+
"objc",
3889
+
"raw-window-handle",
3890
+
"url",
3891
+
"web-sys",
3892
+
]
3893
+
3894
+
[[package]]
3895
+
name = "webpki-roots"
3896
+
version = "1.0.3"
3897
+
source = "registry+https://github.com/rust-lang/crates.io-index"
3898
+
checksum = "32b130c0d2d49f8b6889abc456e795e82525204f27c42cf767cf0d7734e089b8"
3899
+
dependencies = [
3900
+
"rustls-pki-types",
3901
+
]
3902
+
3903
+
[[package]]
3904
+
name = "widestring"
3905
+
version = "1.2.1"
3906
+
source = "registry+https://github.com/rust-lang/crates.io-index"
3907
+
checksum = "72069c3113ab32ab29e5584db3c6ec55d416895e60715417b5b883a357c3e471"
3908
+
3909
+
[[package]]
3910
+
name = "winapi-util"
3911
+
version = "0.1.11"
3912
+
source = "registry+https://github.com/rust-lang/crates.io-index"
3913
+
checksum = "c2a7b1c03c876122aa43f3020e6c3c3ee5c05081c9a00739faf7503aeba10d22"
3914
+
dependencies = [
3915
+
"windows-sys 0.61.2",
3916
+
]
3917
+
3918
+
[[package]]
3919
+
name = "windows-core"
3920
+
version = "0.62.2"
3921
+
source = "registry+https://github.com/rust-lang/crates.io-index"
3922
+
checksum = "b8e83a14d34d0623b51dce9581199302a221863196a1dde71a7663a4c2be9deb"
3923
+
dependencies = [
3924
+
"windows-implement",
3925
+
"windows-interface",
3926
+
"windows-link 0.2.1",
3927
+
"windows-result 0.4.1",
3928
+
"windows-strings 0.5.1",
3929
+
]
3930
+
3931
+
[[package]]
3932
+
name = "windows-implement"
3933
+
version = "0.60.2"
3934
+
source = "registry+https://github.com/rust-lang/crates.io-index"
3935
+
checksum = "053e2e040ab57b9dc951b72c264860db7eb3b0200ba345b4e4c3b14f67855ddf"
3936
+
dependencies = [
3937
+
"proc-macro2",
3938
+
"quote",
3939
+
"syn 2.0.107",
3940
+
]
3941
+
3942
+
[[package]]
3943
+
name = "windows-interface"
3944
+
version = "0.59.3"
3945
+
source = "registry+https://github.com/rust-lang/crates.io-index"
3946
+
checksum = "3f316c4a2570ba26bbec722032c4099d8c8bc095efccdc15688708623367e358"
3947
+
dependencies = [
3948
+
"proc-macro2",
3949
+
"quote",
3950
+
"syn 2.0.107",
3951
+
]
3952
+
3953
+
[[package]]
3954
+
name = "windows-link"
3955
+
version = "0.1.3"
3956
+
source = "registry+https://github.com/rust-lang/crates.io-index"
3957
+
checksum = "5e6ad25900d524eaabdbbb96d20b4311e1e7ae1699af4fb28c17ae66c80d798a"
3958
+
3959
+
[[package]]
3960
+
name = "windows-link"
3961
+
version = "0.2.1"
3962
+
source = "registry+https://github.com/rust-lang/crates.io-index"
3963
+
checksum = "f0805222e57f7521d6a62e36fa9163bc891acd422f971defe97d64e70d0a4fe5"
3964
+
3965
+
[[package]]
3966
+
name = "windows-registry"
3967
+
version = "0.5.3"
3968
+
source = "registry+https://github.com/rust-lang/crates.io-index"
3969
+
checksum = "5b8a9ed28765efc97bbc954883f4e6796c33a06546ebafacbabee9696967499e"
3970
+
dependencies = [
3971
+
"windows-link 0.1.3",
3972
+
"windows-result 0.3.4",
3973
+
"windows-strings 0.4.2",
3974
+
]
3975
+
3976
+
[[package]]
3977
+
name = "windows-result"
3978
+
version = "0.3.4"
3979
+
source = "registry+https://github.com/rust-lang/crates.io-index"
3980
+
checksum = "56f42bd332cc6c8eac5af113fc0c1fd6a8fd2aa08a0119358686e5160d0586c6"
3981
+
dependencies = [
3982
+
"windows-link 0.1.3",
3983
+
]
3984
+
3985
+
[[package]]
3986
+
name = "windows-result"
3987
+
version = "0.4.1"
3988
+
source = "registry+https://github.com/rust-lang/crates.io-index"
3989
+
checksum = "7781fa89eaf60850ac3d2da7af8e5242a5ea78d1a11c49bf2910bb5a73853eb5"
3990
+
dependencies = [
3991
+
"windows-link 0.2.1",
3992
+
]
3993
+
3994
+
[[package]]
3995
+
name = "windows-strings"
3996
+
version = "0.4.2"
3997
+
source = "registry+https://github.com/rust-lang/crates.io-index"
3998
+
checksum = "56e6c93f3a0c3b36176cb1327a4958a0353d5d166c2a35cb268ace15e91d3b57"
3999
+
dependencies = [
4000
+
"windows-link 0.1.3",
4001
+
]
4002
+
4003
+
[[package]]
4004
+
name = "windows-strings"
4005
+
version = "0.5.1"
4006
+
source = "registry+https://github.com/rust-lang/crates.io-index"
4007
+
checksum = "7837d08f69c77cf6b07689544538e017c1bfcf57e34b4c0ff58e6c2cd3b37091"
4008
+
dependencies = [
4009
+
"windows-link 0.2.1",
4010
+
]
4011
+
4012
+
[[package]]
4013
+
name = "windows-sys"
4014
+
version = "0.45.0"
4015
+
source = "registry+https://github.com/rust-lang/crates.io-index"
4016
+
checksum = "75283be5efb2831d37ea142365f009c02ec203cd29a3ebecbc093d52315b66d0"
4017
+
dependencies = [
4018
+
"windows-targets 0.42.2",
4019
+
]
4020
+
4021
+
[[package]]
4022
+
name = "windows-sys"
4023
+
version = "0.48.0"
4024
+
source = "registry+https://github.com/rust-lang/crates.io-index"
4025
+
checksum = "677d2418bec65e3338edb076e806bc1ec15693c5d0104683f2efe857f61056a9"
4026
+
dependencies = [
4027
+
"windows-targets 0.48.5",
4028
+
]
4029
+
4030
+
[[package]]
4031
+
name = "windows-sys"
4032
+
version = "0.52.0"
4033
+
source = "registry+https://github.com/rust-lang/crates.io-index"
4034
+
checksum = "282be5f36a8ce781fad8c8ae18fa3f9beff57ec1b52cb3de0789201425d9a33d"
4035
+
dependencies = [
4036
+
"windows-targets 0.52.6",
4037
+
]
4038
+
4039
+
[[package]]
4040
+
name = "windows-sys"
4041
+
version = "0.59.0"
4042
+
source = "registry+https://github.com/rust-lang/crates.io-index"
4043
+
checksum = "1e38bc4d79ed67fd075bcc251a1c39b32a1776bbe92e5bef1f0bf1f8c531853b"
4044
+
dependencies = [
4045
+
"windows-targets 0.52.6",
4046
+
]
4047
+
4048
+
[[package]]
4049
+
name = "windows-sys"
4050
+
version = "0.60.2"
4051
+
source = "registry+https://github.com/rust-lang/crates.io-index"
4052
+
checksum = "f2f500e4d28234f72040990ec9d39e3a6b950f9f22d3dba18416c35882612bcb"
4053
+
dependencies = [
4054
+
"windows-targets 0.53.5",
4055
+
]
4056
+
4057
+
[[package]]
4058
+
name = "windows-sys"
4059
+
version = "0.61.2"
4060
+
source = "registry+https://github.com/rust-lang/crates.io-index"
4061
+
checksum = "ae137229bcbd6cdf0f7b80a31df61766145077ddf49416a728b02cb3921ff3fc"
4062
+
dependencies = [
4063
+
"windows-link 0.2.1",
4064
+
]
4065
+
4066
+
[[package]]
4067
+
name = "windows-targets"
4068
+
version = "0.42.2"
4069
+
source = "registry+https://github.com/rust-lang/crates.io-index"
4070
+
checksum = "8e5180c00cd44c9b1c88adb3693291f1cd93605ded80c250a75d472756b4d071"
4071
+
dependencies = [
4072
+
"windows_aarch64_gnullvm 0.42.2",
4073
+
"windows_aarch64_msvc 0.42.2",
4074
+
"windows_i686_gnu 0.42.2",
4075
+
"windows_i686_msvc 0.42.2",
4076
+
"windows_x86_64_gnu 0.42.2",
4077
+
"windows_x86_64_gnullvm 0.42.2",
4078
+
"windows_x86_64_msvc 0.42.2",
4079
+
]
4080
+
4081
+
[[package]]
4082
+
name = "windows-targets"
4083
+
version = "0.48.5"
4084
+
source = "registry+https://github.com/rust-lang/crates.io-index"
4085
+
checksum = "9a2fa6e2155d7247be68c096456083145c183cbbbc2764150dda45a87197940c"
4086
+
dependencies = [
4087
+
"windows_aarch64_gnullvm 0.48.5",
4088
+
"windows_aarch64_msvc 0.48.5",
4089
+
"windows_i686_gnu 0.48.5",
4090
+
"windows_i686_msvc 0.48.5",
4091
+
"windows_x86_64_gnu 0.48.5",
4092
+
"windows_x86_64_gnullvm 0.48.5",
4093
+
"windows_x86_64_msvc 0.48.5",
4094
+
]
4095
+
4096
+
[[package]]
4097
+
name = "windows-targets"
4098
+
version = "0.52.6"
4099
+
source = "registry+https://github.com/rust-lang/crates.io-index"
4100
+
checksum = "9b724f72796e036ab90c1021d4780d4d3d648aca59e491e6b98e725b84e99973"
4101
+
dependencies = [
4102
+
"windows_aarch64_gnullvm 0.52.6",
4103
+
"windows_aarch64_msvc 0.52.6",
4104
+
"windows_i686_gnu 0.52.6",
4105
+
"windows_i686_gnullvm 0.52.6",
4106
+
"windows_i686_msvc 0.52.6",
4107
+
"windows_x86_64_gnu 0.52.6",
4108
+
"windows_x86_64_gnullvm 0.52.6",
4109
+
"windows_x86_64_msvc 0.52.6",
4110
+
]
4111
+
4112
+
[[package]]
4113
+
name = "windows-targets"
4114
+
version = "0.53.5"
4115
+
source = "registry+https://github.com/rust-lang/crates.io-index"
4116
+
checksum = "4945f9f551b88e0d65f3db0bc25c33b8acea4d9e41163edf90dcd0b19f9069f3"
4117
+
dependencies = [
4118
+
"windows-link 0.2.1",
4119
+
"windows_aarch64_gnullvm 0.53.1",
4120
+
"windows_aarch64_msvc 0.53.1",
4121
+
"windows_i686_gnu 0.53.1",
4122
+
"windows_i686_gnullvm 0.53.1",
4123
+
"windows_i686_msvc 0.53.1",
4124
+
"windows_x86_64_gnu 0.53.1",
4125
+
"windows_x86_64_gnullvm 0.53.1",
4126
+
"windows_x86_64_msvc 0.53.1",
4127
+
]
4128
+
4129
+
[[package]]
4130
+
name = "windows_aarch64_gnullvm"
4131
+
version = "0.42.2"
4132
+
source = "registry+https://github.com/rust-lang/crates.io-index"
4133
+
checksum = "597a5118570b68bc08d8d59125332c54f1ba9d9adeedeef5b99b02ba2b0698f8"
4134
+
4135
+
[[package]]
4136
+
name = "windows_aarch64_gnullvm"
4137
+
version = "0.48.5"
4138
+
source = "registry+https://github.com/rust-lang/crates.io-index"
4139
+
checksum = "2b38e32f0abccf9987a4e3079dfb67dcd799fb61361e53e2882c3cbaf0d905d8"
4140
+
4141
+
[[package]]
4142
+
name = "windows_aarch64_gnullvm"
4143
+
version = "0.52.6"
4144
+
source = "registry+https://github.com/rust-lang/crates.io-index"
4145
+
checksum = "32a4622180e7a0ec044bb555404c800bc9fd9ec262ec147edd5989ccd0c02cd3"
4146
+
4147
+
[[package]]
4148
+
name = "windows_aarch64_gnullvm"
4149
+
version = "0.53.1"
4150
+
source = "registry+https://github.com/rust-lang/crates.io-index"
4151
+
checksum = "a9d8416fa8b42f5c947f8482c43e7d89e73a173cead56d044f6a56104a6d1b53"
4152
+
4153
+
[[package]]
4154
+
name = "windows_aarch64_msvc"
4155
+
version = "0.42.2"
4156
+
source = "registry+https://github.com/rust-lang/crates.io-index"
4157
+
checksum = "e08e8864a60f06ef0d0ff4ba04124db8b0fb3be5776a5cd47641e942e58c4d43"
4158
+
4159
+
[[package]]
4160
+
name = "windows_aarch64_msvc"
4161
+
version = "0.48.5"
4162
+
source = "registry+https://github.com/rust-lang/crates.io-index"
4163
+
checksum = "dc35310971f3b2dbbf3f0690a219f40e2d9afcf64f9ab7cc1be722937c26b4bc"
4164
+
4165
+
[[package]]
4166
+
name = "windows_aarch64_msvc"
4167
+
version = "0.52.6"
4168
+
source = "registry+https://github.com/rust-lang/crates.io-index"
4169
+
checksum = "09ec2a7bb152e2252b53fa7803150007879548bc709c039df7627cabbd05d469"
4170
+
4171
+
[[package]]
4172
+
name = "windows_aarch64_msvc"
4173
+
version = "0.53.1"
4174
+
source = "registry+https://github.com/rust-lang/crates.io-index"
4175
+
checksum = "b9d782e804c2f632e395708e99a94275910eb9100b2114651e04744e9b125006"
4176
+
4177
+
[[package]]
4178
+
name = "windows_i686_gnu"
4179
+
version = "0.42.2"
4180
+
source = "registry+https://github.com/rust-lang/crates.io-index"
4181
+
checksum = "c61d927d8da41da96a81f029489353e68739737d3beca43145c8afec9a31a84f"
4182
+
4183
+
[[package]]
4184
+
name = "windows_i686_gnu"
4185
+
version = "0.48.5"
4186
+
source = "registry+https://github.com/rust-lang/crates.io-index"
4187
+
checksum = "a75915e7def60c94dcef72200b9a8e58e5091744960da64ec734a6c6e9b3743e"
4188
+
4189
+
[[package]]
4190
+
name = "windows_i686_gnu"
4191
+
version = "0.52.6"
4192
+
source = "registry+https://github.com/rust-lang/crates.io-index"
4193
+
checksum = "8e9b5ad5ab802e97eb8e295ac6720e509ee4c243f69d781394014ebfe8bbfa0b"
4194
+
4195
+
[[package]]
4196
+
name = "windows_i686_gnu"
4197
+
version = "0.53.1"
4198
+
source = "registry+https://github.com/rust-lang/crates.io-index"
4199
+
checksum = "960e6da069d81e09becb0ca57a65220ddff016ff2d6af6a223cf372a506593a3"
4200
+
4201
+
[[package]]
4202
+
name = "windows_i686_gnullvm"
4203
+
version = "0.52.6"
4204
+
source = "registry+https://github.com/rust-lang/crates.io-index"
4205
+
checksum = "0eee52d38c090b3caa76c563b86c3a4bd71ef1a819287c19d586d7334ae8ed66"
4206
+
4207
+
[[package]]
4208
+
name = "windows_i686_gnullvm"
4209
+
version = "0.53.1"
4210
+
source = "registry+https://github.com/rust-lang/crates.io-index"
4211
+
checksum = "fa7359d10048f68ab8b09fa71c3daccfb0e9b559aed648a8f95469c27057180c"
4212
+
4213
+
[[package]]
4214
+
name = "windows_i686_msvc"
4215
+
version = "0.42.2"
4216
+
source = "registry+https://github.com/rust-lang/crates.io-index"
4217
+
checksum = "44d840b6ec649f480a41c8d80f9c65108b92d89345dd94027bfe06ac444d1060"
4218
+
4219
+
[[package]]
4220
+
name = "windows_i686_msvc"
4221
+
version = "0.48.5"
4222
+
source = "registry+https://github.com/rust-lang/crates.io-index"
4223
+
checksum = "8f55c233f70c4b27f66c523580f78f1004e8b5a8b659e05a4eb49d4166cca406"
4224
+
4225
+
[[package]]
4226
+
name = "windows_i686_msvc"
4227
+
version = "0.52.6"
4228
+
source = "registry+https://github.com/rust-lang/crates.io-index"
4229
+
checksum = "240948bc05c5e7c6dabba28bf89d89ffce3e303022809e73deaefe4f6ec56c66"
4230
+
4231
+
[[package]]
4232
+
name = "windows_i686_msvc"
4233
+
version = "0.53.1"
4234
+
source = "registry+https://github.com/rust-lang/crates.io-index"
4235
+
checksum = "1e7ac75179f18232fe9c285163565a57ef8d3c89254a30685b57d83a38d326c2"
4236
+
4237
+
[[package]]
4238
+
name = "windows_x86_64_gnu"
4239
+
version = "0.42.2"
4240
+
source = "registry+https://github.com/rust-lang/crates.io-index"
4241
+
checksum = "8de912b8b8feb55c064867cf047dda097f92d51efad5b491dfb98f6bbb70cb36"
4242
+
4243
+
[[package]]
4244
+
name = "windows_x86_64_gnu"
4245
+
version = "0.48.5"
4246
+
source = "registry+https://github.com/rust-lang/crates.io-index"
4247
+
checksum = "53d40abd2583d23e4718fddf1ebec84dbff8381c07cae67ff7768bbf19c6718e"
4248
+
4249
+
[[package]]
4250
+
name = "windows_x86_64_gnu"
4251
+
version = "0.52.6"
4252
+
source = "registry+https://github.com/rust-lang/crates.io-index"
4253
+
checksum = "147a5c80aabfbf0c7d901cb5895d1de30ef2907eb21fbbab29ca94c5b08b1a78"
4254
+
4255
+
[[package]]
4256
+
name = "windows_x86_64_gnu"
4257
+
version = "0.53.1"
4258
+
source = "registry+https://github.com/rust-lang/crates.io-index"
4259
+
checksum = "9c3842cdd74a865a8066ab39c8a7a473c0778a3f29370b5fd6b4b9aa7df4a499"
4260
+
4261
+
[[package]]
4262
+
name = "windows_x86_64_gnullvm"
4263
+
version = "0.42.2"
4264
+
source = "registry+https://github.com/rust-lang/crates.io-index"
4265
+
checksum = "26d41b46a36d453748aedef1486d5c7a85db22e56aff34643984ea85514e94a3"
4266
+
4267
+
[[package]]
4268
+
name = "windows_x86_64_gnullvm"
4269
+
version = "0.48.5"
4270
+
source = "registry+https://github.com/rust-lang/crates.io-index"
4271
+
checksum = "0b7b52767868a23d5bab768e390dc5f5c55825b6d30b86c844ff2dc7414044cc"
4272
+
4273
+
[[package]]
4274
+
name = "windows_x86_64_gnullvm"
4275
+
version = "0.52.6"
4276
+
source = "registry+https://github.com/rust-lang/crates.io-index"
4277
+
checksum = "24d5b23dc417412679681396f2b49f3de8c1473deb516bd34410872eff51ed0d"
4278
+
4279
+
[[package]]
4280
+
name = "windows_x86_64_gnullvm"
4281
+
version = "0.53.1"
4282
+
source = "registry+https://github.com/rust-lang/crates.io-index"
4283
+
checksum = "0ffa179e2d07eee8ad8f57493436566c7cc30ac536a3379fdf008f47f6bb7ae1"
4284
+
4285
+
[[package]]
4286
+
name = "windows_x86_64_msvc"
4287
+
version = "0.42.2"
4288
+
source = "registry+https://github.com/rust-lang/crates.io-index"
4289
+
checksum = "9aec5da331524158c6d1a4ac0ab1541149c0b9505fde06423b02f5ef0106b9f0"
4290
+
4291
+
[[package]]
4292
+
name = "windows_x86_64_msvc"
4293
+
version = "0.48.5"
4294
+
source = "registry+https://github.com/rust-lang/crates.io-index"
4295
+
checksum = "ed94fce61571a4006852b7389a063ab983c02eb1bb37b47f8272ce92d06d9538"
4296
+
4297
+
[[package]]
4298
+
name = "windows_x86_64_msvc"
4299
+
version = "0.52.6"
4300
+
source = "registry+https://github.com/rust-lang/crates.io-index"
4301
+
checksum = "589f6da84c646204747d1270a2a5661ea66ed1cced2631d546fdfb155959f9ec"
4302
+
4303
+
[[package]]
4304
+
name = "windows_x86_64_msvc"
4305
+
version = "0.53.1"
4306
+
source = "registry+https://github.com/rust-lang/crates.io-index"
4307
+
checksum = "d6bbff5f0aada427a1e5a6da5f1f98158182f26556f345ac9e04d36d0ebed650"
4308
+
4309
+
[[package]]
4310
+
name = "winreg"
4311
+
version = "0.50.0"
4312
+
source = "registry+https://github.com/rust-lang/crates.io-index"
4313
+
checksum = "524e57b2c537c0f9b1e69f1965311ec12182b4122e45035b1508cd24d2adadb1"
4314
+
dependencies = [
4315
+
"cfg-if",
4316
+
"windows-sys 0.48.0",
4317
+
]
4318
+
4319
+
[[package]]
4320
+
name = "wit-bindgen"
4321
+
version = "0.46.0"
4322
+
source = "registry+https://github.com/rust-lang/crates.io-index"
4323
+
checksum = "f17a85883d4e6d00e8a97c586de764dabcc06133f7f1d55dce5cdc070ad7fe59"
4324
+
4325
+
[[package]]
4326
+
name = "writeable"
4327
+
version = "0.6.1"
4328
+
source = "registry+https://github.com/rust-lang/crates.io-index"
4329
+
checksum = "ea2f10b9bb0928dfb1b42b65e1f9e36f7f54dbdf08457afefb38afcdec4fa2bb"
4330
+
4331
+
[[package]]
4332
+
name = "yansi"
4333
+
version = "1.0.1"
4334
+
source = "registry+https://github.com/rust-lang/crates.io-index"
4335
+
checksum = "cfe53a6657fd280eaa890a3bc59152892ffa3e30101319d168b781ed6529b049"
4336
+
4337
+
[[package]]
4338
+
name = "yoke"
4339
+
version = "0.8.0"
4340
+
source = "registry+https://github.com/rust-lang/crates.io-index"
4341
+
checksum = "5f41bb01b8226ef4bfd589436a297c53d118f65921786300e427be8d487695cc"
4342
+
dependencies = [
4343
+
"serde",
4344
+
"stable_deref_trait",
4345
+
"yoke-derive",
4346
+
"zerofrom",
4347
+
]
4348
+
4349
+
[[package]]
4350
+
name = "yoke-derive"
4351
+
version = "0.8.0"
4352
+
source = "registry+https://github.com/rust-lang/crates.io-index"
4353
+
checksum = "38da3c9736e16c5d3c8c597a9aaa5d1fa565d0532ae05e27c24aa62fb32c0ab6"
4354
+
dependencies = [
4355
+
"proc-macro2",
4356
+
"quote",
4357
+
"syn 2.0.107",
4358
+
"synstructure",
4359
+
]
4360
+
4361
+
[[package]]
4362
+
name = "zerocopy"
4363
+
version = "0.8.27"
4364
+
source = "registry+https://github.com/rust-lang/crates.io-index"
4365
+
checksum = "0894878a5fa3edfd6da3f88c4805f4c8558e2b996227a3d864f47fe11e38282c"
4366
+
dependencies = [
4367
+
"zerocopy-derive",
4368
+
]
4369
+
4370
+
[[package]]
4371
+
name = "zerocopy-derive"
4372
+
version = "0.8.27"
4373
+
source = "registry+https://github.com/rust-lang/crates.io-index"
4374
+
checksum = "88d2b8d9c68ad2b9e4340d7832716a4d21a22a1154777ad56ea55c51a9cf3831"
4375
+
dependencies = [
4376
+
"proc-macro2",
4377
+
"quote",
4378
+
"syn 2.0.107",
4379
+
]
4380
+
4381
+
[[package]]
4382
+
name = "zerofrom"
4383
+
version = "0.1.6"
4384
+
source = "registry+https://github.com/rust-lang/crates.io-index"
4385
+
checksum = "50cc42e0333e05660c3587f3bf9d0478688e15d870fab3346451ce7f8c9fbea5"
4386
+
dependencies = [
4387
+
"zerofrom-derive",
4388
+
]
4389
+
4390
+
[[package]]
4391
+
name = "zerofrom-derive"
4392
+
version = "0.1.6"
4393
+
source = "registry+https://github.com/rust-lang/crates.io-index"
4394
+
checksum = "d71e5d6e06ab090c67b5e44993ec16b72dcbaabc526db883a360057678b48502"
4395
+
dependencies = [
4396
+
"proc-macro2",
4397
+
"quote",
4398
+
"syn 2.0.107",
4399
+
"synstructure",
4400
+
]
4401
+
4402
+
[[package]]
4403
+
name = "zeroize"
4404
+
version = "1.8.2"
4405
+
source = "registry+https://github.com/rust-lang/crates.io-index"
4406
+
checksum = "b97154e67e32c85465826e8bcc1c59429aaaf107c1e4a9e53c8d8ccd5eff88d0"
4407
+
dependencies = [
4408
+
"serde",
4409
+
]
4410
+
4411
+
[[package]]
4412
+
name = "zerotrie"
4413
+
version = "0.2.2"
4414
+
source = "registry+https://github.com/rust-lang/crates.io-index"
4415
+
checksum = "36f0bbd478583f79edad978b407914f61b2972f5af6fa089686016be8f9af595"
4416
+
dependencies = [
4417
+
"displaydoc",
4418
+
"yoke",
4419
+
"zerofrom",
4420
+
]
4421
+
4422
+
[[package]]
4423
+
name = "zerovec"
4424
+
version = "0.11.4"
4425
+
source = "registry+https://github.com/rust-lang/crates.io-index"
4426
+
checksum = "e7aa2bd55086f1ab526693ecbe444205da57e25f4489879da80635a46d90e73b"
4427
+
dependencies = [
4428
+
"yoke",
4429
+
"zerofrom",
4430
+
"zerovec-derive",
4431
+
]
4432
+
4433
+
[[package]]
4434
+
name = "zerovec-derive"
4435
+
version = "0.11.1"
4436
+
source = "registry+https://github.com/rust-lang/crates.io-index"
4437
+
checksum = "5b96237efa0c878c64bd89c436f661be4e46b2f3eff1ebb976f7ef2321d2f58f"
4438
+
dependencies = [
4439
+
"proc-macro2",
4440
+
"quote",
4441
+
"syn 2.0.107",
4442
+
]
+16
-1
upload/Cargo.toml
+16
-1
upload/Cargo.toml
···
1
+
[workspace]
2
+
resolver = "3"
3
+
members = ["lexicons"]
4
+
1
5
[package]
2
6
name = "atcities-upload"
3
-
version = "0.1.0"
7
+
version = "1.0.1"
4
8
edition = "2024"
5
9
6
10
[dependencies]
11
+
lexicons = { path = "./lexicons" }
12
+
clap = { version = "4.5.49", features = ["derive"] }
13
+
ignore = "0.4.23"
14
+
regex = "1.12.2"
15
+
mime_guess = "2.0.5"
16
+
tokio = { version = "1.48.0", features = [] }
17
+
jacquard = "0.6.0"
18
+
reqwest = "0.12.24"
19
+
env_logger = "0.11.8"
20
+
miette = { version = "7.6.0", features = ["derive", "fancy"] }
21
+
thiserror = "2.0.17"
+17
upload/lexicons/Cargo.toml
+17
upload/lexicons/Cargo.toml
···
1
+
[package]
2
+
name = "lexicons"
3
+
version = "1.0.0"
4
+
edition = "2024"
5
+
6
+
[features]
7
+
default = ["dev_atcities"]
8
+
dev_atcities = []
9
+
10
+
[dependencies]
11
+
bon = "3.8.1"
12
+
bytes = { version = "1.10.1", features = ["serde"] }
13
+
miette = "7.6.0"
14
+
serde = "1.0.228"
15
+
thiserror = "2.0.17"
16
+
jacquard-common = "0.6.0"
17
+
jacquard-derive = "0.6.0"
+77
upload/lexicons/src/dev_atcities/route.rs
+77
upload/lexicons/src/dev_atcities/route.rs
···
1
+
// @generated by jacquard-lexicon. DO NOT EDIT.
2
+
//
3
+
// Lexicon: dev.atcities.route
4
+
//
5
+
// This file was automatically generated from Lexicon schemas.
6
+
// Any manual changes will be overwritten on the next regeneration.
7
+
8
+
#[jacquard_derive::lexicon]
9
+
#[derive(
10
+
serde::Serialize,
11
+
serde::Deserialize,
12
+
Debug,
13
+
Clone,
14
+
PartialEq,
15
+
Eq,
16
+
jacquard_derive::IntoStatic,
17
+
bon::Builder,
18
+
)]
19
+
#[serde(rename_all = "camelCase")]
20
+
pub struct Blob<'a> {
21
+
#[serde(borrow)]
22
+
pub blob: jacquard_common::types::blob::Blob<'a>,
23
+
}
24
+
25
+
/// Page URL maps directly to a record key
26
+
#[jacquard_derive::lexicon]
27
+
#[derive(
28
+
serde::Serialize,
29
+
serde::Deserialize,
30
+
Debug,
31
+
Clone,
32
+
PartialEq,
33
+
Eq,
34
+
jacquard_derive::IntoStatic,
35
+
bon::Builder,
36
+
)]
37
+
#[serde(rename_all = "camelCase")]
38
+
pub struct Route<'a> {
39
+
#[serde(borrow)]
40
+
pub page: crate::dev_atcities::route::Blob<'a>,
41
+
}
42
+
43
+
/// Typed wrapper for GetRecord response with this collection's record type.
44
+
#[derive(
45
+
serde::Serialize, serde::Deserialize, Debug, Clone, PartialEq, Eq, jacquard_derive::IntoStatic,
46
+
)]
47
+
#[serde(rename_all = "camelCase")]
48
+
pub struct RouteGetRecordOutput<'a> {
49
+
#[serde(skip_serializing_if = "std::option::Option::is_none")]
50
+
#[serde(borrow)]
51
+
pub cid: std::option::Option<jacquard_common::types::string::Cid<'a>>,
52
+
#[serde(borrow)]
53
+
pub uri: jacquard_common::types::string::AtUri<'a>,
54
+
#[serde(borrow)]
55
+
pub value: Route<'a>,
56
+
}
57
+
58
+
/// Marker type for deserializing records from this collection.
59
+
pub struct RouteRecord;
60
+
impl jacquard_common::xrpc::XrpcResp for RouteRecord {
61
+
const NSID: &'static str = "dev.atcities.route";
62
+
const ENCODING: &'static str = "application/json";
63
+
type Output<'de> = RouteGetRecordOutput<'de>;
64
+
type Err<'de> = jacquard_common::types::collection::RecordError<'de>;
65
+
}
66
+
67
+
impl jacquard_common::types::collection::Collection for Route<'_> {
68
+
const NSID: &'static str = "dev.atcities.route";
69
+
type Record = RouteRecord;
70
+
}
71
+
72
+
impl From<RouteGetRecordOutput<'_>> for Route<'_> {
73
+
fn from(output: RouteGetRecordOutput<'_>) -> Self {
74
+
use jacquard_common::IntoStatic;
75
+
output.value.into_static()
76
+
}
77
+
}
+6
upload/lexicons/src/dev_atcities.rs
+6
upload/lexicons/src/dev_atcities.rs
+7
upload/lexicons/src/lib.rs
+7
upload/lexicons/src/lib.rs
-81
upload/src/config.rs
-81
upload/src/config.rs
···
1
-
pub struct Config {
2
-
pub user: String,
3
-
pub pword: String,
4
-
pub dir: String,
5
-
}
6
-
7
-
pub enum ConfigErr {
8
-
TooManyDirectories,
9
-
NotEnoughArgs(String),
10
-
UnknownArg(String),
11
-
NotADirectory,
12
-
}
13
-
14
-
pub fn extract() -> Result<Config, ConfigErr> {
15
-
let mut user: Option<String> = None;
16
-
let mut pword: Option<String> = None;
17
-
let mut dir: Option<String> = None;
18
-
19
-
let mut args = std::env::args().into_iter();
20
-
// skip first arg
21
-
args.next();
22
-
while let Some(arg) = args.next() {
23
-
match arg.as_str() {
24
-
"--user" => user = args.next(),
25
-
"--password" => pword = args.next(),
26
-
_ => {
27
-
if arg.starts_with("--") {
28
-
return Err(ConfigErr::UnknownArg(arg));
29
-
}
30
-
if dir.is_some() {
31
-
return Err(ConfigErr::TooManyDirectories);
32
-
}
33
-
dir = Some(arg);
34
-
}
35
-
}
36
-
}
37
-
38
-
if let Some(user) = user.clone()
39
-
&& let Some(pword) = pword.clone()
40
-
&& let Some(dir) = dir.clone()
41
-
{
42
-
return Ok(Config {
43
-
user,
44
-
pword,
45
-
dir: dir.to_owned(),
46
-
});
47
-
}
48
-
49
-
return Err(ConfigErr::NotEnoughArgs(String::from(
50
-
// xxx
51
-
if user.is_none() && pword.is_none() && dir.is_none() {
52
-
"--user, --password, and <dir>"
53
-
}
54
-
// yxx
55
-
else if user.is_some() && pword.is_none() && dir.is_none() {
56
-
"--password and <dir>"
57
-
}
58
-
// xyx
59
-
else if user.is_none() && pword.is_some() && dir.is_none() {
60
-
"--user and <dir>"
61
-
}
62
-
// yyx
63
-
else if user.is_some() && pword.is_some() && dir.is_none() {
64
-
"<dir>"
65
-
}
66
-
// xxy
67
-
else if user.is_none() && pword.is_none() && dir.is_some() {
68
-
"--user and --password"
69
-
}
70
-
// yxy
71
-
else if user.is_some() && pword.is_none() && dir.is_some() {
72
-
"--password"
73
-
}
74
-
// xyy
75
-
else if user.is_none() && pword.is_some() && dir.is_some() {
76
-
"--user"
77
-
} else {
78
-
"Invalid State, as all values are provided here"
79
-
},
80
-
)));
81
-
}
+318
-10
upload/src/main.rs
+318
-10
upload/src/main.rs
···
1
-
mod config;
1
+
use clap::{ArgAction, Parser};
2
+
use jacquard::api::com_atproto::repo::apply_writes::{
3
+
self, ApplyWrites, ApplyWritesOutput, ApplyWritesWritesItem,
4
+
};
5
+
use jacquard::client::AgentSessionExt;
6
+
use jacquard::client::MemorySessionStore;
7
+
use jacquard::oauth::loopback::LoopbackConfig;
8
+
use jacquard::oauth::types::AuthorizeOptions;
9
+
use jacquard::types::string::{AtStrError, RecordKey, Rkey};
10
+
use jacquard::{AuthorizationToken, CowStr, atproto, oauth};
11
+
use jacquard::{
12
+
Data,
13
+
api::com_atproto::{self, repo::list_records::ListRecords},
14
+
client::{Agent, credential_session::CredentialSession},
15
+
cowstr::ToCowStr,
16
+
identity::JacquardResolver,
17
+
types::{ident::AtIdentifier, nsid::Nsid, string::AtprotoStr, uri::Uri},
18
+
xrpc::XrpcExt,
19
+
};
20
+
use miette::{Context, IntoDiagnostic, Result};
21
+
use std::io::Write;
22
+
use std::{collections::HashMap, fs, path::PathBuf};
2
23
3
-
fn main() -> Result<(), ()> {
4
-
let config = config::extract();
5
-
if let Err(err) = config {
6
-
match err {
7
-
config::ConfigErr::TooManyDirectories => println!("Too many directories"),
8
-
config::ConfigErr::NotEnoughArgs(args) => println!("Missing {}", args),
9
-
config::ConfigErr::UnknownArg(arg) => println!("Unknown arg {}", arg),
10
-
config::ConfigErr::NotADirectory => println!("Not a directory"),
24
+
use crate::sitemap::{BlobRef, Sitemap, SitemapNode};
25
+
26
+
mod sitemap;
27
+
mod utils;
28
+
29
+
#[derive(Parser, Debug, Clone)]
30
+
#[command(version, about, long_about = None)]
31
+
struct Config {
32
+
/// Handle or DID to authenticate
33
+
#[arg(verbatim_doc_comment)]
34
+
user: String,
35
+
36
+
/// App password to authenticate the client
37
+
/// Normal passwords also work but are not advised
38
+
/// If ommited, oauth will be used instead
39
+
/// Oauth is reccomended where possible.
40
+
#[arg(verbatim_doc_comment, short = 'p', long = "password")]
41
+
password: Option<String>,
42
+
43
+
/// Include dotfiles in upload
44
+
/// Default: false
45
+
#[arg(verbatim_doc_comment, short = 'a', long = "all")]
46
+
all_files: bool,
47
+
48
+
/// Respect gitignore files
49
+
/// Note: gitignore files are not uploaded unless --all is set
50
+
/// Default: true
51
+
#[arg(verbatim_doc_comment, short = 'g', long = "no-gitignore", action = ArgAction::SetFalse, )]
52
+
git_ignore: bool,
53
+
54
+
/// Directory to upload
55
+
#[arg(verbatim_doc_comment)]
56
+
dir: PathBuf,
57
+
}
58
+
59
+
async fn live_records(agent: &impl AgentSessionExt, config: Config) -> Result<Vec<String>> {
60
+
// find live site records
61
+
let mut cursor = None;
62
+
let mut remote_records = Vec::new();
63
+
let user = config.user.clone();
64
+
let user = if user.contains(":") {
65
+
AtIdentifier::Did(user.into())
66
+
} else {
67
+
AtIdentifier::Handle(user.into())
68
+
};
69
+
loop {
70
+
let req = com_atproto::repo::list_records::ListRecords::new()
71
+
.collection(
72
+
Nsid::new("dev.atcities.route").expect("failed to generate dev.atcities.route nsid"),
73
+
)
74
+
.repo(user.clone())
75
+
.limit(100)
76
+
.maybe_cursor(cursor)
77
+
.build();
78
+
79
+
let res = agent
80
+
.xrpc(agent.endpoint().await)
81
+
.send::<ListRecords>(&req)
82
+
.await?
83
+
.into_output()?;
84
+
85
+
for record in res.records {
86
+
match record {
87
+
Data::Object(obj) => {
88
+
let obj = obj.0.clone();
89
+
let uri = obj.get_key_value("uri").and_then(|x| match x.1 {
90
+
Data::String(str) => Some(str),
91
+
_ => None,
92
+
});
93
+
94
+
if let Some(uri) = uri
95
+
&& let AtprotoStr::Uri(uri) = uri
96
+
&& let Uri::At(uri) = uri
97
+
&& let Some(rkey) = uri.rkey()
98
+
{
99
+
let rkey = rkey.0.to_cowstr().to_string();
100
+
remote_records.push(rkey);
101
+
} else {
102
+
panic!("Warning: pds returned invalid data.")
103
+
}
104
+
}
105
+
_ => {
106
+
panic!("Warning: pds returned invalid data.")
107
+
}
108
+
}
11
109
}
12
-
return Err(());
110
+
111
+
cursor = res.cursor;
112
+
if cursor.is_none() {
113
+
break;
114
+
}
13
115
}
116
+
Ok(remote_records)
117
+
}
118
+
119
+
async fn upload_site_blobs(
120
+
agent: &impl AgentSessionExt,
121
+
_config: Config,
122
+
local_sitemap: Sitemap,
123
+
) -> Result<Sitemap> {
124
+
// upload local site blobs
125
+
let mut new_sitemap: Sitemap = HashMap::new();
126
+
for (k, v) in local_sitemap {
127
+
print!("Uploading {k}... ");
128
+
let _ = std::io::stdout().flush();
129
+
let blob = match v.blob {
130
+
BlobRef::Local(path) => path,
131
+
BlobRef::Remote(_) => {
132
+
panic!("Impossible state")
133
+
}
134
+
};
135
+
let blob = fs::read(blob).into_diagnostic()?;
136
+
137
+
let req = com_atproto::repo::upload_blob::UploadBlob::new()
138
+
.body(blob.into())
139
+
.build();
140
+
let res = agent.send(req).await?.into_output()?;
141
+
142
+
new_sitemap.insert(
143
+
k,
144
+
SitemapNode {
145
+
mime_type: v.mime_type,
146
+
blob: BlobRef::Remote(res.blob.into()),
147
+
},
148
+
);
149
+
150
+
println!("Done!");
151
+
}
152
+
153
+
Ok(new_sitemap)
154
+
}
155
+
156
+
async fn update_remote_site(
157
+
agent: &impl AgentSessionExt,
158
+
config: Config,
159
+
auth: AuthorizationToken<'_>,
160
+
remote_records: Vec<String>,
161
+
new_sitemap: Sitemap,
162
+
) -> Result<ApplyWritesOutput<'static>> {
163
+
// batch delete/upload records
164
+
let mut writes = Vec::new();
165
+
let mut delete_records = remote_records
166
+
.into_iter()
167
+
.map(|x| {
168
+
let rkey = RecordKey(Rkey::new_owned(x)?);
169
+
Ok(ApplyWritesWritesItem::Delete(Box::new(
170
+
apply_writes::Delete::builder()
171
+
.collection(Nsid::raw("dev.atcities.route"))
172
+
.rkey(rkey)
173
+
.build(),
174
+
)))
175
+
})
176
+
.collect::<Result<Vec<ApplyWritesWritesItem<'_>>, AtStrError>>()
177
+
.into_diagnostic()?;
178
+
179
+
let mut create_records = new_sitemap
180
+
.into_iter()
181
+
.map(|(k, v)| {
182
+
let k = match k.as_str() {
183
+
"404.html" => String::from("404"),
184
+
"index.html" => String::from("/"),
185
+
_ => match k.strip_suffix("/index.html") {
186
+
Some(k) => format!("/{k}/"),
187
+
None => format!("/{k}"),
188
+
}
189
+
};
190
+
let rkey =
191
+
utils::url_to_rkey(k).wrap_err("Invalid file path. Could not be converted to rkey")?;
192
+
let rkey = RecordKey(Rkey::new_owned(rkey).into_diagnostic()?);
193
+
let blob = match v.blob {
194
+
BlobRef::Local(_) => panic!("Illegal local blob"),
195
+
BlobRef::Remote(cid) => cid,
196
+
};
197
+
let data = atproto!({
198
+
"page": {
199
+
"$type": "dev.atcities.route#blob",
200
+
"blob": {
201
+
"$type": "blob",
202
+
"ref": {
203
+
"$link": blob.r#ref.as_str()
204
+
},
205
+
"mimeType": blob.mime_type.0.as_str(),
206
+
"size": blob.size
207
+
}
208
+
}
209
+
});
210
+
Ok(ApplyWritesWritesItem::Create(Box::new(
211
+
apply_writes::Create::builder()
212
+
.collection(Nsid::raw("dev.atcities.route"))
213
+
.rkey(rkey)
214
+
.value(data)
215
+
.build(),
216
+
)))
217
+
})
218
+
.collect::<Result<Vec<ApplyWritesWritesItem<'_>>, miette::Error>>()?;
219
+
220
+
writes.append(&mut delete_records);
221
+
writes.append(&mut create_records);
222
+
223
+
let repo = if config.user.contains(":") {
224
+
AtIdentifier::Did(config.user.into())
225
+
} else {
226
+
AtIdentifier::Handle(config.user.into())
227
+
};
228
+
229
+
let req = com_atproto::repo::apply_writes::ApplyWrites::new()
230
+
.repo(repo)
231
+
.writes(writes)
232
+
.build();
233
+
234
+
let res = agent
235
+
.xrpc(agent.endpoint().await)
236
+
.auth(auth)
237
+
.send::<ApplyWrites>(&req)
238
+
.await?
239
+
.into_output()?;
240
+
241
+
Ok(res)
242
+
}
243
+
244
+
#[tokio::main]
245
+
async fn main() -> Result<(), miette::Error> {
246
+
env_logger::init();
247
+
// get config items
248
+
let config = Config::parse();
249
+
250
+
// get local site info
251
+
let local_sitemap =
252
+
sitemap::local_sitemap(config.dir.clone(), config.all_files, config.git_ignore)?;
253
+
254
+
// create session
255
+
if let Some(password) = config.password.clone() {
256
+
let password = password.into();
257
+
let client = JacquardResolver::default();
258
+
let store = MemorySessionStore::default();
259
+
let session = CredentialSession::new(store.into(), client.into());
260
+
261
+
let auth = session
262
+
.login(config.user.clone().into(), password, None, None, None)
263
+
.await?;
264
+
265
+
let agent = Agent::from(session);
266
+
267
+
let remote_sitemap = live_records(&agent, config.clone()).await?;
268
+
let new_sitemap = upload_site_blobs(&agent, config.clone(), local_sitemap).await?;
269
+
let _ = update_remote_site(
270
+
&agent,
271
+
config.clone(),
272
+
AuthorizationToken::Bearer(auth.access_jwt),
273
+
remote_sitemap,
274
+
new_sitemap,
275
+
)
276
+
.await?;
277
+
278
+
println!(
279
+
"Site is now updated. Live at {}",
280
+
utils::site_handle(config.user)
281
+
);
282
+
} else {
283
+
let oauth = oauth::client::OAuthClient::with_memory_store();
284
+
let session = oauth
285
+
.login_with_local_server(
286
+
config.user.clone(),
287
+
AuthorizeOptions::default(),
288
+
LoopbackConfig::default(),
289
+
)
290
+
.await?;
291
+
292
+
// sick and twisted reference mangling BUT it works So
293
+
// tldr: the cowstr is a borrowed cowstr iiuc,
294
+
// so it needs to be turned into an owned cowstr
295
+
// to break reference to session which gets moved
296
+
let auth = session.access_token().await;
297
+
let auth = match auth {
298
+
AuthorizationToken::Bearer(cow_str) => CowStr::copy_from_str(cow_str.as_str()),
299
+
AuthorizationToken::Dpop(cow_str) => CowStr::copy_from_str(cow_str.as_str()),
300
+
};
301
+
302
+
println!("{}", auth);
303
+
304
+
let agent = Agent::from(session);
305
+
306
+
let remote_sitemap = live_records(&agent, config.clone()).await?;
307
+
let new_sitemap = upload_site_blobs(&agent, config.clone(), local_sitemap).await?;
308
+
let _ = update_remote_site(
309
+
&agent,
310
+
config.clone(),
311
+
AuthorizationToken::Dpop(auth),
312
+
remote_sitemap,
313
+
new_sitemap,
314
+
)
315
+
.await?;
316
+
317
+
println!(
318
+
"Site is now updated. Live at {}",
319
+
utils::site_handle(config.user)
320
+
);
321
+
};
14
322
15
323
Ok(())
16
324
}
+80
upload/src/sitemap.rs
+80
upload/src/sitemap.rs
···
1
+
use ignore::WalkBuilder;
2
+
use jacquard::types::blob::Blob;
3
+
use miette::Diagnostic;
4
+
use mime_guess::mime;
5
+
use std::{collections::HashMap, path::PathBuf};
6
+
use thiserror::Error;
7
+
8
+
pub type Sitemap = HashMap<String, SitemapNode>;
9
+
10
+
#[derive(Debug)]
11
+
pub struct SitemapNode {
12
+
pub mime_type: String,
13
+
pub blob: BlobRef,
14
+
}
15
+
16
+
#[derive(Debug)]
17
+
pub enum BlobRef {
18
+
Local(PathBuf),
19
+
Remote(Blob<'static>),
20
+
}
21
+
22
+
#[derive(Debug, Error, Diagnostic)]
23
+
pub enum SitemapErr {
24
+
#[error("IO error: {}", .0)]
25
+
IoErr(#[from] std::io::Error),
26
+
#[error("Error finding files: {}", .0)]
27
+
IgnoreErr(#[from] ignore::Error),
28
+
#[error("Error normalising file paths: {}", .0)]
29
+
StripPrefixErr(#[from] std::path::StripPrefixError),
30
+
#[error("Found non UTF-8 path")]
31
+
NotUTF8Path,
32
+
}
33
+
34
+
pub fn local_sitemap(
35
+
dir: PathBuf,
36
+
include_dotfiles: bool,
37
+
use_gitignore: bool,
38
+
) -> miette::Result<Sitemap, SitemapErr> {
39
+
let prefix = dir.canonicalize()?;
40
+
41
+
let mut res = HashMap::new();
42
+
for file in WalkBuilder::new(dir)
43
+
.hidden(!include_dotfiles)
44
+
.git_ignore(use_gitignore)
45
+
.git_exclude(use_gitignore)
46
+
.git_global(use_gitignore)
47
+
.follow_links(true)
48
+
.build()
49
+
{
50
+
let file = file?;
51
+
52
+
let metadata = file.metadata()?;
53
+
54
+
if !metadata.is_file() {
55
+
continue;
56
+
};
57
+
58
+
// find the path of the files relative to the source directory
59
+
// source dir `./dist`:
60
+
// ./dist/index.html => index.html
61
+
// ./dist/assets/cat.jpg => cat.jpg
62
+
// etc
63
+
let key = file.path().canonicalize()?;
64
+
let key = key.strip_prefix(&prefix)?;
65
+
let key = String::from(key.to_str().ok_or(SitemapErr::NotUTF8Path)?);
66
+
67
+
let mime = mime_guess::from_path(&key);
68
+
let mime = mime.first().unwrap_or(mime::APPLICATION_OCTET_STREAM);
69
+
let mime = mime.essence_str();
70
+
71
+
res.insert(
72
+
key,
73
+
SitemapNode {
74
+
mime_type: String::from(mime),
75
+
blob: BlobRef::Local(file.path().to_owned()),
76
+
},
77
+
);
78
+
}
79
+
Ok(res)
80
+
}
+76
upload/src/utils.rs
+76
upload/src/utils.rs
···
1
+
use regex::Regex;
2
+
3
+
#[allow(dead_code)]
4
+
pub fn rkey_to_url(rkey: String) -> Option<String> {
5
+
let regex = Regex::new(
6
+
// symbols A-Za-z0-9 -._~: are all valid rkey characters
7
+
// however we use a subset of record keys where : is an escape character
8
+
// allow any rkey character except colons
9
+
// or any of the valid escape sequences
10
+
// from start of string to end between 0 and unlimited times
11
+
r"^(?:[A-Za-z0-9.\-_~]|(?:::)|(?::~)|(?::21)|(?::24)|(?::26)|(?::27)|(?::28)|(?::29)|(?::2A)|(?::2B)|(?::2C)|(?::3A)|(?::3B)|(?::3D)|(?::40))*$",
12
+
)
13
+
.expect("Regex failed to generate");
14
+
15
+
if !regex.is_match(&rkey) {
16
+
return None;
17
+
};
18
+
19
+
let res = rkey
20
+
.replace("::", "/")
21
+
.replace(":~", "%")
22
+
.replace(":21", "!")
23
+
.replace(":24", "$")
24
+
.replace(":26", "&")
25
+
.replace(":27", "'")
26
+
.replace(":28", "(")
27
+
.replace(":29", ")")
28
+
.replace(":2A", "*")
29
+
.replace(":2B", "+")
30
+
.replace(":2C", ",")
31
+
.replace(":3A", ":")
32
+
.replace(":3B", ";")
33
+
.replace(":3D", "=")
34
+
.replace(":40", "@");
35
+
36
+
Some(res)
37
+
}
38
+
39
+
pub fn url_to_rkey(url: String) -> Option<String> {
40
+
let regex = Regex::new(r"^(?:[a-zA-Z0-9/\-._~!$&'()*+,;=:@]|(?:%[0-9a-fA-F]{2}))*$")
41
+
.expect("Regex failed to generate");
42
+
if !regex.is_match(&url) {
43
+
return None;
44
+
}
45
+
46
+
let res = url
47
+
// : replace is hoisted so it doesnt replace colons from elsewhere
48
+
.replace(":", ":3A")
49
+
.replace("/", "::")
50
+
.replace("%", ":~")
51
+
.replace("!", ":21")
52
+
.replace("$", ":24")
53
+
.replace("&", ":26")
54
+
.replace("'", ":27")
55
+
.replace("(", ":28")
56
+
.replace(")", ":29")
57
+
.replace("*", ":2A")
58
+
.replace("+", ":2B")
59
+
.replace(",", ":2C")
60
+
.replace(";", ":3B")
61
+
.replace("=", ":3D")
62
+
.replace("@", ":40");
63
+
64
+
Some(res)
65
+
}
66
+
67
+
pub fn site_handle(user: String) -> String {
68
+
if user.contains(":") {
69
+
let user = user.split(":").collect::<Vec<_>>();
70
+
let method = user[1];
71
+
let did = user[2];
72
+
format!("https://{did}.did-{method}.atcities.dev/")
73
+
} else {
74
+
format!("https://{user}.atcities.dev/")
75
+
}
76
+
}