amplify-astro-adapter 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.
Files changed (53) hide show
  1. package/dist/index.d.ts +7 -0
  2. package/dist/index.d.ts.map +1 -0
  3. package/dist/index.js +211 -0
  4. package/dist/index.js.map +1 -0
  5. package/dist/log-listening-on.d.ts +5 -0
  6. package/dist/log-listening-on.d.ts.map +1 -0
  7. package/dist/log-listening-on.js +55 -0
  8. package/dist/log-listening-on.js.map +1 -0
  9. package/dist/middleware.d.ts +19 -0
  10. package/dist/middleware.d.ts.map +1 -0
  11. package/dist/middleware.js +98 -0
  12. package/dist/middleware.js.map +1 -0
  13. package/dist/node-middleware.d.ts +12 -0
  14. package/dist/node-middleware.d.ts.map +1 -0
  15. package/dist/node-middleware.js +41 -0
  16. package/dist/node-middleware.js.map +1 -0
  17. package/dist/polyfill.d.ts +2 -0
  18. package/dist/polyfill.d.ts.map +1 -0
  19. package/dist/polyfill.js +3 -0
  20. package/dist/polyfill.js.map +1 -0
  21. package/dist/serve-app.d.ts +9 -0
  22. package/dist/serve-app.d.ts.map +1 -0
  23. package/dist/serve-app.js +123 -0
  24. package/dist/serve-app.js.map +1 -0
  25. package/dist/serve-static.d.ts +11 -0
  26. package/dist/serve-static.d.ts.map +1 -0
  27. package/dist/serve-static.js +130 -0
  28. package/dist/serve-static.js.map +1 -0
  29. package/dist/server.d.ts +20 -0
  30. package/dist/server.d.ts.map +1 -0
  31. package/dist/server.js +60 -0
  32. package/dist/server.js.map +1 -0
  33. package/dist/session-driver.d.ts +89 -0
  34. package/dist/session-driver.d.ts.map +1 -0
  35. package/dist/session-driver.js +154 -0
  36. package/dist/session-driver.js.map +1 -0
  37. package/dist/shared.d.ts +2 -0
  38. package/dist/shared.d.ts.map +1 -0
  39. package/dist/shared.js +2 -0
  40. package/dist/shared.js.map +1 -0
  41. package/dist/standalone.d.ts +24 -0
  42. package/dist/standalone.d.ts.map +1 -0
  43. package/dist/standalone.js +77 -0
  44. package/dist/standalone.js.map +1 -0
  45. package/dist/types.d.ts +22 -0
  46. package/dist/types.d.ts.map +1 -0
  47. package/dist/types.js +2 -0
  48. package/dist/types.js.map +1 -0
  49. package/dist/utils/polyfills.d.ts +3 -0
  50. package/dist/utils/polyfills.d.ts.map +1 -0
  51. package/dist/utils/polyfills.js +11 -0
  52. package/dist/utils/polyfills.js.map +1 -0
  53. package/package.json +54 -0
@@ -0,0 +1,7 @@
1
+ import type { AstroIntegration } from 'astro';
2
+ export { createCookieSessionDriver, generateSessionPassword, type CookieSessionDriverOptions, type CookieSetOptions, } from './session-driver.js';
3
+ export interface AwsAmplifyOptions {
4
+ runtime?: 'nodejs20.x' | 'nodejs22.x';
5
+ }
6
+ export default function awsAmplify(options?: AwsAmplifyOptions): AstroIntegration;
7
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAe,gBAAgB,EAAE,MAAM,OAAO,CAAC;AAS3D,OAAO,EACL,yBAAyB,EACzB,uBAAuB,EACvB,KAAK,0BAA0B,EAC/B,KAAK,gBAAgB,GACtB,MAAM,qBAAqB,CAAC;AAE7B,MAAM,WAAW,iBAAiB;IAChC,OAAO,CAAC,EAAE,YAAY,GAAG,YAAY,CAAC;CACvC;AA+FD,MAAM,CAAC,OAAO,UAAU,UAAU,CAAC,OAAO,GAAE,iBAAsB,GAAG,gBAAgB,CAiIpF"}
package/dist/index.js ADDED
@@ -0,0 +1,211 @@
1
+ import { existsSync } from 'node:fs';
2
+ import { writeFile } from 'node:fs/promises';
3
+ import { join } from 'node:path';
4
+ import { fileURLToPath } from 'node:url';
5
+ import { readdir } from 'node:fs/promises';
6
+ // Re-export session driver for convenience
7
+ export { createCookieSessionDriver, generateSessionPassword, } from './session-driver.js';
8
+ async function detectPackageManager(root) {
9
+ const rootPath = fileURLToPath(root);
10
+ const entries = await readdir(rootPath);
11
+ if (entries.includes('pnpm-lock.yaml'))
12
+ return 'pnpm';
13
+ if (entries.includes('yarn.lock'))
14
+ return 'yarn';
15
+ if (entries.includes('package-lock.json'))
16
+ return 'npm';
17
+ if (entries.includes('bun.lockb'))
18
+ return 'bun';
19
+ return 'unknown';
20
+ }
21
+ function getAmplifyYaml(packageManager) {
22
+ const commonBase = `version: 1
23
+ frontend:
24
+ phases:
25
+ preBuild:
26
+ commands:
27
+ `;
28
+ const configs = {
29
+ npm: `${commonBase} - npm ci --cache .npm --prefer-offline
30
+ build:
31
+ commands:
32
+ - npm run build
33
+ - mv node_modules ./.amplify-hosting/compute/default
34
+ artifacts:
35
+ baseDirectory: .amplify-hosting
36
+ files:
37
+ - '**/*'
38
+ cache:
39
+ paths:
40
+ - .npm/**/*`,
41
+ pnpm: `${commonBase} - npm i -g pnpm
42
+ - pnpm config set store-dir .pnpm-store
43
+ - pnpm i
44
+ build:
45
+ commands:
46
+ - pnpm run build
47
+ artifacts:
48
+ baseDirectory: .amplify-hosting
49
+ files:
50
+ - '**/*'
51
+ cache:
52
+ paths:
53
+ - .pnpm-store/**/*`,
54
+ yarn: `${commonBase} - yarn install
55
+ build:
56
+ commands:
57
+ - yarn run build
58
+ - mv node_modules ./.amplify-hosting/compute/default
59
+ artifacts:
60
+ baseDirectory: .amplify-hosting
61
+ files:
62
+ - '**/*'
63
+ cache:
64
+ paths:
65
+ - node_modules/**/*`,
66
+ bun: `${commonBase} - bun install
67
+ build:
68
+ commands:
69
+ - bun run build
70
+ - mv node_modules ./.amplify-hosting/compute/default
71
+ artifacts:
72
+ baseDirectory: .amplify-hosting
73
+ files:
74
+ - '**/*'
75
+ cache:
76
+ paths:
77
+ - node_modules/**/*`,
78
+ unknown: `${commonBase} - npm ci --cache .npm --prefer-offline
79
+ build:
80
+ commands:
81
+ - npm run build
82
+ - mv node_modules ./.amplify-hosting/compute/default
83
+ artifacts:
84
+ baseDirectory: .amplify-hosting
85
+ files:
86
+ - '**/*'
87
+ cache:
88
+ paths:
89
+ - .npm/**/*`,
90
+ };
91
+ return configs[packageManager] || configs.unknown;
92
+ }
93
+ export default function awsAmplify(options = {}) {
94
+ let _config;
95
+ const { runtime = 'nodejs20.x' } = options;
96
+ return {
97
+ name: 'amplify-astro-adapter',
98
+ hooks: {
99
+ 'astro:config:setup': async ({ config, updateConfig, logger, addMiddleware }) => {
100
+ // Generate amplify.yml if it doesn't exist
101
+ const amplifyYmlPath = join(fileURLToPath(config.root), 'amplify.yml');
102
+ const ymlExists = existsSync(amplifyYmlPath);
103
+ if (!ymlExists) {
104
+ const packageManager = await detectPackageManager(config.root);
105
+ const yamlContent = getAmplifyYaml(packageManager);
106
+ await writeFile(amplifyYmlPath, yamlContent);
107
+ logger.info(`Created amplify.yml for ${packageManager} - commit this file to your repository!`);
108
+ }
109
+ // Check if we're using our session driver (auto or manual)
110
+ const isServerMode = config.output === 'server';
111
+ const hasNoDriver = !config.session?.driver;
112
+ const usesOurDriver = config.session?.driver === 'amplify-astro-adapter/session';
113
+ // Add middleware if using our session driver
114
+ if (isServerMode && (hasNoDriver || usesOurDriver)) {
115
+ addMiddleware({
116
+ entrypoint: 'amplify-astro-adapter/middleware',
117
+ order: 'pre',
118
+ });
119
+ }
120
+ // Auto-configure session driver if none specified
121
+ if (isServerMode && hasNoDriver) {
122
+ logger.info('Auto-configuring cookie-based session driver for serverless environment');
123
+ updateConfig({
124
+ build: {
125
+ client: new URL(`./.amplify-hosting/static${config.base}`, config.root),
126
+ server: new URL('./.amplify-hosting/compute/default/', config.root),
127
+ },
128
+ session: {
129
+ driver: 'amplify-astro-adapter/session',
130
+ },
131
+ });
132
+ }
133
+ else {
134
+ updateConfig({
135
+ build: {
136
+ client: new URL(`./.amplify-hosting/static${config.base}`, config.root),
137
+ server: new URL('./.amplify-hosting/compute/default/', config.root),
138
+ },
139
+ });
140
+ }
141
+ },
142
+ 'astro:config:done': ({ config, setAdapter }) => {
143
+ setAdapter({
144
+ name: 'amplify-astro-adapter',
145
+ serverEntrypoint: 'amplify-astro-adapter/server',
146
+ supportedAstroFeatures: {
147
+ serverOutput: 'stable',
148
+ hybridOutput: 'stable',
149
+ staticOutput: 'stable',
150
+ sharpImageService: 'stable',
151
+ envGetSecret: 'stable',
152
+ },
153
+ args: {
154
+ mode: 'standalone',
155
+ client: config.build.client?.toString(),
156
+ server: config.build.server?.toString(),
157
+ host: config.server.host,
158
+ port: 3000,
159
+ assets: config.build.assets,
160
+ experimentalStaticHeaders: false,
161
+ },
162
+ });
163
+ _config = config;
164
+ },
165
+ 'astro:build:done': async () => {
166
+ const deployManifestConfig = {
167
+ version: 1,
168
+ routes: [
169
+ {
170
+ path: `${_config.base}assets/*`,
171
+ target: {
172
+ kind: 'Static',
173
+ },
174
+ },
175
+ {
176
+ path: `${_config.base}*.*`,
177
+ target: {
178
+ kind: 'Static',
179
+ },
180
+ fallback: {
181
+ kind: 'Compute',
182
+ src: 'default',
183
+ },
184
+ },
185
+ {
186
+ path: '/*',
187
+ target: {
188
+ kind: 'Compute',
189
+ src: 'default',
190
+ },
191
+ },
192
+ ],
193
+ computeResources: [
194
+ {
195
+ name: 'default',
196
+ entrypoint: 'entry.mjs',
197
+ runtime,
198
+ },
199
+ ],
200
+ framework: {
201
+ name: 'astro',
202
+ version: '4.0.0',
203
+ },
204
+ };
205
+ const functionsConfigPath = join(fileURLToPath(_config.root), '/.amplify-hosting/deploy-manifest.json');
206
+ await writeFile(functionsConfigPath, JSON.stringify(deployManifestConfig));
207
+ },
208
+ },
209
+ };
210
+ }
211
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,5 @@
1
+ import type http from 'node:http';
2
+ import https from 'node:https';
3
+ import type { AstroIntegrationLogger } from 'astro';
4
+ export declare function logListeningOn(logger: AstroIntegrationLogger, server: http.Server | https.Server, configuredHost: string | boolean | undefined): Promise<void>;
5
+ //# sourceMappingURL=log-listening-on.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"log-listening-on.d.ts","sourceRoot":"","sources":["../src/log-listening-on.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,IAAI,MAAM,WAAW,CAAC;AAClC,OAAO,KAAK,MAAM,YAAY,CAAC;AAG/B,OAAO,KAAK,EAAE,sBAAsB,EAAE,MAAM,OAAO,CAAC;AAIpD,wBAAsB,cAAc,CAClC,MAAM,EAAE,sBAAsB,EAC9B,MAAM,EAAE,IAAI,CAAC,MAAM,GAAG,KAAK,CAAC,MAAM,EAClC,cAAc,EAAE,MAAM,GAAG,OAAO,GAAG,SAAS,iBAe7C"}
@@ -0,0 +1,55 @@
1
+ import https from 'node:https';
2
+ import os from 'node:os';
3
+ const wildcardHosts = new Set(['0.0.0.0', '::', '0000:0000:0000:0000:0000:0000:0000:0000']);
4
+ export async function logListeningOn(logger, server, configuredHost) {
5
+ await new Promise((resolve) => server.once('listening', resolve));
6
+ const protocol = server instanceof https.Server ? 'https' : 'http';
7
+ const host = getResolvedHostForHttpServer(configuredHost);
8
+ const { port } = server.address();
9
+ const address = getNetworkAddress(protocol, host, port);
10
+ if (host === undefined || wildcardHosts.has(host)) {
11
+ logger.info(`Server listening on \n local: ${address.local[0]} \t\n network: ${address.network[0]}\n`);
12
+ }
13
+ else {
14
+ logger.info(`Server listening on ${address.local[0]}`);
15
+ }
16
+ }
17
+ function getResolvedHostForHttpServer(host) {
18
+ if (host === false) {
19
+ return 'localhost';
20
+ }
21
+ else if (host === true) {
22
+ return undefined;
23
+ }
24
+ else {
25
+ return host;
26
+ }
27
+ }
28
+ function getNetworkAddress(protocol = 'http', hostname, port, base) {
29
+ const NetworkAddress = {
30
+ local: [],
31
+ network: [],
32
+ };
33
+ Object.values(os.networkInterfaces())
34
+ .flatMap((nInterface) => nInterface ?? [])
35
+ .filter((detail) => detail &&
36
+ detail.address &&
37
+ (detail.family === 'IPv4' ||
38
+ // @ts-expect-error Node 18.0 - 18.3 returns number
39
+ detail.family === 4))
40
+ .forEach((detail) => {
41
+ let host = detail.address.replace('127.0.0.1', hostname === undefined || wildcardHosts.has(hostname) ? 'localhost' : hostname);
42
+ if (host.includes(':')) {
43
+ host = `[${host}]`;
44
+ }
45
+ const url = `${protocol}://${host}:${port}${base ? base : ''}`;
46
+ if (detail.address.includes('127.0.0.1')) {
47
+ NetworkAddress.local.push(url);
48
+ }
49
+ else {
50
+ NetworkAddress.network.push(url);
51
+ }
52
+ });
53
+ return NetworkAddress;
54
+ }
55
+ //# sourceMappingURL=log-listening-on.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"log-listening-on.js","sourceRoot":"","sources":["../src/log-listening-on.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,19 @@
1
+ import type { MiddlewareHandler } from 'astro';
2
+ /**
3
+ * Middleware that handles cookie-based session storage.
4
+ *
5
+ * Flow:
6
+ * 1. BEFORE next(): Load existing session data from cookie into sessionStore
7
+ * - If dirty in-memory data exists without cookie, mark for deferred sync
8
+ * 2. During request: Astro's session system uses our driver (reads/writes sessionStore)
9
+ * 3. AFTER next(): Write dirty session data from sessionStore back to cookie
10
+ *
11
+ * Deferred Cookie Sync (handles 302 redirect race condition):
12
+ * - POST /api/login -> sets session, returns 302, persist() writes to sessionStore
13
+ * - GET / -> BEFORE detects dirty entry + no cookie -> needsCookieSync=true
14
+ * - Page renders (driver reads from sessionStore)
15
+ * - AFTER phase injects cookie into response
16
+ * - Future requests have the cookie
17
+ */
18
+ export declare const onRequest: MiddlewareHandler;
19
+ //# sourceMappingURL=middleware.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"middleware.d.ts","sourceRoot":"","sources":["../src/middleware.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,OAAO,CAAC;AAK/C;;;;;;;;;;;;;;;GAeG;AACH,eAAO,MAAM,SAAS,EAAE,iBAyFvB,CAAC"}
@@ -0,0 +1,98 @@
1
+ import { sessionStore, getDriverConfig } from './session-driver.js';
2
+ const SESSION_DATA_COOKIE = 'astro-session-data';
3
+ /**
4
+ * Middleware that handles cookie-based session storage.
5
+ *
6
+ * Flow:
7
+ * 1. BEFORE next(): Load existing session data from cookie into sessionStore
8
+ * - If dirty in-memory data exists without cookie, mark for deferred sync
9
+ * 2. During request: Astro's session system uses our driver (reads/writes sessionStore)
10
+ * 3. AFTER next(): Write dirty session data from sessionStore back to cookie
11
+ *
12
+ * Deferred Cookie Sync (handles 302 redirect race condition):
13
+ * - POST /api/login -> sets session, returns 302, persist() writes to sessionStore
14
+ * - GET / -> BEFORE detects dirty entry + no cookie -> needsCookieSync=true
15
+ * - Page renders (driver reads from sessionStore)
16
+ * - AFTER phase injects cookie into response
17
+ * - Future requests have the cookie
18
+ */
19
+ export const onRequest = async (context, next) => {
20
+ // BEFORE: Load existing session data from cookie into sessionStore
21
+ const sessionId = context.cookies.get('astro-session')?.value;
22
+ const existingDataCookie = context.cookies.get(SESSION_DATA_COOKIE)?.value;
23
+ let needsCookieSync = false;
24
+ if (sessionId) {
25
+ let inMemoryEntry = sessionStore.get(sessionId);
26
+ // If we have a sessionId but no cookie and no in-memory entry,
27
+ // the persist() from a previous request might still be running.
28
+ // Wait briefly for it to complete (up to 50ms).
29
+ if (!inMemoryEntry && !existingDataCookie) {
30
+ for (let i = 0; i < 5 && !inMemoryEntry; i++) {
31
+ await new Promise((resolve) => setTimeout(resolve, 10));
32
+ inMemoryEntry = sessionStore.get(sessionId);
33
+ }
34
+ }
35
+ if (inMemoryEntry?.dirty && !existingDataCookie) {
36
+ // We have in-memory data that wasn't written to cookie yet
37
+ // This is the deferred cookie sync case (happens after redirect)
38
+ needsCookieSync = true;
39
+ }
40
+ else if (!inMemoryEntry && existingDataCookie) {
41
+ // No in-memory data, but cookie exists - load from cookie
42
+ sessionStore.set(sessionId, {
43
+ data: existingDataCookie,
44
+ dirty: false,
45
+ timestamp: Date.now(),
46
+ });
47
+ }
48
+ }
49
+ // Run the request - session.persist() happens during this via Astro's finally block
50
+ const response = await next();
51
+ // AFTER: Write dirty session data back to cookie
52
+ // Check for session ID again - it may have been created during the request
53
+ const finalSessionId = context.cookies.get('astro-session')?.value;
54
+ if (finalSessionId) {
55
+ const entry = sessionStore.get(finalSessionId);
56
+ // Write cookie if:
57
+ // 1. Entry is dirty (new/modified session data from this request), OR
58
+ // 2. We detected deferred sync needed in BEFORE phase
59
+ const shouldWriteCookie = entry?.dirty || (needsCookieSync && sessionId === finalSessionId);
60
+ if (shouldWriteCookie && entry) {
61
+ const config = getDriverConfig();
62
+ const ttl = config?.ttl ?? 604800;
63
+ const cookieOptions = config?.cookieOptions;
64
+ if (entry.data) {
65
+ // Auto-detect secure from protocol
66
+ const isSecure = context.request.url.startsWith('https://');
67
+ // Determine domain: undefined for localhost, .domain.com for production
68
+ let domain = cookieOptions?.domain;
69
+ if (domain === undefined) {
70
+ const url = new URL(context.request.url);
71
+ const isLocalhost = url.hostname === 'localhost' || url.hostname === '127.0.0.1';
72
+ domain = isLocalhost ? undefined : `.${url.hostname}`;
73
+ }
74
+ // Set the session data cookie
75
+ context.cookies.set(SESSION_DATA_COOKIE, entry.data, {
76
+ httpOnly: cookieOptions?.httpOnly ?? true,
77
+ secure: cookieOptions?.secure ?? isSecure,
78
+ sameSite: cookieOptions?.sameSite ?? 'lax',
79
+ path: cookieOptions?.path ?? '/',
80
+ domain,
81
+ maxAge: ttl,
82
+ });
83
+ // Mark as clean after writing cookie
84
+ sessionStore.set(finalSessionId, { ...entry, dirty: false, timestamp: Date.now() });
85
+ }
86
+ else {
87
+ // Empty data means destroy - delete cookie AND sessionStore entry
88
+ context.cookies.delete(SESSION_DATA_COOKIE, {
89
+ path: cookieOptions?.path ?? '/',
90
+ domain: cookieOptions?.domain,
91
+ });
92
+ sessionStore.delete(finalSessionId);
93
+ }
94
+ }
95
+ }
96
+ return response;
97
+ };
98
+ //# sourceMappingURL=middleware.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"middleware.js","sourceRoot":"","sources":["../src/middleware.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,12 @@
1
+ import type { NodeApp } from 'astro/app/node';
2
+ import type { Options, RequestHandler } from './types.js';
3
+ /**
4
+ * Creates a middleware that can be used with Express, Connect, etc.
5
+ *
6
+ * Similar to `createAppHandler` but can additionally be placed in the express
7
+ * chain as an error middleware.
8
+ *
9
+ * https://expressjs.com/en/guide/using-middleware.html#middleware.error-handling
10
+ */
11
+ export default function createMiddleware(app: NodeApp, options: Options): RequestHandler;
12
+ //# sourceMappingURL=node-middleware.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"node-middleware.d.ts","sourceRoot":"","sources":["../src/node-middleware.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,gBAAgB,CAAC;AAE9C,OAAO,KAAK,EAAE,OAAO,EAAE,cAAc,EAAE,MAAM,YAAY,CAAC;AAE1D;;;;;;;GAOG;AACH,MAAM,CAAC,OAAO,UAAU,gBAAgB,CAAC,GAAG,EAAE,OAAO,EAAE,OAAO,EAAE,OAAO,GAAG,cAAc,CA4BvF"}
@@ -0,0 +1,41 @@
1
+ import { createAppHandler } from './serve-app.js';
2
+ /**
3
+ * Creates a middleware that can be used with Express, Connect, etc.
4
+ *
5
+ * Similar to `createAppHandler` but can additionally be placed in the express
6
+ * chain as an error middleware.
7
+ *
8
+ * https://expressjs.com/en/guide/using-middleware.html#middleware.error-handling
9
+ */
10
+ export default function createMiddleware(app, options) {
11
+ const handler = createAppHandler(app, options);
12
+ const logger = app.getAdapterLogger();
13
+ // using spread args because express trips up if the function's
14
+ // stringified body includes req, res, next, locals directly
15
+ return async (...args) => {
16
+ // assume normal invocation at first
17
+ const [req, res, next, locals] = args;
18
+ // short circuit if it is an error invocation
19
+ if (req instanceof Error) {
20
+ const error = req;
21
+ if (next) {
22
+ return next(error);
23
+ }
24
+ else {
25
+ throw error;
26
+ }
27
+ }
28
+ try {
29
+ await handler(req, res, next, locals);
30
+ }
31
+ catch (err) {
32
+ logger.error(`Could not render ${req.url}`);
33
+ console.error(err);
34
+ if (!res.headersSent) {
35
+ res.writeHead(500, `Server error`);
36
+ res.end();
37
+ }
38
+ }
39
+ };
40
+ }
41
+ //# sourceMappingURL=node-middleware.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"node-middleware.js","sourceRoot":"","sources":["../src/node-middleware.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,gBAAgB,EAAE,MAAM,gBAAgB,CAAC;AAGlD;;;;;;;GAOG;AACH,MAAM,CAAC,OAAO,UAAU,gBAAgB,CAAC,GAAY,EAAE,OAAgB;IACrE,MAAM,OAAO,GAAG,gBAAgB,CAAC,GAAG,EAAE,OAAO,CAAC,CAAC;IAC/C,MAAM,MAAM,GAAG,GAAG,CAAC,gBAAgB,EAAE,CAAC;IACtC,+DAA+D;IAC/D,4DAA4D;IAC5D,OAAO,KAAK,EAAE,GAAG,IAAI,EAAE,EAAE;QACvB,oCAAoC;QACpC,MAAM,CAAC,GAAG,EAAE,GAAG,EAAE,IAAI,EAAE,MAAM,CAAC,GAAG,IAAI,CAAC;QACtC,6CAA6C;QAC7C,IAAI,GAAG,YAAY,KAAK,EAAE,CAAC;YACzB,MAAM,KAAK,GAAG,GAAG,CAAC;YAClB,IAAI,IAAI,EAAE,CAAC;gBACT,OAAO,IAAI,CAAC,KAAK,CAAC,CAAC;YACrB,CAAC;iBAAM,CAAC;gBACN,MAAM,KAAK,CAAC;YACd,CAAC;QACH,CAAC;QACD,IAAI,CAAC;YACH,MAAM,OAAO,CAAC,GAAG,EAAE,GAAG,EAAE,IAAI,EAAE,MAAM,CAAC,CAAC;QACxC,CAAC;QAAC,OAAO,GAAG,EAAE,CAAC;YACb,MAAM,CAAC,KAAK,CAAC,oBAAoB,GAAG,CAAC,GAAG,EAAE,CAAC,CAAC;YAC5C,OAAO,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC;YACnB,IAAI,CAAC,GAAG,CAAC,WAAW,EAAE,CAAC;gBACrB,GAAG,CAAC,SAAS,CAAC,GAAG,EAAE,cAAc,CAAC,CAAC;gBACnC,GAAG,CAAC,GAAG,EAAE,CAAC;YACZ,CAAC;QACH,CAAC;IACH,CAAC,CAAC;AACJ,CAAC"}
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=polyfill.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"polyfill.d.ts","sourceRoot":"","sources":["../src/polyfill.ts"],"names":[],"mappings":""}
@@ -0,0 +1,3 @@
1
+ import { applyPolyfills } from 'astro/app/node';
2
+ applyPolyfills();
3
+ //# sourceMappingURL=polyfill.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"polyfill.js","sourceRoot":"","sources":["../src/polyfill.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,cAAc,EAAE,MAAM,gBAAgB,CAAC;AAChD,cAAc,EAAE,CAAC"}
@@ -0,0 +1,9 @@
1
+ import { NodeApp } from 'astro/app/node';
2
+ import type { Options, RequestHandler } from './types.js';
3
+ /**
4
+ * Create a request handler for the Astro app.
5
+ * Session cookie handling is primarily done by middleware.
6
+ * This handler provides a fallback for direct responses (e.g., API routes with redirects).
7
+ */
8
+ export declare function createAppHandler(app: NodeApp, options: Options): RequestHandler;
9
+ //# sourceMappingURL=serve-app.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"serve-app.d.ts","sourceRoot":"","sources":["../src/serve-app.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,OAAO,EAAE,MAAM,gBAAgB,CAAC;AACzC,OAAO,KAAK,EAAE,OAAO,EAAE,cAAc,EAAE,MAAM,YAAY,CAAC;AAK1D;;;;GAIG;AACH,wBAAgB,gBAAgB,CAAC,GAAG,EAAE,OAAO,EAAE,OAAO,EAAE,OAAO,GAAG,cAAc,CAiE/E"}
@@ -0,0 +1,123 @@
1
+ import { AsyncLocalStorage } from 'node:async_hooks';
2
+ import { NodeApp } from 'astro/app/node';
3
+ import { sessionStore, getDriverConfig } from './session-driver.js';
4
+ /**
5
+ * Create a request handler for the Astro app.
6
+ * Session cookie handling is primarily done by middleware.
7
+ * This handler provides a fallback for direct responses (e.g., API routes with redirects).
8
+ */
9
+ export function createAppHandler(app, options) {
10
+ const als = new AsyncLocalStorage();
11
+ const logger = app.getAdapterLogger();
12
+ process.on('unhandledRejection', (reason) => {
13
+ const requestUrl = als.getStore();
14
+ logger.error(`Unhandled rejection while rendering ${requestUrl}`);
15
+ console.error(reason);
16
+ });
17
+ const originUrl = options.experimentalErrorPageHost
18
+ ? new URL(options.experimentalErrorPageHost)
19
+ : undefined;
20
+ const prerenderedErrorPageFetch = originUrl
21
+ ? (url) => {
22
+ const errorPageUrl = new URL(url);
23
+ errorPageUrl.protocol = originUrl.protocol;
24
+ errorPageUrl.host = originUrl.host;
25
+ return fetch(errorPageUrl);
26
+ }
27
+ : undefined;
28
+ return async (req, res, next, locals) => {
29
+ let request;
30
+ try {
31
+ request = NodeApp.createRequest(req, {
32
+ allowedDomains: app.getAllowedDomains?.() ?? [],
33
+ });
34
+ }
35
+ catch (err) {
36
+ logger.error(`Could not render ${req.url}`);
37
+ console.error(err);
38
+ res.statusCode = 500;
39
+ res.end('Internal Server Error');
40
+ return;
41
+ }
42
+ const routeData = app.match(request, true);
43
+ if (routeData) {
44
+ // Run render with URL tracking for error reporting
45
+ const response = await als.run(request.url, () => app.render(request, {
46
+ addCookieHeader: true,
47
+ locals,
48
+ routeData,
49
+ prerenderedErrorPageFetch,
50
+ }));
51
+ const finalResponse = await injectSessionCookieIfNeeded(request, response);
52
+ await NodeApp.writeResponse(finalResponse, res);
53
+ }
54
+ else if (next) {
55
+ return next();
56
+ }
57
+ else {
58
+ // Unmatched route
59
+ const response = await app.render(request, {
60
+ addCookieHeader: true,
61
+ prerenderedErrorPageFetch,
62
+ });
63
+ const finalResponse = await injectSessionCookieIfNeeded(request, response);
64
+ await NodeApp.writeResponse(finalResponse, res);
65
+ }
66
+ };
67
+ }
68
+ /**
69
+ * Inject session data cookie into response if needed.
70
+ * Waits for one microtask tick to allow Astro's session.persist() to complete,
71
+ * then checks if session data needs to be written to cookie.
72
+ * If not available yet, middleware will handle it on the next request
73
+ * via deferred cookie sync.
74
+ */
75
+ async function injectSessionCookieIfNeeded(request, response) {
76
+ const setCookieHeaders = response.headers.getSetCookie?.() ?? [];
77
+ let sessionId = null;
78
+ for (const cookie of setCookieHeaders) {
79
+ const match = cookie.match(/^astro-session=([^;]+)/);
80
+ if (match) {
81
+ sessionId = match[1];
82
+ break;
83
+ }
84
+ }
85
+ if (!sessionId) {
86
+ return response;
87
+ }
88
+ // Wait for next event loop tick to allow Astro's session.persist() to complete
89
+ // persist() runs in a finally block after render completes
90
+ await new Promise((resolve) => setImmediate(resolve));
91
+ const entry = sessionStore.get(sessionId);
92
+ // Only inject if we have dirty data ready
93
+ if (!entry?.dirty || !entry.data) {
94
+ return response;
95
+ }
96
+ const config = getDriverConfig();
97
+ const ttl = config?.ttl ?? 604800;
98
+ const cookieOptions = config?.cookieOptions;
99
+ const url = new URL(request.url);
100
+ const isLocalhost = url.hostname === 'localhost' || url.hostname === '127.0.0.1';
101
+ const isSecure = request.url.startsWith('https://');
102
+ const cookieParts = [
103
+ `astro-session-data=${entry.data}`,
104
+ `Path=${cookieOptions?.path ?? '/'}`,
105
+ `Max-Age=${ttl}`,
106
+ cookieOptions?.httpOnly !== false ? 'HttpOnly' : '',
107
+ (cookieOptions?.secure ?? isSecure) ? 'Secure' : '',
108
+ `SameSite=${cookieOptions?.sameSite ?? 'Lax'}`,
109
+ !isLocalhost && cookieOptions?.domain ? `Domain=${cookieOptions.domain}` : '',
110
+ ]
111
+ .filter(Boolean)
112
+ .join('; ');
113
+ const newHeaders = new Headers(response.headers);
114
+ newHeaders.append('Set-Cookie', cookieParts);
115
+ // Mark as clean after writing cookie
116
+ sessionStore.set(sessionId, { ...entry, dirty: false, timestamp: Date.now() });
117
+ return new Response(response.body, {
118
+ status: response.status,
119
+ statusText: response.statusText,
120
+ headers: newHeaders,
121
+ });
122
+ }
123
+ //# sourceMappingURL=serve-app.js.map