@alteran/astro 0.1.5 → 0.1.7
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/index.js +16 -2
- package/package.json +4 -5
- package/src/handlers/root.ts +105 -2
- package/src/worker/runtime.ts +43 -6
- package/types/astro-manifest.d.ts +6 -0
- package/types/worker.d.ts +5 -1
- package/src/pages/index.astro +0 -57
- package/src/pages/index.ts +0 -2
package/index.js
CHANGED
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import { readFileSync } from 'node:fs';
|
|
2
|
+
import { isAbsolute, relative } from 'node:path';
|
|
2
3
|
import { fileURLToPath } from 'node:url';
|
|
3
4
|
|
|
4
5
|
const CORE_ROUTES = [
|
|
@@ -37,7 +38,7 @@ const CORE_ROUTES = [
|
|
|
37
38
|
|
|
38
39
|
const ROOT_ROUTE = {
|
|
39
40
|
pattern: '/',
|
|
40
|
-
entrypoint: './src/
|
|
41
|
+
entrypoint: './src/handlers/root.ts',
|
|
41
42
|
};
|
|
42
43
|
|
|
43
44
|
const DEBUG_ROUTES = [
|
|
@@ -96,8 +97,21 @@ export default function alteran(options = {}) {
|
|
|
96
97
|
order: 'pre',
|
|
97
98
|
});
|
|
98
99
|
|
|
100
|
+
const srcDirUrl = config.srcDir ?? config.root;
|
|
101
|
+
const pagesDirUrl = config.pagesDir ?? new URL('./pages/', srcDirUrl);
|
|
102
|
+
const projectPagesDir = fileURLToPath(pagesDirUrl);
|
|
103
|
+
|
|
99
104
|
for (const route of routes) {
|
|
100
|
-
|
|
105
|
+
const entrypoint = resolvePackagePath(route.entrypoint);
|
|
106
|
+
const relativeToPages = relative(projectPagesDir, entrypoint);
|
|
107
|
+
const entrypointWithinPages =
|
|
108
|
+
relativeToPages === '' || (!relativeToPages.startsWith('..') && !isAbsolute(relativeToPages));
|
|
109
|
+
|
|
110
|
+
if (entrypointWithinPages) {
|
|
111
|
+
continue;
|
|
112
|
+
}
|
|
113
|
+
|
|
114
|
+
injectRoute({ pattern: route.pattern, entrypoint });
|
|
101
115
|
}
|
|
102
116
|
},
|
|
103
117
|
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@alteran/astro",
|
|
3
|
-
"version": "0.1.
|
|
3
|
+
"version": "0.1.7",
|
|
4
4
|
"description": "Astro integration for running a Cloudflare-hosted Bluesky PDS with Alteran.",
|
|
5
5
|
"module": "index.js",
|
|
6
6
|
"types": "index.d.ts",
|
|
@@ -40,15 +40,13 @@
|
|
|
40
40
|
"db:reset:local": "rm -rf .wrangler/state && rm -rf drizzle && bun run db:generate && bun run db:apply:local"
|
|
41
41
|
},
|
|
42
42
|
"devDependencies": {
|
|
43
|
-
"@astrojs/cloudflare": "^
|
|
43
|
+
"@astrojs/cloudflare": "^12.6.9",
|
|
44
44
|
"@atproto/api": "^0.17.0",
|
|
45
45
|
"@cloudflare/vite-plugin": "^1.13.8",
|
|
46
|
-
"alchemy": "^0.70.2",
|
|
47
46
|
"@types/bun": "latest",
|
|
48
|
-
"astro": "^4.16.9",
|
|
49
47
|
"drizzle-kit": "^0.31.5",
|
|
50
48
|
"miniflare": "3",
|
|
51
|
-
"vite": "^
|
|
49
|
+
"vite": "^6.3.6",
|
|
52
50
|
"wrangler": "^4.40.3"
|
|
53
51
|
},
|
|
54
52
|
"peerDependencies": {
|
|
@@ -59,6 +57,7 @@
|
|
|
59
57
|
"@ipld/car": "^5.4.2",
|
|
60
58
|
"@ipld/dag-cbor": "^9.2.5",
|
|
61
59
|
"@noble/hashes": "^2.0.1",
|
|
60
|
+
"astro": "^5.14.1",
|
|
62
61
|
"astro-icon": "^1.1.5",
|
|
63
62
|
"dotenv": "^17.2.3",
|
|
64
63
|
"drizzle-orm": "^0.44.6",
|
package/src/handlers/root.ts
CHANGED
|
@@ -1,5 +1,108 @@
|
|
|
1
1
|
import type { APIContext } from 'astro';
|
|
2
2
|
|
|
3
|
-
|
|
4
|
-
|
|
3
|
+
const HTML_TEMPLATE = (
|
|
4
|
+
handle,
|
|
5
|
+
did,
|
|
6
|
+
) => `<!DOCTYPE html>
|
|
7
|
+
<html lang="en">
|
|
8
|
+
<head>
|
|
9
|
+
<meta charset="utf-8" />
|
|
10
|
+
<meta name="viewport" content="width=device-width, initial-scale=1" />
|
|
11
|
+
<title>Alteran PDS</title>
|
|
12
|
+
<style>
|
|
13
|
+
:root {
|
|
14
|
+
color-scheme: light dark;
|
|
15
|
+
font-family: system-ui, -apple-system, BlinkMacSystemFont, 'Segoe UI', sans-serif;
|
|
16
|
+
}
|
|
17
|
+
body {
|
|
18
|
+
margin: 0;
|
|
19
|
+
min-height: 100vh;
|
|
20
|
+
display: flex;
|
|
21
|
+
justify-content: center;
|
|
22
|
+
align-items: center;
|
|
23
|
+
background: radial-gradient(circle at top, #f5f7ff, #e2e8f0);
|
|
24
|
+
}
|
|
25
|
+
.card {
|
|
26
|
+
background: rgba(255, 255, 255, 0.92);
|
|
27
|
+
backdrop-filter: blur(6px);
|
|
28
|
+
padding: 2.5rem;
|
|
29
|
+
border-radius: 1rem;
|
|
30
|
+
box-shadow: 0 25px 45px rgba(15, 23, 42, 0.18);
|
|
31
|
+
text-align: center;
|
|
32
|
+
max-width: 28rem;
|
|
33
|
+
}
|
|
34
|
+
h1 {
|
|
35
|
+
margin: 0 0 1.5rem;
|
|
36
|
+
font-size: clamp(2rem, 4vw, 2.75rem);
|
|
37
|
+
letter-spacing: -0.02em;
|
|
38
|
+
color: #111827;
|
|
39
|
+
}
|
|
40
|
+
p {
|
|
41
|
+
margin: 0.75rem 0;
|
|
42
|
+
color: #334155;
|
|
43
|
+
line-height: 1.55;
|
|
44
|
+
}
|
|
45
|
+
.pill {
|
|
46
|
+
display: inline-block;
|
|
47
|
+
font-family: 'JetBrains Mono', 'Fira Code', monospace;
|
|
48
|
+
font-size: 0.95rem;
|
|
49
|
+
padding: 0.35rem 0.75rem;
|
|
50
|
+
border-radius: 999px;
|
|
51
|
+
background: rgba(59, 130, 246, 0.13);
|
|
52
|
+
color: #1d4ed8;
|
|
53
|
+
}
|
|
54
|
+
a {
|
|
55
|
+
display: inline-flex;
|
|
56
|
+
align-items: center;
|
|
57
|
+
gap: 0.5rem;
|
|
58
|
+
color: #2563eb;
|
|
59
|
+
text-decoration: none;
|
|
60
|
+
font-weight: 600;
|
|
61
|
+
margin-top: 1.5rem;
|
|
62
|
+
}
|
|
63
|
+
a:hover {
|
|
64
|
+
text-decoration: underline;
|
|
65
|
+
}
|
|
66
|
+
svg {
|
|
67
|
+
width: 1.25rem;
|
|
68
|
+
height: 1.25rem;
|
|
69
|
+
}
|
|
70
|
+
</style>
|
|
71
|
+
</head>
|
|
72
|
+
<body>
|
|
73
|
+
<div class="card">
|
|
74
|
+
<h1>Alteran</h1>
|
|
75
|
+
<p>This single-user ATProto Personal Data Server runs on Cloudflare Workers.</p>
|
|
76
|
+
<p>
|
|
77
|
+
<strong>Handle:</strong>
|
|
78
|
+
<span class="pill">${handle}</span>
|
|
79
|
+
</p>
|
|
80
|
+
<p>
|
|
81
|
+
<strong>DID:</strong>
|
|
82
|
+
<span class="pill">${did}</span>
|
|
83
|
+
</p>
|
|
84
|
+
<a href="https://github.com/alteran-dev/alteran" target="_blank" rel="noopener noreferrer">
|
|
85
|
+
<svg viewBox="0 0 24 24" role="img" aria-hidden="true" focusable="false">
|
|
86
|
+
<path
|
|
87
|
+
fill="currentColor"
|
|
88
|
+
d="M12 .5a12 12 0 0 0-3.79 23.4c.6.11.82-.26.82-.58v-2.02c-3.34.73-4.04-1.61-4.04-1.61-.55-1.4-1.35-1.77-1.35-1.77-1.1-.75.08-.74.08-.74 1.22.09 1.87 1.26 1.87 1.26 1.08 1.85 2.83 1.32 3.52 1.01.11-.79.42-1.32.76-1.62-2.67-.3-5.47-1.34-5.47-5.98 0-1.32.47-2.39 1.25-3.24-.13-.3-.54-1.52.12-3.17 0 0 1.01-.32 3.3 1.24a11.5 11.5 0 0 1 6 0c2.29-1.56 3.3-1.24 3.3-1.24.66 1.65.25 2.87.12 3.17.78.85 1.25 1.92 1.25 3.24 0 4.66-2.8 5.68-5.48 5.97.43.37.81 1.09.81 2.2v3.26c0 .32.22.7.83.58A12 12 0 0 0 12 .5"
|
|
89
|
+
/>
|
|
90
|
+
</svg>
|
|
91
|
+
Source Code
|
|
92
|
+
</a>
|
|
93
|
+
</div>
|
|
94
|
+
</body>
|
|
95
|
+
</html>`;
|
|
96
|
+
|
|
97
|
+
export async function GET({ locals }: APIContext) {
|
|
98
|
+
const { env } = locals.runtime ?? {};
|
|
99
|
+
const handle = env?.PDS_HANDLE ?? 'unknown.handle';
|
|
100
|
+
const did = env?.PDS_DID ?? 'did:plc:unknown';
|
|
101
|
+
|
|
102
|
+
return new Response(HTML_TEMPLATE(handle, did), {
|
|
103
|
+
status: 200,
|
|
104
|
+
headers: {
|
|
105
|
+
'Content-Type': 'text/html; charset=utf-8',
|
|
106
|
+
},
|
|
107
|
+
});
|
|
5
108
|
}
|
package/src/worker/runtime.ts
CHANGED
|
@@ -1,8 +1,7 @@
|
|
|
1
|
-
import { handle } from 'astro/internal/handler';
|
|
2
|
-
import { onRequest } from '../middleware';
|
|
3
1
|
import { seed } from '../db/seed';
|
|
4
2
|
import { validateConfigOrThrow } from '../lib/config';
|
|
5
3
|
import type { Env } from '../env';
|
|
4
|
+
import type { SSRManifest } from 'astro';
|
|
6
5
|
import type {
|
|
7
6
|
ExecutionContext,
|
|
8
7
|
Request as WorkersRequest,
|
|
@@ -15,11 +14,19 @@ export type PdsFetchHandler = (
|
|
|
15
14
|
ctx: ExecutionContext
|
|
16
15
|
) => Promise<WorkersResponse>;
|
|
17
16
|
|
|
17
|
+
export interface CreatePdsFetchHandlerOptions {
|
|
18
|
+
/**
|
|
19
|
+
* Optionally pass the host project's manifest when composing the worker manually.
|
|
20
|
+
* When omitted, the integration will load the manifest lazily from the build output.
|
|
21
|
+
*/
|
|
22
|
+
manifest?: SSRManifest;
|
|
23
|
+
}
|
|
24
|
+
|
|
18
25
|
/**
|
|
19
26
|
* Returns the Alteran PDS Worker fetch handler so downstream apps can
|
|
20
27
|
* compose it inside their own Cloudflare Worker entrypoint.
|
|
21
28
|
*/
|
|
22
|
-
export function createPdsFetchHandler(): PdsFetchHandler {
|
|
29
|
+
export function createPdsFetchHandler(options?: CreatePdsFetchHandlerOptions): PdsFetchHandler {
|
|
23
30
|
return async function fetch(request: WorkersRequest, env: Env, ctx: ExecutionContext) {
|
|
24
31
|
try {
|
|
25
32
|
validateConfigOrThrow(env);
|
|
@@ -53,11 +60,41 @@ export function createPdsFetchHandler(): PdsFetchHandler {
|
|
|
53
60
|
return (await stub.fetch(request as any)) as unknown as WorkersResponse;
|
|
54
61
|
}
|
|
55
62
|
|
|
56
|
-
const
|
|
57
|
-
|
|
63
|
+
const astroFetch = await getAstroFetch(options);
|
|
64
|
+
const response = await astroFetch(request, env as any, ctx);
|
|
65
|
+
return response as unknown as WorkersResponse;
|
|
58
66
|
};
|
|
59
67
|
}
|
|
60
68
|
|
|
61
|
-
|
|
69
|
+
type AstroFetchHandler = (
|
|
70
|
+
request: WorkersRequest,
|
|
71
|
+
env: Env,
|
|
72
|
+
ctx: ExecutionContext
|
|
73
|
+
) => Promise<WorkersResponse>;
|
|
74
|
+
|
|
75
|
+
let cachedFetchPromise: Promise<AstroFetchHandler> | undefined;
|
|
76
|
+
|
|
77
|
+
async function loadAstroFetchFromManifest(manifest: SSRManifest): Promise<AstroFetchHandler> {
|
|
78
|
+
const { createExports } = await import('@astrojs/cloudflare/entrypoints/server.js');
|
|
79
|
+
const exports = createExports(manifest);
|
|
80
|
+
return exports.default.fetch as unknown as AstroFetchHandler;
|
|
81
|
+
}
|
|
82
|
+
|
|
83
|
+
async function getAstroFetch(options?: CreatePdsFetchHandlerOptions): Promise<AstroFetchHandler> {
|
|
84
|
+
if (options?.manifest) {
|
|
85
|
+
return loadAstroFetchFromManifest(options.manifest);
|
|
86
|
+
}
|
|
87
|
+
|
|
88
|
+
if (!cachedFetchPromise) {
|
|
89
|
+
cachedFetchPromise = (async () => {
|
|
90
|
+
const { manifest } = await import('@astrojs-manifest');
|
|
91
|
+
return loadAstroFetchFromManifest(manifest as SSRManifest);
|
|
92
|
+
})();
|
|
93
|
+
}
|
|
94
|
+
|
|
95
|
+
return cachedFetchPromise;
|
|
96
|
+
}
|
|
97
|
+
|
|
98
|
+
export { onRequest } from '../middleware';
|
|
62
99
|
export { seed };
|
|
63
100
|
export { validateConfigOrThrow };
|
package/types/worker.d.ts
CHANGED
|
@@ -1,4 +1,8 @@
|
|
|
1
|
-
export {
|
|
1
|
+
export {
|
|
2
|
+
createPdsFetchHandler,
|
|
3
|
+
type PdsFetchHandler,
|
|
4
|
+
type CreatePdsFetchHandlerOptions,
|
|
5
|
+
} from '../src/worker/runtime';
|
|
2
6
|
export { Sequencer } from '../src/worker/sequencer';
|
|
3
7
|
export { onRequest } from '../src/middleware';
|
|
4
8
|
export { seed } from '../src/db/seed';
|
package/src/pages/index.astro
DELETED
|
@@ -1,57 +0,0 @@
|
|
|
1
|
-
---
|
|
2
|
-
import { Icon } from 'astro-icon/components';
|
|
3
|
-
---
|
|
4
|
-
|
|
5
|
-
<html lang="en">
|
|
6
|
-
<head>
|
|
7
|
-
<meta charset="utf-8" />
|
|
8
|
-
<link rel="icon" type="image/svg+xml" href="/favicon.svg" />
|
|
9
|
-
<meta name="viewport" content="width=device-width" />
|
|
10
|
-
<meta name="generator" content={Astro.generator} />
|
|
11
|
-
<title>Alteran PDS</title>
|
|
12
|
-
<style>
|
|
13
|
-
body {
|
|
14
|
-
font-family: sans-serif;
|
|
15
|
-
display: flex;
|
|
16
|
-
justify-content: center;
|
|
17
|
-
align-items: center;
|
|
18
|
-
height: 100vh;
|
|
19
|
-
background-color: #f0f2f5;
|
|
20
|
-
}
|
|
21
|
-
.card {
|
|
22
|
-
background-color: white;
|
|
23
|
-
padding: 2rem;
|
|
24
|
-
border-radius: 0.5rem;
|
|
25
|
-
box-shadow: 0 0 1rem rgba(0, 0, 0, 0.1);
|
|
26
|
-
text-align: center;
|
|
27
|
-
}
|
|
28
|
-
h1 {
|
|
29
|
-
margin-top: 0;
|
|
30
|
-
}
|
|
31
|
-
.did, .handle {
|
|
32
|
-
font-family: monospace;
|
|
33
|
-
background-color: #eee;
|
|
34
|
-
padding: 0.25rem 0.5rem;
|
|
35
|
-
border-radius: 0.25rem;
|
|
36
|
-
}
|
|
37
|
-
</style>
|
|
38
|
-
</head>
|
|
39
|
-
<body>
|
|
40
|
-
<div class="card">
|
|
41
|
-
<h1>Alteran</h1>
|
|
42
|
-
<p>This is a single-user ATProto Personal Data Server running on Cloudflare.</p>
|
|
43
|
-
<p>
|
|
44
|
-
<strong>Handle:</strong> <span class="handle">{import.meta.env.PDS_HANDLE}</span>
|
|
45
|
-
</p>
|
|
46
|
-
<p>
|
|
47
|
-
<strong>DID:</strong> <span class="did">{import.meta.env.PDS_DID}</span>
|
|
48
|
-
</p>
|
|
49
|
-
<p>
|
|
50
|
-
<a href="https://github.com/alteran-dev/alteran" target="_blank" rel="noopener noreferrer">
|
|
51
|
-
<Icon name="simple-icons:github" />
|
|
52
|
-
Source Code
|
|
53
|
-
</a>
|
|
54
|
-
</p>
|
|
55
|
-
</div>
|
|
56
|
-
</body>
|
|
57
|
-
</html>
|
package/src/pages/index.ts
DELETED