tangled
alpha
login
or
join now
oppi.li
/
atproto-starterkit
1
fork
atom
everything you need to create an atproto appview
1
fork
atom
overview
issues
pulls
pipelines
more noodling
Signed-off-by: oppiliappan <me@oppi.li>
oppi.li
1 week ago
fa9a6e22
5d5ec78c
verified
This commit was signed with the committer's
known signature
.
oppi.li
SSH Key Fingerprint:
SHA256:yQs05DbrlPDC2pBXLxqOdLYEswq3oEBnHaJiBP7bOlM=
+290
-2
8 changed files
expand all
collapse all
unified
split
.gitignore
appview
pages
home.go
pages.go
server
server.go
flake.lock
flake.nix
lexicon-build-config.json
lexicons
status.json
+2
.gitignore
···
3
3
*.db-shm
4
4
*.db-wal
5
5
.env
6
6
+
.envrc
7
7
+
.direnv
+72
appview/pages/home.go
···
2
2
3
3
import (
4
4
"context"
5
5
+
"strconv"
5
6
6
7
. "maragu.dev/gomponents"
7
8
. "maragu.dev/gomponents/html"
9
9
+
"tangled.org/oppi.li/atproto-starterkit/appview/config"
8
10
"tangled.org/oppi.li/atproto-starterkit/appview/types"
9
11
)
10
12
···
81
83
A(Href("/login"), Text("Add another account")),
82
84
),
83
85
}),
86
86
+
),
87
87
+
88
88
+
H2(Text("Configuration")),
89
89
+
ConfigTable(p.config),
90
90
+
)
91
91
+
}
92
92
+
93
93
+
func ConfigTable(c *config.Config) Node {
94
94
+
borderStyle := Style("border: 1px solid #ddd; padding: 8px;")
95
95
+
96
96
+
return Table(
97
97
+
THead(
98
98
+
Tr(
99
99
+
Th(borderStyle, Text("Config Key")),
100
100
+
Th(borderStyle, Text("Value")),
101
101
+
),
102
102
+
),
103
103
+
TBody(
104
104
+
Tr(
105
105
+
Td(borderStyle, Text("Core.Name")),
106
106
+
Td(borderStyle, Text(c.Core.Name)),
107
107
+
),
108
108
+
Tr(
109
109
+
Td(borderStyle, Text("Core.Host")),
110
110
+
Td(borderStyle, Text(c.Core.Host)),
111
111
+
),
112
112
+
Tr(
113
113
+
Td(borderStyle, Text("Core.ListenAddr")),
114
114
+
Td(borderStyle, Text(c.Core.ListenAddr)),
115
115
+
),
116
116
+
Tr(
117
117
+
Td(borderStyle, Text("Core.DbPath")),
118
118
+
Td(borderStyle, Text(c.Core.DbPath)),
119
119
+
),
120
120
+
Tr(
121
121
+
Td(borderStyle, Text("Core.Dev")),
122
122
+
Td(borderStyle, Text(strconv.FormatBool(c.Core.Dev))),
123
123
+
),
124
124
+
Tr(
125
125
+
Td(borderStyle, Text("Core.BaseUrl()")),
126
126
+
Td(borderStyle, Text(c.Core.BaseUrl())),
127
127
+
),
128
128
+
Tr(
129
129
+
Td(borderStyle, Text("Core.CookieSecret")),
130
130
+
Td(borderStyle, Text(c.Core.CookieSecret)),
131
131
+
),
132
132
+
Tr(
133
133
+
Td(borderStyle, Text("OAuth.ClientKid")),
134
134
+
Td(borderStyle, Text(c.OAuth.ClientKid)),
135
135
+
),
136
136
+
Tr(
137
137
+
Td(borderStyle, Text("OAuth.ClientSecret")),
138
138
+
Td(borderStyle, Text(c.OAuth.ClientSecret)),
139
139
+
),
140
140
+
Tr(
141
141
+
Td(borderStyle, Text("Redis.Addr")),
142
142
+
Td(borderStyle, Text(c.Redis.Addr)),
143
143
+
),
144
144
+
Tr(
145
145
+
Td(borderStyle, Text("Redis.DB")),
146
146
+
Td(borderStyle, Textf("%d", c.Redis.DB)),
147
147
+
),
148
148
+
Tr(
149
149
+
Td(borderStyle, Text("Redis.Password")),
150
150
+
Td(borderStyle, Text(c.Redis.Password)),
151
151
+
),
152
152
+
Tr(
153
153
+
Td(borderStyle, Text("Plc.PLCURL")),
154
154
+
Td(borderStyle, Text(c.Plc.PLCURL)),
155
155
+
),
84
156
),
85
157
)
86
158
}
+4
-1
appview/pages/pages.go
···
5
5
"net/http"
6
6
7
7
. "maragu.dev/gomponents"
8
8
+
"tangled.org/oppi.li/atproto-starterkit/appview/config"
8
9
"tangled.org/oppi.li/atproto-starterkit/idresolver"
9
10
)
10
11
11
12
type Pages struct {
12
13
resolver *idresolver.Resolver
14
14
+
config *config.Config
13
15
}
14
16
15
15
-
func New(resolver *idresolver.Resolver) *Pages {
17
17
+
func New(resolver *idresolver.Resolver, cfg *config.Config) *Pages {
16
18
return &Pages{
17
19
resolver: resolver,
20
20
+
config: cfg,
18
21
}
19
22
}
20
23
+1
-1
appview/server/server.go
···
41
41
return nil, fmt.Errorf("failed to start oauth handler: %w", err)
42
42
}
43
43
44
44
-
pages := pages.New(res)
44
44
+
pages := pages.New(res, config)
45
45
46
46
server := &Server{
47
47
d,
+82
flake.lock
···
1
1
+
{
2
2
+
"nodes": {
3
3
+
"flake-utils": {
4
4
+
"inputs": {
5
5
+
"systems": "systems"
6
6
+
},
7
7
+
"locked": {
8
8
+
"lastModified": 1731533236,
9
9
+
"narHash": "sha256-l0KFg5HjrsfsO/JpG+r7fRrqm12kzFHyUHqHCVpMMbI=",
10
10
+
"owner": "numtide",
11
11
+
"repo": "flake-utils",
12
12
+
"rev": "11707dc2f618dd54ca8739b309ec4fc024de578b",
13
13
+
"type": "github"
14
14
+
},
15
15
+
"original": {
16
16
+
"owner": "numtide",
17
17
+
"repo": "flake-utils",
18
18
+
"type": "github"
19
19
+
}
20
20
+
},
21
21
+
"gomod2nix": {
22
22
+
"inputs": {
23
23
+
"flake-utils": "flake-utils",
24
24
+
"nixpkgs": [
25
25
+
"nixpkgs"
26
26
+
]
27
27
+
},
28
28
+
"locked": {
29
29
+
"lastModified": 1770585520,
30
30
+
"narHash": "sha256-yBz9Ozd5Wb56i3e3cHZ8WcbzCQ9RlVaiW18qDYA/AzA=",
31
31
+
"owner": "nix-community",
32
32
+
"repo": "gomod2nix",
33
33
+
"rev": "1201ddd1279c35497754f016ef33d5e060f3da8d",
34
34
+
"type": "github"
35
35
+
},
36
36
+
"original": {
37
37
+
"owner": "nix-community",
38
38
+
"repo": "gomod2nix",
39
39
+
"type": "github"
40
40
+
}
41
41
+
},
42
42
+
"nixpkgs": {
43
43
+
"locked": {
44
44
+
"lastModified": 1771848320,
45
45
+
"narHash": "sha256-0MAd+0mun3K/Ns8JATeHT1sX28faLII5hVLq0L3BdZU=",
46
46
+
"owner": "nixos",
47
47
+
"repo": "nixpkgs",
48
48
+
"rev": "2fc6539b481e1d2569f25f8799236694180c0993",
49
49
+
"type": "github"
50
50
+
},
51
51
+
"original": {
52
52
+
"owner": "nixos",
53
53
+
"ref": "nixos-unstable",
54
54
+
"repo": "nixpkgs",
55
55
+
"type": "github"
56
56
+
}
57
57
+
},
58
58
+
"root": {
59
59
+
"inputs": {
60
60
+
"gomod2nix": "gomod2nix",
61
61
+
"nixpkgs": "nixpkgs"
62
62
+
}
63
63
+
},
64
64
+
"systems": {
65
65
+
"locked": {
66
66
+
"lastModified": 1681028828,
67
67
+
"narHash": "sha256-Vy1rq5AaRuLzOxct8nz4T6wlgyUR7zLU309k9mBC768=",
68
68
+
"owner": "nix-systems",
69
69
+
"repo": "default",
70
70
+
"rev": "da67096a3b9bf56a91d16901293e51ba5b49a27e",
71
71
+
"type": "github"
72
72
+
},
73
73
+
"original": {
74
74
+
"owner": "nix-systems",
75
75
+
"repo": "default",
76
76
+
"type": "github"
77
77
+
}
78
78
+
}
79
79
+
},
80
80
+
"root": "root",
81
81
+
"version": 7
82
82
+
}
+90
flake.nix
···
1
1
+
{
2
2
+
description = "atproto starterkit";
3
3
+
4
4
+
inputs = {
5
5
+
nixpkgs.url = "github:nixos/nixpkgs/nixos-unstable";
6
6
+
gomod2nix = {
7
7
+
url = "github:nix-community/gomod2nix";
8
8
+
inputs.nixpkgs.follows = "nixpkgs";
9
9
+
};
10
10
+
};
11
11
+
12
12
+
outputs = {
13
13
+
self,
14
14
+
nixpkgs,
15
15
+
gomod2nix,
16
16
+
...
17
17
+
}: let
18
18
+
supportedSystems = ["x86_64-linux" "x86_64-darwin" "aarch64-linux" "aarch64-darwin"];
19
19
+
forAllSystems = nixpkgs.lib.genAttrs supportedSystems;
20
20
+
nixpkgsFor = forAllSystems (system: nixpkgs.legacyPackages.${system});
21
21
+
in {
22
22
+
devShells = forAllSystems (system: let
23
23
+
pkgs = nixpkgsFor.${system};
24
24
+
staticShell = pkgs.mkShell.override {
25
25
+
stdenv = pkgs.pkgsStatic.stdenv;
26
26
+
};
27
27
+
in {
28
28
+
default = staticShell {
29
29
+
nativeBuildInputs = [
30
30
+
pkgs.go
31
31
+
pkgs.air
32
32
+
pkgs.gopls
33
33
+
pkgs.httpie
34
34
+
pkgs.litecli
35
35
+
pkgs.websocat
36
36
+
pkgs.tailwindcss
37
37
+
pkgs.nixos-shell
38
38
+
pkgs.redis
39
39
+
pkgs.coreutils # for those of us who are on systems that use busybox (alpine)
40
40
+
gomod2nix.legacyPackages.${system}.gomod2nix
41
41
+
];
42
42
+
shellHook = ''
43
43
+
export TANGLED_OAUTH_CLIENT_KID="$(date +%s)"
44
44
+
'';
45
45
+
env.CGO_ENABLED = 1;
46
46
+
};
47
47
+
});
48
48
+
49
49
+
apps = forAllSystems (system: let
50
50
+
pkgs = nixpkgsFor."${system}";
51
51
+
in {
52
52
+
lexgen = {
53
53
+
type = "app";
54
54
+
program =
55
55
+
(pkgs.writeShellApplication {
56
56
+
name = "lexgen";
57
57
+
text = ''
58
58
+
if ! command -v lexgen > /dev/null; then
59
59
+
echo "error: must be executed from devshell"
60
60
+
exit 1
61
61
+
fi
62
62
+
63
63
+
rootDir=$(jj --ignore-working-copy root || git rev-parse --show-toplevel) || (echo "error: can't find repo root?"; exit 1)
64
64
+
cd "$rootDir"
65
65
+
66
66
+
outdir=api/lexicons
67
67
+
68
68
+
rm -f $outdir/*
69
69
+
lexgen --build-file lexicon-build-config.json lexicons
70
70
+
sed -i.bak 's/\tutil/\/\/\tutil/' $outdir/*
71
71
+
# lexgen generates incomplete Marshaler/Unmarshaler for union types
72
72
+
find $outdir/*.go -not -name "cbor_gen.go" -exec \
73
73
+
sed -i '/^func.*\(MarshalCBOR\|UnmarshalCBOR\)/,/^}/ s/^/\/\/ /' {} +
74
74
+
${pkgs.gotools}/bin/goimports -w $outdir/*
75
75
+
go run ./cmd/cborgen/
76
76
+
lexgen --build-file lexicon-build-config.json lexicons
77
77
+
rm $outdir/*.bak
78
78
+
'';
79
79
+
})
80
80
+
+ /bin/lexgen;
81
81
+
};
82
82
+
gomod2nix = {
83
83
+
type = "app";
84
84
+
program = toString (pkgs.writeShellScript "gomod2nix" ''
85
85
+
${gomod2nix.legacyPackages.${system}.gomod2nix}/bin/gomod2nix generate --outdir ./nix
86
86
+
'');
87
87
+
};
88
88
+
});
89
89
+
};
90
90
+
}
+9
lexicon-build-config.json
···
1
1
+
[
2
2
+
{
3
3
+
"package": "lexicons",
4
4
+
"prefix": "xyz.statusphere",
5
5
+
"outdir": "api/lexicons",
6
6
+
"import": "tangled.org/oppi.li/atproto-starterkit/api/lexicons",
7
7
+
"gen-server": true
8
8
+
}
9
9
+
]
+30
lexicons/status.json
···
1
1
+
{
2
2
+
"id": "xyz.statusphere.status",
3
3
+
"defs": {
4
4
+
"main": {
5
5
+
"key": "tid",
6
6
+
"type": "record",
7
7
+
"record": {
8
8
+
"type": "object",
9
9
+
"required": [
10
10
+
"status",
11
11
+
"createdAt"
12
12
+
],
13
13
+
"properties": {
14
14
+
"status": {
15
15
+
"type": "string",
16
16
+
"maxLength": 32,
17
17
+
"minLength": 1,
18
18
+
"maxGraphemes": 1
19
19
+
},
20
20
+
"createdAt": {
21
21
+
"type": "string",
22
22
+
"format": "datetime"
23
23
+
}
24
24
+
}
25
25
+
}
26
26
+
}
27
27
+
},
28
28
+
"$type": "com.atproto.lexicon.schema",
29
29
+
"lexicon": 1
30
30
+
}