@inflector/aura 0.6.3 → 0.6.5
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/dist/bin.d.ts.map +1 -1
- package/dist/bin.js +3 -15
- package/dist/function.d.ts.map +1 -1
- package/dist/function.js +96 -72
- package/package.json +1 -1
package/dist/bin.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"bin.d.ts","sourceRoot":"","sources":["../src/bin.ts"],"names":[],"mappings":";AAmLA,wBAAgB,KAAK,CAAC,MAAM,UAAQ,QAgDnC;AA0aD,wBAAsB,GAAG,
|
|
1
|
+
{"version":3,"file":"bin.d.ts","sourceRoot":"","sources":["../src/bin.ts"],"names":[],"mappings":";AAmLA,wBAAgB,KAAK,CAAC,MAAM,UAAQ,QAgDnC;AA0aD,wBAAsB,GAAG,kBAwExB"}
|
package/dist/bin.js
CHANGED
|
@@ -581,26 +581,14 @@ export async function dev() {
|
|
|
581
581
|
target: Config.Url,
|
|
582
582
|
changeOrigin: true,
|
|
583
583
|
secure: false,
|
|
584
|
+
ws: false, // disable websocket proxying if unused
|
|
584
585
|
configure(proxy, _options) {
|
|
585
|
-
proxy.on("proxyReq", (proxyReq,
|
|
586
|
+
proxy.on("proxyReq", (proxyReq, req, res) => {
|
|
587
|
+
proxyReq.setHeader("Connection", "close");
|
|
586
588
|
if (AURA_KEY) {
|
|
587
589
|
proxyReq.setHeader("Authorization", `Bearer ${AURA_KEY}`);
|
|
588
590
|
}
|
|
589
591
|
});
|
|
590
|
-
// Handle proxy errors so requests don't stay pending forever
|
|
591
|
-
proxy.on("error", (err, _req, res) => {
|
|
592
|
-
if (res && !res.headersSent) {
|
|
593
|
-
const isTimeout = err.code === "ECONNRESET" ||
|
|
594
|
-
err.code === "ETIMEDOUT" ||
|
|
595
|
-
err.code === "ESOCKETTIMEDOUT";
|
|
596
|
-
const statusCode = isTimeout ? 504 : 502;
|
|
597
|
-
const message = isTimeout
|
|
598
|
-
? "Upstream request timed out"
|
|
599
|
-
: "Upstream proxy failed";
|
|
600
|
-
res.writeHead(statusCode, { "Content-Type": "application/json" });
|
|
601
|
-
res.end(JSON.stringify({ error: message }));
|
|
602
|
-
}
|
|
603
|
-
});
|
|
604
592
|
},
|
|
605
593
|
},
|
|
606
594
|
},
|
package/dist/function.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"function.d.ts","sourceRoot":"","sources":["../src/function.ts"],"names":[],"mappings":"AAAA,wBAAgB,qBAAqB,CACnC,SAAS,EAAE,MAAM,EACjB,eAAe,CAAC,EAAE,MAAM,GACvB,GAAG,
|
|
1
|
+
{"version":3,"file":"function.d.ts","sourceRoot":"","sources":["../src/function.ts"],"names":[],"mappings":"AAAA,wBAAgB,qBAAqB,CACnC,SAAS,EAAE,MAAM,EACjB,eAAe,CAAC,EAAE,MAAM,GACvB,GAAG,CAkJL"}
|
package/dist/function.js
CHANGED
|
@@ -10,6 +10,7 @@ export function createFunctionHandler(workspace, functionsFolder) {
|
|
|
10
10
|
get(_, prop) {
|
|
11
11
|
return createNestedProxy([...path, prop]);
|
|
12
12
|
},
|
|
13
|
+
// 1. Remove 'async' here to prevent native Promise wrapping
|
|
13
14
|
apply(_, __, args) {
|
|
14
15
|
const url = [window.location.origin, "api", "fn", workspace, ...path].join("/");
|
|
15
16
|
const isFormData = args != null && args.length === 1 && args[0] instanceof FormData;
|
|
@@ -19,86 +20,109 @@ export function createFunctionHandler(workspace, functionsFolder) {
|
|
|
19
20
|
};
|
|
20
21
|
if (!isFormData)
|
|
21
22
|
headers["Content-Type"] = "application/json";
|
|
22
|
-
//
|
|
23
|
-
|
|
24
|
-
// would re-execute fetch on every .then()/.await call.
|
|
25
|
-
const resultPromise = fetch(url, {
|
|
23
|
+
// 2. Start the fetch properly (without await)
|
|
24
|
+
const requestPromise = fetch(url, {
|
|
26
25
|
method: "POST",
|
|
27
26
|
body,
|
|
28
27
|
headers,
|
|
29
28
|
credentials: "include",
|
|
30
|
-
})
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
if (
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
}
|
|
46
|
-
throw new Error(errorMessage);
|
|
47
|
-
}
|
|
48
|
-
// ─────────────────────────────────────────────
|
|
49
|
-
// SSE PATH
|
|
50
|
-
// ─────────────────────────────────────────────
|
|
51
|
-
if (contentType.includes("text/event-stream")) {
|
|
52
|
-
if (!response.body) {
|
|
53
|
-
throw new Error("SSE response body is null");
|
|
54
|
-
}
|
|
55
|
-
const reader = response.body.getReader();
|
|
56
|
-
const decoder = new TextDecoder("utf-8");
|
|
57
|
-
let buffer = "";
|
|
58
|
-
const events = [];
|
|
59
|
-
while (true) {
|
|
60
|
-
const { value, done } = await reader.read();
|
|
61
|
-
if (done)
|
|
62
|
-
break;
|
|
63
|
-
buffer += decoder.decode(value, { stream: true });
|
|
64
|
-
// Split by SSE message delimiter
|
|
65
|
-
const parts = buffer.split("\n\n");
|
|
66
|
-
buffer = parts.pop() || ""; // Keep incomplete chunk
|
|
67
|
-
for (const part of parts) {
|
|
68
|
-
if (!part.trim())
|
|
69
|
-
continue;
|
|
70
|
-
const lines = part.split("\n");
|
|
71
|
-
let eventName = "message"; // Default SSE event type
|
|
72
|
-
const dataLines = [];
|
|
73
|
-
for (const line of lines) {
|
|
74
|
-
if (line.startsWith("event: ")) {
|
|
75
|
-
eventName = line.replace(/^event: /, "").trim();
|
|
76
|
-
}
|
|
77
|
-
else if (line.startsWith("data: ")) {
|
|
78
|
-
dataLines.push(line.replace(/^data: /, ""));
|
|
79
|
-
}
|
|
29
|
+
});
|
|
30
|
+
// 3. Return a custom "Thenable" object with full Promise interface
|
|
31
|
+
const thenable = {
|
|
32
|
+
then(onFulfilled, onRejected) {
|
|
33
|
+
requestPromise
|
|
34
|
+
.then(async (response) => {
|
|
35
|
+
const contentType = response.headers.get("Content-Type") || "";
|
|
36
|
+
// ─────────────────────────────────────────────
|
|
37
|
+
// SSE PATH
|
|
38
|
+
// ─────────────────────────────────────────────
|
|
39
|
+
if (contentType.includes("text/event-stream")) {
|
|
40
|
+
if (!response.body) {
|
|
41
|
+
if (onRejected)
|
|
42
|
+
onRejected(new Error("Response body is null"));
|
|
43
|
+
return;
|
|
80
44
|
}
|
|
81
|
-
const
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
45
|
+
const reader = response.body.getReader();
|
|
46
|
+
const decoder = new TextDecoder("utf-8");
|
|
47
|
+
let buffer = "";
|
|
48
|
+
try {
|
|
49
|
+
while (true) {
|
|
50
|
+
const { value, done } = await reader.read();
|
|
51
|
+
if (done)
|
|
52
|
+
break;
|
|
53
|
+
buffer += decoder.decode(value, { stream: true });
|
|
54
|
+
// Split by SSE message delimiter
|
|
55
|
+
const parts = buffer.split("\n\n");
|
|
56
|
+
buffer = parts.pop() || ""; // Keep incomplete chunk
|
|
57
|
+
for (const part of parts) {
|
|
58
|
+
if (!part.trim())
|
|
59
|
+
continue;
|
|
60
|
+
const lines = part.split("\n");
|
|
61
|
+
let eventName = "message"; // Default SSE event type
|
|
62
|
+
const dataLines = [];
|
|
63
|
+
for (const line of lines) {
|
|
64
|
+
if (line.startsWith("event: ")) {
|
|
65
|
+
eventName = line.replace(/^event: /, "").trim();
|
|
66
|
+
}
|
|
67
|
+
else if (line.startsWith("data: ")) {
|
|
68
|
+
dataLines.push(line.replace(/^data: /, ""));
|
|
69
|
+
}
|
|
70
|
+
}
|
|
71
|
+
const message = dataLines.join("\n");
|
|
72
|
+
if (message) {
|
|
73
|
+
try {
|
|
74
|
+
// Emit parsed JSON along with the event name
|
|
75
|
+
const parsedData = JSON.parse(message);
|
|
76
|
+
onFulfilled({
|
|
77
|
+
event: eventName,
|
|
78
|
+
data: parsedData,
|
|
79
|
+
});
|
|
80
|
+
}
|
|
81
|
+
catch {
|
|
82
|
+
// Or emit raw string if parsing fails
|
|
83
|
+
onFulfilled({
|
|
84
|
+
event: eventName,
|
|
85
|
+
data: message,
|
|
86
|
+
});
|
|
87
|
+
}
|
|
88
|
+
}
|
|
89
|
+
}
|
|
89
90
|
}
|
|
90
91
|
}
|
|
92
|
+
catch (err) {
|
|
93
|
+
if (onRejected)
|
|
94
|
+
onRejected(err);
|
|
95
|
+
}
|
|
91
96
|
}
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
97
|
+
// ─────────────────────────────────────────────
|
|
98
|
+
// NORMAL JSON PATH
|
|
99
|
+
// ─────────────────────────────────────────────
|
|
100
|
+
else {
|
|
101
|
+
const data = await response.json();
|
|
102
|
+
onFulfilled(data.data ?? data);
|
|
103
|
+
}
|
|
104
|
+
})
|
|
105
|
+
.catch((err) => {
|
|
106
|
+
if (onRejected)
|
|
107
|
+
onRejected(err);
|
|
108
|
+
});
|
|
109
|
+
// Return 'this' to allow chaining
|
|
110
|
+
return thenable;
|
|
111
|
+
},
|
|
112
|
+
catch(onRejected) {
|
|
113
|
+
return thenable.then(() => { }, onRejected);
|
|
114
|
+
},
|
|
115
|
+
finally(onFinally) {
|
|
116
|
+
return thenable.then((value) => {
|
|
117
|
+
onFinally?.();
|
|
118
|
+
return value;
|
|
119
|
+
}, (err) => {
|
|
120
|
+
onFinally?.();
|
|
121
|
+
throw err;
|
|
122
|
+
});
|
|
123
|
+
},
|
|
124
|
+
};
|
|
125
|
+
return thenable;
|
|
102
126
|
},
|
|
103
127
|
});
|
|
104
128
|
}
|