@effect/platform 0.87.1 → 0.87.3
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/HttpLayerRouter/package.json +6 -0
- package/README.md +271 -0
- package/dist/cjs/HttpApiBuilder.js +15 -1
- package/dist/cjs/HttpApiBuilder.js.map +1 -1
- package/dist/cjs/HttpApiScalar.js +29 -11
- package/dist/cjs/HttpApiScalar.js.map +1 -1
- package/dist/cjs/HttpApiSwagger.js +32 -15
- package/dist/cjs/HttpApiSwagger.js.map +1 -1
- package/dist/cjs/HttpApp.js +41 -4
- package/dist/cjs/HttpApp.js.map +1 -1
- package/dist/cjs/HttpBody.js.map +1 -1
- package/dist/cjs/HttpLayerRouter.js +494 -0
- package/dist/cjs/HttpLayerRouter.js.map +1 -0
- package/dist/cjs/index.js +3 -1
- package/dist/cjs/internal/httpRouter.js +3 -1
- package/dist/cjs/internal/httpRouter.js.map +1 -1
- package/dist/dts/HttpApiBuilder.d.ts +6 -0
- package/dist/dts/HttpApiBuilder.d.ts.map +1 -1
- package/dist/dts/HttpApiScalar.d.ts +14 -2
- package/dist/dts/HttpApiScalar.d.ts.map +1 -1
- package/dist/dts/HttpApiSwagger.d.ts +12 -2
- package/dist/dts/HttpApiSwagger.d.ts.map +1 -1
- package/dist/dts/HttpApp.d.ts +14 -1
- package/dist/dts/HttpApp.d.ts.map +1 -1
- package/dist/dts/HttpBody.d.ts +1 -1
- package/dist/dts/HttpBody.d.ts.map +1 -1
- package/dist/dts/HttpLayerRouter.d.ts +481 -0
- package/dist/dts/HttpLayerRouter.d.ts.map +1 -0
- package/dist/dts/index.d.ts +4 -0
- package/dist/dts/index.d.ts.map +1 -1
- package/dist/dts/internal/httpRouter.d.ts.map +1 -1
- package/dist/esm/HttpApiBuilder.js +14 -0
- package/dist/esm/HttpApiBuilder.js.map +1 -1
- package/dist/esm/HttpApiScalar.js +28 -10
- package/dist/esm/HttpApiScalar.js.map +1 -1
- package/dist/esm/HttpApiSwagger.js +31 -14
- package/dist/esm/HttpApiSwagger.js.map +1 -1
- package/dist/esm/HttpApp.js +37 -2
- package/dist/esm/HttpApp.js.map +1 -1
- package/dist/esm/HttpBody.js.map +1 -1
- package/dist/esm/HttpLayerRouter.js +468 -0
- package/dist/esm/HttpLayerRouter.js.map +1 -0
- package/dist/esm/index.js +4 -0
- package/dist/esm/index.js.map +1 -1
- package/dist/esm/internal/httpRouter.js +3 -1
- package/dist/esm/internal/httpRouter.js.map +1 -1
- package/package.json +10 -2
- package/src/HttpApiBuilder.ts +30 -0
- package/src/HttpApiScalar.ts +79 -41
- package/src/HttpApiSwagger.ts +49 -18
- package/src/HttpApp.ts +55 -2
- package/src/HttpBody.ts +1 -2
- package/src/HttpLayerRouter.ts +920 -0
- package/src/index.ts +5 -0
- package/src/internal/httpRouter.ts +4 -1
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@effect/platform",
|
|
3
|
-
"version": "0.87.
|
|
3
|
+
"version": "0.87.3",
|
|
4
4
|
"description": "Unified interfaces for common platform-specific services",
|
|
5
5
|
"license": "MIT",
|
|
6
6
|
"repository": {
|
|
@@ -16,7 +16,7 @@
|
|
|
16
16
|
"multipasta": "^0.2.5"
|
|
17
17
|
},
|
|
18
18
|
"peerDependencies": {
|
|
19
|
-
"effect": "^3.16.
|
|
19
|
+
"effect": "^3.16.11"
|
|
20
20
|
},
|
|
21
21
|
"publishConfig": {
|
|
22
22
|
"provenance": true
|
|
@@ -171,6 +171,11 @@
|
|
|
171
171
|
"import": "./dist/esm/HttpIncomingMessage.js",
|
|
172
172
|
"default": "./dist/cjs/HttpIncomingMessage.js"
|
|
173
173
|
},
|
|
174
|
+
"./HttpLayerRouter": {
|
|
175
|
+
"types": "./dist/dts/HttpLayerRouter.d.ts",
|
|
176
|
+
"import": "./dist/esm/HttpLayerRouter.js",
|
|
177
|
+
"default": "./dist/cjs/HttpLayerRouter.js"
|
|
178
|
+
},
|
|
174
179
|
"./HttpMethod": {
|
|
175
180
|
"types": "./dist/dts/HttpMethod.d.ts",
|
|
176
181
|
"import": "./dist/esm/HttpMethod.js",
|
|
@@ -418,6 +423,9 @@
|
|
|
418
423
|
"HttpIncomingMessage": [
|
|
419
424
|
"./dist/dts/HttpIncomingMessage.d.ts"
|
|
420
425
|
],
|
|
426
|
+
"HttpLayerRouter": [
|
|
427
|
+
"./dist/dts/HttpLayerRouter.d.ts"
|
|
428
|
+
],
|
|
421
429
|
"HttpMethod": [
|
|
422
430
|
"./dist/dts/HttpMethod.d.ts"
|
|
423
431
|
],
|
package/src/HttpApiBuilder.ts
CHANGED
|
@@ -123,6 +123,36 @@ export const httpApp: Effect.Effect<
|
|
|
123
123
|
) as any
|
|
124
124
|
})
|
|
125
125
|
|
|
126
|
+
/**
|
|
127
|
+
* @since 1.0.0
|
|
128
|
+
* @category constructors
|
|
129
|
+
*/
|
|
130
|
+
export const buildMiddleware: <Id extends string, Groups extends HttpApiGroup.HttpApiGroup.Any, E, R>(
|
|
131
|
+
api: HttpApi.HttpApi<Id, Groups, E, R>
|
|
132
|
+
) => Effect.Effect<
|
|
133
|
+
(
|
|
134
|
+
effect: Effect.Effect<HttpServerResponse.HttpServerResponse, unknown>
|
|
135
|
+
) => Effect.Effect<HttpServerResponse.HttpServerResponse, unknown, never>
|
|
136
|
+
> = Effect.fnUntraced(
|
|
137
|
+
function*<Id extends string, Groups extends HttpApiGroup.HttpApiGroup.Any, E, R>(
|
|
138
|
+
api: HttpApi.HttpApi<Id, Groups, E, R>
|
|
139
|
+
) {
|
|
140
|
+
const context = yield* Effect.context<never>()
|
|
141
|
+
const middlewareMap = makeMiddlewareMap(api.middlewares, context)
|
|
142
|
+
const errorSchema = makeErrorSchema(api as any)
|
|
143
|
+
const encodeError = Schema.encodeUnknown(errorSchema)
|
|
144
|
+
return (effect: Effect.Effect<HttpServerResponse.HttpServerResponse, unknown>) =>
|
|
145
|
+
Effect.catchAllCause(
|
|
146
|
+
applyMiddleware(middlewareMap, effect),
|
|
147
|
+
(cause) =>
|
|
148
|
+
Effect.matchEffect(Effect.provide(encodeError(Cause.squash(cause)), context), {
|
|
149
|
+
onFailure: () => Effect.failCause(cause),
|
|
150
|
+
onSuccess: Effect.succeed
|
|
151
|
+
})
|
|
152
|
+
)
|
|
153
|
+
}
|
|
154
|
+
)
|
|
155
|
+
|
|
126
156
|
/**
|
|
127
157
|
* Construct an http web handler from an `HttpApi` instance.
|
|
128
158
|
*
|
package/src/HttpApiScalar.ts
CHANGED
|
@@ -2,9 +2,11 @@
|
|
|
2
2
|
* @since 1.0.0
|
|
3
3
|
*/
|
|
4
4
|
import * as Effect from "effect/Effect"
|
|
5
|
-
import
|
|
5
|
+
import * as Layer from "effect/Layer"
|
|
6
6
|
import { Api } from "./HttpApi.js"
|
|
7
|
+
import type * as HttpApi from "./HttpApi.js"
|
|
7
8
|
import { Router } from "./HttpApiBuilder.js"
|
|
9
|
+
import * as HttpLayerRouter from "./HttpLayerRouter.js"
|
|
8
10
|
import * as HttpServerResponse from "./HttpServerResponse.js"
|
|
9
11
|
import * as Html from "./internal/html.js"
|
|
10
12
|
import * as internal from "./internal/httpApiScalar.js"
|
|
@@ -120,52 +122,45 @@ export type ScalarConfig = {
|
|
|
120
122
|
defaultOpenAllTags?: boolean
|
|
121
123
|
}
|
|
122
124
|
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
* @category layers
|
|
126
|
-
*/
|
|
127
|
-
export const layer = (options?: {
|
|
128
|
-
readonly path?: `/${string}` | undefined
|
|
125
|
+
const makeHandler = (options: {
|
|
126
|
+
readonly api: HttpApi.HttpApi.Any
|
|
129
127
|
readonly source?: ScalarScriptSource
|
|
130
128
|
readonly scalar?: ScalarConfig
|
|
131
|
-
})
|
|
132
|
-
|
|
133
|
-
Effect.gen(function*() {
|
|
134
|
-
const { api } = yield* Api
|
|
135
|
-
const spec = OpenApi.fromApi(api)
|
|
129
|
+
}) => {
|
|
130
|
+
const spec = OpenApi.fromApi(options.api as any)
|
|
136
131
|
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
132
|
+
const source = options?.source
|
|
133
|
+
const defaultScript = internal.javascript
|
|
134
|
+
const src: string | null = source
|
|
135
|
+
? typeof source === "string"
|
|
136
|
+
? source
|
|
137
|
+
: source.type === "cdn"
|
|
138
|
+
? `https://cdn.jsdelivr.net/npm/@scalar/api-reference@${
|
|
139
|
+
source.version ?? "latest"
|
|
140
|
+
}/dist/browser/standalone.min.js`
|
|
141
|
+
: null
|
|
142
|
+
: null
|
|
148
143
|
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
144
|
+
const scalarConfig = {
|
|
145
|
+
_integration: "http",
|
|
146
|
+
...options?.scalar
|
|
147
|
+
}
|
|
153
148
|
|
|
154
|
-
|
|
149
|
+
const response = HttpServerResponse.html(`<!doctype html>
|
|
155
150
|
<html>
|
|
156
151
|
<head>
|
|
157
152
|
<meta charset="utf-8" />
|
|
158
153
|
<title>${Html.escape(spec.info.title)}</title>
|
|
159
154
|
${
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
155
|
+
!spec.info.description
|
|
156
|
+
? ""
|
|
157
|
+
: `<meta name="description" content="${Html.escape(spec.info.description)}"/>`
|
|
158
|
+
}
|
|
164
159
|
${
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
160
|
+
!spec.info.description
|
|
161
|
+
? ""
|
|
162
|
+
: `<meta name="og:description" content="${Html.escape(spec.info.description)}"/>`
|
|
163
|
+
}
|
|
169
164
|
<meta
|
|
170
165
|
name="viewport"
|
|
171
166
|
content="width=device-width, initial-scale=1" />
|
|
@@ -178,12 +173,55 @@ export const layer = (options?: {
|
|
|
178
173
|
document.getElementById('api-reference').dataset.configuration = JSON.stringify(${Html.escapeJson(scalarConfig)})
|
|
179
174
|
</script>
|
|
180
175
|
${
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
|
|
176
|
+
src
|
|
177
|
+
? `<script src="${src}" crossorigin></script>`
|
|
178
|
+
: `<script>${defaultScript}</script>`
|
|
179
|
+
}
|
|
185
180
|
</body>
|
|
186
181
|
</html>`)
|
|
187
|
-
|
|
182
|
+
|
|
183
|
+
return Effect.succeed(response)
|
|
184
|
+
}
|
|
185
|
+
|
|
186
|
+
/**
|
|
187
|
+
* @since 1.0.0
|
|
188
|
+
* @category layers
|
|
189
|
+
*/
|
|
190
|
+
export const layer = (options?: {
|
|
191
|
+
readonly path?: `/${string}` | undefined
|
|
192
|
+
readonly source?: ScalarScriptSource
|
|
193
|
+
readonly scalar?: ScalarConfig
|
|
194
|
+
}): Layer.Layer<never, never, Api> =>
|
|
195
|
+
Router.use((router) =>
|
|
196
|
+
Effect.gen(function*() {
|
|
197
|
+
const { api } = yield* Api
|
|
198
|
+
const handler = makeHandler({ ...options, api })
|
|
199
|
+
yield* router.get(options?.path ?? "/docs", handler)
|
|
188
200
|
})
|
|
189
201
|
)
|
|
202
|
+
|
|
203
|
+
/**
|
|
204
|
+
* @since 1.0.0
|
|
205
|
+
* @category layers
|
|
206
|
+
*/
|
|
207
|
+
export const layerHttpLayerRouter: (
|
|
208
|
+
options: {
|
|
209
|
+
readonly api: HttpApi.HttpApi.Any
|
|
210
|
+
readonly path: `/${string}`
|
|
211
|
+
readonly source?: ScalarScriptSource
|
|
212
|
+
readonly scalar?: ScalarConfig
|
|
213
|
+
}
|
|
214
|
+
) => Layer.Layer<
|
|
215
|
+
never,
|
|
216
|
+
never,
|
|
217
|
+
HttpLayerRouter.HttpRouter
|
|
218
|
+
> = Effect.fnUntraced(function*(options: {
|
|
219
|
+
readonly api: HttpApi.HttpApi.Any
|
|
220
|
+
readonly path: `/${string}`
|
|
221
|
+
readonly source?: ScalarScriptSource
|
|
222
|
+
readonly scalar?: ScalarConfig
|
|
223
|
+
}) {
|
|
224
|
+
const router = yield* HttpLayerRouter.HttpRouter
|
|
225
|
+
const handler = makeHandler(options)
|
|
226
|
+
yield* router.add("GET", options.path, handler)
|
|
227
|
+
}, Layer.effectDiscard)
|
package/src/HttpApiSwagger.ts
CHANGED
|
@@ -2,30 +2,21 @@
|
|
|
2
2
|
* @since 1.0.0
|
|
3
3
|
*/
|
|
4
4
|
import * as Effect from "effect/Effect"
|
|
5
|
-
import
|
|
5
|
+
import * as Layer from "effect/Layer"
|
|
6
6
|
import { Api } from "./HttpApi.js"
|
|
7
|
+
import type * as HttpApi from "./HttpApi.js"
|
|
7
8
|
import { Router } from "./HttpApiBuilder.js"
|
|
9
|
+
import * as HttpLayerRouter from "./HttpLayerRouter.js"
|
|
8
10
|
import * as HttpServerResponse from "./HttpServerResponse.js"
|
|
9
11
|
import * as Html from "./internal/html.js"
|
|
10
12
|
import * as internal from "./internal/httpApiSwagger.js"
|
|
11
13
|
import * as OpenApi from "./OpenApi.js"
|
|
12
14
|
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
* @since 1.0.0
|
|
19
|
-
* @category layers
|
|
20
|
-
*/
|
|
21
|
-
export const layer = (options?: {
|
|
22
|
-
readonly path?: `/${string}` | undefined
|
|
23
|
-
}): Layer<never, never, Api> =>
|
|
24
|
-
Router.use((router) =>
|
|
25
|
-
Effect.gen(function*() {
|
|
26
|
-
const { api } = yield* Api
|
|
27
|
-
const spec = OpenApi.fromApi(api)
|
|
28
|
-
const response = HttpServerResponse.html(`<!DOCTYPE html>
|
|
15
|
+
const makeHandler = (options: {
|
|
16
|
+
readonly api: HttpApi.HttpApi.Any
|
|
17
|
+
}) => {
|
|
18
|
+
const spec = OpenApi.fromApi(options.api as any)
|
|
19
|
+
const response = HttpServerResponse.html(`<!DOCTYPE html>
|
|
29
20
|
<html lang="en">
|
|
30
21
|
<head>
|
|
31
22
|
<meta charset="utf-8" />
|
|
@@ -49,6 +40,46 @@ export const layer = (options?: {
|
|
|
49
40
|
</script>
|
|
50
41
|
</body>
|
|
51
42
|
</html>`)
|
|
52
|
-
|
|
43
|
+
return Effect.succeed(response)
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
/**
|
|
47
|
+
* Exported layer mounting Swagger/OpenAPI documentation UI.
|
|
48
|
+
*
|
|
49
|
+
* @param options.path Optional mount path (default "/docs").
|
|
50
|
+
*
|
|
51
|
+
* @since 1.0.0
|
|
52
|
+
* @category layers
|
|
53
|
+
*/
|
|
54
|
+
export const layer = (options?: {
|
|
55
|
+
readonly path?: `/${string}` | undefined
|
|
56
|
+
}): Layer.Layer<never, never, Api> =>
|
|
57
|
+
Router.use((router) =>
|
|
58
|
+
Effect.gen(function*() {
|
|
59
|
+
const { api } = yield* Api
|
|
60
|
+
const handler = makeHandler({ api })
|
|
61
|
+
yield* router.get(options?.path ?? "/docs", handler)
|
|
53
62
|
})
|
|
54
63
|
)
|
|
64
|
+
|
|
65
|
+
/**
|
|
66
|
+
* @since 1.0.0
|
|
67
|
+
* @category layers
|
|
68
|
+
*/
|
|
69
|
+
export const layerHttpLayerRouter: (
|
|
70
|
+
options: {
|
|
71
|
+
readonly api: HttpApi.HttpApi.Any
|
|
72
|
+
readonly path: `/${string}`
|
|
73
|
+
}
|
|
74
|
+
) => Layer.Layer<
|
|
75
|
+
never,
|
|
76
|
+
never,
|
|
77
|
+
HttpLayerRouter.HttpRouter
|
|
78
|
+
> = Effect.fnUntraced(function*(options: {
|
|
79
|
+
readonly api: HttpApi.HttpApi.Any
|
|
80
|
+
readonly path: `/${string}`
|
|
81
|
+
}) {
|
|
82
|
+
const router = yield* HttpLayerRouter.HttpRouter
|
|
83
|
+
const handler = makeHandler(options)
|
|
84
|
+
yield* router.add("GET", options.path, handler)
|
|
85
|
+
}, Layer.effectDiscard)
|
package/src/HttpApp.ts
CHANGED
|
@@ -4,12 +4,16 @@
|
|
|
4
4
|
import * as Context from "effect/Context"
|
|
5
5
|
import * as Effect from "effect/Effect"
|
|
6
6
|
import * as Exit from "effect/Exit"
|
|
7
|
+
import * as Fiber from "effect/Fiber"
|
|
7
8
|
import * as FiberRef from "effect/FiberRef"
|
|
9
|
+
import * as GlobalValue from "effect/GlobalValue"
|
|
8
10
|
import * as Layer from "effect/Layer"
|
|
9
|
-
import
|
|
11
|
+
import * as Option from "effect/Option"
|
|
10
12
|
import * as Runtime from "effect/Runtime"
|
|
11
13
|
import * as Scope from "effect/Scope"
|
|
14
|
+
import * as Stream from "effect/Stream"
|
|
12
15
|
import { unify } from "effect/Unify"
|
|
16
|
+
import * as HttpBody from "./HttpBody.js"
|
|
13
17
|
import type { HttpMiddleware } from "./HttpMiddleware.js"
|
|
14
18
|
import * as ServerError from "./HttpServerError.js"
|
|
15
19
|
import * as ServerRequest from "./HttpServerRequest.js"
|
|
@@ -115,9 +119,57 @@ export const toHandled = <E, R, _, EH, RH>(
|
|
|
115
119
|
})
|
|
116
120
|
)
|
|
117
121
|
|
|
118
|
-
return Effect.uninterruptible(
|
|
122
|
+
return Effect.uninterruptible(scoped(withMiddleware)) as any
|
|
119
123
|
}
|
|
120
124
|
|
|
125
|
+
/**
|
|
126
|
+
* If you want to finalize the http request scope elsewhere, you can use this
|
|
127
|
+
* function to eject from the default scope closure.
|
|
128
|
+
*
|
|
129
|
+
* @since 1.0.0
|
|
130
|
+
* @category Scope
|
|
131
|
+
*/
|
|
132
|
+
export const ejectDefaultScopeClose = (scope: Scope.Scope): void => {
|
|
133
|
+
ejectedScopes.add(scope)
|
|
134
|
+
}
|
|
135
|
+
|
|
136
|
+
/**
|
|
137
|
+
* @since 1.0.0
|
|
138
|
+
* @category Scope
|
|
139
|
+
*/
|
|
140
|
+
export const unsafeEjectStreamScope = (
|
|
141
|
+
response: ServerResponse.HttpServerResponse
|
|
142
|
+
): ServerResponse.HttpServerResponse => {
|
|
143
|
+
if (response.body._tag !== "Stream") {
|
|
144
|
+
return response
|
|
145
|
+
}
|
|
146
|
+
const fiber = Option.getOrThrow(Fiber.getCurrentFiber())
|
|
147
|
+
const scope = Context.unsafeGet(fiber.currentContext, Scope.Scope) as Scope.CloseableScope
|
|
148
|
+
ejectDefaultScopeClose(scope)
|
|
149
|
+
return ServerResponse.setBody(
|
|
150
|
+
response,
|
|
151
|
+
HttpBody.stream(
|
|
152
|
+
Stream.ensuring(response.body.stream, Scope.close(scope, Exit.void)),
|
|
153
|
+
response.body.contentType,
|
|
154
|
+
response.body.contentLength
|
|
155
|
+
)
|
|
156
|
+
)
|
|
157
|
+
}
|
|
158
|
+
|
|
159
|
+
const ejectedScopes = GlobalValue.globalValue(
|
|
160
|
+
"@effect/platform/HttpApp/ejectedScopes",
|
|
161
|
+
() => new WeakSet<Scope.Scope>()
|
|
162
|
+
)
|
|
163
|
+
|
|
164
|
+
const scoped = <A, E, R>(effect: Effect.Effect<A, E, R>) =>
|
|
165
|
+
Effect.flatMap(Scope.make(), (scope) =>
|
|
166
|
+
Effect.onExit(Scope.extend(effect, scope), (exit) => {
|
|
167
|
+
if (ejectedScopes.has(scope)) {
|
|
168
|
+
return Effect.void
|
|
169
|
+
}
|
|
170
|
+
return Scope.close(scope, exit)
|
|
171
|
+
}))
|
|
172
|
+
|
|
121
173
|
/**
|
|
122
174
|
* @since 1.0.0
|
|
123
175
|
* @category models
|
|
@@ -156,6 +208,7 @@ export const toWebHandlerRuntime = <R>(runtime: Runtime.Runtime<R>) => {
|
|
|
156
208
|
return <E>(self: Default<E, R | Scope.Scope>, middleware?: HttpMiddleware | undefined) => {
|
|
157
209
|
const resolveSymbol = Symbol.for("@effect/platform/HttpApp/resolve")
|
|
158
210
|
const httpApp = toHandled(self, (request, response) => {
|
|
211
|
+
response = unsafeEjectStreamScope(response)
|
|
159
212
|
;(request as any)[resolveSymbol](
|
|
160
213
|
ServerResponse.toWeb(response, { withoutBody: request.method === "HEAD", runtime })
|
|
161
214
|
)
|
package/src/HttpBody.ts
CHANGED
|
@@ -238,8 +238,7 @@ export interface Stream extends HttpBody.Proto {
|
|
|
238
238
|
export const stream: (
|
|
239
239
|
body: Stream_.Stream<globalThis.Uint8Array, unknown>,
|
|
240
240
|
contentType?: string,
|
|
241
|
-
contentLength?: number
|
|
242
|
-
etag?: string
|
|
241
|
+
contentLength?: number
|
|
243
242
|
) => Stream = internal.stream
|
|
244
243
|
|
|
245
244
|
/**
|