@scriptc/compiler 0.1.3 → 0.1.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/ambient/scriptc-node-fallback.d.ts +275 -62
- package/dist/backend/c/async.d.ts +25 -0
- package/dist/backend/c/async.js +167 -0
- package/dist/backend/c/async.js.map +1 -1
- package/dist/backend/c/c-emitter.d.ts +15 -1
- package/dist/backend/c/c-emitter.js +36 -11
- package/dist/backend/c/c-emitter.js.map +1 -1
- package/dist/backend/c/exprs.d.ts +2 -2
- package/dist/backend/c/exprs.js +556 -71
- package/dist/backend/c/exprs.js.map +1 -1
- package/dist/backend/c/stmts.js +5 -3
- package/dist/backend/c/stmts.js.map +1 -1
- package/dist/backend/c/types.d.ts +2 -3
- package/dist/backend/c/types.js +10 -1
- package/dist/backend/c/types.js.map +1 -1
- package/dist/backend/c/walkers.js +1 -1
- package/dist/backend/c/walkers.js.map +1 -1
- package/dist/backend/link-plan.d.ts +3 -1
- package/dist/backend/link-plan.js +3 -1
- package/dist/backend/link-plan.js.map +1 -1
- package/dist/backend/llvm/dyn.js +1 -1
- package/dist/backend/llvm/dyn.js.map +1 -1
- package/dist/backend/llvm/emitter.js +42 -12
- package/dist/backend/llvm/emitter.js.map +1 -1
- package/dist/backend/llvm/expr-bytes.d.ts +1 -2
- package/dist/backend/llvm/expr-bytes.js +28 -23
- package/dist/backend/llvm/expr-bytes.js.map +1 -1
- package/dist/backend/llvm/expr-callbacks.d.ts +9 -0
- package/dist/backend/llvm/expr-callbacks.js +125 -0
- package/dist/backend/llvm/expr-callbacks.js.map +1 -1
- package/dist/backend/llvm/expr-containers.d.ts +1 -0
- package/dist/backend/llvm/expr-containers.js +32 -4
- package/dist/backend/llvm/expr-containers.js.map +1 -1
- package/dist/backend/llvm/expr-context.d.ts +19 -3
- package/dist/backend/llvm/expr-dispatch.js +1 -0
- package/dist/backend/llvm/expr-dispatch.js.map +1 -1
- package/dist/backend/llvm/expr-primitives.d.ts +1 -1
- package/dist/backend/llvm/expr-primitives.js +49 -13
- package/dist/backend/llvm/expr-primitives.js.map +1 -1
- package/dist/backend/llvm/expr-primitives.test.d.ts +1 -0
- package/dist/backend/llvm/expr-primitives.test.js +38 -0
- package/dist/backend/llvm/expr-primitives.test.js.map +1 -0
- package/dist/backend/llvm/expr-stream-callbacks.d.ts +3 -0
- package/dist/backend/llvm/expr-stream-callbacks.js +69 -0
- package/dist/backend/llvm/expr-stream-callbacks.js.map +1 -1
- package/dist/backend/llvm/lib-filesystem.js +80 -10
- package/dist/backend/llvm/lib-filesystem.js.map +1 -1
- package/dist/backend/llvm/lib-network.js +69 -10
- package/dist/backend/llvm/lib-network.js.map +1 -1
- package/dist/backend/llvm/lib-process.js +156 -6
- package/dist/backend/llvm/lib-process.js.map +1 -1
- package/dist/backend/llvm/lib-shared.js +100 -0
- package/dist/backend/llvm/lib-shared.js.map +1 -1
- package/dist/backend/llvm/lib-stream.js +23 -0
- package/dist/backend/llvm/lib-stream.js.map +1 -1
- package/dist/backend/native-toolchain.d.ts +5 -0
- package/dist/backend/native-toolchain.js +4 -1
- package/dist/backend/native-toolchain.js.map +1 -1
- package/dist/backend/runtime-pack.test.js +28 -10
- package/dist/backend/runtime-pack.test.js.map +1 -1
- package/dist/backend/targets.d.ts +7 -0
- package/dist/backend/targets.js +26 -0
- package/dist/backend/targets.js.map +1 -1
- package/dist/backend/targets.test.js +8 -1
- package/dist/backend/targets.test.js.map +1 -1
- package/dist/coverage/surface-manifest.js +14 -4
- package/dist/coverage/surface-manifest.js.map +1 -1
- package/dist/diagnostics/diagnostic.js +1 -1
- package/dist/diagnostics/diagnostic.js.map +1 -1
- package/dist/executable/executable-cache.d.ts +4 -0
- package/dist/executable/executable-cache.js +6 -1
- package/dist/executable/executable-cache.js.map +1 -1
- package/dist/executable/executable-cache.test.js +3 -3
- package/dist/executable/executable-cache.test.js.map +1 -1
- package/dist/frontend/fork-target.d.ts +17 -0
- package/dist/frontend/fork-target.js +256 -0
- package/dist/frontend/fork-target.js.map +1 -0
- package/dist/frontend/lowering/abstract-equality.d.ts +6 -0
- package/dist/frontend/lowering/abstract-equality.js +250 -0
- package/dist/frontend/lowering/abstract-equality.js.map +1 -0
- package/dist/frontend/lowering/containers/bytes.d.ts +1 -1
- package/dist/frontend/lowering/containers/bytes.js +6 -5
- package/dist/frontend/lowering/containers/bytes.js.map +1 -1
- package/dist/frontend/lowering/containers/string-and-regexp.d.ts +7 -6
- package/dist/frontend/lowering/containers/string-and-regexp.js +237 -28
- package/dist/frontend/lowering/containers/string-and-regexp.js.map +1 -1
- package/dist/frontend/lowering/expressions/object-literals.js +8 -0
- package/dist/frontend/lowering/expressions/object-literals.js.map +1 -1
- package/dist/frontend/lowering/lower-assert.js +71 -2
- package/dist/frontend/lowering/lower-assert.js.map +1 -1
- package/dist/frontend/lowering/lower-builtins.d.ts +54 -28
- package/dist/frontend/lowering/lower-builtins.js +957 -116
- package/dist/frontend/lowering/lower-builtins.js.map +1 -1
- package/dist/frontend/lowering/lower-calls.d.ts +32 -23
- package/dist/frontend/lowering/lower-calls.js +835 -206
- package/dist/frontend/lowering/lower-calls.js.map +1 -1
- package/dist/frontend/lowering/lower-classes.js +41 -10
- package/dist/frontend/lowering/lower-classes.js.map +1 -1
- package/dist/frontend/lowering/lower-containers.d.ts +7 -9
- package/dist/frontend/lowering/lower-containers.js +293 -51
- package/dist/frontend/lowering/lower-containers.js.map +1 -1
- package/dist/frontend/lowering/lower-event-emitter.js +212 -21
- package/dist/frontend/lowering/lower-event-emitter.js.map +1 -1
- package/dist/frontend/lowering/lower-exprs.d.ts +12 -0
- package/dist/frontend/lowering/lower-exprs.js +263 -93
- package/dist/frontend/lowering/lower-exprs.js.map +1 -1
- package/dist/frontend/lowering/lower-inspect.d.ts +4 -0
- package/dist/frontend/lowering/lower-inspect.js +1 -1
- package/dist/frontend/lowering/lower-inspect.js.map +1 -1
- package/dist/frontend/lowering/lower-island.d.ts +6 -3
- package/dist/frontend/lowering/lower-island.js +182 -12
- package/dist/frontend/lowering/lower-island.js.map +1 -1
- package/dist/frontend/lowering/lower-modules.d.ts +6 -0
- package/dist/frontend/lowering/lower-modules.js +184 -38
- package/dist/frontend/lowering/lower-modules.js.map +1 -1
- package/dist/frontend/lowering/lower-namespaces.js +7 -0
- package/dist/frontend/lowering/lower-namespaces.js.map +1 -1
- package/dist/frontend/lowering/lower-server.d.ts +3 -5
- package/dist/frontend/lowering/lower-server.js +413 -54
- package/dist/frontend/lowering/lower-server.js.map +1 -1
- package/dist/frontend/lowering/lower-stmts.js +122 -19
- package/dist/frontend/lowering/lower-stmts.js.map +1 -1
- package/dist/frontend/lowering/lower-stream.d.ts +3 -0
- package/dist/frontend/lowering/lower-stream.js +7 -0
- package/dist/frontend/lowering/lower-stream.js.map +1 -1
- package/dist/frontend/lowering/lowerer.d.ts +86 -9
- package/dist/frontend/lowering/lowerer.js +449 -74
- package/dist/frontend/lowering/lowerer.js.map +1 -1
- package/dist/frontend/lowering/optional-arguments.d.ts +9 -1
- package/dist/frontend/lowering/optional-arguments.js +67 -1
- package/dist/frontend/lowering/optional-arguments.js.map +1 -1
- package/dist/frontend/lowering/pairs-snapshot.d.ts +3 -1
- package/dist/frontend/lowering/pairs-snapshot.js +12 -4
- package/dist/frontend/lowering/pairs-snapshot.js.map +1 -1
- package/dist/frontend/lowering/surfaces.d.ts +34 -14
- package/dist/frontend/lowering/surfaces.js +177 -104
- package/dist/frontend/lowering/surfaces.js.map +1 -1
- package/dist/frontend/npm-static-declarations.d.ts +4 -0
- package/dist/frontend/npm-static-declarations.js +56 -0
- package/dist/frontend/npm-static-declarations.js.map +1 -1
- package/dist/frontend/npm-static-declarations.test.js +23 -2
- package/dist/frontend/npm-static-declarations.test.js.map +1 -1
- package/dist/frontend/npm-static-prune.d.ts +6 -0
- package/dist/frontend/npm-static-prune.js +203 -0
- package/dist/frontend/npm-static-prune.js.map +1 -0
- package/dist/frontend/npm-static-prune.test.d.ts +1 -0
- package/dist/frontend/npm-static-prune.test.js +48 -0
- package/dist/frontend/npm-static-prune.test.js.map +1 -0
- package/dist/frontend/npm-static.js +6 -5
- package/dist/frontend/npm-static.js.map +1 -1
- package/dist/frontend/npm.d.ts +15 -3
- package/dist/frontend/npm.js +87 -14
- package/dist/frontend/npm.js.map +1 -1
- package/dist/frontend/npm.test.js +76 -9
- package/dist/frontend/npm.test.js.map +1 -1
- package/dist/frontend/program.js +107 -14
- package/dist/frontend/program.js.map +1 -1
- package/dist/frontend/provenance.js +8 -3
- package/dist/frontend/provenance.js.map +1 -1
- package/dist/frontend/resolve.d.ts +6 -0
- package/dist/frontend/resolve.js +7 -4
- package/dist/frontend/resolve.js.map +1 -1
- package/dist/frontend/type-mapper.d.ts +5 -0
- package/dist/frontend/type-mapper.js +80 -29
- package/dist/frontend/type-mapper.js.map +1 -1
- package/dist/index.d.ts +8 -3
- package/dist/index.js +34 -41
- package/dist/index.js.map +1 -1
- package/dist/ir/analysis.d.ts +5 -3
- package/dist/ir/analysis.js +25 -11
- package/dist/ir/analysis.js.map +1 -1
- package/dist/ir/analysis.test.js +50 -2
- package/dist/ir/analysis.test.js.map +1 -1
- package/dist/ir/constant-tables.d.ts +17 -0
- package/dist/ir/constant-tables.js +99 -0
- package/dist/ir/constant-tables.js.map +1 -0
- package/dist/ir/constant-tables.test.d.ts +1 -0
- package/dist/ir/constant-tables.test.js +78 -0
- package/dist/ir/constant-tables.test.js.map +1 -0
- package/dist/ir/integer-ranges.d.ts +13 -0
- package/dist/ir/integer-ranges.js +122 -0
- package/dist/ir/integer-ranges.js.map +1 -0
- package/dist/ir/integer-ranges.test.d.ts +1 -0
- package/dist/ir/integer-ranges.test.js +63 -0
- package/dist/ir/integer-ranges.test.js.map +1 -0
- package/dist/ir/ir.d.ts +130 -76
- package/dist/ir/ir.js +69 -4
- package/dist/ir/ir.js.map +1 -1
- package/dist/ir/ir.test.js +20 -1
- package/dist/ir/ir.test.js.map +1 -1
- package/dist/ir/scalar-records.d.ts +8 -0
- package/dist/ir/scalar-records.js +216 -0
- package/dist/ir/scalar-records.js.map +1 -0
- package/dist/ir/scalar-records.test.d.ts +1 -0
- package/dist/ir/scalar-records.test.js +142 -0
- package/dist/ir/scalar-records.test.js.map +1 -0
- package/dist/ir/serialize.d.ts +1 -1
- package/dist/ir/serialize.js +1 -1
- package/dist/ir/serialize.js.map +1 -1
- package/dist/ir/validate.js +256 -20
- package/dist/ir/validate.js.map +1 -1
- package/dist/ir/validate.test.d.ts +1 -0
- package/dist/ir/validate.test.js +31 -0
- package/dist/ir/validate.test.js.map +1 -0
- package/dist/library/cache-primitives.d.ts +1 -1
- package/dist/library/cache-primitives.js +3 -3
- package/dist/library/cache-primitives.js.map +1 -1
- package/dist/library/fence-eval.js +11 -4
- package/dist/library/fence-eval.js.map +1 -1
- package/dist/library/int-infer.test.js +4 -4
- package/dist/library/int-infer.test.js.map +1 -1
- package/dist/library/library-cache.js +0 -1
- package/dist/library/library-cache.js.map +1 -1
- package/dist/library/library-cache.test.js +8 -8
- package/dist/library/library-cache.test.js.map +1 -1
- package/package.json +17 -17
- package/surface-manifest.json +186 -79
|
@@ -865,25 +865,26 @@ export function lowerServerCloseOverrideAssignment(lowerer, left, right, loc) {
|
|
|
865
865
|
loc,
|
|
866
866
|
};
|
|
867
867
|
}
|
|
868
|
-
/**
|
|
869
|
-
*
|
|
870
|
-
* routed from lower-stmts' property-assignment path beside the
|
|
871
|
-
* close-override hook. Null when the target isn't one of the two. */
|
|
868
|
+
/** Writable ServerResponse properties consulted by the implicit head and
|
|
869
|
+
* the strict body-length check. Null when the target isn't one of them. */
|
|
872
870
|
export function lowerHttpResPropertyAssignment(lowerer, left, right, loc) {
|
|
873
871
|
if (!ts.isPropertyAccessExpression(left) || left.questionDotToken)
|
|
874
872
|
return null;
|
|
875
873
|
const name = left.name.text;
|
|
876
|
-
if (name !== "statusCode" && name !== "statusMessage"
|
|
874
|
+
if (name !== "statusCode" && name !== "statusMessage" &&
|
|
875
|
+
name !== "sendDate" && name !== "strictContentLength")
|
|
877
876
|
return null;
|
|
878
877
|
if (lowerer.mapTypeOf(lowerer.typeOf(left.expression))?.kind !== "httpRes")
|
|
879
878
|
return null;
|
|
880
879
|
if (!lowerer.isStdlibMember(left))
|
|
881
880
|
return null;
|
|
882
|
-
const receiver = lowerer
|
|
881
|
+
const receiver = coerceToHandle(lowerer, left.expression, HTTPRES_T);
|
|
883
882
|
const value = name === "statusCode"
|
|
884
883
|
? lowerer.lowerExprExpecting(right, F64)
|
|
885
|
-
: lowerer.lowerExprExpecting(right, STRING);
|
|
886
|
-
const fn = name === "statusCode" ? "http.resStatusSet"
|
|
884
|
+
: lowerer.lowerExprExpecting(right, name === "statusMessage" ? STRING : BOOL);
|
|
885
|
+
const fn = name === "statusCode" ? "http.resStatusSet"
|
|
886
|
+
: name === "statusMessage" ? "http.resStatusMsgSet"
|
|
887
|
+
: name === "sendDate" ? "http.resSendDateSet" : "http.resStrictContentLengthSet";
|
|
887
888
|
return {
|
|
888
889
|
kind: "exprStmt",
|
|
889
890
|
expr: { kind: "libCall", fn, args: [receiver, value], type: VOID, loc },
|
|
@@ -924,6 +925,28 @@ function lowerNetServerMethodCall(lowerer, call, access) {
|
|
|
924
925
|
const name = access.name.text;
|
|
925
926
|
const loc = locOf(call);
|
|
926
927
|
const args = call.arguments;
|
|
928
|
+
if (name === "setTimeout") {
|
|
929
|
+
if (args.length < 1 || args.length > 2)
|
|
930
|
+
lowerer.noLowering("server.setTimeout arguments", call, "pass milliseconds and an optional socket callback");
|
|
931
|
+
const receiver = coerceToHandle(lowerer, access.expression, NETSERVER_T);
|
|
932
|
+
const ms = lowerer.lowerExprExpecting(args[0], F64);
|
|
933
|
+
const cb = args.length === 2
|
|
934
|
+
? lowerCallbackArg(lowerer, args[1], "server timeout callbacks", 1, (p) => p.kind === "netSocket", "use (socket) or ()", [NETSOCKET_T]).cb
|
|
935
|
+
: null;
|
|
936
|
+
const fn = cb === null ? "http.serverSetTimeout" : "http.serverSetTimeoutCb";
|
|
937
|
+
const callArgs = cb === null ? [receiver, ms] : [receiver, ms, cb];
|
|
938
|
+
if (resultIsDiscarded(call))
|
|
939
|
+
return { kind: "libCall", fn, args: callArgs, type: VOID, loc };
|
|
940
|
+
return receiverReturningCall(lowerer, fn, callArgs, NETSERVER_T, loc);
|
|
941
|
+
}
|
|
942
|
+
if (name === "closeAllConnections" || name === "closeIdleConnections") {
|
|
943
|
+
requireStatementPosition(lowerer, call, `server.${name}()`);
|
|
944
|
+
if (args.length !== 0)
|
|
945
|
+
lowerer.noLowering(`server.${name} arguments`, call, `${name}() takes no arguments`);
|
|
946
|
+
const receiver = coerceToHandle(lowerer, access.expression, NETSERVER_T);
|
|
947
|
+
const fn = name === "closeAllConnections" ? "http.serverCloseAllConnections" : "http.serverCloseIdleConnections";
|
|
948
|
+
return { kind: "libCall", fn, args: [receiver], type: VOID, loc };
|
|
949
|
+
}
|
|
927
950
|
if (name === "listen") {
|
|
928
951
|
if (args.length < 1 || args.length > 3) {
|
|
929
952
|
lowerer.noLowering(`listen with ${args.length} arguments`, call, "the supported form is listen(port[, host][, callback]) — port 0 binds an ephemeral port");
|
|
@@ -1140,6 +1163,10 @@ function lowerNetServerMethodCall(lowerer, call, access) {
|
|
|
1140
1163
|
const { cb } = lowerCallbackArg(lowerer, args[1], "close listeners", 0, () => false, "use ()", []);
|
|
1141
1164
|
return { kind: "libCall", fn: "net.serverOnClose", args: [receiver, cb, once], type: VOID, loc };
|
|
1142
1165
|
}
|
|
1166
|
+
if (event === "timeout") {
|
|
1167
|
+
const { cb } = lowerCallbackArg(lowerer, args[1], "timeout listeners", 1, (p) => p.kind === "netSocket", "use (socket) or ()", [NETSOCKET_T]);
|
|
1168
|
+
return { kind: "libCall", fn: "http.serverOnTimeout", args: [receiver, cb, once], type: VOID, loc };
|
|
1169
|
+
}
|
|
1143
1170
|
if (event === "listening") {
|
|
1144
1171
|
// The deferred bind emit — listen(port, cb)'s event twin: fires
|
|
1145
1172
|
// once after a successful listen; late registrations on an
|
|
@@ -1517,6 +1544,23 @@ function headersSnapshotHelper(lowerer, shapeId, loc) {
|
|
|
1517
1544
|
callArgs: [varRef("r.0", HTTPREQ_T, loc)],
|
|
1518
1545
|
});
|
|
1519
1546
|
}
|
|
1547
|
+
function trailersSnapshotHelper(lowerer, shapeId, loc) {
|
|
1548
|
+
return pairsSnapshotHelper(lowerer, shapeId, loc, {
|
|
1549
|
+
keyPrefix: "trailers",
|
|
1550
|
+
libCall: "http.reqTrailerPairs",
|
|
1551
|
+
params: [{ localId: "r.0", name: "r", type: HTTPREQ_T }],
|
|
1552
|
+
callArgs: [varRef("r.0", HTTPREQ_T, loc)],
|
|
1553
|
+
});
|
|
1554
|
+
}
|
|
1555
|
+
function distinctSnapshotHelper(lowerer, shapeId, loc, collection) {
|
|
1556
|
+
return pairsSnapshotHelper(lowerer, shapeId, loc, {
|
|
1557
|
+
keyPrefix: collection,
|
|
1558
|
+
libCall: collection === "headersDistinct" ? "http.reqHeaderPairs" : "http.reqTrailerPairs",
|
|
1559
|
+
lookupValue: collection === "headersDistinct" ? "http.reqHeaderValues" : "http.reqTrailerValues",
|
|
1560
|
+
params: [{ localId: "r.0", name: "r", type: HTTPREQ_T }],
|
|
1561
|
+
callArgs: [varRef("r.0", HTTPREQ_T, loc)],
|
|
1562
|
+
});
|
|
1563
|
+
}
|
|
1520
1564
|
/** The `endStream` boolean of an h2 options object literal, as a literal
|
|
1521
1565
|
* bool. Returns undefined when absent (or the arg is absent). Fences on
|
|
1522
1566
|
* a non-literal endStream value or unknown keys that would matter. */
|
|
@@ -1789,6 +1833,10 @@ export function lowerServerProperty(lowerer, expr) {
|
|
|
1789
1833
|
// req.headers.NAME — the `string | undefined` union (envGet's type).
|
|
1790
1834
|
const recvKind = lowerer.mapTypeOf(lowerer.typeOf(expr.expression))?.kind;
|
|
1791
1835
|
if (recvKind === "netServer" && lowerer.isStdlibMember(expr)) {
|
|
1836
|
+
if (expr.name.text === "listening") {
|
|
1837
|
+
const receiver = coerceToHandle(lowerer, expr.expression, NETSERVER_T);
|
|
1838
|
+
return { kind: "libCall", fn: "net.serverListening", args: [receiver], type: BOOL, loc };
|
|
1839
|
+
}
|
|
1792
1840
|
const field = httpServerTimeoutField(expr.name.text);
|
|
1793
1841
|
if (field !== null) {
|
|
1794
1842
|
const receiver = coerceToHandle(lowerer, expr.expression, NETSERVER_T);
|
|
@@ -1809,7 +1857,7 @@ export function lowerServerProperty(lowerer, expr) {
|
|
|
1809
1857
|
const receiver = coerceToHandle(lowerer, expr.expression, HTTPREQ_T);
|
|
1810
1858
|
return { kind: "libCall", fn: "http.reqStatusCode", args: [receiver], type: lowerer.withUndefinedArm(F64), loc };
|
|
1811
1859
|
}
|
|
1812
|
-
if (name === "socket") {
|
|
1860
|
+
if (name === "socket" || name === "connection") {
|
|
1813
1861
|
const receiver = coerceToHandle(lowerer, expr.expression, HTTPREQ_T);
|
|
1814
1862
|
return { kind: "libCall", fn: "http.reqSocket", args: [receiver], type: NETSOCKET_T, loc };
|
|
1815
1863
|
}
|
|
@@ -1829,11 +1877,12 @@ export function lowerServerProperty(lowerer, expr) {
|
|
|
1829
1877
|
const fn = name === "aborted" ? "http.reqAborted" : "http.reqComplete";
|
|
1830
1878
|
return { kind: "libCall", fn, args: [receiver], type: BOOL, loc };
|
|
1831
1879
|
}
|
|
1832
|
-
if (name === "rawHeaders") {
|
|
1880
|
+
if (name === "rawHeaders" || name === "rawTrailers") {
|
|
1833
1881
|
// [name, value, name, value, ...] in arrival order, names in their
|
|
1834
1882
|
// ORIGINAL case — Node's shape; a fresh string[] per read.
|
|
1835
1883
|
const receiver = coerceToHandle(lowerer, expr.expression, HTTPREQ_T);
|
|
1836
|
-
|
|
1884
|
+
const fn = name === "rawHeaders" ? "http.reqRawHeaders" : "http.reqRawTrailers";
|
|
1885
|
+
return { kind: "libCall", fn, args: [receiver], type: arrayOf(STRING), loc };
|
|
1837
1886
|
}
|
|
1838
1887
|
if (name === "statusMessage") {
|
|
1839
1888
|
// `string | undefined` — the reason phrase on client responses (""
|
|
@@ -1870,19 +1919,21 @@ export function lowerServerProperty(lowerer, expr) {
|
|
|
1870
1919
|
// guarded-no-op / unguarded-TypeError stance; other reads fence.
|
|
1871
1920
|
lowerer.noLowering(`reading '${name}' (an HTTP/2-only member) from a request`, expr, "compatibility requests do not expose their backing h2 stream/session yet; guarded method calls no-op and other reads have no lowering");
|
|
1872
1921
|
}
|
|
1873
|
-
if (name === "headers") {
|
|
1874
|
-
//
|
|
1875
|
-
//
|
|
1876
|
-
// copies too; the per-name READS keep their direct lowerings).
|
|
1922
|
+
if (name === "headers" || name === "trailers" || name === "headersDistinct" || name === "trailersDistinct") {
|
|
1923
|
+
// Whole-object reads materialize a typed snapshot record. Per-name
|
|
1924
|
+
// reads retain their direct lowerings.
|
|
1877
1925
|
const mapped = lowerer.mapTypeOf(lowerer.typeOf(expr));
|
|
1878
1926
|
if (mapped?.kind === "record") {
|
|
1879
|
-
const helper =
|
|
1927
|
+
const helper = name === "headers"
|
|
1928
|
+
? headersSnapshotHelper(lowerer, mapped.shapeId, loc)
|
|
1929
|
+
: name === "trailers" ? trailersSnapshotHelper(lowerer, mapped.shapeId, loc)
|
|
1930
|
+
: distinctSnapshotHelper(lowerer, mapped.shapeId, loc, name);
|
|
1880
1931
|
if (helper !== null) {
|
|
1881
1932
|
const receiver = coerceToHandle(lowerer, expr.expression, HTTPREQ_T);
|
|
1882
1933
|
return { kind: "call", callee: helper, args: [receiver], type: mapped, loc };
|
|
1883
1934
|
}
|
|
1884
1935
|
}
|
|
1885
|
-
lowerer.unsupported("SC1090", expr,
|
|
1936
|
+
lowerer.unsupported("SC1090", expr, `req.${name} as a value of this type (read one field: req.${name}.name or req.${name}[name])`);
|
|
1886
1937
|
}
|
|
1887
1938
|
}
|
|
1888
1939
|
if (recvKind === "httpRes" && lowerer.isStdlibMember(expr) && expr.name.text === "stream") {
|
|
@@ -1951,15 +2002,61 @@ export function lowerServerProperty(lowerer, expr) {
|
|
|
1951
2002
|
const receiver = coerceToHandle(lowerer, expr.expression, HTTPCLIENTREQ_T);
|
|
1952
2003
|
return { kind: "libCall", fn: "http.clientDestroyed", args: [receiver], type: BOOL, loc };
|
|
1953
2004
|
}
|
|
1954
|
-
if (
|
|
2005
|
+
if (recvKind === "httpClientReq" && lowerer.isStdlibMember(expr) &&
|
|
2006
|
+
(expr.name.text === "socket" || expr.name.text === "connection")) {
|
|
2007
|
+
const receiver = coerceToHandle(lowerer, expr.expression, HTTPCLIENTREQ_T);
|
|
2008
|
+
return { kind: "libCall", fn: "http.clientSocket", args: [receiver], type: NETSOCKET_T, loc };
|
|
2009
|
+
}
|
|
2010
|
+
if (recvKind === "httpClientReq" && lowerer.isStdlibMember(expr) && expr.name.text === "writableCorked") {
|
|
2011
|
+
const receiver = coerceToHandle(lowerer, expr.expression, HTTPCLIENTREQ_T);
|
|
2012
|
+
return { kind: "libCall", fn: "http.clientWritableCorked", args: [receiver], type: F64, loc };
|
|
2013
|
+
}
|
|
2014
|
+
if (recvKind === "httpClientReq" && lowerer.isStdlibMember(expr)) {
|
|
2015
|
+
const name = expr.name.text;
|
|
2016
|
+
const strFn = name === "method" ? "http.clientMethod"
|
|
2017
|
+
: name === "path" ? "http.clientPath"
|
|
2018
|
+
: name === "host" ? "http.clientHost"
|
|
2019
|
+
: name === "protocol" ? "http.clientProtocol" : null;
|
|
2020
|
+
if (strFn !== null) {
|
|
2021
|
+
const receiver = coerceToHandle(lowerer, expr.expression, HTTPCLIENTREQ_T);
|
|
2022
|
+
return { kind: "libCall", fn: strFn, args: [receiver], type: STRING, loc };
|
|
2023
|
+
}
|
|
2024
|
+
const boolFn = name === "aborted" ? "http.clientAborted"
|
|
2025
|
+
: name === "headersSent" ? "http.clientHeadersSent"
|
|
2026
|
+
: name === "writableEnded" || name === "finished" ? "http.clientWritableEnded"
|
|
2027
|
+
: name === "writableFinished" ? "http.clientWritableFinished"
|
|
2028
|
+
: name === "reusedSocket" ? "http.clientReusedSocket" : null;
|
|
2029
|
+
if (boolFn !== null) {
|
|
2030
|
+
const receiver = coerceToHandle(lowerer, expr.expression, HTTPCLIENTREQ_T);
|
|
2031
|
+
return { kind: "libCall", fn: boolFn, args: [receiver], type: BOOL, loc };
|
|
2032
|
+
}
|
|
2033
|
+
}
|
|
2034
|
+
if (httpReqFieldCollection(lowerer, expr.expression) !== null) {
|
|
2035
|
+
const collection = httpReqFieldCollection(lowerer, expr.expression);
|
|
1955
2036
|
const receiver = coerceToHandle(lowerer, expr.expression.expression, HTTPREQ_T);
|
|
1956
2037
|
const key = { kind: "strLit", value: expr.name.text, type: STRING, loc };
|
|
1957
|
-
|
|
2038
|
+
const fn = collection === "headers" ? "http.reqHeader"
|
|
2039
|
+
: collection === "trailers" ? "http.reqTrailer"
|
|
2040
|
+
: collection === "headersDistinct" ? "http.reqHeaderValues" : "http.reqTrailerValues";
|
|
2041
|
+
const type = collection.endsWith("Distinct") ? lowerer.withUndefinedArm(arrayOf(STRING)) : lowerer.envValueType();
|
|
2042
|
+
return { kind: "libCall", fn, args: [receiver, key], type, loc };
|
|
1958
2043
|
}
|
|
1959
2044
|
if (recvKind === "httpRes" && lowerer.isStdlibMember(expr) && expr.name.text === "headersSent") {
|
|
1960
2045
|
const receiver = coerceToHandle(lowerer, expr.expression, HTTPRES_T);
|
|
1961
2046
|
return { kind: "libCall", fn: "http.resHeadersSent", args: [receiver], type: BOOL, loc };
|
|
1962
2047
|
}
|
|
2048
|
+
if (recvKind === "httpRes" && lowerer.isStdlibMember(expr) && expr.name.text === "writableEnded") {
|
|
2049
|
+
const receiver = coerceToHandle(lowerer, expr.expression, HTTPRES_T);
|
|
2050
|
+
return { kind: "libCall", fn: "http.resWritableEnded", args: [receiver], type: BOOL, loc };
|
|
2051
|
+
}
|
|
2052
|
+
if (recvKind === "httpRes" && lowerer.isStdlibMember(expr) && expr.name.text === "finished") {
|
|
2053
|
+
const receiver = coerceToHandle(lowerer, expr.expression, HTTPRES_T);
|
|
2054
|
+
return { kind: "libCall", fn: "http.resWritableEnded", args: [receiver], type: BOOL, loc };
|
|
2055
|
+
}
|
|
2056
|
+
if (recvKind === "httpRes" && lowerer.isStdlibMember(expr) && expr.name.text === "writableCorked") {
|
|
2057
|
+
const receiver = coerceToHandle(lowerer, expr.expression, HTTPRES_T);
|
|
2058
|
+
return { kind: "libCall", fn: "http.resWritableCorked", args: [receiver], type: F64, loc };
|
|
2059
|
+
}
|
|
1963
2060
|
if (recvKind === "httpRes" && lowerer.isStdlibMember(expr) && expr.name.text === "statusCode") {
|
|
1964
2061
|
// 200 until assigned — Node's fresh-response default; the assignment
|
|
1965
2062
|
// twin lives in lowerHttpResPropertyAssignment.
|
|
@@ -1967,11 +2064,30 @@ export function lowerServerProperty(lowerer, expr) {
|
|
|
1967
2064
|
return { kind: "libCall", fn: "http.resStatusGet", args: [receiver], type: F64, loc };
|
|
1968
2065
|
}
|
|
1969
2066
|
if (recvKind === "httpRes" && lowerer.isStdlibMember(expr) && expr.name.text === "statusMessage") {
|
|
1970
|
-
//
|
|
1971
|
-
// when none was set (Node answers undefined until the head goes out
|
|
1972
|
-
// — divergence: this surface is string-typed, the checker's shape).
|
|
2067
|
+
// Unset until the head is sent; then the assigned or default reason.
|
|
1973
2068
|
const receiver = coerceToHandle(lowerer, expr.expression, HTTPRES_T);
|
|
1974
|
-
return { kind: "libCall", fn: "http.resStatusMsgGet", args: [receiver], type: STRING, loc };
|
|
2069
|
+
return { kind: "libCall", fn: "http.resStatusMsgGet", args: [receiver], type: lowerer.withUndefinedArm(STRING), loc };
|
|
2070
|
+
}
|
|
2071
|
+
if (recvKind === "httpRes" && lowerer.isStdlibMember(expr)) {
|
|
2072
|
+
const name = expr.name.text;
|
|
2073
|
+
if (name === "req") {
|
|
2074
|
+
const receiver = coerceToHandle(lowerer, expr.expression, HTTPRES_T);
|
|
2075
|
+
return { kind: "libCall", fn: "http.resRequest", args: [receiver], type: HTTPREQ_T, loc };
|
|
2076
|
+
}
|
|
2077
|
+
if (name === "socket" || name === "connection") {
|
|
2078
|
+
const receiver = coerceToHandle(lowerer, expr.expression, HTTPRES_T);
|
|
2079
|
+
const type = { kind: "union", unionId: lowerer.unions.intern([NETSOCKET_T, NULL_T]) };
|
|
2080
|
+
return { kind: "libCall", fn: "http.resSocket", args: [receiver], type, loc };
|
|
2081
|
+
}
|
|
2082
|
+
if (name === "writableFinished") {
|
|
2083
|
+
const receiver = coerceToHandle(lowerer, expr.expression, HTTPRES_T);
|
|
2084
|
+
return { kind: "libCall", fn: "http.resWritableFinished", args: [receiver], type: BOOL, loc };
|
|
2085
|
+
}
|
|
2086
|
+
if (name === "sendDate" || name === "strictContentLength") {
|
|
2087
|
+
const receiver = coerceToHandle(lowerer, expr.expression, HTTPRES_T);
|
|
2088
|
+
const fn = name === "sendDate" ? "http.resSendDateGet" : "http.resStrictContentLengthGet";
|
|
2089
|
+
return { kind: "libCall", fn, args: [receiver], type: BOOL, loc };
|
|
2090
|
+
}
|
|
1975
2091
|
}
|
|
1976
2092
|
if (recvKind === "http2Session" && lowerer.isStdlibMember(expr)) {
|
|
1977
2093
|
const m = expr.name.text;
|
|
@@ -2084,6 +2200,7 @@ function lowerHttpServerOptions(lowerer, node, what) {
|
|
|
2084
2200
|
lowerer.noLowering(`${what} with a non-literal options argument`, node, "pass the options as an object literal: { requireHostHeader?, joinDuplicateHeaders? }");
|
|
2085
2201
|
}
|
|
2086
2202
|
let joinDup = false;
|
|
2203
|
+
let allowMissingHost = false;
|
|
2087
2204
|
let keepAliveTimeoutBuffer = null;
|
|
2088
2205
|
for (const prop of node.properties) {
|
|
2089
2206
|
let initializer;
|
|
@@ -2099,13 +2216,15 @@ function lowerHttpServerOptions(lowerer, node, what) {
|
|
|
2099
2216
|
}
|
|
2100
2217
|
const key = prop.name.text;
|
|
2101
2218
|
if (key === "requireHostHeader") {
|
|
2102
|
-
|
|
2103
|
-
|
|
2104
|
-
|
|
2105
|
-
|
|
2106
|
-
if (initializer
|
|
2107
|
-
|
|
2219
|
+
if (initializer !== null && initializer.kind === ts.SyntaxKind.FalseKeyword) {
|
|
2220
|
+
allowMissingHost = true;
|
|
2221
|
+
continue;
|
|
2222
|
+
}
|
|
2223
|
+
if (initializer !== null && initializer.kind === ts.SyntaxKind.TrueKeyword) {
|
|
2224
|
+
allowMissingHost = false;
|
|
2225
|
+
continue;
|
|
2108
2226
|
}
|
|
2227
|
+
lowerer.noLowering(`${what} with a non-literal requireHostHeader option`, prop, "the lowered forms are the literals requireHostHeader: true and false");
|
|
2109
2228
|
continue;
|
|
2110
2229
|
}
|
|
2111
2230
|
if (key === "joinDuplicateHeaders") {
|
|
@@ -2116,7 +2235,8 @@ function lowerHttpServerOptions(lowerer, node, what) {
|
|
|
2116
2235
|
continue;
|
|
2117
2236
|
}
|
|
2118
2237
|
if (initializer !== null && initializer.kind === ts.SyntaxKind.FalseKeyword) {
|
|
2119
|
-
|
|
2238
|
+
joinDup = false; /* Node's default: repeats keep the first value */
|
|
2239
|
+
continue;
|
|
2120
2240
|
}
|
|
2121
2241
|
lowerer.noLowering(`${what} with a non-literal joinDuplicateHeaders option`, prop, "the lowered forms are the literals joinDuplicateHeaders: true (repeats join \", \") and false (the keep-first default)");
|
|
2122
2242
|
}
|
|
@@ -2139,10 +2259,10 @@ function lowerHttpServerOptions(lowerer, node, what) {
|
|
|
2139
2259
|
keepAliveTimeoutBuffer = value;
|
|
2140
2260
|
continue;
|
|
2141
2261
|
}
|
|
2142
|
-
fenceOrDropOptionKey(lowerer, prop, key, what, HTTP_SERVER_DOCUMENTED_OPTIONS, "requireHostHeader
|
|
2262
|
+
fenceOrDropOptionKey(lowerer, prop, key, what, HTTP_SERVER_DOCUMENTED_OPTIONS, "requireHostHeader, joinDuplicateHeaders, and keepAliveTimeoutBuffer are the supported options");
|
|
2143
2263
|
// An undocumented key, dropped like Node drops it.
|
|
2144
2264
|
}
|
|
2145
|
-
return { joinDup, keepAliveTimeoutBuffer };
|
|
2265
|
+
return { joinDup, allowMissingHost, keepAliveTimeoutBuffer };
|
|
2146
2266
|
}
|
|
2147
2267
|
/** The shared createServer([options][, handler]) shapes behind
|
|
2148
2268
|
* http.createServer, http.Server, and `new http.Server`: no arguments
|
|
@@ -2168,18 +2288,18 @@ function lowerHttpCreateServerForms(lowerer, expr, what, loc) {
|
|
|
2168
2288
|
}
|
|
2169
2289
|
const opts = optsNode !== null
|
|
2170
2290
|
? lowerHttpServerOptions(lowerer, optsNode, what)
|
|
2171
|
-
: { joinDup: false, keepAliveTimeoutBuffer: null };
|
|
2291
|
+
: { joinDup: false, allowMissingHost: false, keepAliveTimeoutBuffer: null };
|
|
2172
2292
|
const server = handlerNode !== null
|
|
2173
2293
|
? { kind: "libCall", fn: "http.createServer", args: [lowerRequestHandlerArg(lowerer, handlerNode)], type: NETSERVER_T, loc }
|
|
2174
2294
|
: { kind: "libCall", fn: "http.createServerEmpty", args: [], type: NETSERVER_T, loc };
|
|
2175
|
-
if (!opts.joinDup && opts.keepAliveTimeoutBuffer === null)
|
|
2295
|
+
if (!opts.joinDup && !opts.allowMissingHost && opts.keepAliveTimeoutBuffer === null)
|
|
2176
2296
|
return server;
|
|
2177
2297
|
// The option-setting composition: an interned helper takes the option
|
|
2178
2298
|
// values first (preserving Node's options-before-handler evaluation
|
|
2179
2299
|
// order), then the fresh server, applies the modeled fields, and answers
|
|
2180
2300
|
// the server as the constructor/factory result.
|
|
2181
2301
|
const hasBuffer = opts.keepAliveTimeoutBuffer !== null;
|
|
2182
|
-
const key = `server.opts:${opts.joinDup ? 1 : 0}:${hasBuffer ? 1 : 0}`;
|
|
2302
|
+
const key = `server.opts:${opts.joinDup ? 1 : 0}:${opts.allowMissingHost ? 1 : 0}:${hasBuffer ? 1 : 0}`;
|
|
2183
2303
|
const existing = lowerer.arrHofHelpers.get(key);
|
|
2184
2304
|
const name = existing ?? `%server.opts.${lowerer.arrHofHelpers.size}`;
|
|
2185
2305
|
if (!existing) {
|
|
@@ -2206,6 +2326,13 @@ function lowerHttpCreateServerForms(lowerer, expr, what, loc) {
|
|
|
2206
2326
|
loc,
|
|
2207
2327
|
});
|
|
2208
2328
|
}
|
|
2329
|
+
if (opts.allowMissingHost) {
|
|
2330
|
+
body.push({
|
|
2331
|
+
kind: "exprStmt",
|
|
2332
|
+
expr: { kind: "libCall", fn: "http.serverAllowMissingHostHeader", args: [ref], type: VOID, loc },
|
|
2333
|
+
loc,
|
|
2334
|
+
});
|
|
2335
|
+
}
|
|
2209
2336
|
body.push({ kind: "return", value: ref, loc });
|
|
2210
2337
|
lowerer.liftedFns.push({
|
|
2211
2338
|
name,
|
|
@@ -2351,13 +2478,33 @@ export function lowerHttpServerNew(lowerer, expr) {
|
|
|
2351
2478
|
* (req, res), (req), or () — runtime adapters bridge each shape.
|
|
2352
2479
|
* Everything else the module declares fences qualified. */
|
|
2353
2480
|
function lowerHttpModuleCall(lowerer, expr, bi, loc) {
|
|
2481
|
+
if (bi.member === "validateHeaderName") {
|
|
2482
|
+
requireStatementPosition(lowerer, expr, "http.validateHeaderName(...)");
|
|
2483
|
+
if (expr.arguments.length < 1 || expr.arguments.length > 2 || expr.arguments.some(ts.isSpreadElement)) {
|
|
2484
|
+
lowerer.noLowering("http.validateHeaderName arguments", expr, "pass a header name and an optional label");
|
|
2485
|
+
}
|
|
2486
|
+
const name = lowerer.lowerExprExpecting(expr.arguments[0], STRING);
|
|
2487
|
+
const label = expr.arguments.length === 2
|
|
2488
|
+
? lowerer.lowerExprExpecting(expr.arguments[1], STRING)
|
|
2489
|
+
: strLit("Header name", loc);
|
|
2490
|
+
return { kind: "libCall", fn: "http.validateHeaderName", args: [name, label], type: VOID, loc };
|
|
2491
|
+
}
|
|
2492
|
+
if (bi.member === "validateHeaderValue") {
|
|
2493
|
+
requireStatementPosition(lowerer, expr, "http.validateHeaderValue(...)");
|
|
2494
|
+
if (expr.arguments.length !== 2 || expr.arguments.some(ts.isSpreadElement)) {
|
|
2495
|
+
lowerer.noLowering("http.validateHeaderValue arguments", expr, "pass a header name and a value");
|
|
2496
|
+
}
|
|
2497
|
+
const name = lowerer.lowerExprExpecting(expr.arguments[0], STRING);
|
|
2498
|
+
const value = lowerer.lowerExprExpecting(expr.arguments[1], DYN);
|
|
2499
|
+
return { kind: "libCall", fn: "http.validateHeaderValue", args: [name, value], type: VOID, loc };
|
|
2500
|
+
}
|
|
2354
2501
|
if (bi.member === "createServer" || bi.member === "Server") {
|
|
2355
2502
|
return lowerHttpCreateServerForms(lowerer, expr, `http.${bi.member}`, loc);
|
|
2356
2503
|
}
|
|
2357
2504
|
if (bi.member === "request" || bi.member === "get") {
|
|
2358
2505
|
return lowerHttpClientCall(lowerer, expr, bi.member, loc);
|
|
2359
2506
|
}
|
|
2360
|
-
lowerer.noLowering(`http.${bi.member}`, expr, "createServer, Server, request, and
|
|
2507
|
+
lowerer.noLowering(`http.${bi.member}`, expr, "createServer, Server, request, get, validateHeaderName, and validateHeaderValue are the lowered http module functions", lowerer.resolveValueSymbol(expr.expression));
|
|
2361
2508
|
}
|
|
2362
2509
|
/** The cert/key PEM option of tls.createServer / https.createServer: an
|
|
2363
2510
|
* OBJECT LITERAL whose lowered `cert` and `key` entries are strings or
|
|
@@ -3593,6 +3740,28 @@ function lowerClientHeadersOption(lowerer, node) {
|
|
|
3593
3740
|
}
|
|
3594
3741
|
return { kind: "call", callee: helper, args: [v], type: arrayOf(STRING), loc };
|
|
3595
3742
|
}
|
|
3743
|
+
/** OutgoingMessage.addTrailers accepts an object or a pair-list literal.
|
|
3744
|
+
* Flatten the latter in source order; non-literal nested arrays currently
|
|
3745
|
+
* fence rather than reaching the C runtime with the wrong wire shape. */
|
|
3746
|
+
function lowerHttpTrailersOption(lowerer, node) {
|
|
3747
|
+
if (!ts.isArrayLiteralExpression(node))
|
|
3748
|
+
return lowerClientHeadersOption(lowerer, node);
|
|
3749
|
+
const loc = locOf(node);
|
|
3750
|
+
const flat = [];
|
|
3751
|
+
for (const entry of node.elements) {
|
|
3752
|
+
if (!ts.isArrayLiteralExpression(entry) || entry.elements.length !== 2) {
|
|
3753
|
+
lowerer.noLowering("addTrailers pair list", entry, "use an object/Record or literal [name, value] pairs");
|
|
3754
|
+
}
|
|
3755
|
+
const pair = entry;
|
|
3756
|
+
const name = pair.elements[0];
|
|
3757
|
+
const value = pair.elements[1];
|
|
3758
|
+
if (ts.isSpreadElement(name) || ts.isSpreadElement(value)) {
|
|
3759
|
+
lowerer.noLowering("addTrailers pair with spread", entry, "use direct string name/value expressions");
|
|
3760
|
+
}
|
|
3761
|
+
flat.push(lowerer.lowerExprExpecting(name, STRING), lowerer.lowerExprExpecting(value, STRING));
|
|
3762
|
+
}
|
|
3763
|
+
return { kind: "arrayLit", elems: flat, type: arrayOf(STRING), loc };
|
|
3764
|
+
}
|
|
3596
3765
|
/** Method calls on ClientRequest receivers: write/end/destroy and
|
|
3597
3766
|
* on/once("response" | "error" | "timeout" | "close"). Null for other
|
|
3598
3767
|
* receivers. */
|
|
@@ -3604,6 +3773,83 @@ function lowerHttpClientMethodCall(lowerer, call, access) {
|
|
|
3604
3773
|
const name = access.name.text;
|
|
3605
3774
|
const loc = locOf(call);
|
|
3606
3775
|
const args = call.arguments;
|
|
3776
|
+
if (name === "setHeader") {
|
|
3777
|
+
requireStatementPosition(lowerer, call, "request.setHeader(...)");
|
|
3778
|
+
if (args.length !== 2)
|
|
3779
|
+
lowerer.noLowering("request.setHeader arguments", call, "pass a name and string value");
|
|
3780
|
+
const receiver = coerceToHandle(lowerer, access.expression, HTTPCLIENTREQ_T);
|
|
3781
|
+
const header = lowerer.lowerExprExpecting(args[0], STRING);
|
|
3782
|
+
const value = lowerer.lowerExprExpecting(args[1], STRING);
|
|
3783
|
+
return { kind: "libCall", fn: "http.clientSetHeader", args: [receiver, header, value], type: VOID, loc };
|
|
3784
|
+
}
|
|
3785
|
+
if (name === "getHeader" || name === "hasHeader" || name === "removeHeader") {
|
|
3786
|
+
if (name === "removeHeader")
|
|
3787
|
+
requireStatementPosition(lowerer, call, "request.removeHeader(...)");
|
|
3788
|
+
if (args.length !== 1)
|
|
3789
|
+
lowerer.noLowering(`request.${name} arguments`, call, `pass one header name`);
|
|
3790
|
+
const receiver = coerceToHandle(lowerer, access.expression, HTTPCLIENTREQ_T);
|
|
3791
|
+
const header = lowerer.lowerExprExpecting(args[0], STRING);
|
|
3792
|
+
const fn = name === "getHeader" ? "http.clientGetHeader"
|
|
3793
|
+
: name === "hasHeader" ? "http.clientHasHeader" : "http.clientRemoveHeader";
|
|
3794
|
+
const type = name === "getHeader" ? lowerer.envValueType() : name === "hasHeader" ? BOOL : VOID;
|
|
3795
|
+
return { kind: "libCall", fn, args: [receiver, header], type, loc };
|
|
3796
|
+
}
|
|
3797
|
+
if (name === "getHeaderNames" || name === "getRawHeaderNames" || name === "getHeaders") {
|
|
3798
|
+
if (args.length !== 0)
|
|
3799
|
+
lowerer.noLowering(`request.${name} arguments`, call, `${name}() takes no arguments`);
|
|
3800
|
+
const receiver = coerceToHandle(lowerer, access.expression, HTTPCLIENTREQ_T);
|
|
3801
|
+
const fn = name === "getHeaderNames" ? "http.clientGetHeaderNames"
|
|
3802
|
+
: name === "getRawHeaderNames" ? "http.clientGetRawHeaderNames" : "http.clientGetHeaders";
|
|
3803
|
+
return { kind: "libCall", fn, args: [receiver], type: name === "getHeaders" ? DYN : arrayOf(STRING), loc };
|
|
3804
|
+
}
|
|
3805
|
+
if (name === "flushHeaders" || name === "cork" || name === "uncork") {
|
|
3806
|
+
requireStatementPosition(lowerer, call, `request.${name}()`);
|
|
3807
|
+
if (args.length !== 0)
|
|
3808
|
+
lowerer.noLowering(`request.${name} with arguments`, call, `${name}() takes no arguments`);
|
|
3809
|
+
const receiver = coerceToHandle(lowerer, access.expression, HTTPCLIENTREQ_T);
|
|
3810
|
+
const fn = name === "flushHeaders" ? "http.clientFlushHeaders"
|
|
3811
|
+
: name === "cork" ? "http.clientCork" : "http.clientUncork";
|
|
3812
|
+
return { kind: "libCall", fn, args: [receiver], type: VOID, loc };
|
|
3813
|
+
}
|
|
3814
|
+
if (name === "setNoDelay") {
|
|
3815
|
+
requireStatementPosition(lowerer, call, "request.setNoDelay(...)");
|
|
3816
|
+
if (args.length > 1)
|
|
3817
|
+
lowerer.noLowering("request.setNoDelay arguments", call, "pass an optional boolean");
|
|
3818
|
+
const receiver = coerceToHandle(lowerer, access.expression, HTTPCLIENTREQ_T);
|
|
3819
|
+
const enable = args.length === 0 ? boolLit(true, loc) : lowerer.lowerExprExpecting(args[0], BOOL);
|
|
3820
|
+
return { kind: "libCall", fn: "http.clientSetNoDelay", args: [receiver, enable], type: VOID, loc };
|
|
3821
|
+
}
|
|
3822
|
+
if (name === "setSocketKeepAlive") {
|
|
3823
|
+
requireStatementPosition(lowerer, call, "request.setSocketKeepAlive(...)");
|
|
3824
|
+
if (args.length > 2)
|
|
3825
|
+
lowerer.noLowering("request.setSocketKeepAlive arguments", call, "pass an optional boolean and initial delay in milliseconds");
|
|
3826
|
+
const receiver = coerceToHandle(lowerer, access.expression, HTTPCLIENTREQ_T);
|
|
3827
|
+
const enable = args.length === 0 ? boolLit(true, loc) : lowerer.lowerExprExpecting(args[0], BOOL);
|
|
3828
|
+
const delay = args.length < 2 ? numLit(0, loc) : lowerer.lowerExprExpecting(args[1], F64);
|
|
3829
|
+
return { kind: "libCall", fn: "http.clientSetSocketKeepAlive", args: [receiver, enable, delay], type: VOID, loc };
|
|
3830
|
+
}
|
|
3831
|
+
if (name === "setTimeout") {
|
|
3832
|
+
if (args.length < 1 || args.length > 2)
|
|
3833
|
+
lowerer.noLowering("request.setTimeout arguments", call, "pass milliseconds and an optional callback");
|
|
3834
|
+
const receiver = coerceToHandle(lowerer, access.expression, HTTPCLIENTREQ_T);
|
|
3835
|
+
const ms = lowerer.lowerExprExpecting(args[0], F64);
|
|
3836
|
+
const cb = args.length === 2
|
|
3837
|
+
? lowerCallbackArg(lowerer, args[1], "request timeout callbacks", 0, () => false, "use ()", []).cb
|
|
3838
|
+
: null;
|
|
3839
|
+
const fn = cb === null ? "http.clientSetTimeout" : "http.clientSetTimeoutCb";
|
|
3840
|
+
const callArgs = cb === null ? [receiver, ms] : [receiver, ms, cb];
|
|
3841
|
+
if (resultIsDiscarded(call))
|
|
3842
|
+
return { kind: "libCall", fn, args: callArgs, type: VOID, loc };
|
|
3843
|
+
return receiverReturningCall(lowerer, fn, callArgs, HTTPCLIENTREQ_T, loc);
|
|
3844
|
+
}
|
|
3845
|
+
if (name === "addTrailers") {
|
|
3846
|
+
requireStatementPosition(lowerer, call, "request.addTrailers(...)");
|
|
3847
|
+
if (args.length !== 1)
|
|
3848
|
+
lowerer.noLowering("request.addTrailers argument count", call, "pass one trailer object or pair-list literal");
|
|
3849
|
+
const receiver = coerceToHandle(lowerer, access.expression, HTTPCLIENTREQ_T);
|
|
3850
|
+
const pairs = lowerHttpTrailersOption(lowerer, args[0]);
|
|
3851
|
+
return { kind: "libCall", fn: "http.clientAddTrailers", args: [receiver, pairs], type: VOID, loc };
|
|
3852
|
+
}
|
|
3607
3853
|
if (name === "write" || name === "end") {
|
|
3608
3854
|
requireStatementPosition(lowerer, call, `request.${name}(...)`);
|
|
3609
3855
|
const minArgs = name === "write" ? 1 : 0;
|
|
@@ -3630,13 +3876,13 @@ function lowerHttpClientMethodCall(lowerer, call, access) {
|
|
|
3630
3876
|
}
|
|
3631
3877
|
lowerer.noLowering(`${name} of '${lowerer.fmt(data.type)}' data`, args[0] ?? call, NARROW_DATA_HINT);
|
|
3632
3878
|
}
|
|
3633
|
-
if (name === "destroy") {
|
|
3634
|
-
requireStatementPosition(lowerer, call,
|
|
3879
|
+
if (name === "destroy" || name === "abort") {
|
|
3880
|
+
requireStatementPosition(lowerer, call, `request.${name}()`);
|
|
3635
3881
|
if (args.length !== 0) {
|
|
3636
|
-
lowerer.noLowering(
|
|
3882
|
+
lowerer.noLowering(`${name} with ${args.length} arguments`, call, `${name}() takes no arguments here`);
|
|
3637
3883
|
}
|
|
3638
3884
|
const receiver = lowerer.lowerExpr(access.expression);
|
|
3639
|
-
return { kind: "libCall", fn: "http.clientDestroy", args: [receiver], type: VOID, loc };
|
|
3885
|
+
return { kind: "libCall", fn: name === "destroy" ? "http.clientDestroy" : "http.clientAbort", args: [receiver], type: VOID, loc };
|
|
3640
3886
|
}
|
|
3641
3887
|
if ((name === "on" || name === "once" || name === "addListener") && args.length === 2) {
|
|
3642
3888
|
requireStatementPosition(lowerer, call, `request.${name}(...)`);
|
|
@@ -3648,13 +3894,19 @@ function lowerHttpClientMethodCall(lowerer, call, access) {
|
|
|
3648
3894
|
const { cb } = lowerCallbackArg(lowerer, args[1], "response listeners", 1, (p) => p.kind === "httpReq", "use (res) or ()", [HTTPREQ_T]);
|
|
3649
3895
|
return { kind: "libCall", fn: "http.clientOnResponse", args: [receiver, cb, once], type: VOID, loc };
|
|
3650
3896
|
}
|
|
3897
|
+
if (event === "socket") {
|
|
3898
|
+
const { cb } = lowerCallbackArg(lowerer, args[1], "socket listeners", 1, (p) => p.kind === "netSocket", "use (socket) or ()", [NETSOCKET_T]);
|
|
3899
|
+
return { kind: "libCall", fn: "http.clientOnSocket", args: [receiver, cb, once], type: VOID, loc };
|
|
3900
|
+
}
|
|
3651
3901
|
if (event === "error") {
|
|
3652
3902
|
const { cb } = lowerCallbackArg(lowerer, args[1], "error listeners", 1, (p) => p.kind === "object" && p.className === "%Error", "use (err) or ()", [ERROR_T]);
|
|
3653
3903
|
return { kind: "libCall", fn: "http.clientOnError", args: [receiver, cb, once], type: VOID, loc };
|
|
3654
3904
|
}
|
|
3655
|
-
if (event === "timeout" || event === "close") {
|
|
3905
|
+
if (event === "timeout" || event === "close" || event === "finish" || event === "abort") {
|
|
3656
3906
|
const { cb } = lowerCallbackArg(lowerer, args[1], `${event} listeners`, 0, () => false, "use ()", []);
|
|
3657
|
-
const fn = event === "timeout" ? "http.clientOnTimeout"
|
|
3907
|
+
const fn = event === "timeout" ? "http.clientOnTimeout"
|
|
3908
|
+
: event === "close" ? "http.clientOnClose"
|
|
3909
|
+
: event === "abort" ? "http.clientOnAbort" : "http.clientOnFinish";
|
|
3658
3910
|
return { kind: "libCall", fn, args: [receiver, cb, once], type: VOID, loc };
|
|
3659
3911
|
}
|
|
3660
3912
|
if (event === "upgrade") {
|
|
@@ -3676,9 +3928,9 @@ function lowerHttpClientMethodCall(lowerer, call, access) {
|
|
|
3676
3928
|
}
|
|
3677
3929
|
return { kind: "libCall", fn: "http.clientOnUpgrade", args: [receiver, cb, once], type: VOID, loc };
|
|
3678
3930
|
}
|
|
3679
|
-
lowerer.noLowering(`request.${name}(${event === null ? "non-literal event" : `"${event}"`}, ...)`, args[0], '"response", "upgrade", "error", "timeout", and "close" are the supported request events (as literals)');
|
|
3931
|
+
lowerer.noLowering(`request.${name}(${event === null ? "non-literal event" : `"${event}"`}, ...)`, args[0], '"response", "socket", "upgrade", "error", "timeout", "finish", "abort", and "close" are the supported request events (as literals)');
|
|
3680
3932
|
}
|
|
3681
|
-
lowerer.noLowering(`ClientRequest.${name}`, call, "write, end, destroy,
|
|
3933
|
+
lowerer.noLowering(`ClientRequest.${name}`, call, "header reads/mutations, write, end, destroy, and on/once of response/error/timeout/close are the supported ClientRequest members", lowerer.checker.getSymbolAtLocation(access.name));
|
|
3682
3934
|
}
|
|
3683
3935
|
/** True when `node` is the h2-only stream/session CALL shape —
|
|
3684
3936
|
* `req.stream.destroy()` / `req.session.m(...)` on an identifier
|
|
@@ -3728,31 +3980,37 @@ export function lowerSocketInstanceOf(lowerer, expr, loc) {
|
|
|
3728
3980
|
}
|
|
3729
3981
|
/** True when `node` reads `.headers` off an IncomingMessage — the
|
|
3730
3982
|
* receiver shape of both header-read forms. */
|
|
3731
|
-
function
|
|
3732
|
-
|
|
3983
|
+
function httpReqFieldCollection(lowerer, node) {
|
|
3984
|
+
if (ts.isPropertyAccessExpression(node) &&
|
|
3733
3985
|
!node.questionDotToken &&
|
|
3734
|
-
node.name.text === "headers"
|
|
3986
|
+
(node.name.text === "headers" || node.name.text === "trailers" ||
|
|
3987
|
+
node.name.text === "headersDistinct" || node.name.text === "trailersDistinct") &&
|
|
3735
3988
|
lowerer.mapTypeOf(lowerer.typeOf(node.expression))?.kind === "httpReq" &&
|
|
3736
|
-
lowerer.isStdlibMember(node))
|
|
3989
|
+
lowerer.isStdlibMember(node))
|
|
3990
|
+
return node.name.text;
|
|
3991
|
+
return null;
|
|
3737
3992
|
}
|
|
3738
3993
|
/** `req.headers["x-name"]` — the element twin of the property read below;
|
|
3739
3994
|
* called from lowerElementAccess (the process.env precedent). Answers the
|
|
3740
3995
|
* interned `string | undefined` union; names match case-insensitively
|
|
3741
3996
|
* (the runtime stores them lowercased, like Node). */
|
|
3742
3997
|
export function lowerHttpHeadersElement(lowerer, expr) {
|
|
3743
|
-
|
|
3998
|
+
const collection = httpReqFieldCollection(lowerer, expr.expression);
|
|
3999
|
+
if (collection === null)
|
|
3744
4000
|
return null;
|
|
3745
4001
|
const recv = expr.expression.expression;
|
|
3746
4002
|
const key = lowerer.lowerExpr(expr.argumentExpression);
|
|
3747
4003
|
if (key.type.kind !== "string") {
|
|
3748
|
-
lowerer.unsupported("SC1090", expr.argumentExpression,
|
|
4004
|
+
lowerer.unsupported("SC1090", expr.argumentExpression, `indexing req.${collection} with non-string keys`);
|
|
3749
4005
|
}
|
|
3750
4006
|
const receiver = lowerer.lowerExpr(recv);
|
|
3751
4007
|
return {
|
|
3752
4008
|
kind: "libCall",
|
|
3753
|
-
fn: "http.reqHeader"
|
|
4009
|
+
fn: collection === "headers" ? "http.reqHeader"
|
|
4010
|
+
: collection === "trailers" ? "http.reqTrailer"
|
|
4011
|
+
: collection === "headersDistinct" ? "http.reqHeaderValues" : "http.reqTrailerValues",
|
|
3754
4012
|
args: [receiver, key],
|
|
3755
|
-
type: lowerer.envValueType(),
|
|
4013
|
+
type: collection.endsWith("Distinct") ? lowerer.withUndefinedArm(arrayOf(STRING)) : lowerer.envValueType(),
|
|
3756
4014
|
loc: locOf(expr),
|
|
3757
4015
|
};
|
|
3758
4016
|
}
|
|
@@ -3766,6 +4024,17 @@ function lowerHttpReqMethodCall(lowerer, call, access) {
|
|
|
3766
4024
|
const name = access.name.text;
|
|
3767
4025
|
const loc = locOf(call);
|
|
3768
4026
|
const args = call.arguments;
|
|
4027
|
+
if (name === "setTimeout") {
|
|
4028
|
+
requireStatementPosition(lowerer, call, "message.setTimeout(...)");
|
|
4029
|
+
if (args.length < 1 || args.length > 2)
|
|
4030
|
+
lowerer.noLowering("message.setTimeout arguments", call, "pass milliseconds and an optional callback");
|
|
4031
|
+
const receiver = coerceToHandle(lowerer, access.expression, HTTPREQ_T);
|
|
4032
|
+
const ms = lowerer.lowerExprExpecting(args[0], F64);
|
|
4033
|
+
if (args.length === 1)
|
|
4034
|
+
return { kind: "libCall", fn: "http.reqSetTimeout", args: [receiver, ms], type: VOID, loc };
|
|
4035
|
+
const { cb } = lowerCallbackArg(lowerer, args[1], "message timeout callbacks", 0, () => false, "use ()", []);
|
|
4036
|
+
return { kind: "libCall", fn: "http.reqSetTimeoutCb", args: [receiver, ms, cb], type: VOID, loc };
|
|
4037
|
+
}
|
|
3769
4038
|
if (name === "resume" || name === "destroy") {
|
|
3770
4039
|
requireStatementPosition(lowerer, call, `req.${name}()`);
|
|
3771
4040
|
if (args.length !== 0) {
|
|
@@ -3848,6 +4117,92 @@ function lowerHttpResMethodCall(lowerer, call, access) {
|
|
|
3848
4117
|
const name = access.name.text;
|
|
3849
4118
|
const loc = locOf(call);
|
|
3850
4119
|
const args = call.arguments;
|
|
4120
|
+
if (name === "setTimeout") {
|
|
4121
|
+
if (args.length < 1 || args.length > 2) {
|
|
4122
|
+
lowerer.noLowering(`res.setTimeout with ${args.length} arguments`, call, "use setTimeout(milliseconds[, callback])");
|
|
4123
|
+
}
|
|
4124
|
+
const receiver = coerceToHandle(lowerer, access.expression, HTTPRES_T);
|
|
4125
|
+
const ms = lowerer.lowerExprExpecting(args[0], F64);
|
|
4126
|
+
const cb = args.length === 2
|
|
4127
|
+
? lowerCallbackArg(lowerer, args[1], "response timeout callbacks", 0, () => false, "use ()", []).cb
|
|
4128
|
+
: null;
|
|
4129
|
+
const fn = cb === null ? "http.resSetTimeout" : "http.resSetTimeoutCb";
|
|
4130
|
+
const callArgs = cb === null ? [receiver, ms] : [receiver, ms, cb];
|
|
4131
|
+
if (resultIsDiscarded(call))
|
|
4132
|
+
return { kind: "libCall", fn, args: callArgs, type: VOID, loc };
|
|
4133
|
+
return receiverReturningCall(lowerer, fn, callArgs, HTTPRES_T, loc);
|
|
4134
|
+
}
|
|
4135
|
+
if (name === "writeContinue" || name === "writeProcessing" || name === "writeEarlyHints") {
|
|
4136
|
+
requireStatementPosition(lowerer, call, `res.${name}(...)`);
|
|
4137
|
+
if (lowerer.typeOf(access.expression).getSymbol()?.name === "Http2ServerResponse") {
|
|
4138
|
+
lowerer.noLowering(`Http2ServerResponse.${name}`, call, "HTTP/2 informational responses are not supported by the static runtime yet");
|
|
4139
|
+
}
|
|
4140
|
+
const receiver = coerceToHandle(lowerer, access.expression, HTTPRES_T);
|
|
4141
|
+
if (name !== "writeEarlyHints") {
|
|
4142
|
+
if (args.length !== 0)
|
|
4143
|
+
lowerer.noLowering(`res.${name} callback`, call, `${name}() supports no callback here`);
|
|
4144
|
+
return { kind: "libCall", fn: name === "writeContinue" ? "http.resWriteContinue" : "http.resWriteProcessing", args: [receiver], type: VOID, loc };
|
|
4145
|
+
}
|
|
4146
|
+
if (args.length !== 1)
|
|
4147
|
+
lowerer.noLowering("res.writeEarlyHints arguments", call, "pass one header object or Record<string, string> without a callback");
|
|
4148
|
+
const node = args[0];
|
|
4149
|
+
let pairs;
|
|
4150
|
+
if (ts.isObjectLiteralExpression(node)) {
|
|
4151
|
+
const elems = [];
|
|
4152
|
+
for (const prop of node.properties) {
|
|
4153
|
+
const key = ts.isPropertyAssignment(prop) ? staticHeaderKeyOf(lowerer, prop) : null;
|
|
4154
|
+
if (!ts.isPropertyAssignment(prop) || key === null) {
|
|
4155
|
+
lowerer.noLowering("writeEarlyHints headers with dynamic keys, spreads, or shorthand entries", prop, "use literal header keys and string values");
|
|
4156
|
+
}
|
|
4157
|
+
const value = lowerer.lowerExpr(prop.initializer);
|
|
4158
|
+
if (value.type.kind !== "string") {
|
|
4159
|
+
lowerer.noLowering(`writeEarlyHints value of type '${lowerer.fmt(value.type)}'`, prop.initializer, "header values must be strings here");
|
|
4160
|
+
}
|
|
4161
|
+
elems.push({ kind: "strLit", value: key, type: STRING, loc }, value);
|
|
4162
|
+
}
|
|
4163
|
+
pairs = { kind: "arrayLit", elems, type: arrayOf(STRING), loc };
|
|
4164
|
+
}
|
|
4165
|
+
else {
|
|
4166
|
+
const value = lowerer.lowerExpr(node);
|
|
4167
|
+
if (value.type.kind !== "record") {
|
|
4168
|
+
lowerer.noLowering(`writeEarlyHints headers of '${lowerer.fmt(value.type)}'`, node, "pass an object literal or a Record<string, string>");
|
|
4169
|
+
}
|
|
4170
|
+
const helper = lowerer.envToPairsHelper(value.type.shapeId, loc);
|
|
4171
|
+
if (helper === null) {
|
|
4172
|
+
lowerer.noLowering("writeEarlyHints header values", node, "use a Record<string, string> with string values");
|
|
4173
|
+
}
|
|
4174
|
+
pairs = { kind: "call", callee: helper, args: [value], type: arrayOf(STRING), loc };
|
|
4175
|
+
}
|
|
4176
|
+
return { kind: "libCall", fn: "http.resWriteEarlyHints", args: [receiver, pairs], type: VOID, loc };
|
|
4177
|
+
}
|
|
4178
|
+
if (name === "getHeaderNames" || name === "getRawHeaderNames" || name === "getHeaders") {
|
|
4179
|
+
if (args.length !== 0)
|
|
4180
|
+
lowerer.noLowering(`res.${name} arguments`, call, `${name}() takes no arguments`);
|
|
4181
|
+
const receiver = coerceToHandle(lowerer, access.expression, HTTPRES_T);
|
|
4182
|
+
const fn = name === "getHeaderNames" ? "http.resGetHeaderNames"
|
|
4183
|
+
: name === "getRawHeaderNames" ? "http.resGetRawHeaderNames" : "http.resGetHeaders";
|
|
4184
|
+
return { kind: "libCall", fn, args: [receiver], type: name === "getHeaders" ? DYN : arrayOf(STRING), loc };
|
|
4185
|
+
}
|
|
4186
|
+
if (name === "flushHeaders" || name === "cork" || name === "uncork") {
|
|
4187
|
+
requireStatementPosition(lowerer, call, `res.${name}()`);
|
|
4188
|
+
if (args.length !== 0)
|
|
4189
|
+
lowerer.noLowering(`res.${name} with arguments`, call, `${name}() takes no arguments`);
|
|
4190
|
+
const receiver = coerceToHandle(lowerer, access.expression, HTTPRES_T);
|
|
4191
|
+
const fn = name === "flushHeaders" ? "http.resFlushHeaders"
|
|
4192
|
+
: name === "cork" ? "http.resCork" : "http.resUncork";
|
|
4193
|
+
return { kind: "libCall", fn, args: [receiver], type: VOID, loc };
|
|
4194
|
+
}
|
|
4195
|
+
if (name === "addTrailers") {
|
|
4196
|
+
requireStatementPosition(lowerer, call, "res.addTrailers(...)");
|
|
4197
|
+
if (lowerer.typeOf(access.expression).getSymbol()?.name === "Http2ServerResponse") {
|
|
4198
|
+
lowerer.noLowering("Http2ServerResponse.addTrailers", call, "HTTP/2 response trailers are not supported by the static runtime yet");
|
|
4199
|
+
}
|
|
4200
|
+
if (args.length !== 1)
|
|
4201
|
+
lowerer.noLowering("res.addTrailers argument count", call, "pass one trailer object or pair-list literal");
|
|
4202
|
+
const receiver = coerceToHandle(lowerer, access.expression, HTTPRES_T);
|
|
4203
|
+
const pairs = lowerHttpTrailersOption(lowerer, args[0]);
|
|
4204
|
+
return { kind: "libCall", fn: "http.resAddTrailers", args: [receiver, pairs], type: VOID, loc };
|
|
4205
|
+
}
|
|
3851
4206
|
if (name === "setHeader") {
|
|
3852
4207
|
requireStatementPosition(lowerer, call, "res.setHeader(...)");
|
|
3853
4208
|
if (args.length !== 2) {
|
|
@@ -4094,8 +4449,12 @@ function lowerHttpResMethodCall(lowerer, call, access) {
|
|
|
4094
4449
|
const { cb } = lowerCallbackArg(lowerer, args[1], "close listeners", 0, () => false, "use ()", []);
|
|
4095
4450
|
return { kind: "libCall", fn: "http.resOnClose", args: [receiver, cb, once], type: VOID, loc };
|
|
4096
4451
|
}
|
|
4097
|
-
|
|
4452
|
+
if (event === "finish") {
|
|
4453
|
+
const { cb } = lowerCallbackArg(lowerer, args[1], "finish listeners", 0, () => false, "use ()", []);
|
|
4454
|
+
return { kind: "libCall", fn: "http.resOnFinish", args: [receiver, cb], type: VOID, loc };
|
|
4455
|
+
}
|
|
4456
|
+
lowerer.noLowering(`res.${name}(${event === null ? "non-literal event" : `"${event}"`}, ...)`, args[0], '"close" and "finish" are the supported response events (as literals)');
|
|
4098
4457
|
}
|
|
4099
|
-
lowerer.noLowering(`ServerResponse.${name}`, call, "setHeader, getHeader, hasHeader, removeHeader, writeHead, write, end, destroy,
|
|
4458
|
+
lowerer.noLowering(`ServerResponse.${name}`, call, "setHeader, getHeader, hasHeader, removeHeader, writeHead, writeContinue, writeProcessing, writeEarlyHints, setTimeout, write, end, destroy, response state reads, and on/once of close are the supported ServerResponse members", lowerer.checker.getSymbolAtLocation(access.name));
|
|
4100
4459
|
}
|
|
4101
4460
|
//# sourceMappingURL=lower-server.js.map
|