create-backbone-template 0.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +33 -0
- package/bin/create-backbone-template.js +5 -0
- package/package.json +30 -0
- package/src/create-backbone-template.js +204 -0
- package/template/.agents/skills/agent-browser/SKILL.md +55 -0
- package/template/.agents/skills/create-plan/SKILL.md +52 -0
- package/template/.agents/skills/create-plan/agents/openai.yaml +4 -0
- package/template/.agents/skills/create-pr-presentation/SKILL.md +86 -0
- package/template/.agents/skills/create-pr-presentation/agents/openai.yaml +4 -0
- package/template/.agents/skills/implement-plan/SKILL.md +26 -0
- package/template/.agents/skills/implement-plan/agents/openai.yaml +4 -0
- package/template/.agents/skills/review-plan/SKILL.md +38 -0
- package/template/.agents/skills/review-plan/agents/openai.yaml +4 -0
- package/template/.env.schema +30 -0
- package/template/.env.test +6 -0
- package/template/.oxlintrc.json +67 -0
- package/template/.vscode/extensions.json +3 -0
- package/template/.vscode/settings.json +23 -0
- package/template/AGENTS.md +55 -0
- package/template/Cargo.lock +2648 -0
- package/template/Cargo.toml +29 -0
- package/template/Justfile +140 -0
- package/template/README.md +72 -0
- package/template/TODO.md +1 -0
- package/template/_gitignore +12 -0
- package/template/buf.gen.yaml +7 -0
- package/template/buf.yaml +10 -0
- package/template/client/.oxfmtrc.json +8 -0
- package/template/client/.oxlintrc.json +57 -0
- package/template/client/README.md +19 -0
- package/template/client/_gitignore +5 -0
- package/template/client/index.html +12 -0
- package/template/client/package.json +47 -0
- package/template/client/packages/design-system/package.json +19 -0
- package/template/client/packages/design-system/src/index.ts +2 -0
- package/template/client/packages/design-system-basic/package.json +18 -0
- package/template/client/packages/design-system-basic/src/button.stories.tsx +50 -0
- package/template/client/packages/design-system-basic/src/button.tsx +26 -0
- package/template/client/packages/design-system-basic/src/empty-state.stories.tsx +18 -0
- package/template/client/packages/design-system-basic/src/empty-state.tsx +17 -0
- package/template/client/packages/design-system-basic/src/form-field.stories.tsx +15 -0
- package/template/client/packages/design-system-basic/src/form-field.tsx +10 -0
- package/template/client/packages/design-system-basic/src/form.stories.tsx +27 -0
- package/template/client/packages/design-system-basic/src/form.tsx +9 -0
- package/template/client/packages/design-system-basic/src/heading.stories.tsx +14 -0
- package/template/client/packages/design-system-basic/src/heading.tsx +25 -0
- package/template/client/packages/design-system-basic/src/index.tsx +15 -0
- package/template/client/packages/design-system-basic/src/inline.stories.tsx +13 -0
- package/template/client/packages/design-system-basic/src/inline.tsx +5 -0
- package/template/client/packages/design-system-basic/src/layout.stories.tsx +24 -0
- package/template/client/packages/design-system-basic/src/layout.tsx +14 -0
- package/template/client/packages/design-system-basic/src/loader.stories.tsx +8 -0
- package/template/client/packages/design-system-basic/src/loader.tsx +11 -0
- package/template/client/packages/design-system-basic/src/navigation.stories.tsx +16 -0
- package/template/client/packages/design-system-basic/src/navigation.tsx +18 -0
- package/template/client/packages/design-system-basic/src/notice.stories.tsx +13 -0
- package/template/client/packages/design-system-basic/src/notice.tsx +5 -0
- package/template/client/packages/design-system-basic/src/stack.stories.tsx +17 -0
- package/template/client/packages/design-system-basic/src/stack.tsx +5 -0
- package/template/client/packages/design-system-basic/src/styles.css +254 -0
- package/template/client/packages/design-system-basic/src/text-input.stories.tsx +13 -0
- package/template/client/packages/design-system-basic/src/text-input.tsx +5 -0
- package/template/client/packages/design-system-basic/src/text.stories.tsx +21 -0
- package/template/client/packages/design-system-basic/src/text.tsx +5 -0
- package/template/client/packages/design-system-contract/package.json +15 -0
- package/template/client/packages/design-system-contract/src/button.ts +10 -0
- package/template/client/packages/design-system-contract/src/empty-state.ts +9 -0
- package/template/client/packages/design-system-contract/src/form-field.ts +9 -0
- package/template/client/packages/design-system-contract/src/form.ts +9 -0
- package/template/client/packages/design-system-contract/src/heading.ts +9 -0
- package/template/client/packages/design-system-contract/src/index.ts +13 -0
- package/template/client/packages/design-system-contract/src/inline.ts +7 -0
- package/template/client/packages/design-system-contract/src/layout.ts +8 -0
- package/template/client/packages/design-system-contract/src/loader.ts +7 -0
- package/template/client/packages/design-system-contract/src/navigation.ts +13 -0
- package/template/client/packages/design-system-contract/src/notice.ts +8 -0
- package/template/client/packages/design-system-contract/src/stack.ts +8 -0
- package/template/client/packages/design-system-contract/src/text-input.ts +5 -0
- package/template/client/packages/design-system-contract/src/text.ts +9 -0
- package/template/client/packages/design-system-lint/fixtures/invalid/external-ui-import.tsx +5 -0
- package/template/client/packages/design-system-lint/fixtures/invalid/raw-dom-jsx.tsx +3 -0
- package/template/client/packages/design-system-lint/fixtures/invalid/two-violations.tsx +7 -0
- package/template/client/packages/design-system-lint/fixtures/valid/design-system-only.tsx +13 -0
- package/template/client/packages/design-system-lint/package.json +23 -0
- package/template/client/packages/design-system-lint/src/check-design-system-architecture.ts +22 -0
- package/template/client/packages/design-system-lint/src/design-system-architecture.ts +286 -0
- package/template/client/packages/design-system-lint/src/oxlint-plugin.ts +11 -0
- package/template/client/packages/design-system-lint/src/page-architecture.ts +382 -0
- package/template/client/packages/design-system-lint/src/rules.ts +111 -0
- package/template/client/packages/design-system-lint/test/design-system-architecture.test.ts +243 -0
- package/template/client/packages/design-system-lint/test/oxlint-fixtures.test.ts +159 -0
- package/template/client/packages/design-system-lint/test/page-architecture.test.ts +175 -0
- package/template/client/packages/design-system-lint/test/rules.test.ts +65 -0
- package/template/client/packages/design-system-lint/tsconfig.json +29 -0
- package/template/client/src/App.tsx +77 -0
- package/template/client/src/design-system-components.test.tsx +75 -0
- package/template/client/src/gen/helloworld/v1/helloworld_pb.ts +63 -0
- package/template/client/src/main.tsx +18 -0
- package/template/client/src/pages/hello/hello-page.stories.tsx +20 -0
- package/template/client/src/pages/hello/hello-page.test.tsx +90 -0
- package/template/client/src/pages/hello/hello-page.tsx +126 -0
- package/template/client/src/pages/page.ts +20 -0
- package/template/client/src/testing/create-preview-events.test.ts +36 -0
- package/template/client/src/testing/create-preview-events.ts +30 -0
- package/template/client/src/vite-env.d.ts +1 -0
- package/template/client/tsconfig.json +32 -0
- package/template/client/vite.config.ts +21 -0
- package/template/client/vite.ladle.config.ts +5 -0
- package/template/e2e/.gherkin-lintrc +20 -0
- package/template/e2e/.oxfmtrc.json +15 -0
- package/template/e2e/.oxlintrc.json +37 -0
- package/template/e2e/_gitignore +4 -0
- package/template/e2e/features/helloworld.feature +10 -0
- package/template/e2e/package.json +42 -0
- package/template/e2e/playwright.config.ts +16 -0
- package/template/e2e/support/app-gherkin.ts +4 -0
- package/template/e2e/support/fixtures.ts +236 -0
- package/template/e2e/support/gherkin-fixtures/duplicate-id.feature +9 -0
- package/template/e2e/support/gherkin-fixtures/duplicate-id.spec.ts +7 -0
- package/template/e2e/support/gherkin-fixtures/extra-implementation.spec.ts +7 -0
- package/template/e2e/support/gherkin-fixtures/extra-step.spec.ts +10 -0
- package/template/e2e/support/gherkin-fixtures/happy-path.spec.ts +4 -0
- package/template/e2e/support/gherkin-fixtures/missing-id.feature +4 -0
- package/template/e2e/support/gherkin-fixtures/missing-id.spec.ts +7 -0
- package/template/e2e/support/gherkin-fixtures/missing-implementation.spec.ts +7 -0
- package/template/e2e/support/gherkin-fixtures/missing-step.spec.ts +7 -0
- package/template/e2e/support/gherkin-fixtures/playwright.config.ts +7 -0
- package/template/e2e/support/gherkin-fixtures/scenario-outline.feature +9 -0
- package/template/e2e/support/gherkin-fixtures/scenario-outline.spec.ts +7 -0
- package/template/e2e/support/gherkin-fixtures/step-mismatch.spec.ts +9 -0
- package/template/e2e/support/gherkin-fixtures/valid-implementations.ts +23 -0
- package/template/e2e/support/gherkin-fixtures/valid-scenarios.feature +26 -0
- package/template/e2e/support/gherkin.test.ts +184 -0
- package/template/e2e/support/gherkin.ts +321 -0
- package/template/e2e/support/oxlint-plugin.test.ts +328 -0
- package/template/e2e/support/oxlint-plugin.ts +485 -0
- package/template/e2e/tests/helloworld.spec.ts +39 -0
- package/template/e2e/tsconfig.json +26 -0
- package/template/e2e/tsconfig.oxlint-plugin.json +12 -0
- package/template/package.json +9 -0
- package/template/pnpm-lock.yaml +10723 -0
- package/template/pnpm-workspace.yaml +8 -0
- package/template/pr-slide/README.md +95 -0
- package/template/pr-slide/package.json +23 -0
- package/template/pr-slide/src/cli.js +262 -0
- package/template/pr-slide/src/generate-pr-deck.js +833 -0
- package/template/pr-slide/src/git-context.js +91 -0
- package/template/pr-slide/src/presentation-paths.js +9 -0
- package/template/pr-slide/src/presentations.js +53 -0
- package/template/pr-slide/test/generate-pr-deck.test.js +118 -0
- package/template/pr-slide/test/presentation-paths.test.js +14 -0
- package/template/pr-slide/test/presentations.test.js +50 -0
- package/template/proto/helloworld/v1/helloworld.proto +15 -0
- package/template/scripts/run-e2e.sh +10 -0
- package/template/server/Cargo.toml +26 -0
- package/template/server/build.rs +9 -0
- package/template/server/dylint/backbone_server_lints/.cargo/config.toml +6 -0
- package/template/server/dylint/backbone_server_lints/Cargo.lock +1581 -0
- package/template/server/dylint/backbone_server_lints/Cargo.toml +21 -0
- package/template/server/dylint/backbone_server_lints/README.md +5 -0
- package/template/server/dylint/backbone_server_lints/_gitignore +1 -0
- package/template/server/dylint/backbone_server_lints/rust-toolchain +3 -0
- package/template/server/dylint/backbone_server_lints/src/lib.rs +612 -0
- package/template/server/dylint/backbone_server_lints/ui/lib.rs +4 -0
- package/template/server/dylint/backbone_server_lints/ui/lib.stderr +10 -0
- package/template/server/dylint/backbone_server_lints/ui/long_file.rs +303 -0
- package/template/server/dylint/backbone_server_lints/ui/long_file.stderr +6 -0
- package/template/server/dylint/backbone_server_lints/ui/main.rs +59 -0
- package/template/server/dylint/backbone_server_lints/ui/main.stderr +85 -0
- package/template/server/migrations/20260520120000_create_projects.sql +12 -0
- package/template/server/migrations/20260524160000_create_hello_world_inputs.sql +12 -0
- package/template/server/src/config.rs +27 -0
- package/template/server/src/db/hello_world.rs +34 -0
- package/template/server/src/db/hello_world_tests.rs +11 -0
- package/template/server/src/db/mod.rs +39 -0
- package/template/server/src/lib.rs +10 -0
- package/template/server/src/main.rs +43 -0
- package/template/server/src/rpc/greeter/mod.rs +31 -0
- package/template/server/src/rpc/greeter/say_hello.rs +27 -0
- package/template/server/src/rpc/mod.rs +8 -0
- package/template/server/src/state.rs +13 -0
- package/template/skills-lock.json +11 -0
|
@@ -0,0 +1,303 @@
|
|
|
1
|
+
// filler line 001
|
|
2
|
+
// filler line 002
|
|
3
|
+
// filler line 003
|
|
4
|
+
// filler line 004
|
|
5
|
+
// filler line 005
|
|
6
|
+
// filler line 006
|
|
7
|
+
// filler line 007
|
|
8
|
+
// filler line 008
|
|
9
|
+
// filler line 009
|
|
10
|
+
// filler line 010
|
|
11
|
+
// filler line 011
|
|
12
|
+
// filler line 012
|
|
13
|
+
// filler line 013
|
|
14
|
+
// filler line 014
|
|
15
|
+
// filler line 015
|
|
16
|
+
// filler line 016
|
|
17
|
+
// filler line 017
|
|
18
|
+
// filler line 018
|
|
19
|
+
// filler line 019
|
|
20
|
+
// filler line 020
|
|
21
|
+
// filler line 021
|
|
22
|
+
// filler line 022
|
|
23
|
+
// filler line 023
|
|
24
|
+
// filler line 024
|
|
25
|
+
// filler line 025
|
|
26
|
+
// filler line 026
|
|
27
|
+
// filler line 027
|
|
28
|
+
// filler line 028
|
|
29
|
+
// filler line 029
|
|
30
|
+
// filler line 030
|
|
31
|
+
// filler line 031
|
|
32
|
+
// filler line 032
|
|
33
|
+
// filler line 033
|
|
34
|
+
// filler line 034
|
|
35
|
+
// filler line 035
|
|
36
|
+
// filler line 036
|
|
37
|
+
// filler line 037
|
|
38
|
+
// filler line 038
|
|
39
|
+
// filler line 039
|
|
40
|
+
// filler line 040
|
|
41
|
+
// filler line 041
|
|
42
|
+
// filler line 042
|
|
43
|
+
// filler line 043
|
|
44
|
+
// filler line 044
|
|
45
|
+
// filler line 045
|
|
46
|
+
// filler line 046
|
|
47
|
+
// filler line 047
|
|
48
|
+
// filler line 048
|
|
49
|
+
// filler line 049
|
|
50
|
+
// filler line 050
|
|
51
|
+
// filler line 051
|
|
52
|
+
// filler line 052
|
|
53
|
+
// filler line 053
|
|
54
|
+
// filler line 054
|
|
55
|
+
// filler line 055
|
|
56
|
+
// filler line 056
|
|
57
|
+
// filler line 057
|
|
58
|
+
// filler line 058
|
|
59
|
+
// filler line 059
|
|
60
|
+
// filler line 060
|
|
61
|
+
// filler line 061
|
|
62
|
+
// filler line 062
|
|
63
|
+
// filler line 063
|
|
64
|
+
// filler line 064
|
|
65
|
+
// filler line 065
|
|
66
|
+
// filler line 066
|
|
67
|
+
// filler line 067
|
|
68
|
+
// filler line 068
|
|
69
|
+
// filler line 069
|
|
70
|
+
// filler line 070
|
|
71
|
+
// filler line 071
|
|
72
|
+
// filler line 072
|
|
73
|
+
// filler line 073
|
|
74
|
+
// filler line 074
|
|
75
|
+
// filler line 075
|
|
76
|
+
// filler line 076
|
|
77
|
+
// filler line 077
|
|
78
|
+
// filler line 078
|
|
79
|
+
// filler line 079
|
|
80
|
+
// filler line 080
|
|
81
|
+
// filler line 081
|
|
82
|
+
// filler line 082
|
|
83
|
+
// filler line 083
|
|
84
|
+
// filler line 084
|
|
85
|
+
// filler line 085
|
|
86
|
+
// filler line 086
|
|
87
|
+
// filler line 087
|
|
88
|
+
// filler line 088
|
|
89
|
+
// filler line 089
|
|
90
|
+
// filler line 090
|
|
91
|
+
// filler line 091
|
|
92
|
+
// filler line 092
|
|
93
|
+
// filler line 093
|
|
94
|
+
// filler line 094
|
|
95
|
+
// filler line 095
|
|
96
|
+
// filler line 096
|
|
97
|
+
// filler line 097
|
|
98
|
+
// filler line 098
|
|
99
|
+
// filler line 099
|
|
100
|
+
// filler line 100
|
|
101
|
+
// filler line 101
|
|
102
|
+
// filler line 102
|
|
103
|
+
// filler line 103
|
|
104
|
+
// filler line 104
|
|
105
|
+
// filler line 105
|
|
106
|
+
// filler line 106
|
|
107
|
+
// filler line 107
|
|
108
|
+
// filler line 108
|
|
109
|
+
// filler line 109
|
|
110
|
+
// filler line 110
|
|
111
|
+
// filler line 111
|
|
112
|
+
// filler line 112
|
|
113
|
+
// filler line 113
|
|
114
|
+
// filler line 114
|
|
115
|
+
// filler line 115
|
|
116
|
+
// filler line 116
|
|
117
|
+
// filler line 117
|
|
118
|
+
// filler line 118
|
|
119
|
+
// filler line 119
|
|
120
|
+
// filler line 120
|
|
121
|
+
// filler line 121
|
|
122
|
+
// filler line 122
|
|
123
|
+
// filler line 123
|
|
124
|
+
// filler line 124
|
|
125
|
+
// filler line 125
|
|
126
|
+
// filler line 126
|
|
127
|
+
// filler line 127
|
|
128
|
+
// filler line 128
|
|
129
|
+
// filler line 129
|
|
130
|
+
// filler line 130
|
|
131
|
+
// filler line 131
|
|
132
|
+
// filler line 132
|
|
133
|
+
// filler line 133
|
|
134
|
+
// filler line 134
|
|
135
|
+
// filler line 135
|
|
136
|
+
// filler line 136
|
|
137
|
+
// filler line 137
|
|
138
|
+
// filler line 138
|
|
139
|
+
// filler line 139
|
|
140
|
+
// filler line 140
|
|
141
|
+
// filler line 141
|
|
142
|
+
// filler line 142
|
|
143
|
+
// filler line 143
|
|
144
|
+
// filler line 144
|
|
145
|
+
// filler line 145
|
|
146
|
+
// filler line 146
|
|
147
|
+
// filler line 147
|
|
148
|
+
// filler line 148
|
|
149
|
+
// filler line 149
|
|
150
|
+
// filler line 150
|
|
151
|
+
// filler line 151
|
|
152
|
+
// filler line 152
|
|
153
|
+
// filler line 153
|
|
154
|
+
// filler line 154
|
|
155
|
+
// filler line 155
|
|
156
|
+
// filler line 156
|
|
157
|
+
// filler line 157
|
|
158
|
+
// filler line 158
|
|
159
|
+
// filler line 159
|
|
160
|
+
// filler line 160
|
|
161
|
+
// filler line 161
|
|
162
|
+
// filler line 162
|
|
163
|
+
// filler line 163
|
|
164
|
+
// filler line 164
|
|
165
|
+
// filler line 165
|
|
166
|
+
// filler line 166
|
|
167
|
+
// filler line 167
|
|
168
|
+
// filler line 168
|
|
169
|
+
// filler line 169
|
|
170
|
+
// filler line 170
|
|
171
|
+
// filler line 171
|
|
172
|
+
// filler line 172
|
|
173
|
+
// filler line 173
|
|
174
|
+
// filler line 174
|
|
175
|
+
// filler line 175
|
|
176
|
+
// filler line 176
|
|
177
|
+
// filler line 177
|
|
178
|
+
// filler line 178
|
|
179
|
+
// filler line 179
|
|
180
|
+
// filler line 180
|
|
181
|
+
// filler line 181
|
|
182
|
+
// filler line 182
|
|
183
|
+
// filler line 183
|
|
184
|
+
// filler line 184
|
|
185
|
+
// filler line 185
|
|
186
|
+
// filler line 186
|
|
187
|
+
// filler line 187
|
|
188
|
+
// filler line 188
|
|
189
|
+
// filler line 189
|
|
190
|
+
// filler line 190
|
|
191
|
+
// filler line 191
|
|
192
|
+
// filler line 192
|
|
193
|
+
// filler line 193
|
|
194
|
+
// filler line 194
|
|
195
|
+
// filler line 195
|
|
196
|
+
// filler line 196
|
|
197
|
+
// filler line 197
|
|
198
|
+
// filler line 198
|
|
199
|
+
// filler line 199
|
|
200
|
+
// filler line 200
|
|
201
|
+
// filler line 201
|
|
202
|
+
// filler line 202
|
|
203
|
+
// filler line 203
|
|
204
|
+
// filler line 204
|
|
205
|
+
// filler line 205
|
|
206
|
+
// filler line 206
|
|
207
|
+
// filler line 207
|
|
208
|
+
// filler line 208
|
|
209
|
+
// filler line 209
|
|
210
|
+
// filler line 210
|
|
211
|
+
// filler line 211
|
|
212
|
+
// filler line 212
|
|
213
|
+
// filler line 213
|
|
214
|
+
// filler line 214
|
|
215
|
+
// filler line 215
|
|
216
|
+
// filler line 216
|
|
217
|
+
// filler line 217
|
|
218
|
+
// filler line 218
|
|
219
|
+
// filler line 219
|
|
220
|
+
// filler line 220
|
|
221
|
+
// filler line 221
|
|
222
|
+
// filler line 222
|
|
223
|
+
// filler line 223
|
|
224
|
+
// filler line 224
|
|
225
|
+
// filler line 225
|
|
226
|
+
// filler line 226
|
|
227
|
+
// filler line 227
|
|
228
|
+
// filler line 228
|
|
229
|
+
// filler line 229
|
|
230
|
+
// filler line 230
|
|
231
|
+
// filler line 231
|
|
232
|
+
// filler line 232
|
|
233
|
+
// filler line 233
|
|
234
|
+
// filler line 234
|
|
235
|
+
// filler line 235
|
|
236
|
+
// filler line 236
|
|
237
|
+
// filler line 237
|
|
238
|
+
// filler line 238
|
|
239
|
+
// filler line 239
|
|
240
|
+
// filler line 240
|
|
241
|
+
// filler line 241
|
|
242
|
+
// filler line 242
|
|
243
|
+
// filler line 243
|
|
244
|
+
// filler line 244
|
|
245
|
+
// filler line 245
|
|
246
|
+
// filler line 246
|
|
247
|
+
// filler line 247
|
|
248
|
+
// filler line 248
|
|
249
|
+
// filler line 249
|
|
250
|
+
// filler line 250
|
|
251
|
+
// filler line 251
|
|
252
|
+
// filler line 252
|
|
253
|
+
// filler line 253
|
|
254
|
+
// filler line 254
|
|
255
|
+
// filler line 255
|
|
256
|
+
// filler line 256
|
|
257
|
+
// filler line 257
|
|
258
|
+
// filler line 258
|
|
259
|
+
// filler line 259
|
|
260
|
+
// filler line 260
|
|
261
|
+
// filler line 261
|
|
262
|
+
// filler line 262
|
|
263
|
+
// filler line 263
|
|
264
|
+
// filler line 264
|
|
265
|
+
// filler line 265
|
|
266
|
+
// filler line 266
|
|
267
|
+
// filler line 267
|
|
268
|
+
// filler line 268
|
|
269
|
+
// filler line 269
|
|
270
|
+
// filler line 270
|
|
271
|
+
// filler line 271
|
|
272
|
+
// filler line 272
|
|
273
|
+
// filler line 273
|
|
274
|
+
// filler line 274
|
|
275
|
+
// filler line 275
|
|
276
|
+
// filler line 276
|
|
277
|
+
// filler line 277
|
|
278
|
+
// filler line 278
|
|
279
|
+
// filler line 279
|
|
280
|
+
// filler line 280
|
|
281
|
+
// filler line 281
|
|
282
|
+
// filler line 282
|
|
283
|
+
// filler line 283
|
|
284
|
+
// filler line 284
|
|
285
|
+
// filler line 285
|
|
286
|
+
// filler line 286
|
|
287
|
+
// filler line 287
|
|
288
|
+
// filler line 288
|
|
289
|
+
// filler line 289
|
|
290
|
+
// filler line 290
|
|
291
|
+
// filler line 291
|
|
292
|
+
// filler line 292
|
|
293
|
+
// filler line 293
|
|
294
|
+
// filler line 294
|
|
295
|
+
// filler line 295
|
|
296
|
+
// filler line 296
|
|
297
|
+
// filler line 297
|
|
298
|
+
// filler line 298
|
|
299
|
+
// filler line 299
|
|
300
|
+
// filler line 300
|
|
301
|
+
// filler line 301
|
|
302
|
+
|
|
303
|
+
fn main() {}
|
|
@@ -0,0 +1,59 @@
|
|
|
1
|
+
mod sqlx {
|
|
2
|
+
pub fn query<T>(_sql: T) {}
|
|
3
|
+
}
|
|
4
|
+
|
|
5
|
+
mod reqwest {
|
|
6
|
+
pub struct Client;
|
|
7
|
+
}
|
|
8
|
+
|
|
9
|
+
mod connectrpc {
|
|
10
|
+
pub struct ConnectError;
|
|
11
|
+
pub struct ErrorCode;
|
|
12
|
+
}
|
|
13
|
+
|
|
14
|
+
mod axum {
|
|
15
|
+
pub mod http {
|
|
16
|
+
pub struct StatusCode;
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
pub mod response {
|
|
20
|
+
pub trait IntoResponse {}
|
|
21
|
+
}
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
use axum::{http::StatusCode, response::IntoResponse};
|
|
25
|
+
use connectrpc::{ConnectError, ErrorCode};
|
|
26
|
+
use reqwest::Client;
|
|
27
|
+
|
|
28
|
+
trait TasksService {
|
|
29
|
+
fn list_tasks(&self);
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
struct TasksRpcService;
|
|
33
|
+
|
|
34
|
+
impl TasksService for TasksRpcService {
|
|
35
|
+
fn list_tasks(&self) {}
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
pub fn external_webhook_handler() {}
|
|
39
|
+
|
|
40
|
+
fn read_database_url() {
|
|
41
|
+
let _ = std::env::var("DATABASE_URL");
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
fn list_rows() {
|
|
45
|
+
sqlx::query("SELECT 1");
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
fn dynamic_rows(table: &str) {
|
|
49
|
+
sqlx::query(format!("SELECT * FROM {table}"));
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
fn main() {
|
|
53
|
+
read_database_url();
|
|
54
|
+
list_rows();
|
|
55
|
+
dynamic_rows("tasks");
|
|
56
|
+
let _ = (Client, ConnectError, ErrorCode, StatusCode);
|
|
57
|
+
let service = TasksRpcService;
|
|
58
|
+
service.list_tasks();
|
|
59
|
+
}
|
|
@@ -0,0 +1,85 @@
|
|
|
1
|
+
error: Axum response error types should only be mapped in rest modules
|
|
2
|
+
--> $DIR/main.rs:24:12
|
|
3
|
+
|
|
|
4
|
+
LL | use axum::{http::StatusCode, response::IntoResponse};
|
|
5
|
+
| ^^^^^^^^^^^^^^^^
|
|
6
|
+
|
|
|
7
|
+
= note: `#[deny(rest_errors_mapped_at_boundary)]` on by default
|
|
8
|
+
|
|
9
|
+
error: Axum response error types should only be mapped in rest modules
|
|
10
|
+
--> $DIR/main.rs:24:30
|
|
11
|
+
|
|
|
12
|
+
LL | use axum::{http::StatusCode, response::IntoResponse};
|
|
13
|
+
| ^^^^^^^^^^^^^^^^^^^^^^
|
|
14
|
+
|
|
15
|
+
error: Connect RPC errors should only be mapped in rpc modules
|
|
16
|
+
--> $DIR/main.rs:25:18
|
|
17
|
+
|
|
|
18
|
+
LL | use connectrpc::{ConnectError, ErrorCode};
|
|
19
|
+
| ^^^^^^^^^^^^
|
|
20
|
+
|
|
|
21
|
+
= note: `#[deny(rpc_errors_mapped_at_boundary)]` on by default
|
|
22
|
+
|
|
23
|
+
error: Connect RPC errors should only be mapped in rpc modules
|
|
24
|
+
--> $DIR/main.rs:25:32
|
|
25
|
+
|
|
|
26
|
+
LL | use connectrpc::{ConnectError, ErrorCode};
|
|
27
|
+
| ^^^^^^^^^
|
|
28
|
+
|
|
29
|
+
error: reqwest usage should live behind integrations modules
|
|
30
|
+
--> $DIR/main.rs:26:1
|
|
31
|
+
|
|
|
32
|
+
LL | use reqwest::Client;
|
|
33
|
+
| ^^^^^^^^^^^^^^^^^^^^
|
|
34
|
+
|
|
|
35
|
+
= note: `#[deny(no_http_client_outside_integrations)]` on by default
|
|
36
|
+
|
|
37
|
+
error: RPC method implementations should be bridged from rpc/<service>/mod.rs with logic in a sibling method file
|
|
38
|
+
--> $DIR/main.rs:35:5
|
|
39
|
+
|
|
|
40
|
+
LL | fn list_tasks(&self) {}
|
|
41
|
+
| ^^^^^^^^^^^^^^^^^^^^^^^
|
|
42
|
+
|
|
|
43
|
+
= note: `#[deny(rpc_method_in_separate_file)]` on by default
|
|
44
|
+
|
|
45
|
+
error: Axum endpoint handlers should live in rest modules
|
|
46
|
+
--> $DIR/main.rs:38:1
|
|
47
|
+
|
|
|
48
|
+
LL | pub fn external_webhook_handler() {}
|
|
49
|
+
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
|
50
|
+
|
|
|
51
|
+
= note: `#[deny(rest_endpoint_in_rest_folder)]` on by default
|
|
52
|
+
|
|
53
|
+
error: environment variable access should be centralized in config modules
|
|
54
|
+
--> $DIR/main.rs:41:13
|
|
55
|
+
|
|
|
56
|
+
LL | let _ = std::env::var("DATABASE_URL");
|
|
57
|
+
| ^^^^^^^^^^^^^
|
|
58
|
+
|
|
|
59
|
+
= note: `#[deny(no_direct_env_var_outside_config)]` on by default
|
|
60
|
+
|
|
61
|
+
error: sqlx calls are only allowed in db modules
|
|
62
|
+
--> $DIR/main.rs:45:5
|
|
63
|
+
|
|
|
64
|
+
LL | sqlx::query("SELECT 1");
|
|
65
|
+
| ^^^^^^^^^^^
|
|
66
|
+
|
|
|
67
|
+
= note: `#[deny(sqlx_only_in_db_folder)]` on by default
|
|
68
|
+
|
|
69
|
+
warning: sqlx query strings should be string literals or sqlx macros
|
|
70
|
+
--> $DIR/main.rs:48:1
|
|
71
|
+
|
|
|
72
|
+
LL | / fn dynamic_rows(table: &str) {
|
|
73
|
+
LL | | sqlx::query(format!("SELECT * FROM {table}"));
|
|
74
|
+
LL | | }
|
|
75
|
+
| |_^
|
|
76
|
+
|
|
|
77
|
+
= note: `#[warn(no_sql_string_construction)]` on by default
|
|
78
|
+
|
|
79
|
+
error: sqlx calls are only allowed in db modules
|
|
80
|
+
--> $DIR/main.rs:49:5
|
|
81
|
+
|
|
|
82
|
+
LL | sqlx::query(format!("SELECT * FROM {table}"));
|
|
83
|
+
| ^^^^^^^^^^^
|
|
84
|
+
|
|
85
|
+
error: aborting due to 10 previous errors; 1 warning emitted
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
CREATE TABLE projects (
|
|
2
|
+
id TEXT PRIMARY KEY NOT NULL DEFAULT (
|
|
3
|
+
lower(hex(randomblob(4))) || '-' ||
|
|
4
|
+
lower(hex(randomblob(2))) || '-4' ||
|
|
5
|
+
substr(lower(hex(randomblob(2))), 2) || '-' ||
|
|
6
|
+
substr('89ab', abs(random()) % 4 + 1, 1) ||
|
|
7
|
+
substr(lower(hex(randomblob(2))), 2) || '-' ||
|
|
8
|
+
lower(hex(randomblob(6)))
|
|
9
|
+
),
|
|
10
|
+
project_user TEXT NOT NULL,
|
|
11
|
+
project_name TEXT NOT NULL
|
|
12
|
+
);
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
CREATE TABLE hello_world_inputs (
|
|
2
|
+
id TEXT PRIMARY KEY NOT NULL DEFAULT (
|
|
3
|
+
lower(hex(randomblob(4))) || '-' ||
|
|
4
|
+
lower(hex(randomblob(2))) || '-4' ||
|
|
5
|
+
substr(lower(hex(randomblob(2))), 2) || '-' ||
|
|
6
|
+
substr('89ab', abs(random()) % 4 + 1, 1) ||
|
|
7
|
+
substr(lower(hex(randomblob(2))), 2) || '-' ||
|
|
8
|
+
lower(hex(randomblob(6)))
|
|
9
|
+
),
|
|
10
|
+
input TEXT NOT NULL,
|
|
11
|
+
created_at TEXT NOT NULL DEFAULT CURRENT_TIMESTAMP
|
|
12
|
+
);
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
use anyhow::Context as _;
|
|
2
|
+
|
|
3
|
+
#[derive(Clone)]
|
|
4
|
+
pub struct ServerConfig {
|
|
5
|
+
pub host: String,
|
|
6
|
+
pub port: String,
|
|
7
|
+
pub database_url: String,
|
|
8
|
+
}
|
|
9
|
+
|
|
10
|
+
impl ServerConfig {
|
|
11
|
+
pub fn from_env() -> anyhow::Result<Self> {
|
|
12
|
+
Ok(Self {
|
|
13
|
+
host: read_env("SERVER_HOST")?,
|
|
14
|
+
port: read_env("SERVER_PORT")?,
|
|
15
|
+
database_url: read_env("DATABASE_URL")?,
|
|
16
|
+
})
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
#[must_use]
|
|
20
|
+
pub fn bind_addr(&self) -> String {
|
|
21
|
+
format!("{}:{}", self.host, self.port)
|
|
22
|
+
}
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
fn read_env(name: &str) -> anyhow::Result<String> {
|
|
26
|
+
std::env::var(name).with_context(|| format!("read {name}"))
|
|
27
|
+
}
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
use super::Db;
|
|
2
|
+
|
|
3
|
+
impl Db {
|
|
4
|
+
pub async fn record_hello_world_input(&self, input: &str) -> anyhow::Result<()> {
|
|
5
|
+
sqlx::query(
|
|
6
|
+
r"
|
|
7
|
+
INSERT INTO hello_world_inputs (input)
|
|
8
|
+
VALUES (?)
|
|
9
|
+
",
|
|
10
|
+
)
|
|
11
|
+
.bind(input)
|
|
12
|
+
.execute(&self.pool)
|
|
13
|
+
.await?;
|
|
14
|
+
|
|
15
|
+
Ok(())
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
#[cfg(test)]
|
|
19
|
+
pub async fn list_hello_world_inputs(&self) -> anyhow::Result<Vec<String>> {
|
|
20
|
+
let rows = sqlx::query(
|
|
21
|
+
r"
|
|
22
|
+
SELECT input
|
|
23
|
+
FROM hello_world_inputs
|
|
24
|
+
ORDER BY created_at, id
|
|
25
|
+
",
|
|
26
|
+
)
|
|
27
|
+
.fetch_all(&self.pool)
|
|
28
|
+
.await?;
|
|
29
|
+
|
|
30
|
+
rows.into_iter()
|
|
31
|
+
.map(|row| Ok(sqlx::Row::try_get(&row, "input")?))
|
|
32
|
+
.collect()
|
|
33
|
+
}
|
|
34
|
+
}
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
use super::Db;
|
|
2
|
+
|
|
3
|
+
#[tokio::test]
|
|
4
|
+
async fn record_hello_world_input_persists_submitted_names() -> anyhow::Result<()> {
|
|
5
|
+
let db = Db::in_memory().await?;
|
|
6
|
+
|
|
7
|
+
db.record_hello_world_input("Playwright").await?;
|
|
8
|
+
|
|
9
|
+
assert_eq!(db.list_hello_world_inputs().await?, vec!["Playwright"]);
|
|
10
|
+
Ok(())
|
|
11
|
+
}
|
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
mod hello_world;
|
|
2
|
+
#[cfg(test)]
|
|
3
|
+
mod hello_world_tests;
|
|
4
|
+
|
|
5
|
+
use anyhow::Context as _;
|
|
6
|
+
use sqlx::{SqlitePool, sqlite::SqlitePoolOptions};
|
|
7
|
+
|
|
8
|
+
#[derive(Clone)]
|
|
9
|
+
pub struct Db {
|
|
10
|
+
pool: SqlitePool,
|
|
11
|
+
}
|
|
12
|
+
|
|
13
|
+
impl Db {
|
|
14
|
+
pub async fn connect(database_url: &str) -> anyhow::Result<Self> {
|
|
15
|
+
let pool = SqlitePoolOptions::new()
|
|
16
|
+
.max_connections(5)
|
|
17
|
+
.connect(database_url)
|
|
18
|
+
.await
|
|
19
|
+
.context("connect database")?;
|
|
20
|
+
|
|
21
|
+
sqlx::migrate!("./migrations")
|
|
22
|
+
.run(&pool)
|
|
23
|
+
.await
|
|
24
|
+
.context("run database migrations")?;
|
|
25
|
+
|
|
26
|
+
Ok(Self { pool })
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
#[cfg(test)]
|
|
30
|
+
async fn in_memory() -> anyhow::Result<Self> {
|
|
31
|
+
let pool = SqlitePoolOptions::new()
|
|
32
|
+
.max_connections(1)
|
|
33
|
+
.connect("sqlite::memory:")
|
|
34
|
+
.await?;
|
|
35
|
+
|
|
36
|
+
sqlx::migrate!("./migrations").run(&pool).await?;
|
|
37
|
+
Ok(Self { pool })
|
|
38
|
+
}
|
|
39
|
+
}
|
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
use std::{net::SocketAddr, sync::Arc};
|
|
2
|
+
|
|
3
|
+
use anyhow::Context as _;
|
|
4
|
+
use axum::{Router, routing::get};
|
|
5
|
+
use connectrpc::Router as ConnectRouter;
|
|
6
|
+
use server::{
|
|
7
|
+
config::ServerConfig, db::Db, proto::helloworld::v1::GreeterServiceExt,
|
|
8
|
+
rpc::greeter::GreeterRpcService, state::AppState,
|
|
9
|
+
};
|
|
10
|
+
use tower_http::{cors::CorsLayer, trace::TraceLayer};
|
|
11
|
+
use tracing::info;
|
|
12
|
+
use tracing_subscriber::{EnvFilter, fmt};
|
|
13
|
+
|
|
14
|
+
#[tokio::main]
|
|
15
|
+
async fn main() -> anyhow::Result<()> {
|
|
16
|
+
fmt()
|
|
17
|
+
.with_env_filter(EnvFilter::from_default_env().add_directive("server=info".parse()?))
|
|
18
|
+
.init();
|
|
19
|
+
|
|
20
|
+
let config = ServerConfig::from_env()?;
|
|
21
|
+
let bind_addr = config.bind_addr();
|
|
22
|
+
let db = Db::connect(&config.database_url).await?;
|
|
23
|
+
let app_state = AppState::new(db);
|
|
24
|
+
|
|
25
|
+
let connect =
|
|
26
|
+
Arc::new(GreeterRpcService::new(app_state.clone())).register(ConnectRouter::new());
|
|
27
|
+
let app = Router::new()
|
|
28
|
+
.route("/health", get(|| async { "OK" }))
|
|
29
|
+
.fallback_service(connect.into_axum_service())
|
|
30
|
+
.with_state(app_state)
|
|
31
|
+
.layer(CorsLayer::permissive())
|
|
32
|
+
.layer(TraceLayer::new_for_http());
|
|
33
|
+
|
|
34
|
+
let listener = tokio::net::TcpListener::bind(&bind_addr)
|
|
35
|
+
.await
|
|
36
|
+
.with_context(|| format!("bind {bind_addr}"))?;
|
|
37
|
+
let addr: SocketAddr = listener.local_addr().context("read bound address")?;
|
|
38
|
+
|
|
39
|
+
info!("server listening on http://{addr}");
|
|
40
|
+
axum::serve(listener, app).await.context("serve")?;
|
|
41
|
+
|
|
42
|
+
Ok(())
|
|
43
|
+
}
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
mod say_hello;
|
|
2
|
+
|
|
3
|
+
use connectrpc::{ConnectError, RequestContext, Response};
|
|
4
|
+
|
|
5
|
+
use crate::{
|
|
6
|
+
proto::helloworld::v1::{GreeterService, OwnedSayHelloRequestView, SayHelloResponse},
|
|
7
|
+
state::AppState,
|
|
8
|
+
};
|
|
9
|
+
|
|
10
|
+
#[derive(Clone)]
|
|
11
|
+
pub struct GreeterRpcService {
|
|
12
|
+
pub(super) state: AppState,
|
|
13
|
+
}
|
|
14
|
+
|
|
15
|
+
impl GreeterRpcService {
|
|
16
|
+
#[must_use]
|
|
17
|
+
pub fn new(state: AppState) -> Self {
|
|
18
|
+
Self { state }
|
|
19
|
+
}
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
#[allow(refining_impl_trait)]
|
|
23
|
+
impl GreeterService for GreeterRpcService {
|
|
24
|
+
async fn say_hello(
|
|
25
|
+
&self,
|
|
26
|
+
ctx: RequestContext,
|
|
27
|
+
request: OwnedSayHelloRequestView,
|
|
28
|
+
) -> Result<Response<SayHelloResponse>, ConnectError> {
|
|
29
|
+
say_hello::handle(self, ctx, &request).await
|
|
30
|
+
}
|
|
31
|
+
}
|