tangled
alpha
login
or
join now
kris.darkworld.download
/
darkworld
1
fork
atom
The code for darkworld.download
darkworld.download
1
fork
atom
overview
issues
pulls
pipelines
chore: atproto starter
kris.darkworld.download
4 days ago
0a241b6c
97029324
verified
This commit was signed with the committer's
known signature
.
kris.darkworld.download
SSH Key Fingerprint:
SHA256:4iiUkypaBzJPnEeVlazWCFBrJncWXreVhtJPB4DlswE=
+218
5 changed files
expand all
collapse all
unified
split
.dockerignore
bun.lock
lexicons
download.darkworld.state.json
package.json
scripts
publish-lexicons.ts
+1
.dockerignore
···
1
1
dist
2
2
node_modules
3
3
+
.env
+31
bun.lock
···
4
4
"": {
5
5
"name": "bun-react-template",
6
6
"dependencies": {
7
7
+
"@atproto/api": "^0.19.3",
7
8
"bun-plugin-tailwind": "^0.1.2",
8
9
"react": "^19",
9
10
"react-dom": "^19",
···
18
19
},
19
20
},
20
21
"packages": {
22
22
+
"@atproto/api": ["@atproto/api@0.19.3", "", { "dependencies": { "@atproto/common-web": "^0.4.18", "@atproto/lexicon": "^0.6.2", "@atproto/syntax": "^0.5.0", "@atproto/xrpc": "^0.7.7", "await-lock": "^2.2.2", "multiformats": "^9.9.0", "tlds": "^1.234.0", "zod": "^3.23.8" } }, "sha512-G8YpBpRouHdTAIagi/QQIUZOhGd1jfBQWkJy9QfxAzjjEpPvaVOSk4e1S85QzGLm/xbzVONzGkmdtiOSfP6wVg=="],
23
23
+
24
24
+
"@atproto/common-web": ["@atproto/common-web@0.4.18", "", { "dependencies": { "@atproto/lex-data": "^0.0.13", "@atproto/lex-json": "^0.0.13", "@atproto/syntax": "^0.5.0", "zod": "^3.23.8" } }, "sha512-ilImzP+9N/mtse440kN60pGrEzG7wi4xsV13nGeLrS+Zocybc/ISOpKlbZM13o+twPJ+Q7veGLw9CtGg0GAFoQ=="],
25
25
+
26
26
+
"@atproto/lex-data": ["@atproto/lex-data@0.0.13", "", { "dependencies": { "multiformats": "^9.9.0", "tslib": "^2.8.1", "uint8arrays": "3.0.0", "unicode-segmenter": "^0.14.0" } }, "sha512-7Z7RwZ1Y/JzBF/Tcn/I4UJ/vIGfh5zn1zjv0KX+flke2JtgFkSE8uh2hOtqgBQMNqE3zdJFM+dcSWln86hR3MQ=="],
27
27
+
28
28
+
"@atproto/lex-json": ["@atproto/lex-json@0.0.13", "", { "dependencies": { "@atproto/lex-data": "^0.0.13", "tslib": "^2.8.1" } }, "sha512-hwLhkKaIHulGJpt0EfXAEWdrxqM2L1tV/tvilzhMp3QxPqYgXchFnrfVmLsyFDx6P6qkH1GsX/XC2V36U0UlPQ=="],
29
29
+
30
30
+
"@atproto/lexicon": ["@atproto/lexicon@0.6.2", "", { "dependencies": { "@atproto/common-web": "^0.4.18", "@atproto/syntax": "^0.5.0", "iso-datestring-validator": "^2.2.2", "multiformats": "^9.9.0", "zod": "^3.23.8" } }, "sha512-p3Ly6hinVZW0ETuAXZMeUGwuMm3g8HvQMQ41yyEE6AL0hAkfeKFaZKos6BdBrr6CjkpbrDZqE8M+5+QOceysMw=="],
31
31
+
32
32
+
"@atproto/syntax": ["@atproto/syntax@0.5.0", "", { "dependencies": { "tslib": "^2.8.1" } }, "sha512-UA2DSpGdOQzUQ4gi5SH+NEJz/YR3a3Fg3y2oh+xETDSiTRmA4VhHRCojhXAVsBxUT6EnItw190C/KN+DWW90kw=="],
33
33
+
34
34
+
"@atproto/xrpc": ["@atproto/xrpc@0.7.7", "", { "dependencies": { "@atproto/lexicon": "^0.6.0", "zod": "^3.23.8" } }, "sha512-K1ZyO/BU8JNtXX5dmPp7b5UrkLMMqpsIa/Lrj5D3Su+j1Xwq1m6QJ2XJ1AgjEjkI1v4Muzm7klianLE6XGxtmA=="],
35
35
+
21
36
"@oven/bun-darwin-aarch64": ["@oven/bun-darwin-aarch64@1.3.9", "", { "os": "darwin", "cpu": "arm64" }, "sha512-df7smckMWSUfaT5mzwN9Lfpd3ZGkOqo+vmQ8VV2a32gl14v6uZ/qeeo+1RlANXn8M0uzXPWWCkrKZIWSZUR0qw=="],
22
37
23
38
"@oven/bun-darwin-x64": ["@oven/bun-darwin-x64@1.3.9", "", { "os": "darwin", "cpu": "x64" }, "sha512-YiLxfsPzQqaVvT2a+nxH9do0YfUjrlxF3tKP0b1DDgvfgCcVKGsrQH3Wa82qHgL4dnT8h2bqi94JxXESEuPmcA=="],
···
48
63
49
64
"@types/react-dom": ["@types/react-dom@19.2.3", "", { "peerDependencies": { "@types/react": "^19.2.0" } }, "sha512-jp2L/eY6fn+KgVVQAOqYItbF0VY/YApe5Mz2F0aykSO8gx31bYCZyvSeYxCHKvzHG5eZjc+zyaS5BrBWya2+kQ=="],
50
65
66
66
+
"await-lock": ["await-lock@2.2.2", "", {}, "sha512-aDczADvlvTGajTDjcjpJMqRkOF6Qdz3YbPZm/PyW6tKPkx2hlYBzxMhEywM/tU72HrVZjgl5VCdRuMlA7pZ8Gw=="],
67
67
+
51
68
"bun": ["bun@1.3.9", "", { "optionalDependencies": { "@oven/bun-darwin-aarch64": "1.3.9", "@oven/bun-darwin-x64": "1.3.9", "@oven/bun-darwin-x64-baseline": "1.3.9", "@oven/bun-linux-aarch64": "1.3.9", "@oven/bun-linux-aarch64-musl": "1.3.9", "@oven/bun-linux-x64": "1.3.9", "@oven/bun-linux-x64-baseline": "1.3.9", "@oven/bun-linux-x64-musl": "1.3.9", "@oven/bun-linux-x64-musl-baseline": "1.3.9", "@oven/bun-windows-x64": "1.3.9", "@oven/bun-windows-x64-baseline": "1.3.9" }, "os": [ "linux", "win32", "darwin", ], "cpu": [ "x64", "arm64", ], "bin": { "bun": "bin/bun.exe", "bunx": "bin/bunx.exe" } }, "sha512-v5hkh1us7sMNjfimWE70flYbD5I1/qWQaqmJ45q2qk5H/7muQVa478LSVRSFyGTBUBog2LsPQnfIRdjyWJRY+A=="],
52
69
53
70
"bun-plugin-tailwind": ["bun-plugin-tailwind@0.1.2", "", { "peerDependencies": { "bun": ">=1.0.0" } }, "sha512-41jNC1tZRSK3s1o7pTNrLuQG8kL/0vR/JgiTmZAJ1eHwe0w5j6HFPKeqEk0WAD13jfrUC7+ULuewFBBCoADPpg=="],
···
56
73
57
74
"csstype": ["csstype@3.2.3", "", {}, "sha512-z1HGKcYy2xA8AGQfwrn0PAy+PB7X/GSj3UVJW9qKyn43xWa+gl5nXmU4qqLMRzWVLFC8KusUX8T/0kCiOYpAIQ=="],
58
75
76
76
+
"iso-datestring-validator": ["iso-datestring-validator@2.2.2", "", {}, "sha512-yLEMkBbLZTlVQqOnQ4FiMujR6T4DEcCb1xizmvXS+OxuhwcbtynoosRzdMA69zZCShCNAbi+gJ71FxZBBXx1SA=="],
77
77
+
78
78
+
"multiformats": ["multiformats@9.9.0", "", {}, "sha512-HoMUjhH9T8DDBNT+6xzkrd9ga/XiBI4xLr58LJACwK6G3HTOPeMz4nB4KJs33L2BelrIJa7P0VuNaVF3hMYfjg=="],
79
79
+
59
80
"react": ["react@19.2.4", "", {}, "sha512-9nfp2hYpCwOjAN+8TZFGhtWEwgvWHXqESH8qT89AT/lWklpLON22Lc8pEtnpsZz7VmawabSU0gCjnj8aC0euHQ=="],
60
81
61
82
"react-dom": ["react-dom@19.2.4", "", { "dependencies": { "scheduler": "^0.27.0" }, "peerDependencies": { "react": "^19.2.4" } }, "sha512-AXJdLo8kgMbimY95O2aKQqsz2iWi9jMgKJhRBAxECE4IFxfcazB2LmzloIoibJI3C12IlY20+KFaLv+71bUJeQ=="],
···
66
87
67
88
"tailwindcss": ["tailwindcss@4.1.18", "", {}, "sha512-4+Z+0yiYyEtUVCScyfHCxOYP06L5Ne+JiHhY2IjR2KWMIWhJOYZKLSGZaP5HkZ8+bY0cxfzwDE5uOmzFXyIwxw=="],
68
89
90
90
+
"tlds": ["tlds@1.261.0", "", { "bin": { "tlds": "bin.js" } }, "sha512-QXqwfEl9ddlGBaRFXIvNKK6OhipSiLXuRuLJX5DErz0o0Q0rYxulWLdFryTkV5PkdZct5iMInwYEGe/eR++1AA=="],
91
91
+
92
92
+
"tslib": ["tslib@2.8.1", "", {}, "sha512-oJFu94HQb+KVduSUQL7wnpmqnfmLsOA/nAh6b6EH0wCEoK0/mPeXU6c3wKDV83MkOuHPRHtSXKKU99IBazS/2w=="],
93
93
+
94
94
+
"uint8arrays": ["uint8arrays@3.0.0", "", { "dependencies": { "multiformats": "^9.4.2" } }, "sha512-HRCx0q6O9Bfbp+HHSfQQKD7wU70+lydKVt4EghkdOvlK/NlrF90z+eXV34mUd48rNvVJXwkrMSPpCATkct8fJA=="],
95
95
+
69
96
"undici-types": ["undici-types@7.16.0", "", {}, "sha512-Zz+aZWSj8LE6zoxD+xrjh4VfkIG8Ya6LvYkZqtUQGJPZjYl53ypCaUwWqo7eI0x66KBGeRo+mlBEkMSeSZ38Nw=="],
97
97
+
98
98
+
"unicode-segmenter": ["unicode-segmenter@0.14.5", "", {}, "sha512-jHGmj2LUuqDcX3hqY12Ql+uhUTn8huuxNZGq7GvtF6bSybzH3aFgedYu/KTzQStEgt1Ra2F3HxadNXsNjb3m3g=="],
99
99
+
100
100
+
"zod": ["zod@3.25.76", "", {}, "sha512-gzUt/qt81nXsFGKIFcC3YnfEAx5NkunCfnDlvuBSSFS02bcXu4Lmea0AFIUwbLWxWPx3d9p8S5QoaujKcNQxcQ=="],
70
101
}
71
102
}
+99
lexicons/download.darkworld.state.json
···
1
1
+
{
2
2
+
"id": "download.darkworld.state",
3
3
+
"defs": {
4
4
+
"main": {
5
5
+
"key": "literal:self",
6
6
+
"type": "record",
7
7
+
"record": {
8
8
+
"type": "object",
9
9
+
"required": [
10
10
+
"site",
11
11
+
"favorite"
12
12
+
],
13
13
+
"properties": {
14
14
+
"site": {
15
15
+
"description": "Describe the site's content/look.",
16
16
+
"refs": [
17
17
+
"#site"
18
18
+
],
19
19
+
"type": "union",
20
20
+
"closed": true
21
21
+
},
22
22
+
"favorite": {
23
23
+
"description": "The user's favorites/likes/preferences.",
24
24
+
"refs": [
25
25
+
"#favorite"
26
26
+
],
27
27
+
"type": "union",
28
28
+
"closed": true
29
29
+
}
30
30
+
}
31
31
+
},
32
32
+
"description": "The record used by darkworld.download to determine the website's content."
33
33
+
},
34
34
+
"site": {
35
35
+
"type": "object",
36
36
+
"required": [
37
37
+
"susieProphecy"
38
38
+
],
39
39
+
"properties": {
40
40
+
"titleColors": {
41
41
+
"description": "TBD",
42
42
+
"refs": [
43
43
+
"#titleColorsEnby",
44
44
+
"#titleColorsTrans"
45
45
+
],
46
46
+
"type": "union"
47
47
+
},
48
48
+
"susieProphecy": {
49
49
+
"description": "Swap out Kris with Susie in the prophecy panel.",
50
50
+
"type": "boolean"
51
51
+
}
52
52
+
}
53
53
+
},
54
54
+
"favorite": {
55
55
+
"type": "object",
56
56
+
"required": [
57
57
+
"game",
58
58
+
"artist",
59
59
+
"album",
60
60
+
"deltaruneCharacter"
61
61
+
],
62
62
+
"properties": {
63
63
+
"game": {
64
64
+
"type": "array",
65
65
+
"items": {
66
66
+
"type": "string"
67
67
+
}
68
68
+
},
69
69
+
"album": {
70
70
+
"type": "array",
71
71
+
"items": {
72
72
+
"type": "string"
73
73
+
}
74
74
+
},
75
75
+
"artist": {
76
76
+
"type": "array",
77
77
+
"items": {
78
78
+
"type": "string"
79
79
+
}
80
80
+
},
81
81
+
"deltaruneCharacter": {
82
82
+
"type": "array",
83
83
+
"items": {
84
84
+
"type": "string"
85
85
+
}
86
86
+
}
87
87
+
}
88
88
+
},
89
89
+
"titleColorsEnby": {
90
90
+
"type": "object",
91
91
+
"properties": {}
92
92
+
},
93
93
+
"titleColorsTrans": {
94
94
+
"type": "object",
95
95
+
"properties": {}
96
96
+
}
97
97
+
},
98
98
+
"lexicon": 1
99
99
+
}
+1
package.json
···
9
9
"build": "bun run build.ts"
10
10
},
11
11
"dependencies": {
12
12
+
"@atproto/api": "^0.19.3",
12
13
"bun-plugin-tailwind": "^0.1.2",
13
14
"react": "^19",
14
15
"react-dom": "^19",
+86
scripts/publish-lexicons.ts
···
1
1
+
#!/usr/bin/env bun
2
2
+
3
3
+
import AtpAgent from "@atproto/api";
4
4
+
import { Glob } from "bun";
5
5
+
import { readFileSync } from "fs";
6
6
+
import { homedir } from "os";
7
7
+
import { join } from "path";
8
8
+
9
9
+
function getTokenAndPds(): {
10
10
+
did: string,
11
11
+
password: string,
12
12
+
pds: string
13
13
+
} | null {
14
14
+
try {
15
15
+
const f = readFileSync(`${homedir()}/.local/state/goat/auth-session.json`, "utf-8");
16
16
+
return JSON.parse(f) || null;
17
17
+
} catch { }
18
18
+
return null;
19
19
+
}
20
20
+
21
21
+
async function getWorkingClient(): Promise<AtpAgent> {
22
22
+
const a = getTokenAndPds()!;
23
23
+
if (!a.did) throw "not logged in";
24
24
+
const b = new AtpAgent({
25
25
+
service: a?.pds!,
26
26
+
});
27
27
+
28
28
+
console.log(`Logging in on ${a.pds} as ${a.did}`)
29
29
+
30
30
+
const c = await b.login({
31
31
+
identifier: a.did!,
32
32
+
password: a?.password!
33
33
+
})
34
34
+
35
35
+
console.log(`Logged in as ${c.data.handle} (${process.env.MASK_EMAIL || c.data.email || "unknown-email"}), account status: ${c.data.active}`);
36
36
+
37
37
+
const status = (await b.com.atproto.sync.getRepoStatus({ did: c.data.did! })).data;
38
38
+
console.log(`Repository status: ${status.status}, current rev: ${status.rev}`);
39
39
+
40
40
+
return b;
41
41
+
}
42
42
+
43
43
+
const lexiconGlobPath = join(__dirname, "..", "lexicons", "*");
44
44
+
console.log("Glob path:", lexiconGlobPath);
45
45
+
46
46
+
const lexs = new Glob(lexiconGlobPath).scanSync();
47
47
+
48
48
+
const writes: { lex: string, data: Object }[] = [];
49
49
+
50
50
+
for await (const lex of lexs) {
51
51
+
try {
52
52
+
const d = JSON.parse(readFileSync(lex, "utf-8"));
53
53
+
if (d.id) {
54
54
+
console.log("Found lexicon:", d.id);
55
55
+
writes.push({
56
56
+
lex: d.id as string,
57
57
+
data: {
58
58
+
...d,
59
59
+
lexicon: 1,
60
60
+
$type: "com.atproto.lexicon.schema"
61
61
+
}
62
62
+
})
63
63
+
}
64
64
+
} catch { };
65
65
+
}
66
66
+
67
67
+
const cl = await getWorkingClient();
68
68
+
69
69
+
let nWrite = 0
70
70
+
for (const lex of writes) {
71
71
+
nWrite++;
72
72
+
console.log(`Applying writes (${nWrite}/${writes.length}): ${lex.lex}`);
73
73
+
try {
74
74
+
await cl.com.atproto.repo.putRecord({
75
75
+
repo: cl.did as any,
76
76
+
collection: "com.atproto.lexicon.schema",
77
77
+
rkey: lex.lex,
78
78
+
validate: true,
79
79
+
record: lex.data as any
80
80
+
})
81
81
+
} catch (e_) {
82
82
+
console.error(e_)
83
83
+
}
84
84
+
}
85
85
+
86
86
+
await cl.logout();