Skip to content
This repository has been archived by the owner on Jul 16, 2024. It is now read-only.

Commit

Permalink
wip
Browse files Browse the repository at this point in the history
  • Loading branch information
tim-smart committed Dec 16, 2023
1 parent 6abdeaf commit a7bab0c
Show file tree
Hide file tree
Showing 6 changed files with 84 additions and 57 deletions.
6 changes: 6 additions & 0 deletions .changeset/many-rats-notice.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
---
"@effect/platform-node": patch
"@effect/platform": patch
---

change UrlParams to ReadonlyArray
35 changes: 23 additions & 12 deletions docs/platform/Http/Headers.ts.md
Original file line number Diff line number Diff line change
Expand Up @@ -15,13 +15,14 @@ Added in v1.0.0
- [combinators](#combinators)
- [get](#get)
- [has](#has)
- [merge](#merge)
- [remove](#remove)
- [set](#set)
- [setAll](#setall)
- [unsafeSet](#unsafeset)
- [constructors](#constructors)
- [empty](#empty)
- [fromInput](#frominput)
- [unsafeFromRecord](#unsafefromrecord)
- [models](#models)
- [Headers (type alias)](#headers-type-alias)
- [Input (type alias)](#input-type-alias)
Expand Down Expand Up @@ -56,6 +57,19 @@ export declare const has: { (key: string): (self: Headers) => boolean; (self: He
Added in v1.0.0
## merge
**Signature**
```ts
export declare const merge: {
(headers: Headers): (self: Headers) => Headers
(self: Headers, headers: Headers): Headers
}
```
Added in v1.0.0
## remove
**Signature**
Expand Down Expand Up @@ -89,37 +103,34 @@ export declare const setAll: { (headers: Input): (self: Headers) => Headers; (se
Added in v1.0.0
## unsafeSet
# constructors
## empty
**Signature**
```ts
export declare const unsafeSet: {
(key: string, value: string): (self: Headers) => Headers
(self: Headers, key: string, value: string): Headers
}
export declare const empty: Headers
```
Added in v1.0.0
# constructors
## empty
## fromInput
**Signature**
```ts
export declare const empty: Headers
export declare const fromInput: (input?: Input) => Headers
```
Added in v1.0.0
## fromInput
## unsafeFromRecord
**Signature**
```ts
export declare const fromInput: (input?: Input) => Headers
export declare const unsafeFromRecord: (input: ReadonlyRecord.ReadonlyRecord<string>) => Headers
```
Added in v1.0.0
Expand Down
11 changes: 7 additions & 4 deletions packages/platform-node/src/internal/http/platform.ts
Original file line number Diff line number Diff line change
Expand Up @@ -25,10 +25,13 @@ export const make = Platform.make({
},
fileWebResponse(file, status, statusText, headers, _options) {
return ServerResponse.raw(Readable.fromWeb(file.stream() as any), {
headers: Headers.setAll(headers, {
"content-type": headers["content-type"] ?? Mime.getType(file.name) ?? "application/octet-stream",
"content-length": file.size.toString()
}),
headers: Headers.merge(
headers,
Headers.unsafeFromRecord({
"content-type": headers["content-type"] ?? Mime.getType(file.name) ?? "application/octet-stream",
"content-length": file.size.toString()
})
),
status,
statusText
})
Expand Down
40 changes: 23 additions & 17 deletions packages/platform/src/Http/Headers.ts
Original file line number Diff line number Diff line change
Expand Up @@ -29,13 +29,13 @@ export type Headers = Brand.Branded<ReadonlyRecord.ReadonlyRecord<string>, Heade
* @since 1.0.0
* @category models
*/
export type Input = Headers | ReadonlyRecord.ReadonlyRecord<string> | Iterable<readonly [string, string]>
export type Input = ReadonlyRecord.ReadonlyRecord<string> | Iterable<readonly [string, string]>

/**
* @since 1.0.0
* @category constructors
*/
export const empty: Headers = {} as Headers
export const empty: Headers = Object.create(null) as Headers

/**
* @since 1.0.0
Expand All @@ -55,6 +55,12 @@ export const fromInput: (input?: Input) => Headers = (input) => {
) as Headers
}

/**
* @since 1.0.0
* @category constructors
*/
export const unsafeFromRecord = (input: ReadonlyRecord.ReadonlyRecord<string>): Headers => input as Headers

/**
* @since 1.0.0
* @category combinators
Expand Down Expand Up @@ -94,21 +100,6 @@ export const set: {
[key.toLowerCase()]: value
}))

/**
* @since 1.0.0
* @category combinators
*/
export const unsafeSet: {
(key: string, value: string): (self: Headers) => Headers
(self: Headers, key: string, value: string): Headers
} = dual<
(key: string, value: string) => (self: Headers) => Headers,
(self: Headers, key: string, value: string) => Headers
>(3, (self, key, value) => {
;(self as any)[key.toLowerCase()] = value
return self
})

/**
* @since 1.0.0
* @category combinators
Expand All @@ -124,6 +115,21 @@ export const setAll: {
...fromInput(headers)
}))

/**
* @since 1.0.0
* @category combinators
*/
export const merge: {
(headers: Headers): (self: Headers) => Headers
(self: Headers, headers: Headers): Headers
} = dual<
(headers: Headers) => (self: Headers) => Headers,
(self: Headers, headers: Headers) => Headers
>(2, (self, headers) => ({
...self,
...headers
}))

/**
* @since 1.0.0
* @category combinators
Expand Down
36 changes: 17 additions & 19 deletions packages/platform/src/Http/UrlParams.ts
Original file line number Diff line number Diff line change
@@ -1,40 +1,38 @@
/**
* @since 1.0.0
*/
import * as Chunk from "effect/Chunk"
import * as Effect from "effect/Effect"
import { dual } from "effect/Function"
import * as ReadonlyArray from "effect/ReadonlyArray"

/**
* @since 1.0.0
* @category models
*/
export interface UrlParams extends Chunk.Chunk<[string, string]> {}
export interface UrlParams extends ReadonlyArray<readonly [string, string]> {}

/**
* @since 1.0.0
* @category models
*/
export type Input = UrlParams | Readonly<Record<string, string>> | Iterable<readonly [string, string]> | URLSearchParams
export type Input = Readonly<Record<string, string>> | Iterable<readonly [string, string]> | URLSearchParams

/**
* @since 1.0.0
* @category constructors
*/
export const fromInput = (input: Input): UrlParams => {
if (Chunk.isChunk(input)) {
return input
} else if (Symbol.iterator in input) {
return Chunk.fromIterable(input) as UrlParams
if (Symbol.iterator in input) {
return ReadonlyArray.fromIterable(input)
}
return Chunk.fromIterable(Object.entries(input))
return ReadonlyArray.fromIterable(Object.entries(input))
}

/**
* @since 1.0.0
* @category constructors
*/
export const empty: UrlParams = Chunk.empty()
export const empty: UrlParams = []

/**
* @since 1.0.0
Expand All @@ -47,8 +45,8 @@ export const set: {
(key: string, value: string) => (self: UrlParams) => UrlParams,
(self: UrlParams, key: string, value: string) => UrlParams
>(3, (self, key, value) =>
Chunk.append(
Chunk.filter(self, ([k]) => k !== key),
ReadonlyArray.append(
ReadonlyArray.filter(self, ([k]) => k !== key),
[key, value]
))

Expand All @@ -64,9 +62,9 @@ export const setAll: {
(self: UrlParams, input: Input) => UrlParams
>(2, (self, input) => {
const toSet = fromInput(input)
const keys = Chunk.toReadonlyArray(toSet).map(([k]) => k)
return Chunk.appendAll(
Chunk.filter(self, ([k]) => keys.includes(k)),
const keys = toSet.map(([k]) => k)
return ReadonlyArray.appendAll(
ReadonlyArray.filter(self, ([k]) => keys.includes(k)),
toSet
)
})
Expand All @@ -82,7 +80,7 @@ export const append: {
(key: string, value: string) => (self: UrlParams) => UrlParams,
(self: UrlParams, key: string, value: string) => UrlParams
>(3, (self, key, value) =>
Chunk.append(
ReadonlyArray.append(
self,
[key, value]
))
Expand All @@ -98,7 +96,7 @@ export const appendAll: {
(input: Input) => (self: UrlParams) => UrlParams,
(self: UrlParams, input: Input) => UrlParams
>(2, (self, input) =>
Chunk.appendAll(
ReadonlyArray.appendAll(
self,
fromInput(input)
))
Expand All @@ -113,13 +111,13 @@ export const remove: {
} = dual<
(key: string) => (self: UrlParams) => UrlParams,
(self: UrlParams, key: string) => UrlParams
>(2, (self, key) => Chunk.filter(self, ([k]) => k !== key))
>(2, (self, key) => ReadonlyArray.filter(self, ([k]) => k !== key))

/**
* @since 1.0.0
* @category combinators
*/
export const toString = (self: UrlParams): string => new URLSearchParams(Chunk.toReadonlyArray(self) as any).toString()
export const toString = (self: UrlParams): string => new URLSearchParams(self as any).toString()

/**
* @since 1.0.0
Expand All @@ -129,7 +127,7 @@ export const makeUrl = <E>(url: string, params: UrlParams, onError: (e: unknown)
Effect.try({
try: () => {
const urlInstance = new URL(url, baseUrl())
Chunk.forEach(params, ([key, value]) => {
ReadonlyArray.forEach(params, ([key, value]) => {
if (value !== undefined) {
urlInstance.searchParams.append(key, value)
}
Expand Down
13 changes: 8 additions & 5 deletions packages/platform/src/internal/http/platform.ts
Original file line number Diff line number Diff line change
Expand Up @@ -48,7 +48,7 @@ export const make = (impl: {
const end = options?.bytesToRead !== undefined ? start + Number(options.bytesToRead) : undefined
const headers = Headers.set(options?.headers ?? Headers.empty, "etag", Etag.toString(etag))
if (info.mtime._tag === "Some") {
Headers.unsafeSet(headers, "last-modified", info.mtime.value.toUTCString())
;(headers as any)["last-modified"] = info.mtime.value.toUTCString()
}
const contentLength = end !== undefined ? end - start : Number(info.size) - start
return impl.fileResponse(
Expand All @@ -65,10 +65,13 @@ export const make = (impl: {
},
fileWebResponse(file, options) {
return Effect.map(etagGen.fromFileWeb(file), (etag) => {
const headers = Headers.setAll(options?.headers ?? Headers.empty, {
etag: Etag.toString(etag),
"last-modified": new Date(file.lastModified).toUTCString()
})
const headers = Headers.merge(
options?.headers ?? Headers.empty,
Headers.unsafeFromRecord({
etag: Etag.toString(etag),
"last-modified": new Date(file.lastModified).toUTCString()
})
)
return impl.fileWebResponse(
file,
options?.status ?? 200,
Expand Down

0 comments on commit a7bab0c

Please sign in to comment.