tangled
alpha
login
or
join now
nekomimi.pet
/
wisp.place-monorepo
88
fork
atom
Monorepo for wisp.place. A static site hosting service built on top of the AT Protocol.
wisp.place
88
fork
atom
overview
issues
9
pulls
pipelines
admin dashboard
nekomimi.pet
1 month ago
c60a6241
52757cbe
1/2
deploy-wisp.yml
success
35s
test.yml
failed
28s
+114
-1
2 changed files
expand all
collapse all
unified
split
apps
main-app
build.ts
src
index.ts
+91
-1
apps/main-app/build.ts
···
112
112
113
113
await Bun.write(`${distDir}/editor/index.html`, htmlContent)
114
114
115
115
+
// Create admin directory
116
116
+
await mkdir(`${distDir}/admin`, { recursive: true })
117
117
+
118
118
+
// Build the admin React app
119
119
+
const adminResult = await Bun.build({
120
120
+
entrypoints: [`${publicDir}/admin/admin.tsx`],
121
121
+
outdir: `${distDir}/admin`,
122
122
+
target: 'browser',
123
123
+
format: 'esm',
124
124
+
minify: true,
125
125
+
sourcemap: 'none',
126
126
+
splitting: true,
127
127
+
naming: {
128
128
+
entry: '[name].[hash].js',
129
129
+
chunk: '[name].[hash].js',
130
130
+
asset: '[name].[hash][ext]'
131
131
+
}
132
132
+
})
133
133
+
134
134
+
if (!adminResult.success) {
135
135
+
console.error('❌ Admin build failed:')
136
136
+
for (const log of adminResult.logs) {
137
137
+
console.error(log)
138
138
+
}
139
139
+
process.exit(1)
140
140
+
}
141
141
+
142
142
+
// Find the main entry bundle for admin
143
143
+
const adminBundle = adminResult.outputs.find(o => o.path.includes('admin.') && o.path.endsWith('.js'))
144
144
+
145
145
+
if (!adminBundle) {
146
146
+
console.error('❌ Could not find admin bundle in outputs')
147
147
+
process.exit(1)
148
148
+
}
149
149
+
150
150
+
const adminBundleName = path.basename(adminBundle.path)
151
151
+
152
152
+
// Generate the production HTML for admin
153
153
+
const adminHtmlContent = `<!doctype html>
154
154
+
<html lang="en">
155
155
+
<head>
156
156
+
<meta charset="UTF-8" />
157
157
+
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
158
158
+
<title>Admin - wisp.place</title>
159
159
+
<meta name="description" content="Admin dashboard for wisp.place decentralized static site hosting." />
160
160
+
<meta name="robots" content="noindex, nofollow" />
161
161
+
162
162
+
<!-- Theme -->
163
163
+
<meta name="theme-color" content="#7c3aed" />
164
164
+
165
165
+
<link rel="icon" type="image/x-icon" href="/favicon.ico">
166
166
+
<link rel="icon" type="image/png" sizes="32x32" href="/favicon-32x32.png">
167
167
+
<link rel="icon" type="image/png" sizes="16x16" href="/favicon-16x16.png">
168
168
+
<link rel="apple-touch-icon" sizes="180x180" href="/apple-touch-icon.png">
169
169
+
<link rel="manifest" href="/site.webmanifest">
170
170
+
<link rel="stylesheet" href="/dist/styles.css">
171
171
+
<style>
172
172
+
/* Dark theme fallback styles for before JS loads */
173
173
+
@media (prefers-color-scheme: dark) {
174
174
+
body {
175
175
+
background-color: oklch(0.23 0.015 285);
176
176
+
color: oklch(0.90 0.005 285);
177
177
+
}
178
178
+
179
179
+
pre {
180
180
+
background-color: oklch(0.33 0.015 285) !important;
181
181
+
color: oklch(0.90 0.005 285) !important;
182
182
+
}
183
183
+
184
184
+
.bg-muted {
185
185
+
background-color: oklch(0.33 0.015 285) !important;
186
186
+
}
187
187
+
}
188
188
+
</style>
189
189
+
</head>
190
190
+
<body>
191
191
+
<div id="root"></div>
192
192
+
<script type="module" src="/admin/${adminBundleName}"></script>
193
193
+
</body>
194
194
+
</html>
195
195
+
`
196
196
+
197
197
+
await Bun.write(`${distDir}/admin/index.html`, adminHtmlContent)
198
198
+
115
199
console.log('✅ Build successful!')
116
116
-
console.log(`📦 Generated ${editorResult.outputs.length + 1} file(s):`)
200
200
+
console.log(`📦 Generated ${editorResult.outputs.length + adminResult.outputs.length + 2} file(s):`)
201
201
+
console.log(`\n Editor:`)
117
202
console.log(` - ${distDir}/editor/index.html`)
118
203
for (const output of editorResult.outputs) {
119
204
console.log(` - ${output.path}`)
120
205
}
206
206
+
console.log(`\n Admin:`)
207
207
+
console.log(` - ${distDir}/admin/index.html`)
208
208
+
for (const output of adminResult.outputs) {
209
209
+
console.log(` - ${output.path}`)
210
210
+
}
+23
apps/main-app/src/index.ts
···
226
226
})
227
227
: (app) => app
228
228
)
229
229
+
// Production only: serve built admin assets
230
230
+
.use(
231
231
+
Bun.env.NODE_ENV === 'production'
232
232
+
? await staticPlugin({
233
233
+
assets: './apps/main-app/dist/admin',
234
234
+
prefix: '/admin'
235
235
+
})
236
236
+
: (app) => app
237
237
+
)
238
238
+
// Production only: serve built HTML for /admin
239
239
+
.use(
240
240
+
Bun.env.NODE_ENV === 'production'
241
241
+
? new Elysia()
242
242
+
.get('/admin', async ({ set }) => {
243
243
+
set.headers['Content-Type'] = 'text/html; charset=utf-8'
244
244
+
return await Bun.file('./apps/main-app/dist/admin/index.html').text()
245
245
+
})
246
246
+
.get('/admin/*', async ({ set }) => {
247
247
+
set.headers['Content-Type'] = 'text/html; charset=utf-8'
248
248
+
return await Bun.file('./apps/main-app/dist/admin/index.html').text()
249
249
+
})
250
250
+
: (app) => app
251
251
+
)
229
252
.get('/wisp.css', ({ set }) => {
230
253
set.headers['Content-Type'] = 'text/css; charset=utf-8'
231
254
set.headers['Cache-Control'] = 'public, max-age=86400'