@vercel/node 3.0.5 → 3.0.6

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.
@@ -1,96 +1,1187 @@
1
- const entrypoint = process.env.VERCEL_DEV_ENTRYPOINT;
2
- delete process.env.VERCEL_DEV_ENTRYPOINT;
3
- if (!entrypoint) {
4
- throw new Error('`VERCEL_DEV_ENTRYPOINT` must be defined');
5
- }
6
- import { join } from 'path';
7
- import { createEdgeEventHandler } from './edge-functions/edge-handler.mjs';
8
- import { createServer } from 'http';
9
- import { createServerlessEventHandler } from './serverless-functions/serverless-handler.mjs';
10
- import { isEdgeRuntime, logError, validateConfiguredRuntime } from './utils.js';
11
- import { toToReadable } from '@edge-runtime/node-utils';
12
- import { getConfig } from '@vercel/static-config';
13
- import { Project } from 'ts-morph';
14
- import { listen } from 'async-listen';
15
- const parseConfig = (entryPointPath) => getConfig(new Project(), entryPointPath);
16
- async function createEventHandler(entrypoint, config, options) {
17
- const entrypointPath = join(process.cwd(), entrypoint);
18
- const staticConfig = parseConfig(entrypointPath);
19
- const runtime = staticConfig?.runtime;
20
- validateConfiguredRuntime(runtime, entrypoint);
21
- // `middleware.js`/`middleware.ts` file is always run as
22
- // an Edge Function, otherwise needs to be opted-in via
23
- // `export const config = { runtime: 'edge' }`
24
- if (config.middleware === true || isEdgeRuntime(runtime)) {
25
- return createEdgeEventHandler(entrypointPath, entrypoint, config.middleware || false, config.zeroConfig);
26
- }
27
- return createServerlessEventHandler(entrypointPath, {
28
- mode: staticConfig?.supportsResponseStreaming ? 'streaming' : 'buffer',
29
- shouldAddHelpers: options.shouldAddHelpers,
30
- });
1
+ var __create = Object.create;
2
+ var __defProp = Object.defineProperty;
3
+ var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
4
+ var __getOwnPropNames = Object.getOwnPropertyNames;
5
+ var __getProtoOf = Object.getPrototypeOf;
6
+ var __hasOwnProp = Object.prototype.hasOwnProperty;
7
+ var __esm = (fn, res) => function __init() {
8
+ return fn && (res = (0, fn[__getOwnPropNames(fn)[0]])(fn = 0)), res;
9
+ };
10
+ var __commonJS = (cb, mod) => function __require() {
11
+ return mod || (0, cb[__getOwnPropNames(cb)[0]])((mod = { exports: {} }).exports, mod), mod.exports;
12
+ };
13
+ var __export = (target, all) => {
14
+ for (var name in all)
15
+ __defProp(target, name, { get: all[name], enumerable: true });
16
+ };
17
+ var __copyProps = (to, from, except, desc) => {
18
+ if (from && typeof from === "object" || typeof from === "function") {
19
+ for (let key of __getOwnPropNames(from))
20
+ if (!__hasOwnProp.call(to, key) && key !== except)
21
+ __defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
22
+ }
23
+ return to;
24
+ };
25
+ var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__getProtoOf(mod)) : {}, __copyProps(
26
+ // If the importer is in node compatibility mode or this is not an ESM
27
+ // file that has been converted to a CommonJS file using a Babel-
28
+ // compatible transform (i.e. "__esModule" has not been set), then set
29
+ // "default" to the CommonJS "module.exports" for node compatibility.
30
+ isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", { value: mod, enumerable: true }) : target,
31
+ mod
32
+ ));
33
+
34
+ // ../../node_modules/.pnpm/content-type@1.0.5/node_modules/content-type/index.js
35
+ var require_content_type = __commonJS({
36
+ "../../node_modules/.pnpm/content-type@1.0.5/node_modules/content-type/index.js"(exports) {
37
+ "use strict";
38
+ var PARAM_REGEXP = /; *([!#$%&'*+.^_`|~0-9A-Za-z-]+) *= *("(?:[\u000b\u0020\u0021\u0023-\u005b\u005d-\u007e\u0080-\u00ff]|\\[\u000b\u0020-\u00ff])*"|[!#$%&'*+.^_`|~0-9A-Za-z-]+) */g;
39
+ var TEXT_REGEXP = /^[\u000b\u0020-\u007e\u0080-\u00ff]+$/;
40
+ var TOKEN_REGEXP = /^[!#$%&'*+.^_`|~0-9A-Za-z-]+$/;
41
+ var QESC_REGEXP = /\\([\u000b\u0020-\u00ff])/g;
42
+ var QUOTE_REGEXP = /([\\"])/g;
43
+ var TYPE_REGEXP = /^[!#$%&'*+.^_`|~0-9A-Za-z-]+\/[!#$%&'*+.^_`|~0-9A-Za-z-]+$/;
44
+ exports.format = format;
45
+ exports.parse = parse;
46
+ function format(obj) {
47
+ if (!obj || typeof obj !== "object") {
48
+ throw new TypeError("argument obj is required");
49
+ }
50
+ var parameters = obj.parameters;
51
+ var type = obj.type;
52
+ if (!type || !TYPE_REGEXP.test(type)) {
53
+ throw new TypeError("invalid type");
54
+ }
55
+ var string = type;
56
+ if (parameters && typeof parameters === "object") {
57
+ var param;
58
+ var params = Object.keys(parameters).sort();
59
+ for (var i = 0; i < params.length; i++) {
60
+ param = params[i];
61
+ if (!TOKEN_REGEXP.test(param)) {
62
+ throw new TypeError("invalid parameter name");
63
+ }
64
+ string += "; " + param + "=" + qstring(parameters[param]);
65
+ }
66
+ }
67
+ return string;
68
+ }
69
+ function parse(string) {
70
+ if (!string) {
71
+ throw new TypeError("argument string is required");
72
+ }
73
+ var header = typeof string === "object" ? getcontenttype(string) : string;
74
+ if (typeof header !== "string") {
75
+ throw new TypeError("argument string is required to be a string");
76
+ }
77
+ var index = header.indexOf(";");
78
+ var type = index !== -1 ? header.slice(0, index).trim() : header.trim();
79
+ if (!TYPE_REGEXP.test(type)) {
80
+ throw new TypeError("invalid media type");
81
+ }
82
+ var obj = new ContentType(type.toLowerCase());
83
+ if (index !== -1) {
84
+ var key;
85
+ var match;
86
+ var value;
87
+ PARAM_REGEXP.lastIndex = index;
88
+ while (match = PARAM_REGEXP.exec(header)) {
89
+ if (match.index !== index) {
90
+ throw new TypeError("invalid parameter format");
91
+ }
92
+ index += match[0].length;
93
+ key = match[1].toLowerCase();
94
+ value = match[2];
95
+ if (value.charCodeAt(0) === 34) {
96
+ value = value.slice(1, -1);
97
+ if (value.indexOf("\\") !== -1) {
98
+ value = value.replace(QESC_REGEXP, "$1");
99
+ }
100
+ }
101
+ obj.parameters[key] = value;
102
+ }
103
+ if (index !== header.length) {
104
+ throw new TypeError("invalid parameter format");
105
+ }
106
+ }
107
+ return obj;
108
+ }
109
+ function getcontenttype(obj) {
110
+ var header;
111
+ if (typeof obj.getHeader === "function") {
112
+ header = obj.getHeader("content-type");
113
+ } else if (typeof obj.headers === "object") {
114
+ header = obj.headers && obj.headers["content-type"];
115
+ }
116
+ if (typeof header !== "string") {
117
+ throw new TypeError("content-type header is missing from object");
118
+ }
119
+ return header;
120
+ }
121
+ function qstring(val) {
122
+ var str = String(val);
123
+ if (TOKEN_REGEXP.test(str)) {
124
+ return str;
125
+ }
126
+ if (str.length > 0 && !TEXT_REGEXP.test(str)) {
127
+ throw new TypeError("invalid parameter value");
128
+ }
129
+ return '"' + str.replace(QUOTE_REGEXP, "\\$1") + '"';
130
+ }
131
+ function ContentType(type) {
132
+ this.parameters = /* @__PURE__ */ Object.create(null);
133
+ this.type = type;
134
+ }
135
+ }
136
+ });
137
+
138
+ // ../../node_modules/.pnpm/cookie@0.4.0/node_modules/cookie/index.js
139
+ var require_cookie = __commonJS({
140
+ "../../node_modules/.pnpm/cookie@0.4.0/node_modules/cookie/index.js"(exports) {
141
+ "use strict";
142
+ exports.parse = parse;
143
+ exports.serialize = serialize;
144
+ var decode = decodeURIComponent;
145
+ var encode = encodeURIComponent;
146
+ var pairSplitRegExp = /; */;
147
+ var fieldContentRegExp = /^[\u0009\u0020-\u007e\u0080-\u00ff]+$/;
148
+ function parse(str, options) {
149
+ if (typeof str !== "string") {
150
+ throw new TypeError("argument str must be a string");
151
+ }
152
+ var obj = {};
153
+ var opt = options || {};
154
+ var pairs = str.split(pairSplitRegExp);
155
+ var dec = opt.decode || decode;
156
+ for (var i = 0; i < pairs.length; i++) {
157
+ var pair = pairs[i];
158
+ var eq_idx = pair.indexOf("=");
159
+ if (eq_idx < 0) {
160
+ continue;
161
+ }
162
+ var key = pair.substr(0, eq_idx).trim();
163
+ var val = pair.substr(++eq_idx, pair.length).trim();
164
+ if ('"' == val[0]) {
165
+ val = val.slice(1, -1);
166
+ }
167
+ if (void 0 == obj[key]) {
168
+ obj[key] = tryDecode(val, dec);
169
+ }
170
+ }
171
+ return obj;
172
+ }
173
+ function serialize(name, val, options) {
174
+ var opt = options || {};
175
+ var enc = opt.encode || encode;
176
+ if (typeof enc !== "function") {
177
+ throw new TypeError("option encode is invalid");
178
+ }
179
+ if (!fieldContentRegExp.test(name)) {
180
+ throw new TypeError("argument name is invalid");
181
+ }
182
+ var value = enc(val);
183
+ if (value && !fieldContentRegExp.test(value)) {
184
+ throw new TypeError("argument val is invalid");
185
+ }
186
+ var str = name + "=" + value;
187
+ if (null != opt.maxAge) {
188
+ var maxAge = opt.maxAge - 0;
189
+ if (isNaN(maxAge))
190
+ throw new Error("maxAge should be a Number");
191
+ str += "; Max-Age=" + Math.floor(maxAge);
192
+ }
193
+ if (opt.domain) {
194
+ if (!fieldContentRegExp.test(opt.domain)) {
195
+ throw new TypeError("option domain is invalid");
196
+ }
197
+ str += "; Domain=" + opt.domain;
198
+ }
199
+ if (opt.path) {
200
+ if (!fieldContentRegExp.test(opt.path)) {
201
+ throw new TypeError("option path is invalid");
202
+ }
203
+ str += "; Path=" + opt.path;
204
+ }
205
+ if (opt.expires) {
206
+ if (typeof opt.expires.toUTCString !== "function") {
207
+ throw new TypeError("option expires is invalid");
208
+ }
209
+ str += "; Expires=" + opt.expires.toUTCString();
210
+ }
211
+ if (opt.httpOnly) {
212
+ str += "; HttpOnly";
213
+ }
214
+ if (opt.secure) {
215
+ str += "; Secure";
216
+ }
217
+ if (opt.sameSite) {
218
+ var sameSite = typeof opt.sameSite === "string" ? opt.sameSite.toLowerCase() : opt.sameSite;
219
+ switch (sameSite) {
220
+ case true:
221
+ str += "; SameSite=Strict";
222
+ break;
223
+ case "lax":
224
+ str += "; SameSite=Lax";
225
+ break;
226
+ case "strict":
227
+ str += "; SameSite=Strict";
228
+ break;
229
+ case "none":
230
+ str += "; SameSite=None";
231
+ break;
232
+ default:
233
+ throw new TypeError("option sameSite is invalid");
234
+ }
235
+ }
236
+ return str;
237
+ }
238
+ function tryDecode(str, decode2) {
239
+ try {
240
+ return decode2(str);
241
+ } catch (e) {
242
+ return str;
243
+ }
244
+ }
245
+ }
246
+ });
247
+
248
+ // src/serverless-functions/helpers-web.ts
249
+ var helpers_web_exports = {};
250
+ __export(helpers_web_exports, {
251
+ getWebExportsHandler: () => getWebExportsHandler
252
+ });
253
+ import { buildToNodeHandler } from "@edge-runtime/node-utils";
254
+ function getWebExportsHandler(listener, methods) {
255
+ const handlerByMethod = {};
256
+ for (const key of methods) {
257
+ handlerByMethod[key] = typeof listener[key] !== "undefined" ? webHandlerToNodeHandler(listener[key]) : defaultHttpHandler;
258
+ }
259
+ return (req, res) => {
260
+ const method = req.method ?? "GET";
261
+ handlerByMethod[method](req, res);
262
+ };
31
263
  }
32
- let handleEvent;
33
- let handlerEventError;
34
- async function main() {
35
- const config = JSON.parse(process.env.VERCEL_DEV_CONFIG || '{}');
36
- delete process.env.VERCEL_DEV_CONFIG;
37
- const buildEnv = JSON.parse(process.env.VERCEL_DEV_BUILD_ENV || '{}');
38
- delete process.env.VERCEL_DEV_BUILD_ENV;
39
- const shouldAddHelpers = !(config.helpers === false || buildEnv.NODEJS_HELPERS === '0');
40
- const proxyServer = createServer(onDevRequest);
41
- await listen(proxyServer, { host: '127.0.0.1', port: 0 });
42
- try {
43
- handleEvent = await createEventHandler(entrypoint, config, {
44
- shouldAddHelpers,
264
+ function addDuplexToInit(init) {
265
+ if (typeof init === "undefined" || typeof init === "object") {
266
+ return { duplex: "half", ...init };
267
+ }
268
+ return init;
269
+ }
270
+ function defaultHttpHandler(_, res) {
271
+ res.statusCode = 405;
272
+ res.end();
273
+ }
274
+ var FetchEvent, webHandlerToNodeHandler;
275
+ var init_helpers_web = __esm({
276
+ "src/serverless-functions/helpers-web.ts"() {
277
+ "use strict";
278
+ FetchEvent = class {
279
+ constructor(request) {
280
+ this.request = request;
281
+ this.response = null;
282
+ this.awaiting = /* @__PURE__ */ new Set();
283
+ }
284
+ respondWith(response) {
285
+ this.response = response;
286
+ }
287
+ waitUntil() {
288
+ throw new Error("waitUntil is not implemented yet for Node.js");
289
+ }
290
+ };
291
+ webHandlerToNodeHandler = buildToNodeHandler(
292
+ {
293
+ Headers,
294
+ ReadableStream,
295
+ // @ts-expect-error Property 'duplex' is missing in type 'Request'
296
+ Request: class extends Request {
297
+ constructor(input, init) {
298
+ super(input, addDuplexToInit(init));
299
+ }
300
+ },
301
+ Uint8Array,
302
+ FetchEvent
303
+ },
304
+ { defaultOrigin: "https://vercel.com" }
305
+ );
306
+ }
307
+ });
308
+
309
+ // src/dev-server.mts
310
+ import { join } from "path";
311
+
312
+ // src/edge-functions/edge-wasm-plugin.mts
313
+ import { createHash } from "crypto";
314
+ import { promises as fs } from "fs";
315
+ var WasmAssets = class {
316
+ constructor() {
317
+ this.assets = /* @__PURE__ */ new Map();
318
+ }
319
+ /**
320
+ * Declare a WebAssembly binding
321
+ */
322
+ async declare(filePath) {
323
+ const hash = sha1(await fs.readFile(filePath));
324
+ const name = `wasm_${hash}`;
325
+ this.assets.set(name, filePath);
326
+ return name;
327
+ }
328
+ /**
329
+ * Get an object with the context needed to execute the code
330
+ * built with the plugin
331
+ */
332
+ async getContext() {
333
+ const promises = [];
334
+ const context = {};
335
+ for (const [name, filePath] of this.assets) {
336
+ promises.push(
337
+ (async () => {
338
+ const bytes = await fs.readFile(filePath);
339
+ context[name] = await WebAssembly.compile(bytes);
340
+ })()
341
+ );
342
+ }
343
+ await Promise.all(promises);
344
+ return context;
345
+ }
346
+ /**
347
+ * Allow to iterate easily
348
+ */
349
+ [Symbol.iterator]() {
350
+ return this.assets[Symbol.iterator]();
351
+ }
352
+ };
353
+ function createEdgeWasmPlugin() {
354
+ const wasmAssets = new WasmAssets();
355
+ const plugin = {
356
+ name: "vercel-wasm",
357
+ setup(b) {
358
+ b.onResolve({ filter: /\.wasm\?module/i }, async (data) => {
359
+ const wasmFile = data.path.replace(/\?module$/, "");
360
+ const resolvedPath = await b.resolve(wasmFile, {
361
+ importer: data.importer,
362
+ resolveDir: data.resolveDir
45
363
  });
364
+ if (!resolvedPath.path) {
365
+ return {
366
+ errors: [
367
+ { text: `WebAssembly file could not be located: ${wasmFile}` }
368
+ ]
369
+ };
370
+ }
371
+ const name = await wasmAssets.declare(resolvedPath.path);
372
+ return {
373
+ path: name,
374
+ namespace: "vercel-wasm"
375
+ };
376
+ });
377
+ b.onLoad({ namespace: "vercel-wasm", filter: /.+/ }, (args) => {
378
+ return {
379
+ loader: "js",
380
+ contents: `export default globalThis[${JSON.stringify(args.path)}]`
381
+ };
382
+ });
46
383
  }
47
- catch (error) {
48
- logError(error);
49
- handlerEventError = error;
384
+ };
385
+ return { plugin, wasmAssets };
386
+ }
387
+ function sha1(data) {
388
+ return createHash("sha1").update(data).digest("hex");
389
+ }
390
+
391
+ // src/edge-functions/edge-node-compat-plugin.mts
392
+ import BufferImplementation from "buffer";
393
+ import EventsImplementation from "events";
394
+ import AsyncHooksImplementation from "async_hooks";
395
+ import AssertImplementation from "assert";
396
+ import UtilImplementation from "util";
397
+ var SUPPORTED_NODE_MODULES = [
398
+ "buffer",
399
+ "events",
400
+ "assert",
401
+ "util",
402
+ "async_hooks"
403
+ ];
404
+ var getSupportedNodeModuleRegex = () => new RegExp(`^(?:node:)?(?:${SUPPORTED_NODE_MODULES.join("|")})$`);
405
+ function pick(obj, keys) {
406
+ const res = {};
407
+ for (const key of keys) {
408
+ res[key] = obj[key];
409
+ }
410
+ return res;
411
+ }
412
+ var NativeModuleMap = () => {
413
+ const mods = {
414
+ buffer: pick(BufferImplementation, [
415
+ "constants",
416
+ "kMaxLength",
417
+ "kStringMaxLength",
418
+ "Buffer",
419
+ "SlowBuffer"
420
+ ]),
421
+ events: pick(EventsImplementation, [
422
+ "EventEmitter",
423
+ "captureRejectionSymbol",
424
+ "defaultMaxListeners",
425
+ "errorMonitor",
426
+ "listenerCount",
427
+ "on",
428
+ "once"
429
+ ]),
430
+ async_hooks: pick(AsyncHooksImplementation, [
431
+ "AsyncLocalStorage",
432
+ "AsyncResource"
433
+ ]),
434
+ assert: pick(AssertImplementation, [
435
+ "AssertionError",
436
+ "deepEqual",
437
+ "deepStrictEqual",
438
+ "doesNotMatch",
439
+ "doesNotReject",
440
+ "doesNotThrow",
441
+ "equal",
442
+ "fail",
443
+ "ifError",
444
+ "match",
445
+ "notDeepEqual",
446
+ "notDeepStrictEqual",
447
+ "notEqual",
448
+ "notStrictEqual",
449
+ "ok",
450
+ "rejects",
451
+ "strict",
452
+ "strictEqual",
453
+ "throws"
454
+ ]),
455
+ util: pick(UtilImplementation, [
456
+ "_extend",
457
+ "callbackify",
458
+ "format",
459
+ "inherits",
460
+ "promisify",
461
+ "types"
462
+ ])
463
+ };
464
+ return new Map(Object.entries(mods));
465
+ };
466
+ var NODE_COMPAT_NAMESPACE = "vercel-node-compat";
467
+ var NodeCompatBindings = class {
468
+ constructor() {
469
+ this.bindings = /* @__PURE__ */ new Map();
470
+ }
471
+ use(modulePath) {
472
+ const stripped = modulePath.replace(/^node:/, "");
473
+ const name = `__vc_node_${stripped}__`;
474
+ if (!this.bindings.has(modulePath)) {
475
+ const value = NativeModuleMap().get(stripped);
476
+ if (value === void 0) {
477
+ throw new Error(`Could not find module ${modulePath}`);
478
+ }
479
+ this.bindings.set(modulePath, {
480
+ modulePath,
481
+ name,
482
+ value
483
+ });
50
484
  }
51
- const address = proxyServer.address();
52
- if (typeof process.send === 'function') {
53
- process.send(address);
485
+ return name;
486
+ }
487
+ getContext() {
488
+ const context = {};
489
+ for (const binding of this.bindings.values()) {
490
+ context[binding.name] = binding.value;
54
491
  }
55
- else {
56
- console.log('Dev server listening:', address);
492
+ return context;
493
+ }
494
+ };
495
+ function createNodeCompatPlugin() {
496
+ const bindings = new NodeCompatBindings();
497
+ const plugin = {
498
+ name: "vc-node-compat",
499
+ setup(b) {
500
+ b.onResolve({ filter: getSupportedNodeModuleRegex() }, async (args) => {
501
+ const importee = args.path.replace("node:", "");
502
+ if (!SUPPORTED_NODE_MODULES.includes(importee)) {
503
+ return;
504
+ }
505
+ return {
506
+ namespace: NODE_COMPAT_NAMESPACE,
507
+ path: args.path
508
+ };
509
+ });
510
+ b.onLoad(
511
+ { filter: /.+/, namespace: NODE_COMPAT_NAMESPACE },
512
+ async (args) => {
513
+ const fullName = args.path.startsWith("node:") ? args.path : `node:${args.path}`;
514
+ const globalName = bindings.use(fullName);
515
+ return {
516
+ contents: `module.exports = ${globalName};`,
517
+ loader: "js"
518
+ };
519
+ }
520
+ );
57
521
  }
522
+ };
523
+ return {
524
+ plugin,
525
+ bindings
526
+ };
58
527
  }
59
- async function onDevRequest(req, res) {
60
- if (handlerEventError) {
61
- // this error state is already logged, but we have to wait until here to exit the process
62
- // this matches the serverless function bridge launcher's behavior when
63
- // an error is thrown in the function
64
- process.exit(1);
528
+
529
+ // src/edge-functions/edge-handler.mts
530
+ import { EdgeRuntime, runServer } from "edge-runtime";
531
+ import { fetch, Headers as Headers2 } from "undici";
532
+ import { isError } from "@vercel/error-utils";
533
+ import { readFileSync } from "fs";
534
+
535
+ // src/utils.ts
536
+ import { debug, streamToBuffer } from "@vercel/build-utils";
537
+ import { pathToRegexp } from "path-to-regexp";
538
+ import { extname } from "path";
539
+ function entrypointToOutputPath(entrypoint2, zeroConfig) {
540
+ if (zeroConfig) {
541
+ const ext = extname(entrypoint2);
542
+ return entrypoint2.slice(0, entrypoint2.length - ext.length);
543
+ }
544
+ return entrypoint2;
545
+ }
546
+ function logError(error) {
547
+ let message = error.message;
548
+ if (!message.startsWith("Error:")) {
549
+ message = `Error: ${message}`;
550
+ }
551
+ console.error(message);
552
+ if (error.stack) {
553
+ const errorPrefixLength = "Error: ".length;
554
+ const errorMessageLength = errorPrefixLength + error.message.length;
555
+ debug(error.stack.substring(errorMessageLength + 1));
556
+ }
557
+ }
558
+ var EdgeRuntimes = /* @__PURE__ */ ((EdgeRuntimes2) => {
559
+ EdgeRuntimes2["Edge"] = "edge";
560
+ EdgeRuntimes2["ExperimentalEdge"] = "experimental-edge";
561
+ return EdgeRuntimes2;
562
+ })(EdgeRuntimes || {});
563
+ function isEdgeRuntime(runtime) {
564
+ return runtime !== void 0 && Object.values(EdgeRuntimes).includes(runtime);
565
+ }
566
+ var ALLOWED_RUNTIMES = Object.values(EdgeRuntimes);
567
+ function validateConfiguredRuntime(runtime, entrypoint2) {
568
+ if (runtime) {
569
+ if (runtime === "nodejs") {
570
+ throw new Error(
571
+ `${entrypoint2}: \`config.runtime: "nodejs"\` semantics will evolve soon. Please remove the \`runtime\` key to keep the existing behavior.`
572
+ );
65
573
  }
66
- if (!handleEvent) {
67
- res.statusCode = 500;
68
- res.end('Bridge is not ready, please try again');
69
- return;
574
+ if (!ALLOWED_RUNTIMES.includes(runtime)) {
575
+ throw new Error(
576
+ `${entrypoint2}: unsupported "runtime" value in \`config\`: ${JSON.stringify(
577
+ runtime
578
+ )} (must be one of: ${JSON.stringify(
579
+ ALLOWED_RUNTIMES
580
+ )}). Learn more: https://vercel.link/creating-edge-functions`
581
+ );
70
582
  }
71
- try {
72
- const { headers, body, status } = await handleEvent(req);
73
- res.statusCode = status;
74
- for (const [key, value] of headers) {
75
- if (value !== undefined)
76
- res.setHeader(key, key === 'set-cookie' ? headers.getSetCookie() : value);
77
- }
78
- if (body === null) {
79
- res.end();
583
+ }
584
+ }
585
+ async function serializeBody(request) {
586
+ return request.method !== "GET" && request.method !== "HEAD" ? await streamToBuffer(request) : void 0;
587
+ }
588
+
589
+ // src/edge-functions/edge-handler.mts
590
+ import esbuild from "esbuild";
591
+ import exitHook from "exit-hook";
592
+ import { fileURLToPath } from "url";
593
+ var NODE_VERSION_MAJOR = process.version.match(/^v(\d+)\.\d+/)?.[1];
594
+ var NODE_VERSION_IDENTIFIER = `node${NODE_VERSION_MAJOR}`;
595
+ if (!NODE_VERSION_MAJOR) {
596
+ throw new Error(
597
+ `Unable to determine current node version: process.version=${process.version}`
598
+ );
599
+ }
600
+ var __dirname = fileURLToPath(new URL(".", import.meta.url));
601
+ var edgeHandlerTemplate = readFileSync(
602
+ `${__dirname}/edge-handler-template.js`
603
+ );
604
+ async function compileUserCode(entrypointFullPath, entrypointRelativePath, isMiddleware) {
605
+ const { wasmAssets, plugin: edgeWasmPlugin } = createEdgeWasmPlugin();
606
+ const nodeCompatPlugin = createNodeCompatPlugin();
607
+ try {
608
+ const result = await esbuild.build({
609
+ // bundling behavior: use globals (like "browser") instead
610
+ // of "require" statements for core libraries (like "node")
611
+ platform: "browser",
612
+ conditions: ["edge-light", "development"],
613
+ // target syntax: only use syntax available on the current
614
+ // version of node
615
+ target: NODE_VERSION_IDENTIFIER,
616
+ sourcemap: "inline",
617
+ legalComments: "none",
618
+ bundle: true,
619
+ plugins: [
620
+ edgeWasmPlugin,
621
+ nodeCompatPlugin.plugin,
622
+ {
623
+ name: "import.meta.url",
624
+ setup({ onLoad }) {
625
+ onLoad({ filter: /\.[cm]?js$/, namespace: "file" }, (args) => {
626
+ let code = readFileSync(args.path, "utf8");
627
+ code = code.replace(
628
+ /\bimport\.meta\.url\b/g,
629
+ JSON.stringify(import.meta.url)
630
+ );
631
+ return { contents: code };
632
+ });
633
+ }
80
634
  }
81
- else if (body instanceof Buffer) {
82
- res.end(body);
635
+ ],
636
+ entryPoints: [entrypointFullPath],
637
+ write: false,
638
+ // operate in memory
639
+ format: "cjs"
640
+ });
641
+ const compiledFile = result.outputFiles?.[0];
642
+ if (!compiledFile) {
643
+ throw new Error(
644
+ `Compilation of ${entrypointRelativePath} produced no output files.`
645
+ );
646
+ }
647
+ const userCode = `
648
+ // strict mode
649
+ "use strict";var regeneratorRuntime;
650
+
651
+ // user code
652
+ (() => {
653
+ ${compiledFile.text};
654
+ })();
655
+
656
+ const userModule = module.exports;
657
+
658
+ // request metadata
659
+ const isMiddleware = ${isMiddleware};
660
+ const entrypointLabel = '${entrypointRelativePath}';
661
+
662
+ // edge handler
663
+ ${edgeHandlerTemplate};
664
+ const dependencies = { Request, Response };
665
+ const options = { isMiddleware, entrypointLabel };
666
+ registerFetchListener(userModule, options, dependencies);
667
+ `;
668
+ return {
669
+ userCode,
670
+ wasmAssets,
671
+ nodeCompatBindings: nodeCompatPlugin.bindings
672
+ };
673
+ } catch (error) {
674
+ console.error(`Failed to compile user code for edge runtime.`);
675
+ if (isError(error))
676
+ logError(error);
677
+ return void 0;
678
+ }
679
+ }
680
+ async function createEdgeRuntimeServer(params) {
681
+ try {
682
+ if (!params) {
683
+ return void 0;
684
+ }
685
+ const wasmBindings = await params.wasmAssets.getContext();
686
+ const nodeCompatBindings = params.nodeCompatBindings.getContext();
687
+ const runtime = new EdgeRuntime({
688
+ initialCode: params.userCode,
689
+ extend: (context) => {
690
+ Object.assign(context, {
691
+ // This is required for esbuild wrapping logic to resolve
692
+ module: {},
693
+ // This is required for environment variable access.
694
+ // In production, env var access is provided by static analysis
695
+ // so that only the used values are available.
696
+ process: {
697
+ env: process.env
698
+ },
699
+ // These are the global bindings for Node.js compatibility
700
+ ...nodeCompatBindings,
701
+ // These are the global bindings for WebAssembly module
702
+ ...wasmBindings
703
+ });
704
+ return context;
705
+ }
706
+ });
707
+ const server = await runServer({ runtime });
708
+ exitHook(() => server.close());
709
+ return server;
710
+ } catch (error) {
711
+ console.error("Failed to instantiate edge runtime.");
712
+ logError(error);
713
+ return void 0;
714
+ }
715
+ }
716
+ async function createEdgeEventHandler(entrypointFullPath, entrypointRelativePath, isMiddleware, isZeroConfig) {
717
+ const userCode = await compileUserCode(
718
+ entrypointFullPath,
719
+ entrypointRelativePath,
720
+ isMiddleware
721
+ );
722
+ const server = await createEdgeRuntimeServer(userCode);
723
+ return async function(request) {
724
+ if (!server) {
725
+ process.exit(1);
726
+ }
727
+ const headers = new Headers2(request.headers);
728
+ const body = await serializeBody(request);
729
+ if (body !== void 0)
730
+ headers.set("content-length", String(body.length));
731
+ const url = new URL(request.url ?? "/", server.url);
732
+ const response = await fetch(url, {
733
+ body,
734
+ headers,
735
+ method: request.method,
736
+ redirect: "manual"
737
+ });
738
+ const isUserError = response.headers.get("x-vercel-failed") === "edge-wrapper";
739
+ if (isUserError && response.status >= 500) {
740
+ const body2 = await response.text();
741
+ const fakeStackTrace = ` at (${entrypointRelativePath})`;
742
+ const requestPath = entrypointToRequestPath(
743
+ entrypointRelativePath,
744
+ isZeroConfig
745
+ );
746
+ console.log(
747
+ `Error from API Route ${requestPath}: ${body2}
748
+ ${fakeStackTrace}`
749
+ );
750
+ process.exit(1);
751
+ }
752
+ return {
753
+ status: response.status,
754
+ headers: response.headers,
755
+ body: response.body,
756
+ encoding: "utf8"
757
+ };
758
+ };
759
+ }
760
+ function entrypointToRequestPath(entrypointRelativePath, isZeroConfig) {
761
+ return "/" + entrypointToOutputPath(entrypointRelativePath, isZeroConfig);
762
+ }
763
+
764
+ // src/dev-server.mts
765
+ import { createServer as createServer2 } from "http";
766
+
767
+ // src/serverless-functions/helpers.ts
768
+ var import_content_type = __toESM(require_content_type());
769
+ import { PassThrough } from "stream";
770
+ import { parse as parseURL } from "url";
771
+ import { parse as parseQS } from "querystring";
772
+ import etag from "etag";
773
+ var ApiError = class extends Error {
774
+ constructor(statusCode, message) {
775
+ super(message);
776
+ this.statusCode = statusCode;
777
+ }
778
+ };
779
+ function normalizeContentType(contentType) {
780
+ if (!contentType) {
781
+ return "text/plain";
782
+ }
783
+ const { type } = (0, import_content_type.parse)(contentType);
784
+ return type;
785
+ }
786
+ function getBodyParser(body, contentType) {
787
+ return function parseBody() {
788
+ const type = normalizeContentType(contentType);
789
+ if (type === "application/json") {
790
+ try {
791
+ const str = body.toString();
792
+ return str ? JSON.parse(str) : {};
793
+ } catch (error) {
794
+ throw new ApiError(400, "Invalid JSON");
795
+ }
796
+ }
797
+ if (type === "application/octet-stream")
798
+ return body;
799
+ if (type === "application/x-www-form-urlencoded") {
800
+ return parseQS(body.toString());
801
+ }
802
+ if (type === "text/plain")
803
+ return body.toString();
804
+ return void 0;
805
+ };
806
+ }
807
+ function getQueryParser({ url = "/" }) {
808
+ return function parseQuery() {
809
+ return parseURL(url, true).query;
810
+ };
811
+ }
812
+ function getCookieParser(req) {
813
+ return function parseCookie() {
814
+ const header = req.headers.cookie;
815
+ if (!header)
816
+ return {};
817
+ const { parse } = require_cookie();
818
+ return parse(Array.isArray(header) ? header.join(";") : header);
819
+ };
820
+ }
821
+ function status(res, statusCode) {
822
+ res.statusCode = statusCode;
823
+ return res;
824
+ }
825
+ function setCharset(type, charset) {
826
+ const { parse, format } = require_content_type();
827
+ const parsed = parse(type);
828
+ parsed.parameters.charset = charset;
829
+ return format(parsed);
830
+ }
831
+ function redirect(res, statusOrUrl, url) {
832
+ if (typeof statusOrUrl === "string") {
833
+ url = statusOrUrl;
834
+ statusOrUrl = 307;
835
+ }
836
+ if (typeof statusOrUrl !== "number" || typeof url !== "string") {
837
+ throw new Error(
838
+ `Invalid redirect arguments. Please use a single argument URL, e.g. res.redirect('/destination') or use a status code and URL, e.g. res.redirect(307, '/destination').`
839
+ );
840
+ }
841
+ res.writeHead(statusOrUrl, { Location: url }).end();
842
+ return res;
843
+ }
844
+ function setLazyProp(req, prop, getter) {
845
+ const opts = { configurable: true, enumerable: true };
846
+ const optsReset = { ...opts, writable: true };
847
+ Object.defineProperty(req, prop, {
848
+ ...opts,
849
+ get: () => {
850
+ const value = getter();
851
+ Object.defineProperty(req, prop, { ...optsReset, value });
852
+ return value;
853
+ },
854
+ set: (value) => {
855
+ Object.defineProperty(req, prop, { ...optsReset, value });
856
+ }
857
+ });
858
+ }
859
+ function createETag(body, encoding) {
860
+ const buf = !Buffer.isBuffer(body) ? Buffer.from(body, encoding) : body;
861
+ return etag(buf, { weak: true });
862
+ }
863
+ function json(req, res, jsonBody) {
864
+ const body = JSON.stringify(jsonBody);
865
+ if (!res.getHeader("content-type")) {
866
+ res.setHeader("content-type", "application/json; charset=utf-8");
867
+ }
868
+ return send(req, res, body);
869
+ }
870
+ function send(req, res, body) {
871
+ let chunk = body;
872
+ let encoding;
873
+ switch (typeof chunk) {
874
+ case "string":
875
+ if (!res.getHeader("content-type")) {
876
+ res.setHeader("content-type", "text/html");
877
+ }
878
+ break;
879
+ case "boolean":
880
+ case "number":
881
+ case "object":
882
+ if (chunk === null) {
883
+ chunk = "";
884
+ } else if (Buffer.isBuffer(chunk)) {
885
+ if (!res.getHeader("content-type")) {
886
+ res.setHeader("content-type", "application/octet-stream");
83
887
  }
84
- else {
85
- toToReadable(body).pipe(res);
888
+ } else {
889
+ return json(req, res, chunk);
890
+ }
891
+ break;
892
+ }
893
+ if (typeof chunk === "string") {
894
+ encoding = "utf8";
895
+ const type = res.getHeader("content-type");
896
+ if (typeof type === "string") {
897
+ res.setHeader("content-type", setCharset(type, "utf-8"));
898
+ }
899
+ }
900
+ let len;
901
+ if (chunk !== void 0) {
902
+ if (Buffer.isBuffer(chunk)) {
903
+ len = chunk.length;
904
+ } else if (typeof chunk === "string") {
905
+ if (chunk.length < 1e3) {
906
+ len = Buffer.byteLength(chunk, encoding);
907
+ } else {
908
+ const buf = Buffer.from(chunk, encoding);
909
+ len = buf.length;
910
+ chunk = buf;
911
+ encoding = void 0;
912
+ }
913
+ } else {
914
+ throw new Error(
915
+ "`body` is not a valid string, object, boolean, number, Stream, or Buffer"
916
+ );
917
+ }
918
+ if (len !== void 0) {
919
+ res.setHeader("content-length", len);
920
+ }
921
+ }
922
+ let etag2;
923
+ if (!res.getHeader("etag") && len !== void 0 && (etag2 = createETag(chunk, encoding))) {
924
+ res.setHeader("etag", etag2);
925
+ }
926
+ if (204 === res.statusCode || 304 === res.statusCode) {
927
+ res.removeHeader("Content-Type");
928
+ res.removeHeader("Content-Length");
929
+ res.removeHeader("Transfer-Encoding");
930
+ chunk = "";
931
+ }
932
+ if (req.method === "HEAD") {
933
+ res.end();
934
+ } else if (encoding) {
935
+ res.end(chunk, encoding);
936
+ } else {
937
+ res.end(chunk);
938
+ }
939
+ return res;
940
+ }
941
+ function restoreBody(req, body) {
942
+ const replicateBody = new PassThrough();
943
+ const on = replicateBody.on.bind(replicateBody);
944
+ const originalOn = req.on.bind(req);
945
+ req.read = replicateBody.read.bind(replicateBody);
946
+ req.on = req.addListener = (name, cb) => (
947
+ // @ts-expect-error
948
+ name === "data" || name === "end" ? on(name, cb) : originalOn(name, cb)
949
+ );
950
+ replicateBody.write(body);
951
+ replicateBody.end();
952
+ }
953
+ async function readBody(req) {
954
+ const body = await serializeBody(req) || Buffer.from("");
955
+ restoreBody(req, body);
956
+ return body;
957
+ }
958
+ async function addHelpers(_req, _res) {
959
+ const req = _req;
960
+ const res = _res;
961
+ setLazyProp(req, "cookies", getCookieParser(req));
962
+ setLazyProp(req, "query", getQueryParser(req));
963
+ const contentType = req.headers["content-type"];
964
+ const body = contentType === void 0 ? Buffer.from("") : await readBody(req);
965
+ setLazyProp(req, "body", getBodyParser(body, contentType));
966
+ res.status = (statusCode) => status(res, statusCode);
967
+ res.redirect = (statusOrUrl, url) => redirect(res, statusOrUrl, url);
968
+ res.send = (body2) => send(req, res, body2);
969
+ res.json = (jsonBody) => json(req, res, jsonBody);
970
+ }
971
+
972
+ // src/serverless-functions/serverless-handler.mts
973
+ import { createServer } from "http";
974
+ import exitHook2 from "exit-hook";
975
+ import { Headers as Headers3, fetch as fetch2 } from "undici";
976
+ import { listen } from "async-listen";
977
+ import { isAbsolute } from "path";
978
+ import { pathToFileURL } from "url";
979
+ import zlib from "zlib";
980
+ var [NODE_MAJOR] = process.versions.node.split(".").map((v) => Number(v));
981
+ var HTTP_METHODS = [
982
+ "GET",
983
+ "HEAD",
984
+ "OPTIONS",
985
+ "POST",
986
+ "PUT",
987
+ "DELETE",
988
+ "PATCH"
989
+ ];
990
+ function compress(body, encoding) {
991
+ switch (encoding) {
992
+ case "br":
993
+ return zlib.brotliCompressSync(body, {
994
+ params: {
995
+ [zlib.constants.BROTLI_PARAM_QUALITY]: 0
86
996
  }
997
+ });
998
+ case "gzip":
999
+ return zlib.gzipSync(body, {
1000
+ level: zlib.constants.Z_BEST_SPEED
1001
+ });
1002
+ case "deflate":
1003
+ return zlib.deflateSync(body, {
1004
+ level: zlib.constants.Z_BEST_SPEED
1005
+ });
1006
+ default:
1007
+ throw new Error(`encoding '${encoding}' not supported`);
1008
+ }
1009
+ }
1010
+ async function createServerlessServer(userCode) {
1011
+ const server = createServer(userCode);
1012
+ exitHook2(() => server.close());
1013
+ return { url: await listen(server) };
1014
+ }
1015
+ async function compileUserCode2(entrypointPath, options) {
1016
+ const id = isAbsolute(entrypointPath) ? pathToFileURL(entrypointPath).href : entrypointPath;
1017
+ let listener = await import(id);
1018
+ for (let i = 0; i < 5; i++) {
1019
+ if (listener.default)
1020
+ listener = listener.default;
1021
+ }
1022
+ if (HTTP_METHODS.some((method) => typeof listener[method] === "function")) {
1023
+ if (NODE_MAJOR < 18) {
1024
+ throw new Error(
1025
+ "Node.js v18 or above is required to use HTTP method exports in your functions."
1026
+ );
87
1027
  }
88
- catch (error) {
89
- res.statusCode = 500;
90
- res.end(error.stack);
1028
+ const { getWebExportsHandler: getWebExportsHandler2 } = await Promise.resolve().then(() => (init_helpers_web(), helpers_web_exports));
1029
+ return getWebExportsHandler2(listener, HTTP_METHODS);
1030
+ }
1031
+ return async (req, res) => {
1032
+ if (options.shouldAddHelpers)
1033
+ await addHelpers(req, res);
1034
+ return listener(req, res);
1035
+ };
1036
+ }
1037
+ async function createServerlessEventHandler(entrypointPath, options) {
1038
+ const userCode = await compileUserCode2(entrypointPath, options);
1039
+ const server = await createServerlessServer(userCode);
1040
+ const isStreaming = options.mode === "streaming";
1041
+ return async function(request) {
1042
+ const url = new URL(request.url ?? "/", server.url);
1043
+ const response = await fetch2(url, {
1044
+ body: await serializeBody(request),
1045
+ compress: !isStreaming,
1046
+ // @ts-expect-error
1047
+ headers: {
1048
+ ...request.headers,
1049
+ host: request.headers["x-forwarded-host"]
1050
+ },
1051
+ method: request.method,
1052
+ redirect: "manual"
1053
+ });
1054
+ let body = null;
1055
+ let headers = response.headers;
1056
+ if (isStreaming) {
1057
+ body = response.body;
1058
+ } else {
1059
+ body = Buffer.from(await response.arrayBuffer());
1060
+ const contentEncoding = response.headers.get("content-encoding");
1061
+ if (contentEncoding) {
1062
+ body = compress(body, contentEncoding);
1063
+ const clonedHeaders = [];
1064
+ for (const [key, value] of response.headers.entries()) {
1065
+ if (key !== "transfer-encoding") {
1066
+ clonedHeaders.push([key, value]);
1067
+ }
1068
+ }
1069
+ clonedHeaders.push(["content-length", String(Buffer.byteLength(body))]);
1070
+ headers = new Headers3(clonedHeaders);
1071
+ }
91
1072
  }
1073
+ return {
1074
+ status: response.status,
1075
+ headers,
1076
+ body,
1077
+ encoding: "utf8"
1078
+ };
1079
+ };
92
1080
  }
93
- main().catch(err => {
94
- logError(err);
1081
+
1082
+ // src/dev-server.mts
1083
+ import { toToReadable } from "@edge-runtime/node-utils";
1084
+ import { getConfig } from "@vercel/static-config";
1085
+ import { Project } from "ts-morph";
1086
+ import { listen as listen2 } from "async-listen";
1087
+ var entrypoint = process.env.VERCEL_DEV_ENTRYPOINT;
1088
+ delete process.env.VERCEL_DEV_ENTRYPOINT;
1089
+ if (!entrypoint) {
1090
+ throw new Error("`VERCEL_DEV_ENTRYPOINT` must be defined");
1091
+ }
1092
+ var parseConfig = (entryPointPath) => getConfig(new Project(), entryPointPath);
1093
+ async function createEventHandler(entrypoint2, config, options) {
1094
+ const entrypointPath = join(process.cwd(), entrypoint2);
1095
+ const staticConfig = parseConfig(entrypointPath);
1096
+ const runtime = staticConfig?.runtime;
1097
+ validateConfiguredRuntime(runtime, entrypoint2);
1098
+ if (config.middleware === true || isEdgeRuntime(runtime)) {
1099
+ return createEdgeEventHandler(
1100
+ entrypointPath,
1101
+ entrypoint2,
1102
+ config.middleware || false,
1103
+ config.zeroConfig
1104
+ );
1105
+ }
1106
+ return createServerlessEventHandler(entrypointPath, {
1107
+ mode: staticConfig?.supportsResponseStreaming ? "streaming" : "buffer",
1108
+ shouldAddHelpers: options.shouldAddHelpers
1109
+ });
1110
+ }
1111
+ var handleEvent;
1112
+ var handlerEventError;
1113
+ async function main() {
1114
+ const config = JSON.parse(process.env.VERCEL_DEV_CONFIG || "{}");
1115
+ delete process.env.VERCEL_DEV_CONFIG;
1116
+ const buildEnv = JSON.parse(process.env.VERCEL_DEV_BUILD_ENV || "{}");
1117
+ delete process.env.VERCEL_DEV_BUILD_ENV;
1118
+ const shouldAddHelpers = !(config.helpers === false || buildEnv.NODEJS_HELPERS === "0");
1119
+ const proxyServer = createServer2(onDevRequest);
1120
+ await listen2(proxyServer, { host: "127.0.0.1", port: 0 });
1121
+ try {
1122
+ handleEvent = await createEventHandler(entrypoint, config, {
1123
+ shouldAddHelpers
1124
+ });
1125
+ } catch (error) {
1126
+ logError(error);
1127
+ handlerEventError = error;
1128
+ }
1129
+ const address = proxyServer.address();
1130
+ if (typeof process.send === "function") {
1131
+ process.send(address);
1132
+ } else {
1133
+ console.log("Dev server listening:", address);
1134
+ }
1135
+ }
1136
+ async function onDevRequest(req, res) {
1137
+ if (handlerEventError) {
95
1138
  process.exit(1);
1139
+ }
1140
+ if (!handleEvent) {
1141
+ res.statusCode = 500;
1142
+ res.end("Bridge is not ready, please try again");
1143
+ return;
1144
+ }
1145
+ try {
1146
+ const { headers, body, status: status2 } = await handleEvent(req);
1147
+ res.statusCode = status2;
1148
+ for (const [key, value] of headers) {
1149
+ if (value !== void 0)
1150
+ res.setHeader(
1151
+ key,
1152
+ key === "set-cookie" ? headers.getSetCookie() : value
1153
+ );
1154
+ }
1155
+ if (body === null) {
1156
+ res.end();
1157
+ } else if (body instanceof Buffer) {
1158
+ res.end(body);
1159
+ } else {
1160
+ toToReadable(body).pipe(res);
1161
+ }
1162
+ } catch (error) {
1163
+ res.statusCode = 500;
1164
+ res.end(error.stack);
1165
+ }
1166
+ }
1167
+ main().catch((err) => {
1168
+ logError(err);
1169
+ process.exit(1);
96
1170
  });
1171
+ /*! Bundled license information:
1172
+
1173
+ content-type/index.js:
1174
+ (*!
1175
+ * content-type
1176
+ * Copyright(c) 2015 Douglas Christopher Wilson
1177
+ * MIT Licensed
1178
+ *)
1179
+
1180
+ cookie/index.js:
1181
+ (*!
1182
+ * cookie
1183
+ * Copyright(c) 2012-2014 Roman Shtylman
1184
+ * Copyright(c) 2015 Douglas Christopher Wilson
1185
+ * MIT Licensed
1186
+ *)
1187
+ */