amplify-astro-adapter 0.1.0 → 0.1.2
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 +412 -0
- package/package.json +1 -1
package/README.md
ADDED
|
@@ -0,0 +1,412 @@
|
|
|
1
|
+
# amplify-astro-adapter
|
|
2
|
+
|
|
3
|
+
AWS Amplify adapter for Astro. Extends `@astrojs/node` with Amplify Hosting deployment configuration.
|
|
4
|
+
|
|
5
|
+
## Version 0.1.0
|
|
6
|
+
|
|
7
|
+
This adapter is based on `@astrojs/node` architecture, adding AWS Amplify-specific deployment features and cookie-based session support.
|
|
8
|
+
|
|
9
|
+
### Features
|
|
10
|
+
|
|
11
|
+
- Astro 4.x and 5.x support
|
|
12
|
+
- **envGetSecret** support for type-safe environment variables
|
|
13
|
+
- **Cookie-based sessions** (built-in, zero setup)
|
|
14
|
+
- **Auto-generates `amplify.yml`** - detects your package manager and creates the build spec for you
|
|
15
|
+
- Configurable Node.js runtime (nodejs20.x, nodejs22.x)
|
|
16
|
+
- Generates proper `deploy-manifest.json` for Amplify Hosting
|
|
17
|
+
|
|
18
|
+
## Installation
|
|
19
|
+
|
|
20
|
+
```bash
|
|
21
|
+
# Using npm
|
|
22
|
+
npm install amplify-astro-adapter
|
|
23
|
+
|
|
24
|
+
# Using yarn
|
|
25
|
+
yarn add amplify-astro-adapter
|
|
26
|
+
|
|
27
|
+
# Using pnpm
|
|
28
|
+
pnpm add amplify-astro-adapter
|
|
29
|
+
```
|
|
30
|
+
|
|
31
|
+
## Configuration
|
|
32
|
+
|
|
33
|
+
Add the adapter to your Astro config:
|
|
34
|
+
|
|
35
|
+
```js
|
|
36
|
+
// astro.config.mjs
|
|
37
|
+
import { defineConfig } from 'astro/config';
|
|
38
|
+
import amplify from 'amplify-astro-adapter';
|
|
39
|
+
|
|
40
|
+
export default defineConfig({
|
|
41
|
+
output: 'server', // or 'hybrid'
|
|
42
|
+
adapter: amplify({
|
|
43
|
+
runtime: 'nodejs20.x' // or 'nodejs22.x'
|
|
44
|
+
})
|
|
45
|
+
});
|
|
46
|
+
```
|
|
47
|
+
|
|
48
|
+
### Configuration Options
|
|
49
|
+
|
|
50
|
+
| Option | Type | Default | Description |
|
|
51
|
+
|--------|------|---------|-------------|
|
|
52
|
+
| `runtime` | `'nodejs20.x' \| 'nodejs22.x'` | `'nodejs20.x'` | Node.js runtime for AWS Lambda |
|
|
53
|
+
| `experimentalDisableStreaming` | `boolean` | `false` | Disable HTML streaming (useful for Lambda response constraints) |
|
|
54
|
+
| `experimentalStaticHeaders` | `boolean` | `false` | Enable static header file processing (`_headers.json`) |
|
|
55
|
+
| `experimentalErrorPageHost` | `string \| URL` | - | Custom host for fetching prerendered error pages |
|
|
56
|
+
|
|
57
|
+
```js
|
|
58
|
+
// Advanced configuration example
|
|
59
|
+
export default defineConfig({
|
|
60
|
+
output: 'server',
|
|
61
|
+
adapter: amplify({
|
|
62
|
+
runtime: 'nodejs22.x',
|
|
63
|
+
experimentalDisableStreaming: true,
|
|
64
|
+
experimentalStaticHeaders: false,
|
|
65
|
+
experimentalErrorPageHost: 'https://errors.example.com',
|
|
66
|
+
})
|
|
67
|
+
});
|
|
68
|
+
```
|
|
69
|
+
|
|
70
|
+
### Server Modes
|
|
71
|
+
|
|
72
|
+
The adapter supports two server modes (inherited from `@astrojs/node`):
|
|
73
|
+
|
|
74
|
+
- **`standalone`** (default) - Auto-starts an HTTP server, serves static files, handles all requests. Used by AWS Amplify Lambda.
|
|
75
|
+
- **`middleware`** - Exports a handler for integration with Express, Fastify, or other Node.js frameworks.
|
|
76
|
+
|
|
77
|
+
## Sessions
|
|
78
|
+
|
|
79
|
+
This adapter includes built-in cookie-based session support as the **default Astro session driver**. No external session storage (Redis, DynamoDB, etc.) is needed - sessions are stored in HTTP-only cookies and work immediately with AWS Lambda.
|
|
80
|
+
|
|
81
|
+
### Key Features
|
|
82
|
+
|
|
83
|
+
- **Zero configuration** - Cookie sessions are enabled by default
|
|
84
|
+
- **Encrypted with iron-session** - Session data is securely encrypted
|
|
85
|
+
- **Automatic chunking** - Large sessions are automatically split across multiple cookies
|
|
86
|
+
- **No external dependencies** - No Redis, DynamoDB, or other storage required
|
|
87
|
+
|
|
88
|
+
### Environment Variable
|
|
89
|
+
|
|
90
|
+
Set a session secret for encryption (32+ characters recommended):
|
|
91
|
+
|
|
92
|
+
```bash
|
|
93
|
+
SESSION_SECRET=your-32-character-or-longer-secret
|
|
94
|
+
```
|
|
95
|
+
|
|
96
|
+
> **Note:** If `SESSION_SECRET` is not set, a default secret is used in development. Always set a secure secret in production.
|
|
97
|
+
|
|
98
|
+
### Auto-Configuration
|
|
99
|
+
|
|
100
|
+
Sessions are automatically enabled when you use this adapter (no configuration needed):
|
|
101
|
+
|
|
102
|
+
```js
|
|
103
|
+
// astro.config.mjs
|
|
104
|
+
import { defineConfig } from 'astro/config';
|
|
105
|
+
import amplify from 'amplify-astro-adapter';
|
|
106
|
+
|
|
107
|
+
export default defineConfig({
|
|
108
|
+
output: 'server',
|
|
109
|
+
adapter: amplify(),
|
|
110
|
+
session: {
|
|
111
|
+
// Cookie session is the default - no driver config needed!
|
|
112
|
+
// Or explicitly:
|
|
113
|
+
// driver: 'amplify-astro-adapter/session',
|
|
114
|
+
},
|
|
115
|
+
});
|
|
116
|
+
```
|
|
117
|
+
|
|
118
|
+
### Custom Session Options
|
|
119
|
+
|
|
120
|
+
If you want to customize the session behavior, you can manually configure it:
|
|
121
|
+
|
|
122
|
+
```js
|
|
123
|
+
import { defineConfig } from 'astro/config';
|
|
124
|
+
import amplify from 'amplify-astro-adapter';
|
|
125
|
+
import { createSessionStorage } from 'amplify-astro-adapter/session';
|
|
126
|
+
|
|
127
|
+
export default defineConfig({
|
|
128
|
+
adapter: amplify({ runtime: 'nodejs20.x' }),
|
|
129
|
+
session: createSessionStorage({
|
|
130
|
+
prefix: 'myapp_session',
|
|
131
|
+
cookie: {
|
|
132
|
+
maxAge: 60 * 60 * 24 * 30, // 30 days
|
|
133
|
+
sameSite: 'lax',
|
|
134
|
+
httpOnly: true,
|
|
135
|
+
secure: true,
|
|
136
|
+
}
|
|
137
|
+
})
|
|
138
|
+
});
|
|
139
|
+
```
|
|
140
|
+
|
|
141
|
+
### Using Sessions in Pages
|
|
142
|
+
|
|
143
|
+
Access sessions directly in `.astro` files:
|
|
144
|
+
|
|
145
|
+
```astro
|
|
146
|
+
---
|
|
147
|
+
// src/pages/dashboard.astro
|
|
148
|
+
const session = await Astro.session;
|
|
149
|
+
const user = await session?.get('user');
|
|
150
|
+
await session?.set('lastVisit', new Date().toISOString());
|
|
151
|
+
---
|
|
152
|
+
|
|
153
|
+
<html>
|
|
154
|
+
<body>
|
|
155
|
+
{user ? (
|
|
156
|
+
<h1>Welcome back, {user.name}!</h1>
|
|
157
|
+
) : (
|
|
158
|
+
<a href="/login">Please log in</a>
|
|
159
|
+
)}
|
|
160
|
+
</body>
|
|
161
|
+
</html>
|
|
162
|
+
```
|
|
163
|
+
|
|
164
|
+
### Using Sessions in API Routes
|
|
165
|
+
|
|
166
|
+
```ts
|
|
167
|
+
// src/pages/api/session.ts
|
|
168
|
+
import type { APIRoute } from 'astro';
|
|
169
|
+
|
|
170
|
+
export const POST: APIRoute = async ({ session }) => {
|
|
171
|
+
// Set session data
|
|
172
|
+
await session?.set('userId', '123');
|
|
173
|
+
await session?.set('cart', ['item1', 'item2']);
|
|
174
|
+
|
|
175
|
+
return Response.json({ success: true });
|
|
176
|
+
};
|
|
177
|
+
|
|
178
|
+
export const GET: APIRoute = async ({ session }) => {
|
|
179
|
+
// Get session data
|
|
180
|
+
const userId = await session?.get('userId');
|
|
181
|
+
const cart = await session?.get('cart') ?? [];
|
|
182
|
+
|
|
183
|
+
return Response.json({ userId, cart });
|
|
184
|
+
};
|
|
185
|
+
|
|
186
|
+
export const DELETE: APIRoute = async ({ session }) => {
|
|
187
|
+
// Destroy session
|
|
188
|
+
await session?.delete('userId');
|
|
189
|
+
// or destroy entire session:
|
|
190
|
+
await session?.destroy();
|
|
191
|
+
|
|
192
|
+
return Response.json({ success: true });
|
|
193
|
+
};
|
|
194
|
+
```
|
|
195
|
+
|
|
196
|
+
### Direct Cookie Helpers (Bypass Astro Sessions)
|
|
197
|
+
|
|
198
|
+
For simple cases where you don't need the full Astro session API, you can use the helper functions directly:
|
|
199
|
+
|
|
200
|
+
```ts
|
|
201
|
+
import type { APIRoute } from 'astro';
|
|
202
|
+
import { getSession, setSession, destroySession } from 'amplify-astro-adapter/session';
|
|
203
|
+
|
|
204
|
+
export const POST: APIRoute = async ({ cookies }) => {
|
|
205
|
+
await setSession(cookies, { userId: '123', cart: ['item1', 'item2'] });
|
|
206
|
+
return Response.json({ success: true });
|
|
207
|
+
};
|
|
208
|
+
|
|
209
|
+
export const GET: APIRoute = async ({ cookies }) => {
|
|
210
|
+
const session = await getSession(cookies);
|
|
211
|
+
return Response.json({ session });
|
|
212
|
+
};
|
|
213
|
+
|
|
214
|
+
export const DELETE: APIRoute = async ({ cookies }) => {
|
|
215
|
+
await destroySession(cookies);
|
|
216
|
+
return Response.json({ success: true });
|
|
217
|
+
};
|
|
218
|
+
```
|
|
219
|
+
|
|
220
|
+
### Middleware Integration
|
|
221
|
+
|
|
222
|
+
To make sessions available automatically across your app, add this to your `src/env.d.ts`:
|
|
223
|
+
|
|
224
|
+
```typescript
|
|
225
|
+
/// <reference types="astro/client" />
|
|
226
|
+
|
|
227
|
+
declare namespace App {
|
|
228
|
+
interface Locals {
|
|
229
|
+
/**
|
|
230
|
+
* Session data automatically available in middleware and pages
|
|
231
|
+
*/
|
|
232
|
+
session?: import('amplify-astro-adapter/session').SessionData;
|
|
233
|
+
}
|
|
234
|
+
}
|
|
235
|
+
```
|
|
236
|
+
|
|
237
|
+
Then create `src/middleware.ts`:
|
|
238
|
+
|
|
239
|
+
```ts
|
|
240
|
+
import { defineMiddleware } from 'astro:middleware';
|
|
241
|
+
import { getSession } from 'amplify-astro-adapter/session';
|
|
242
|
+
|
|
243
|
+
export const onRequest = defineMiddleware(async (context) => {
|
|
244
|
+
// Load session into context.locals
|
|
245
|
+
context.locals.session = await getSession(context.cookies);
|
|
246
|
+
|
|
247
|
+
// Session is now automatically available in all pages
|
|
248
|
+
return next();
|
|
249
|
+
});
|
|
250
|
+
```
|
|
251
|
+
|
|
252
|
+
Access the session in components:
|
|
253
|
+
|
|
254
|
+
```astro
|
|
255
|
+
---
|
|
256
|
+
// Session is automatically available via Astro.locals
|
|
257
|
+
const userId = Astro.locals.session?.userId;
|
|
258
|
+
---
|
|
259
|
+
<h1>Welcome {userId}</h1>
|
|
260
|
+
```
|
|
261
|
+
|
|
262
|
+
### Session Limitations
|
|
263
|
+
|
|
264
|
+
- **4KB size limit** per cookie (browsers support ~50+ cookies = ~200KB total)
|
|
265
|
+
- **Client-stored** - data can be viewed by the user (use httpOnly for XSS protection)
|
|
266
|
+
- **Cannot invalidate** before expiration (delete the cookie to invalidate)
|
|
267
|
+
|
|
268
|
+
**What fits in 4KB:**
|
|
269
|
+
- User IDs, auth tokens
|
|
270
|
+
- Shopping cart contents
|
|
271
|
+
- User preferences
|
|
272
|
+
- Session metadata
|
|
273
|
+
|
|
274
|
+
**What doesn't fit:**
|
|
275
|
+
- Large file uploads
|
|
276
|
+
- Extensive logging data
|
|
277
|
+
- Large datasets
|
|
278
|
+
|
|
279
|
+
## envGetSecret Support
|
|
280
|
+
|
|
281
|
+
Use type-safe environment variables with Astro's `astro:env/server`:
|
|
282
|
+
|
|
283
|
+
```ts
|
|
284
|
+
import { getSecret } from 'astro:env/server';
|
|
285
|
+
|
|
286
|
+
const apiKey = await getSecret('API_KEY');
|
|
287
|
+
```
|
|
288
|
+
|
|
289
|
+
## AWS Amplify Hosting
|
|
290
|
+
|
|
291
|
+
### amplify.yml Auto-Generation
|
|
292
|
+
|
|
293
|
+
When you run `astro build` for the first time, this adapter automatically generates an `amplify.yml` file in your project root. It detects your package manager (npm, pnpm, yarn, or bun) and creates the appropriate build specification.
|
|
294
|
+
|
|
295
|
+
Just commit the generated `amplify.yml` to your repository and deploy!
|
|
296
|
+
|
|
297
|
+
### Build Settings
|
|
298
|
+
|
|
299
|
+
Set the custom image environment variable:
|
|
300
|
+
|
|
301
|
+
```
|
|
302
|
+
_CUSTOM_IMAGE=amplify:al2023
|
|
303
|
+
```
|
|
304
|
+
|
|
305
|
+
### Build Specifications (Reference)
|
|
306
|
+
|
|
307
|
+
The adapter generates these for you, but for reference:
|
|
308
|
+
|
|
309
|
+
**npm:**
|
|
310
|
+
```yaml
|
|
311
|
+
version: 1
|
|
312
|
+
frontend:
|
|
313
|
+
phases:
|
|
314
|
+
preBuild:
|
|
315
|
+
commands:
|
|
316
|
+
- npm ci
|
|
317
|
+
build:
|
|
318
|
+
commands:
|
|
319
|
+
- npm run build
|
|
320
|
+
- mv node_modules ./.amplify-hosting/compute/default
|
|
321
|
+
artifacts:
|
|
322
|
+
baseDirectory: .amplify-hosting
|
|
323
|
+
files:
|
|
324
|
+
- '**/*'
|
|
325
|
+
cache:
|
|
326
|
+
paths:
|
|
327
|
+
- node_modules/**/*
|
|
328
|
+
```
|
|
329
|
+
|
|
330
|
+
**pnpm:**
|
|
331
|
+
```yaml
|
|
332
|
+
version: 1
|
|
333
|
+
frontend:
|
|
334
|
+
phases:
|
|
335
|
+
preBuild:
|
|
336
|
+
commands:
|
|
337
|
+
- npm i -g pnpm
|
|
338
|
+
- pnpm config set store-dir .pnpm-store
|
|
339
|
+
- pnpm i
|
|
340
|
+
build:
|
|
341
|
+
commands:
|
|
342
|
+
- pnpm run build
|
|
343
|
+
artifacts:
|
|
344
|
+
baseDirectory: .amplify-hosting
|
|
345
|
+
files:
|
|
346
|
+
- '**/*'
|
|
347
|
+
cache:
|
|
348
|
+
paths:
|
|
349
|
+
- .pnpm-store/**/*
|
|
350
|
+
```
|
|
351
|
+
|
|
352
|
+
**yarn:**
|
|
353
|
+
```yaml
|
|
354
|
+
version: 1
|
|
355
|
+
frontend:
|
|
356
|
+
phases:
|
|
357
|
+
preBuild:
|
|
358
|
+
commands:
|
|
359
|
+
- yarn install
|
|
360
|
+
build:
|
|
361
|
+
commands:
|
|
362
|
+
- yarn run build
|
|
363
|
+
- mv node_modules ./.amplify-hosting/compute/default
|
|
364
|
+
artifacts:
|
|
365
|
+
baseDirectory: .amplify-hosting
|
|
366
|
+
files:
|
|
367
|
+
- '**/*'
|
|
368
|
+
cache:
|
|
369
|
+
paths:
|
|
370
|
+
- node_modules/**/*
|
|
371
|
+
```
|
|
372
|
+
|
|
373
|
+
## Migration from astro-aws-amplify
|
|
374
|
+
|
|
375
|
+
If you're migrating from the old `astro-aws-amplify` package:
|
|
376
|
+
|
|
377
|
+
1. Update your dependencies:
|
|
378
|
+
```bash
|
|
379
|
+
npm uninstall astro-aws-amplify
|
|
380
|
+
npm install amplify-astro-adapter
|
|
381
|
+
```
|
|
382
|
+
|
|
383
|
+
2. Update your import:
|
|
384
|
+
```diff
|
|
385
|
+
- import awsAmplify from 'astro-aws-amplify';
|
|
386
|
+
+ import amplify from 'amplify-astro-adapter';
|
|
387
|
+
```
|
|
388
|
+
|
|
389
|
+
3. No other changes needed - configuration is the same!
|
|
390
|
+
|
|
391
|
+
## Package Exports
|
|
392
|
+
|
|
393
|
+
The adapter provides multiple entry points:
|
|
394
|
+
|
|
395
|
+
| Export | Description |
|
|
396
|
+
|--------|-------------|
|
|
397
|
+
| `amplify-astro-adapter` | Main adapter function |
|
|
398
|
+
| `amplify-astro-adapter/server` | Server runtime (used internally by Astro) |
|
|
399
|
+
| `amplify-astro-adapter/session` | Session driver and helpers |
|
|
400
|
+
| `amplify-astro-adapter/middleware` | Cookie context middleware (used internally) |
|
|
401
|
+
|
|
402
|
+
## License
|
|
403
|
+
|
|
404
|
+
MIT
|
|
405
|
+
|
|
406
|
+
## Author
|
|
407
|
+
|
|
408
|
+
Zach Handley <zachhandley@gmail.com>
|
|
409
|
+
|
|
410
|
+
## Acknowledgements
|
|
411
|
+
|
|
412
|
+
Extends the official [`@astrojs/node`](https://github.com/withastro/astro/tree/main/packages/integrations/node) adapter with AWS Amplify Hosting deployment configuration.
|