@ripple-ts/adapter-vercel 0.2.214 → 0.2.216
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/CHANGELOG.md +16 -0
- package/package.json +3 -3
- package/src/adapt.js +28 -32
- package/tests/adapt.test.js +35 -19
- package/tsconfig.json +8 -0
- package/types/index.d.ts +6 -0
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,21 @@
|
|
|
1
1
|
# @ripple-ts/adapter-vercel
|
|
2
2
|
|
|
3
|
+
## 0.2.216
|
|
4
|
+
|
|
5
|
+
### Patch Changes
|
|
6
|
+
|
|
7
|
+
- Updated dependencies []:
|
|
8
|
+
- @ripple-ts/adapter@0.2.216
|
|
9
|
+
- @ripple-ts/adapter-node@0.2.216
|
|
10
|
+
|
|
11
|
+
## 0.2.215
|
|
12
|
+
|
|
13
|
+
### Patch Changes
|
|
14
|
+
|
|
15
|
+
- Updated dependencies []:
|
|
16
|
+
- @ripple-ts/adapter@0.2.215
|
|
17
|
+
- @ripple-ts/adapter-node@0.2.215
|
|
18
|
+
|
|
3
19
|
## 0.2.214
|
|
4
20
|
|
|
5
21
|
### Patch Changes
|
package/package.json
CHANGED
|
@@ -3,7 +3,7 @@
|
|
|
3
3
|
"description": "Vercel adapter for Ripple metaframework (Build Output API v3)",
|
|
4
4
|
"license": "MIT",
|
|
5
5
|
"author": "Dominic Gannaway",
|
|
6
|
-
"version": "0.2.
|
|
6
|
+
"version": "0.2.216",
|
|
7
7
|
"type": "module",
|
|
8
8
|
"module": "src/index.js",
|
|
9
9
|
"main": "src/index.js",
|
|
@@ -19,8 +19,8 @@
|
|
|
19
19
|
},
|
|
20
20
|
"dependencies": {
|
|
21
21
|
"@vercel/nft": "^1.0.0",
|
|
22
|
-
"@ripple-ts/adapter": "0.2.
|
|
23
|
-
"@ripple-ts/adapter-node": "0.2.
|
|
22
|
+
"@ripple-ts/adapter": "0.2.216",
|
|
23
|
+
"@ripple-ts/adapter-node": "0.2.216"
|
|
24
24
|
},
|
|
25
25
|
"homepage": "https://ripple-ts.com",
|
|
26
26
|
"repository": {
|
package/src/adapt.js
CHANGED
|
@@ -161,10 +161,11 @@ async function trace_and_copy_dependencies(entry, func_dir, project_root) {
|
|
|
161
161
|
/**
|
|
162
162
|
* Generate the serverless function handler source code.
|
|
163
163
|
*
|
|
164
|
-
* Vercel's
|
|
165
|
-
*
|
|
166
|
-
*
|
|
167
|
-
*
|
|
164
|
+
* Uses Vercel's native Web Standard API: the handler receives a Web Request
|
|
165
|
+
* and returns a Web Response. No Node.js (req, res) conversion needed.
|
|
166
|
+
*
|
|
167
|
+
* Same-origin fetch short-circuiting is handled at the framework level
|
|
168
|
+
* by patch_global_fetch in @ripple-ts/adapter.
|
|
168
169
|
*
|
|
169
170
|
* @param {string} server_entry_relative - Relative path from the function dir to
|
|
170
171
|
* the server entry file
|
|
@@ -175,26 +176,19 @@ function generate_handler_source(server_entry_relative) {
|
|
|
175
176
|
// Auto-generated by @ripple-ts/adapter-vercel
|
|
176
177
|
// Vercel Serverless Function handler for Ripple
|
|
177
178
|
//
|
|
178
|
-
//
|
|
179
|
-
// fetch-
|
|
179
|
+
// Uses Vercel's native Web Standard API (Request => Response).
|
|
180
|
+
// Same-origin fetch short-circuiting is handled at the framework level.
|
|
180
181
|
import { handler } from ${JSON.stringify(server_entry_relative)};
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
const response = await handler(request);
|
|
190
|
-
webResponseToNodeResponse(response, res, req.method ?? 'GET');
|
|
191
|
-
} catch (err) {
|
|
192
|
-
console.error('[ripple] Serverless handler error:', err);
|
|
193
|
-
if (!res.headersSent) {
|
|
194
|
-
res.statusCode = 500;
|
|
195
|
-
res.end('Internal Server Error');
|
|
182
|
+
|
|
183
|
+
export default {
|
|
184
|
+
async fetch(request) {
|
|
185
|
+
try {
|
|
186
|
+
return await handler(request);
|
|
187
|
+
} catch (err) {
|
|
188
|
+
console.error('[ripple] Serverless handler error:', err);
|
|
189
|
+
return new Response('Internal Server Error', { status: 500 });
|
|
196
190
|
}
|
|
197
|
-
}
|
|
191
|
+
},
|
|
198
192
|
};
|
|
199
193
|
`;
|
|
200
194
|
}
|
|
@@ -305,7 +299,9 @@ function generate_vercel_config(options) {
|
|
|
305
299
|
* @returns {Promise<void>}
|
|
306
300
|
*/
|
|
307
301
|
export async function adapt(options = {}) {
|
|
308
|
-
const { outDir = 'dist', serverless = {}, isr = false } = options;
|
|
302
|
+
const { outDir = 'dist', serverless = {}, isr = false, verbose = true } = options;
|
|
303
|
+
|
|
304
|
+
const log = verbose ? console.log.bind(console) : () => {};
|
|
309
305
|
|
|
310
306
|
const project_root = process.cwd();
|
|
311
307
|
const build_dir = resolve(project_root, outDir);
|
|
@@ -336,7 +332,7 @@ export async function adapt(options = {}) {
|
|
|
336
332
|
// Clean and create output directory
|
|
337
333
|
// ------------------------------------------------------------------
|
|
338
334
|
|
|
339
|
-
|
|
335
|
+
log('[adapter-vercel] Generating Vercel Build Output...');
|
|
340
336
|
|
|
341
337
|
rmSync(output_dir, { recursive: true, force: true });
|
|
342
338
|
mkdirSync(output_dir, { recursive: true });
|
|
@@ -347,7 +343,7 @@ export async function adapt(options = {}) {
|
|
|
347
343
|
|
|
348
344
|
const static_dir = join(output_dir, 'static');
|
|
349
345
|
|
|
350
|
-
|
|
346
|
+
log('[adapter-vercel] Copying static assets...');
|
|
351
347
|
copy_dir(client_dir, static_dir);
|
|
352
348
|
|
|
353
349
|
// Remove index.html from static output — SSR handles the root route.
|
|
@@ -365,7 +361,7 @@ export async function adapt(options = {}) {
|
|
|
365
361
|
const func_dir = join(output_dir, 'functions', 'index.func');
|
|
366
362
|
mkdirSync(func_dir, { recursive: true });
|
|
367
363
|
|
|
368
|
-
|
|
364
|
+
log('[adapter-vercel] Tracing server dependencies...');
|
|
369
365
|
|
|
370
366
|
// Trace and copy all dependencies of the server entry.
|
|
371
367
|
// The trace result tells us the project-relative path where the entry
|
|
@@ -426,7 +422,7 @@ export async function adapt(options = {}) {
|
|
|
426
422
|
|
|
427
423
|
vc_config.prerender = prerender;
|
|
428
424
|
|
|
429
|
-
|
|
425
|
+
log(
|
|
430
426
|
`[adapter-vercel] ISR enabled (expiration: ${isr.expiration === false ? 'never' : isr.expiration + 's'})`,
|
|
431
427
|
);
|
|
432
428
|
}
|
|
@@ -437,7 +433,7 @@ export async function adapt(options = {}) {
|
|
|
437
433
|
// 3. Generate the Build Output API config
|
|
438
434
|
// ------------------------------------------------------------------
|
|
439
435
|
|
|
440
|
-
|
|
436
|
+
log('[adapter-vercel] Writing config...');
|
|
441
437
|
|
|
442
438
|
const vercel_config = generate_vercel_config(options);
|
|
443
439
|
write(join(output_dir, 'config.json'), JSON.stringify(vercel_config, null, '\t'));
|
|
@@ -446,8 +442,8 @@ export async function adapt(options = {}) {
|
|
|
446
442
|
// Summary
|
|
447
443
|
// ------------------------------------------------------------------
|
|
448
444
|
|
|
449
|
-
|
|
450
|
-
|
|
451
|
-
|
|
452
|
-
|
|
445
|
+
log('[adapter-vercel] Build output generated at .vercel/output/');
|
|
446
|
+
log(` Static: ${static_dir}`);
|
|
447
|
+
log(` Function: ${func_dir}`);
|
|
448
|
+
log(` Runtime: ${runtime}`);
|
|
453
449
|
}
|
package/tests/adapt.test.js
CHANGED
|
@@ -72,7 +72,7 @@ describe('adapt()', () => {
|
|
|
72
72
|
const { adapt } = await import('../src/adapt.js');
|
|
73
73
|
create_build_output(tmp_dir);
|
|
74
74
|
|
|
75
|
-
await adapt();
|
|
75
|
+
await adapt({ verbose: false });
|
|
76
76
|
|
|
77
77
|
const output_dir = join(tmp_dir, '.vercel', 'output');
|
|
78
78
|
|
|
@@ -97,7 +97,7 @@ describe('adapt()', () => {
|
|
|
97
97
|
const { adapt } = await import('../src/adapt.js');
|
|
98
98
|
create_build_output(tmp_dir);
|
|
99
99
|
|
|
100
|
-
await adapt();
|
|
100
|
+
await adapt({ verbose: false });
|
|
101
101
|
|
|
102
102
|
const config = JSON.parse(
|
|
103
103
|
readFileSync(join(tmp_dir, '.vercel', 'output', 'config.json'), 'utf-8'),
|
|
@@ -128,7 +128,7 @@ describe('adapt()', () => {
|
|
|
128
128
|
const { adapt } = await import('../src/adapt.js');
|
|
129
129
|
create_build_output(tmp_dir);
|
|
130
130
|
|
|
131
|
-
await adapt();
|
|
131
|
+
await adapt({ verbose: false });
|
|
132
132
|
|
|
133
133
|
const vc_config = JSON.parse(
|
|
134
134
|
readFileSync(
|
|
@@ -149,7 +149,7 @@ describe('adapt()', () => {
|
|
|
149
149
|
const { adapt } = await import('../src/adapt.js');
|
|
150
150
|
create_build_output(tmp_dir);
|
|
151
151
|
|
|
152
|
-
await adapt();
|
|
152
|
+
await adapt({ verbose: false });
|
|
153
153
|
|
|
154
154
|
const pkg = JSON.parse(
|
|
155
155
|
readFileSync(
|
|
@@ -161,27 +161,36 @@ describe('adapt()', () => {
|
|
|
161
161
|
expect(pkg.type).toBe('module');
|
|
162
162
|
});
|
|
163
163
|
|
|
164
|
-
it('generates
|
|
164
|
+
it('generates Web Standard handler using Vercel native fetch API', async () => {
|
|
165
165
|
const { adapt } = await import('../src/adapt.js');
|
|
166
166
|
create_build_output(tmp_dir);
|
|
167
167
|
|
|
168
|
-
await adapt();
|
|
168
|
+
await adapt({ verbose: false });
|
|
169
169
|
|
|
170
170
|
const handler_source = readFileSync(
|
|
171
171
|
join(tmp_dir, '.vercel', 'output', 'functions', 'index.func', 'index.js'),
|
|
172
172
|
'utf-8',
|
|
173
173
|
);
|
|
174
174
|
|
|
175
|
+
// Uses static import (not dynamic await import)
|
|
175
176
|
expect(handler_source).toContain('import { handler }');
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
);
|
|
179
|
-
expect(handler_source).toContain('
|
|
180
|
-
expect(handler_source).toContain('
|
|
181
|
-
|
|
177
|
+
|
|
178
|
+
// Uses Vercel's native Web Standard export format
|
|
179
|
+
expect(handler_source).toContain('export default');
|
|
180
|
+
expect(handler_source).toContain('async fetch(request)');
|
|
181
|
+
expect(handler_source).toContain('handler(request)');
|
|
182
|
+
|
|
183
|
+
// No Node.js (req, res) bridge — no adapter-node dependency
|
|
184
|
+
expect(handler_source).not.toContain('adapter-node');
|
|
185
|
+
expect(handler_source).not.toContain('webResponseToNodeResponse');
|
|
186
|
+
expect(handler_source).not.toContain('bufferRequestBody');
|
|
187
|
+
expect(handler_source).not.toContain('(req, res)');
|
|
188
|
+
|
|
189
|
+
// No self-referential fetch hack — handled at framework level
|
|
190
|
+
expect(handler_source).not.toContain('_selfHosts');
|
|
191
|
+
expect(handler_source).not.toContain('_realFetch');
|
|
182
192
|
|
|
183
193
|
// Handler should import the server entry at its project-relative path
|
|
184
|
-
// (dist/server/entry.js), not just "entry.js"
|
|
185
194
|
expect(handler_source).toContain('dist/server/entry.js');
|
|
186
195
|
});
|
|
187
196
|
|
|
@@ -189,7 +198,7 @@ describe('adapt()', () => {
|
|
|
189
198
|
const { adapt } = await import('../src/adapt.js');
|
|
190
199
|
create_build_output(tmp_dir, { outDir: 'build' });
|
|
191
200
|
|
|
192
|
-
await adapt({ outDir: 'build' });
|
|
201
|
+
await adapt({ verbose: false, outDir: 'build' });
|
|
193
202
|
|
|
194
203
|
expect(existsSync(join(tmp_dir, '.vercel', 'output', 'config.json'))).toBe(true);
|
|
195
204
|
expect(existsSync(join(tmp_dir, '.vercel', 'output', 'functions', 'index.func'))).toBe(true);
|
|
@@ -200,6 +209,7 @@ describe('adapt()', () => {
|
|
|
200
209
|
create_build_output(tmp_dir);
|
|
201
210
|
|
|
202
211
|
await adapt({
|
|
212
|
+
verbose: false,
|
|
203
213
|
serverless: {
|
|
204
214
|
runtime: 'nodejs22.x',
|
|
205
215
|
regions: ['iad1', 'sfo1'],
|
|
@@ -226,6 +236,7 @@ describe('adapt()', () => {
|
|
|
226
236
|
create_build_output(tmp_dir);
|
|
227
237
|
|
|
228
238
|
await adapt({
|
|
239
|
+
verbose: false,
|
|
229
240
|
redirects: [{ source: '/old', destination: '/new', permanent: true }],
|
|
230
241
|
});
|
|
231
242
|
|
|
@@ -246,6 +257,7 @@ describe('adapt()', () => {
|
|
|
246
257
|
create_build_output(tmp_dir);
|
|
247
258
|
|
|
248
259
|
await adapt({
|
|
260
|
+
verbose: false,
|
|
249
261
|
headers: [
|
|
250
262
|
{
|
|
251
263
|
source: '/(.*)',
|
|
@@ -270,6 +282,7 @@ describe('adapt()', () => {
|
|
|
270
282
|
create_build_output(tmp_dir);
|
|
271
283
|
|
|
272
284
|
await adapt({
|
|
285
|
+
verbose: false,
|
|
273
286
|
images: {
|
|
274
287
|
sizes: [640, 1080, 1920],
|
|
275
288
|
domains: ['example.com'],
|
|
@@ -297,7 +310,7 @@ describe('adapt()', () => {
|
|
|
297
310
|
mkdirSync(stale_dir, { recursive: true });
|
|
298
311
|
writeFileSync(join(stale_dir, 'old-file.txt'), 'stale');
|
|
299
312
|
|
|
300
|
-
await adapt();
|
|
313
|
+
await adapt({ verbose: false });
|
|
301
314
|
|
|
302
315
|
// Stale file should be gone
|
|
303
316
|
expect(existsSync(join(stale_dir, 'old-file.txt'))).toBe(false);
|
|
@@ -309,7 +322,7 @@ describe('adapt()', () => {
|
|
|
309
322
|
const { adapt } = await import('../src/adapt.js');
|
|
310
323
|
create_build_output(tmp_dir);
|
|
311
324
|
|
|
312
|
-
await adapt({ trailingSlash: true });
|
|
325
|
+
await adapt({ verbose: false, trailingSlash: true });
|
|
313
326
|
|
|
314
327
|
const config = JSON.parse(
|
|
315
328
|
readFileSync(join(tmp_dir, '.vercel', 'output', 'config.json'), 'utf-8'),
|
|
@@ -322,7 +335,7 @@ describe('adapt()', () => {
|
|
|
322
335
|
const { adapt } = await import('../src/adapt.js');
|
|
323
336
|
create_build_output(tmp_dir);
|
|
324
337
|
|
|
325
|
-
await adapt({ cleanUrls: false });
|
|
338
|
+
await adapt({ verbose: false, cleanUrls: false });
|
|
326
339
|
|
|
327
340
|
const config = JSON.parse(
|
|
328
341
|
readFileSync(join(tmp_dir, '.vercel', 'output', 'config.json'), 'utf-8'),
|
|
@@ -340,6 +353,7 @@ describe('adapt()', () => {
|
|
|
340
353
|
create_build_output(tmp_dir);
|
|
341
354
|
|
|
342
355
|
await adapt({
|
|
356
|
+
verbose: false,
|
|
343
357
|
isr: {
|
|
344
358
|
expiration: 60,
|
|
345
359
|
},
|
|
@@ -361,6 +375,7 @@ describe('adapt()', () => {
|
|
|
361
375
|
create_build_output(tmp_dir);
|
|
362
376
|
|
|
363
377
|
await adapt({
|
|
378
|
+
verbose: false,
|
|
364
379
|
isr: {
|
|
365
380
|
expiration: false,
|
|
366
381
|
},
|
|
@@ -382,6 +397,7 @@ describe('adapt()', () => {
|
|
|
382
397
|
create_build_output(tmp_dir);
|
|
383
398
|
|
|
384
399
|
await adapt({
|
|
400
|
+
verbose: false,
|
|
385
401
|
isr: {
|
|
386
402
|
expiration: 300,
|
|
387
403
|
bypassToken: 'my-secret-token',
|
|
@@ -405,7 +421,7 @@ describe('adapt()', () => {
|
|
|
405
421
|
const { adapt } = await import('../src/adapt.js');
|
|
406
422
|
create_build_output(tmp_dir);
|
|
407
423
|
|
|
408
|
-
await adapt({ isr: false });
|
|
424
|
+
await adapt({ verbose: false, isr: false });
|
|
409
425
|
|
|
410
426
|
const vc_config = JSON.parse(
|
|
411
427
|
readFileSync(
|
|
@@ -421,7 +437,7 @@ describe('adapt()', () => {
|
|
|
421
437
|
const { adapt } = await import('../src/adapt.js');
|
|
422
438
|
create_build_output(tmp_dir);
|
|
423
439
|
|
|
424
|
-
await adapt();
|
|
440
|
+
await adapt({ verbose: false });
|
|
425
441
|
|
|
426
442
|
const vc_config = JSON.parse(
|
|
427
443
|
readFileSync(
|
package/tsconfig.json
ADDED
package/types/index.d.ts
CHANGED