@easel-sh/cli 0.1.0-alpha.12 → 0.1.0-alpha.13

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.
@@ -3,6 +3,7 @@
3
3
  * - Fetch Web Standard: export default { fetch(request) { return new Response(...); } };
4
4
  * - HTTP method exports: export function GET(request) { return new Response(...); }
5
5
  * - Node-style: export default (req, res) => { ... } with Vercel-like helpers (query, cookies, body, status, send, json, redirect).
6
+ * Uses Lambda response streaming (awslambda.streamifyResponse) so streaming Fetch responses are piped to the client.
6
7
  */
7
8
  export declare function generateHandlerWrapper(handlerFile: string): string;
8
9
  //# sourceMappingURL=handler-wrapper.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"handler-wrapper.d.ts","sourceRoot":"","sources":["../src/handler-wrapper.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AACH,wBAAgB,sBAAsB,CAAC,WAAW,EAAE,MAAM,GAAG,MAAM,CAiTlE"}
1
+ {"version":3,"file":"handler-wrapper.d.ts","sourceRoot":"","sources":["../src/handler-wrapper.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AACH,wBAAgB,sBAAsB,CAAC,WAAW,EAAE,MAAM,GAAG,MAAM,CAsRlE"}
@@ -3,12 +3,14 @@
3
3
  * - Fetch Web Standard: export default { fetch(request) { return new Response(...); } };
4
4
  * - HTTP method exports: export function GET(request) { return new Response(...); }
5
5
  * - Node-style: export default (req, res) => { ... } with Vercel-like helpers (query, cookies, body, status, send, json, redirect).
6
+ * Uses Lambda response streaming (awslambda.streamifyResponse) so streaming Fetch responses are piped to the client.
6
7
  */
7
8
  export function generateHandlerWrapper(handlerFile) {
8
9
  const handlerPath = JSON.stringify("./" + handlerFile.replace(/\\/g, "/"));
9
10
  return `/* eslint-disable @typescript-eslint/no-require-imports */
10
11
 
11
12
  const { Readable } = require("stream");
13
+ const { pipeline } = require("stream/promises");
12
14
  const { EventEmitter } = require("events");
13
15
 
14
16
  const HTTP_METHODS = ["GET", "POST", "PUT", "DELETE", "PATCH", "OPTIONS", "HEAD"];
@@ -22,292 +24,264 @@ function getModule() {
22
24
  }
23
25
 
24
26
  function normalizeStatus(status) {
25
- // Valid HTTP status is 100-599. Response.status can be 0 for error/opaque (Fetch API).
26
27
  if (typeof status === "number" && status >= 100 && status < 600) return status;
27
- if (status === 0) return 502; // error/opaque response
28
+ if (status === 0) return 502;
28
29
  return 200;
29
30
  }
30
31
 
31
- async function responseToLambda(response) {
32
- const responseHeaders = {};
33
- response.headers.forEach((value, key) => {
34
- responseHeaders[key.toLowerCase()] = value;
32
+ function getResponseHeaders(response) {
33
+ const out = {};
34
+ response.headers.forEach(function (value, key) {
35
+ out[key.toLowerCase()] = value;
35
36
  });
36
- const body = await response.text();
37
- return {
38
- statusCode: normalizeStatus(response.status),
39
- headers: responseHeaders,
40
- body: body,
41
- };
37
+ return out;
42
38
  }
43
39
 
44
- module.exports.handler = async (event, _context) => {
40
+ function writeStreamFirstLine(responseStream, statusCode, headers) {
41
+ const line = JSON.stringify({ statusCode: statusCode, headers: headers }) + "\\n";
42
+ responseStream.write(line);
43
+ }
44
+
45
+ function writeErrorToStream(responseStream, err) {
46
+ writeStreamFirstLine(responseStream, 502, { "content-type": "application/json" });
47
+ responseStream.write(JSON.stringify({ error: err instanceof Error ? err.message : String(err) }));
48
+ responseStream.end();
49
+ }
50
+
51
+ async function writeFetchResponseToStream(responseStream, response) {
52
+ const statusCode = normalizeStatus(response.status);
53
+ const headers = getResponseHeaders(response);
54
+ writeStreamFirstLine(responseStream, statusCode, headers);
55
+
56
+ if (response.body != null && typeof response.body.getReader === "function") {
57
+ const nodeReadable = Readable.fromWeb(response.body);
58
+ await pipeline(nodeReadable, responseStream);
59
+ } else {
60
+ const body = await response.text();
61
+ responseStream.write(body);
62
+ responseStream.end();
63
+ }
64
+ }
65
+
66
+ async function runStreamingHandler(event, responseStream, context) {
67
+ try {
68
+ const mod = await getModule();
69
+ const handler = mod.default !== undefined ? mod.default : mod;
70
+
71
+ const isV2 = event.requestContext && event.requestContext.http;
72
+ const method = isV2 ? event.requestContext.http.method : event.httpMethod || "GET";
73
+
74
+ const normalizedHeaders = {};
75
+ if (event.headers) {
76
+ Object.entries(event.headers).forEach(function (entry) {
77
+ const key = entry[0];
78
+ const value = entry[1];
79
+ normalizedHeaders[key.toLowerCase()] = value;
80
+ });
81
+ }
82
+
83
+ const queryParams = { ...(event.queryStringParameters || {}) };
84
+ const originalPath = normalizedHeaders["x-router-original-path"];
85
+ const pathFromEvent = isV2 ? event.rawPath || event.path || "/" : event.path || "/";
86
+ const path = (originalPath && originalPath.trim())
87
+ ? (originalPath.trim().startsWith("/") ? originalPath.trim() : "/" + originalPath.trim())
88
+ : pathFromEvent;
89
+ const host = event.headers && (event.headers.host || event.headers["host"]) || "localhost";
90
+ const url = new URL(path, "http://" + host);
91
+ Object.entries(queryParams).forEach(function (entry) {
92
+ url.searchParams.set(entry[0], entry[1]);
93
+ });
94
+
95
+ let bodyBuffer = null;
96
+ if (event.body) {
97
+ bodyBuffer = event.isBase64Encoded
98
+ ? Buffer.from(event.body, "base64")
99
+ : Buffer.from(event.body, "utf8");
100
+ }
101
+
102
+ const requestUrl = "http://" + host + url.pathname + url.search;
103
+ const webRequest = new Request(requestUrl, {
104
+ method: method,
105
+ headers: normalizedHeaders,
106
+ body: bodyBuffer && bodyBuffer.length > 0 ? bodyBuffer : undefined,
107
+ });
108
+
109
+ console.log("[handler] reconstructed request:", JSON.stringify({
110
+ method: method,
111
+ url: requestUrl,
112
+ path: url.pathname,
113
+ query: queryParams,
114
+ headers: normalizedHeaders,
115
+ bodyLength: bodyBuffer ? bodyBuffer.length : 0,
116
+ }));
117
+
118
+ if (HTTP_METHODS.includes(method) && typeof mod[method] === "function") {
119
+ const response = await Promise.resolve(mod[method](webRequest));
120
+ await writeFetchResponseToStream(responseStream, response);
121
+ return;
122
+ }
123
+
124
+ if (handler && typeof handler.fetch === "function") {
125
+ const response = await handler.fetch(webRequest, context);
126
+ await writeFetchResponseToStream(responseStream, response);
127
+ return;
128
+ }
129
+
130
+ if (typeof handler !== "function") {
131
+ throw new TypeError(
132
+ "Handler must export a function (req, res), an object with fetch(request), or named GET/POST/etc. Got: " + typeof handler
133
+ );
134
+ }
135
+
136
+ var result = await runNodeStyleHandler(handler, method, url, normalizedHeaders, queryParams, bodyBuffer);
137
+ writeStreamFirstLine(responseStream, result.statusCode || 200, result.headers);
138
+ responseStream.write(result.body || "");
139
+ responseStream.end();
140
+ } catch (err) {
141
+ writeErrorToStream(responseStream, err);
142
+ }
143
+ }
144
+
145
+ function responseToLambda(response) {
146
+ const responseHeaders = getResponseHeaders(response);
147
+ return response.text().then(function (body) {
148
+ return {
149
+ statusCode: normalizeStatus(response.status),
150
+ headers: responseHeaders,
151
+ body: body,
152
+ };
153
+ });
154
+ }
155
+
156
+ async function runBufferedHandler(event, context) {
45
157
  const mod = await getModule();
46
158
  const handler = mod.default !== undefined ? mod.default : mod;
47
-
48
159
  const isV2 = event.requestContext && event.requestContext.http;
49
160
  const method = isV2 ? event.requestContext.http.method : event.httpMethod || "GET";
50
-
51
161
  const normalizedHeaders = {};
52
162
  if (event.headers) {
53
- Object.entries(event.headers).forEach(([key, value]) => {
54
- normalizedHeaders[key.toLowerCase()] = value;
163
+ Object.entries(event.headers).forEach(function (entry) {
164
+ normalizedHeaders[entry[0].toLowerCase()] = entry[1];
55
165
  });
56
166
  }
57
-
58
167
  const queryParams = { ...(event.queryStringParameters || {}) };
59
- // Prefer original client path from router when present so Lambda sees the same URL the client requested (event.rawPath may be wrong if event was built by API Gateway or an older gateway)
60
168
  const originalPath = normalizedHeaders["x-router-original-path"];
61
169
  const pathFromEvent = isV2 ? event.rawPath || event.path || "/" : event.path || "/";
62
170
  const path = (originalPath && originalPath.trim())
63
171
  ? (originalPath.trim().startsWith("/") ? originalPath.trim() : "/" + originalPath.trim())
64
172
  : pathFromEvent;
65
- const host = event.headers?.host || event.headers?.["host"] || "localhost";
173
+ const host = event.headers && (event.headers.host || event.headers["host"]) || "localhost";
66
174
  const url = new URL(path, "http://" + host);
67
- Object.entries(queryParams).forEach(([key, value]) => {
68
- url.searchParams.set(key, value);
69
- });
70
-
175
+ Object.entries(queryParams).forEach(function (entry) { url.searchParams.set(entry[0], entry[1]); });
71
176
  let bodyBuffer = null;
72
177
  if (event.body) {
73
- bodyBuffer = event.isBase64Encoded
74
- ? Buffer.from(event.body, "base64")
75
- : Buffer.from(event.body, "utf8");
178
+ bodyBuffer = event.isBase64Encoded ? Buffer.from(event.body, "base64") : Buffer.from(event.body, "utf8");
76
179
  }
77
-
78
180
  const requestUrl = "http://" + host + url.pathname + url.search;
79
181
  const webRequest = new Request(requestUrl, {
80
182
  method: method,
81
183
  headers: normalizedHeaders,
82
184
  body: bodyBuffer && bodyBuffer.length > 0 ? bodyBuffer : undefined,
83
185
  });
84
-
85
- const requestDetails = {
86
- method: method,
87
- url: requestUrl,
88
- path: url.pathname,
89
- query: queryParams,
90
- headers: normalizedHeaders,
91
- bodyLength: bodyBuffer ? bodyBuffer.length : 0,
92
- };
93
- console.log("[handler] reconstructed request:", JSON.stringify(requestDetails));
94
-
95
- // Vercel: named method export (e.g. export function GET(request) { ... })
96
186
  if (HTTP_METHODS.includes(method) && typeof mod[method] === "function") {
97
- const response = await Promise.resolve(mod[method](webRequest));
187
+ var response = await Promise.resolve(mod[method](webRequest));
98
188
  return responseToLambda(response);
99
189
  }
100
-
101
- // Vercel/Nitro: default export with fetch(request)
102
190
  if (handler && typeof handler.fetch === "function") {
103
- const response = await handler.fetch(webRequest, _context);
191
+ var response = await handler.fetch(webRequest, context);
104
192
  return responseToLambda(response);
105
193
  }
106
-
107
- // Node-style: default export as function (req, res), with Vercel-like helpers
108
194
  if (typeof handler !== "function") {
109
- throw new TypeError(
110
- "Handler must export a function (req, res), an object with fetch(request), or named GET/POST/etc. Got: " + typeof handler
111
- );
195
+ throw new TypeError("Handler must export a function (req, res), an object with fetch(request), or named GET/POST/etc. Got: " + typeof handler);
112
196
  }
197
+ return runNodeStyleHandler(handler, method, url, normalizedHeaders, queryParams, bodyBuffer);
198
+ }
113
199
 
114
- return new Promise((resolve, reject) => {
115
- let _bodyParsed = undefined;
200
+ function runNodeStyleHandler(handler, method, url, normalizedHeaders, queryParams, bodyBuffer) {
201
+ return new Promise(function (resolve, reject) {
202
+ var _bodyParsed, cookiesObj;
116
203
  function getParsedBody() {
117
204
  if (_bodyParsed !== undefined) return _bodyParsed;
118
- if (!bodyBuffer || bodyBuffer.length === 0) {
119
- _bodyParsed = undefined;
120
- return _bodyParsed;
121
- }
122
- const ct = (normalizedHeaders["content-type"] || "").toLowerCase();
123
- const text = bodyBuffer.toString("utf8");
205
+ if (!bodyBuffer || bodyBuffer.length === 0) return undefined;
206
+ var ct = (normalizedHeaders["content-type"] || "").toLowerCase();
207
+ var text = bodyBuffer.toString("utf8");
124
208
  try {
125
- if (ct.includes("application/json")) _bodyParsed = JSON.parse(text);
126
- else if (ct.includes("application/x-www-form-urlencoded")) {
127
- _bodyParsed = Object.fromEntries(new URLSearchParams(text));
128
- }
129
- else if (ct.includes("text/plain")) _bodyParsed = text;
130
- else if (ct.includes("application/octet-stream")) _bodyParsed = bodyBuffer;
131
- else _bodyParsed = undefined;
209
+ if (ct.indexOf("application/json") !== -1) return _bodyParsed = JSON.parse(text);
210
+ if (ct.indexOf("application/x-www-form-urlencoded") !== -1) return _bodyParsed = Object.fromEntries(new URLSearchParams(text));
211
+ if (ct.indexOf("text/plain") !== -1) return _bodyParsed = text;
212
+ if (ct.indexOf("application/octet-stream") !== -1) return _bodyParsed = bodyBuffer;
132
213
  } catch (e) {
133
- if (ct.includes("application/json")) throw e;
134
- _bodyParsed = undefined;
214
+ if (ct.indexOf("application/json") !== -1) throw e;
135
215
  }
136
- return _bodyParsed;
216
+ return _bodyParsed = undefined;
137
217
  }
138
-
139
- let cookiesObj = undefined;
140
218
  function getCookies() {
141
219
  if (cookiesObj !== undefined) return cookiesObj;
142
220
  cookiesObj = {};
143
- const cookieHeader = normalizedHeaders["cookie"];
221
+ var cookieHeader = normalizedHeaders["cookie"];
144
222
  if (cookieHeader) {
145
223
  cookieHeader.split(";").forEach(function (part) {
146
- const eq = part.indexOf("=");
147
- if (eq > 0) {
148
- const key = part.slice(0, eq).trim();
149
- const val = part.slice(eq + 1).trim();
150
- cookiesObj[key] = val;
151
- }
224
+ var eq = part.indexOf("=");
225
+ if (eq > 0) cookiesObj[part.slice(0, eq).trim()] = part.slice(eq + 1).trim();
152
226
  });
153
227
  }
154
228
  return cookiesObj;
155
229
  }
156
-
157
- const req = Object.assign(
158
- new Readable({
159
- read() {
160
- if (bodyBuffer) this.push(bodyBuffer);
161
- this.push(null);
162
- },
163
- }),
164
- {
165
- method: method,
166
- url: url.pathname + url.search,
167
- headers: normalizedHeaders,
168
- query: queryParams,
169
- }
230
+ var req = Object.assign(
231
+ new Readable({ read: function () { if (bodyBuffer) this.push(bodyBuffer); this.push(null); } }),
232
+ { method: method, url: url.pathname + url.search, headers: normalizedHeaders, query: queryParams }
170
233
  );
171
- Object.defineProperty(req, "body", {
172
- get: getParsedBody,
173
- set: function (val) { _bodyParsed = val; },
174
- enumerable: true,
175
- configurable: true,
176
- });
177
- Object.defineProperty(req, "cookies", {
178
- get: getCookies,
179
- set: function (val) { cookiesObj = val; },
180
- enumerable: true,
181
- configurable: true,
182
- });
183
-
184
- let statusCode = 200;
185
- let statusMessage = "";
186
- const headers = {};
187
- let body = "";
188
- let headersSent = false;
189
- let resolved = false;
190
- let _destroyed = false;
191
- let _errored = null;
192
-
234
+ Object.defineProperty(req, "body", { get: getParsedBody, set: function (v) { _bodyParsed = v; }, enumerable: true, configurable: true });
235
+ Object.defineProperty(req, "cookies", { get: getCookies, set: function (v) { cookiesObj = v; }, enumerable: true, configurable: true });
236
+ var statusCode = 200, headers = {}, body = "", headersSent = false, resolved = false;
193
237
  function finishRes() {
194
238
  if (resolved) return;
195
239
  resolved = true;
196
- const out = {};
197
- Object.entries(headers).forEach(([k, v]) => {
198
- out[k] = Array.isArray(v) ? v.join(", ") : v;
199
- });
240
+ var out = {};
241
+ Object.entries(headers).forEach(function (e) { out[e[0]] = Array.isArray(e[1]) ? e[1].join(", ") : e[1]; });
200
242
  resolve({ statusCode: statusCode || 200, headers: out, body: body });
201
243
  }
202
-
203
- const res = Object.assign(new EventEmitter(), {
204
- setHeader: (key, value) => {
205
- if (!headersSent) headers[key.toLowerCase()] = value;
206
- },
207
- getHeader: (key) => headers[key.toLowerCase()],
208
- removeHeader: (key) => { delete headers[key.toLowerCase()]; },
209
- appendHeader: (key, value) => {
244
+ var res = Object.assign(new EventEmitter(), {
245
+ setHeader: function (k, v) { if (!headersSent) headers[k.toLowerCase()] = v; },
246
+ getHeader: function (k) { return headers[k.toLowerCase()]; },
247
+ removeHeader: function (k) { delete headers[k.toLowerCase()]; },
248
+ appendHeader: function (k, v) {
210
249
  if (!headersSent) {
211
- const lowerKey = key.toLowerCase();
212
- const existing = headers[lowerKey];
213
- headers[lowerKey] = existing
214
- ? (Array.isArray(existing) ? existing.concat(value) : [existing, value])
215
- : value;
250
+ var l = k.toLowerCase();
251
+ headers[l] = headers[l] ? (Array.isArray(headers[l]) ? headers[l].concat(v) : [headers[l], v]) : v;
216
252
  }
217
253
  },
218
- hasHeader: (key) => key.toLowerCase() in headers,
219
- getHeaderNames: () => Object.keys(headers),
220
- writeHead: (code, responseHeaders) => {
221
- if (!headersSent) {
222
- statusCode = code;
223
- if (responseHeaders) {
224
- Object.entries(responseHeaders).forEach(([key, value]) => {
225
- headers[key.toLowerCase()] = value;
226
- });
227
- }
228
- headersSent = true;
229
- }
230
- return res;
231
- },
232
- flushHeaders: () => {
233
- if (!headersSent) headersSent = true;
254
+ hasHeader: function (k) { return k.toLowerCase() in headers; },
255
+ getHeaderNames: function () { return Object.keys(headers); },
256
+ writeHead: function (code, h) {
257
+ if (!headersSent) { statusCode = code; if (h) Object.entries(h).forEach(function (e) { headers[e[0].toLowerCase()] = e[1]; }); headersSent = true; }
234
258
  return res;
235
259
  },
236
- write: (chunk) => {
237
- if (!headersSent) headersSent = true;
238
- body += chunk.toString();
239
- return true;
260
+ flushHeaders: function () { headersSent = true; return res; },
261
+ write: function (chunk) { headersSent = true; body += chunk.toString(); return true; },
262
+ end: function (chunk) { if (chunk) body += chunk.toString(); if (!resolved) { finishRes(); res.emit("finish"); res.emit("close"); } },
263
+ destroy: function (err) { if (!resolved) { res.emit("close"); reject(err || new Error("Response destroyed")); } return res; },
264
+ flush: function () {},
265
+ status: function (c) { statusCode = c; return res; },
266
+ send: function (val) {
267
+ if (typeof val === "object" && val !== null && !Buffer.isBuffer(val)) { if (!headers["content-type"]) headers["content-type"] = "application/json"; body = JSON.stringify(val); }
268
+ else body = val == null ? "" : String(val);
269
+ finishRes(); return res;
240
270
  },
241
- end: (chunk) => {
242
- if (chunk) body += chunk.toString();
243
- if (!resolved) {
244
- finishRes();
245
- res.emit("finish");
246
- res.emit("close");
247
- }
248
- },
249
- destroy: (err) => {
250
- if (resolved) return res;
251
- _destroyed = true;
252
- _errored = err ?? null;
253
- res.emit("close");
254
- reject(_errored ?? new Error("Response destroyed"));
255
- return res;
256
- },
257
- flush: () => { /* no-op for compression middleware */ },
258
- status: (code) => {
259
- statusCode = code;
260
- return res;
261
- },
262
- send: (val) => {
263
- if (typeof val === "object" && val !== null && !Buffer.isBuffer(val)) {
264
- if (!headers["content-type"]) headers["content-type"] = "application/json";
265
- body = JSON.stringify(val);
266
- } else {
267
- body = val == null ? "" : String(val);
268
- }
269
- finishRes();
270
- return res;
271
- },
272
- json: (obj) => {
273
- headers["content-type"] = "application/json";
274
- body = JSON.stringify(obj);
275
- finishRes();
276
- return res;
277
- },
278
- redirect: (a, b) => {
279
- const code = typeof a === "number" ? a : 307;
280
- const loc = typeof a === "number" ? b : a;
281
- statusCode = code;
282
- headers["location"] = loc;
283
- finishRes();
284
- return res;
285
- },
286
- get writableFinished() { return resolved; },
287
- get errored() { return _errored; },
288
- get destroyed() { return _destroyed; },
289
- get statusMessage() { return statusMessage; },
290
- set statusMessage(value) { statusMessage = value; },
271
+ json: function (obj) { headers["content-type"] = "application/json"; body = JSON.stringify(obj); finishRes(); return res; },
272
+ redirect: function (a, b) { statusCode = typeof a === "number" ? a : 307; headers["location"] = typeof a === "number" ? b : a; finishRes(); return res; },
291
273
  headersSent: false,
292
274
  });
293
-
294
- Object.defineProperty(res, "statusCode", {
295
- get: () => statusCode,
296
- set: (value) => { statusCode = value; },
297
- enumerable: true,
298
- configurable: true,
299
- });
300
-
275
+ Object.defineProperty(res, "statusCode", { get: function () { return statusCode; }, set: function (v) { statusCode = v; }, enumerable: true, configurable: true });
301
276
  req.on("error", reject);
302
277
  res.on("error", reject);
303
-
304
- try {
305
- handler(req, res);
306
- } catch (error) {
307
- reject(error);
308
- }
278
+ try { handler(req, res); } catch (e) { reject(e); }
309
279
  });
310
- };
280
+ }
281
+
282
+ module.exports.handler = typeof awslambda !== "undefined" && awslambda.streamifyResponse
283
+ ? awslambda.streamifyResponse(runStreamingHandler)
284
+ : runBufferedHandler;
311
285
  `;
312
286
  }
313
287
  //# sourceMappingURL=handler-wrapper.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"handler-wrapper.js","sourceRoot":"","sources":["../src/handler-wrapper.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AACH,MAAM,UAAU,sBAAsB,CAAC,WAAmB;IACxD,MAAM,WAAW,GAAG,IAAI,CAAC,SAAS,CAAC,IAAI,GAAG,WAAW,CAAC,OAAO,CAAC,KAAK,EAAE,GAAG,CAAC,CAAC,CAAC;IAC3E,OAAO;;;;;;;;;;iCAUwB,WAAW;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CAoS3C,CAAC;AACF,CAAC"}
1
+ {"version":3,"file":"handler-wrapper.js","sourceRoot":"","sources":["../src/handler-wrapper.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AACH,MAAM,UAAU,sBAAsB,CAAC,WAAmB;IACxD,MAAM,WAAW,GAAG,IAAI,CAAC,SAAS,CAAC,IAAI,GAAG,WAAW,CAAC,OAAO,CAAC,KAAK,EAAE,GAAG,CAAC,CAAC,CAAC;IAC3E,OAAO;;;;;;;;;;;iCAWwB,WAAW;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CAwQ3C,CAAC;AACF,CAAC"}
@@ -49,5 +49,24 @@ describe("handler-wrapper", () => {
49
49
  expect(result.statusCode).toBe(200);
50
50
  expect(result.body).toBe("ok");
51
51
  });
52
+ it("buffered path: Fetch GET returning Response with text body returns status and body", async () => {
53
+ const wrapperCode = generateHandlerWrapper("index.mjs");
54
+ fs.writeFileSync(path.join(tmpDir, "handler.js"), wrapperCode, "utf8");
55
+ fs.writeFileSync(path.join(tmpDir, "index.mjs"), `export function GET() {
56
+ return new Response("hello world", { status: 200, headers: { "content-type": "text/plain" } });
57
+ }`, "utf8");
58
+ const handler = require(path.join(tmpDir, "handler.js")).handler;
59
+ const mockEvent = {
60
+ requestContext: { http: { method: "GET" } },
61
+ headers: { host: "localhost" },
62
+ rawPath: "/",
63
+ };
64
+ const result = await handler(mockEvent, {});
65
+ expect(result).toBeDefined();
66
+ expect(result.statusCode).toBe(200);
67
+ expect(result.body).toBe("hello world");
68
+ expect(result.headers).toBeDefined();
69
+ expect(result.headers["content-type"]).toBe("text/plain");
70
+ });
52
71
  });
53
72
  //# sourceMappingURL=handler-wrapper.test.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"handler-wrapper.test.js","sourceRoot":"","sources":["../src/handler-wrapper.test.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,aAAa,EAAE,MAAM,aAAa,CAAC;AAC5C,OAAO,EAAE,MAAM,SAAS,CAAC;AACzB,OAAO,EAAE,MAAM,SAAS,CAAC;AACzB,OAAO,IAAI,MAAM,WAAW,CAAC;AAC7B,OAAO,EAAE,QAAQ,EAAE,EAAE,EAAE,MAAM,EAAE,UAAU,EAAE,SAAS,EAAE,MAAM,QAAQ,CAAC;AACrE,OAAO,EAAE,sBAAsB,EAAE,MAAM,sBAAsB,CAAC;AAE9D,QAAQ,CAAC,iBAAiB,EAAE,GAAG,EAAE;IAC/B,IAAI,MAAc,CAAC;IACnB,MAAM,OAAO,GAAG,aAAa,CAAC,MAAM,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;IAE/C,UAAU,CAAC,GAAG,EAAE;QACd,MAAM,GAAG,EAAE,CAAC,WAAW,CAAC,IAAI,CAAC,IAAI,CAAC,EAAE,CAAC,MAAM,EAAE,EAAE,uBAAuB,CAAC,CAAC,CAAC;IAC3E,CAAC,CAAC,CAAC;IAEH,SAAS,CAAC,GAAG,EAAE;QACb,EAAE,CAAC,MAAM,CAAC,MAAM,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE,KAAK,EAAE,IAAI,EAAE,CAAC,CAAC;IACtD,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,uEAAuE,EAAE,KAAK,IAAI,EAAE;QACrF,MAAM,WAAW,GAAG,sBAAsB,CAAC,WAAW,CAAC,CAAC;QACxD,EAAE,CAAC,aAAa,CAAC,IAAI,CAAC,IAAI,CAAC,MAAM,EAAE,YAAY,CAAC,EAAE,WAAW,EAAE,MAAM,CAAC,CAAC;QACvE,EAAE,CAAC,aAAa,CACd,IAAI,CAAC,IAAI,CAAC,MAAM,EAAE,WAAW,CAAC,EAC9B;;;QAGE,EACF,MAAM,CACP,CAAC;QAEF,MAAM,OAAO,GAAG,OAAO,CAAC,IAAI,CAAC,IAAI,CAAC,MAAM,EAAE,YAAY,CAAC,CAAC,CAAC,OAAO,CAAC;QACjE,MAAM,SAAS,GAAG;YAChB,cAAc,EAAE,EAAE,IAAI,EAAE,EAAE,MAAM,EAAE,KAAK,EAAE,EAAE;YAC3C,OAAO,EAAE,EAAE,IAAI,EAAE,WAAW,EAAE;YAC9B,OAAO,EAAE,GAAG;SACb,CAAC;QAEF,MAAM,MAAM,GAAG,MAAM,OAAO,CAAC,SAAS,EAAE,EAAE,CAAC,CAAC;QAE5C,MAAM,CAAC,MAAM,CAAC,CAAC,WAAW,EAAE,CAAC;QAC7B,MAAM,CAAC,MAAM,CAAC,UAAU,CAAC,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;QACpC,MAAM,CAAC,MAAM,CAAC,IAAI,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;IACjC,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,oEAAoE,EAAE,KAAK,IAAI,EAAE;QAClF,MAAM,WAAW,GAAG,sBAAsB,CAAC,WAAW,CAAC,CAAC;QACxD,EAAE,CAAC,aAAa,CAAC,IAAI,CAAC,IAAI,CAAC,MAAM,EAAE,YAAY,CAAC,EAAE,WAAW,EAAE,MAAM,CAAC,CAAC;QACvE,EAAE,CAAC,aAAa,CACd,IAAI,CAAC,IAAI,CAAC,MAAM,EAAE,WAAW,CAAC,EAC9B;;;QAGE,EACF,MAAM,CACP,CAAC;QAEF,MAAM,OAAO,GAAG,OAAO,CAAC,IAAI,CAAC,IAAI,CAAC,MAAM,EAAE,YAAY,CAAC,CAAC,CAAC,OAAO,CAAC;QACjE,MAAM,SAAS,GAAG;YAChB,cAAc,EAAE,EAAE,IAAI,EAAE,EAAE,MAAM,EAAE,KAAK,EAAE,EAAE;YAC3C,OAAO,EAAE,EAAE,IAAI,EAAE,WAAW,EAAE;YAC9B,OAAO,EAAE,GAAG;SACb,CAAC;QAEF,MAAM,MAAM,GAAG,MAAM,OAAO,CAAC,SAAS,EAAE,EAAE,CAAC,CAAC;QAE5C,MAAM,CAAC,MAAM,CAAC,CAAC,WAAW,EAAE,CAAC;QAC7B,MAAM,CAAC,MAAM,CAAC,UAAU,CAAC,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;QACpC,MAAM,CAAC,MAAM,CAAC,IAAI,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;IACjC,CAAC,CAAC,CAAC;AACL,CAAC,CAAC,CAAC"}
1
+ {"version":3,"file":"handler-wrapper.test.js","sourceRoot":"","sources":["../src/handler-wrapper.test.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,aAAa,EAAE,MAAM,aAAa,CAAC;AAC5C,OAAO,EAAE,MAAM,SAAS,CAAC;AACzB,OAAO,EAAE,MAAM,SAAS,CAAC;AACzB,OAAO,IAAI,MAAM,WAAW,CAAC;AAC7B,OAAO,EAAE,QAAQ,EAAE,EAAE,EAAE,MAAM,EAAE,UAAU,EAAE,SAAS,EAAE,MAAM,QAAQ,CAAC;AACrE,OAAO,EAAE,sBAAsB,EAAE,MAAM,sBAAsB,CAAC;AAE9D,QAAQ,CAAC,iBAAiB,EAAE,GAAG,EAAE;IAC/B,IAAI,MAAc,CAAC;IACnB,MAAM,OAAO,GAAG,aAAa,CAAC,MAAM,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;IAE/C,UAAU,CAAC,GAAG,EAAE;QACd,MAAM,GAAG,EAAE,CAAC,WAAW,CAAC,IAAI,CAAC,IAAI,CAAC,EAAE,CAAC,MAAM,EAAE,EAAE,uBAAuB,CAAC,CAAC,CAAC;IAC3E,CAAC,CAAC,CAAC;IAEH,SAAS,CAAC,GAAG,EAAE;QACb,EAAE,CAAC,MAAM,CAAC,MAAM,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE,KAAK,EAAE,IAAI,EAAE,CAAC,CAAC;IACtD,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,uEAAuE,EAAE,KAAK,IAAI,EAAE;QACrF,MAAM,WAAW,GAAG,sBAAsB,CAAC,WAAW,CAAC,CAAC;QACxD,EAAE,CAAC,aAAa,CAAC,IAAI,CAAC,IAAI,CAAC,MAAM,EAAE,YAAY,CAAC,EAAE,WAAW,EAAE,MAAM,CAAC,CAAC;QACvE,EAAE,CAAC,aAAa,CACd,IAAI,CAAC,IAAI,CAAC,MAAM,EAAE,WAAW,CAAC,EAC9B;;;QAGE,EACF,MAAM,CACP,CAAC;QAEF,MAAM,OAAO,GAAG,OAAO,CAAC,IAAI,CAAC,IAAI,CAAC,MAAM,EAAE,YAAY,CAAC,CAAC,CAAC,OAAO,CAAC;QACjE,MAAM,SAAS,GAAG;YAChB,cAAc,EAAE,EAAE,IAAI,EAAE,EAAE,MAAM,EAAE,KAAK,EAAE,EAAE;YAC3C,OAAO,EAAE,EAAE,IAAI,EAAE,WAAW,EAAE;YAC9B,OAAO,EAAE,GAAG;SACb,CAAC;QAEF,MAAM,MAAM,GAAG,MAAM,OAAO,CAAC,SAAS,EAAE,EAAE,CAAC,CAAC;QAE5C,MAAM,CAAC,MAAM,CAAC,CAAC,WAAW,EAAE,CAAC;QAC7B,MAAM,CAAC,MAAM,CAAC,UAAU,CAAC,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;QACpC,MAAM,CAAC,MAAM,CAAC,IAAI,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;IACjC,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,oEAAoE,EAAE,KAAK,IAAI,EAAE;QAClF,MAAM,WAAW,GAAG,sBAAsB,CAAC,WAAW,CAAC,CAAC;QACxD,EAAE,CAAC,aAAa,CAAC,IAAI,CAAC,IAAI,CAAC,MAAM,EAAE,YAAY,CAAC,EAAE,WAAW,EAAE,MAAM,CAAC,CAAC;QACvE,EAAE,CAAC,aAAa,CACd,IAAI,CAAC,IAAI,CAAC,MAAM,EAAE,WAAW,CAAC,EAC9B;;;QAGE,EACF,MAAM,CACP,CAAC;QAEF,MAAM,OAAO,GAAG,OAAO,CAAC,IAAI,CAAC,IAAI,CAAC,MAAM,EAAE,YAAY,CAAC,CAAC,CAAC,OAAO,CAAC;QACjE,MAAM,SAAS,GAAG;YAChB,cAAc,EAAE,EAAE,IAAI,EAAE,EAAE,MAAM,EAAE,KAAK,EAAE,EAAE;YAC3C,OAAO,EAAE,EAAE,IAAI,EAAE,WAAW,EAAE;YAC9B,OAAO,EAAE,GAAG;SACb,CAAC;QAEF,MAAM,MAAM,GAAG,MAAM,OAAO,CAAC,SAAS,EAAE,EAAE,CAAC,CAAC;QAE5C,MAAM,CAAC,MAAM,CAAC,CAAC,WAAW,EAAE,CAAC;QAC7B,MAAM,CAAC,MAAM,CAAC,UAAU,CAAC,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;QACpC,MAAM,CAAC,MAAM,CAAC,IAAI,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;IACjC,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,oFAAoF,EAAE,KAAK,IAAI,EAAE;QAClG,MAAM,WAAW,GAAG,sBAAsB,CAAC,WAAW,CAAC,CAAC;QACxD,EAAE,CAAC,aAAa,CAAC,IAAI,CAAC,IAAI,CAAC,MAAM,EAAE,YAAY,CAAC,EAAE,WAAW,EAAE,MAAM,CAAC,CAAC;QACvE,EAAE,CAAC,aAAa,CACd,IAAI,CAAC,IAAI,CAAC,MAAM,EAAE,WAAW,CAAC,EAC9B;;QAEE,EACF,MAAM,CACP,CAAC;QAEF,MAAM,OAAO,GAAG,OAAO,CAAC,IAAI,CAAC,IAAI,CAAC,MAAM,EAAE,YAAY,CAAC,CAAC,CAAC,OAAO,CAAC;QACjE,MAAM,SAAS,GAAG;YAChB,cAAc,EAAE,EAAE,IAAI,EAAE,EAAE,MAAM,EAAE,KAAK,EAAE,EAAE;YAC3C,OAAO,EAAE,EAAE,IAAI,EAAE,WAAW,EAAE;YAC9B,OAAO,EAAE,GAAG;SACb,CAAC;QAEF,MAAM,MAAM,GAAG,MAAM,OAAO,CAAC,SAAS,EAAE,EAAE,CAAC,CAAC;QAE5C,MAAM,CAAC,MAAM,CAAC,CAAC,WAAW,EAAE,CAAC;QAC7B,MAAM,CAAC,MAAM,CAAC,UAAU,CAAC,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;QACpC,MAAM,CAAC,MAAM,CAAC,IAAI,CAAC,CAAC,IAAI,CAAC,aAAa,CAAC,CAAC;QACxC,MAAM,CAAC,MAAM,CAAC,OAAO,CAAC,CAAC,WAAW,EAAE,CAAC;QACrC,MAAM,CAAC,MAAM,CAAC,OAAO,CAAC,cAAc,CAAC,CAAC,CAAC,IAAI,CAAC,YAAY,CAAC,CAAC;IAC5D,CAAC,CAAC,CAAC;AACL,CAAC,CAAC,CAAC"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@easel-sh/cli",
3
- "version": "0.1.0-alpha.12",
3
+ "version": "0.1.0-alpha.13",
4
4
  "type": "module",
5
5
  "bin": {
6
6
  "cli": "./dist/cli.js"