New Case Study:See how Anthropic automated 95% of dependency reviews with Socket.Learn More
Socket
Sign inDemoInstall
Socket

@jsenv/server

Package Overview
Dependencies
Maintainers
2
Versions
219
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

@jsenv/server - npm Package Compare versions

Comparing version 12.8.0 to 13.0.0

src/content_negotiation/pick_accepted_content.js

2

package.json
{
"name": "@jsenv/server",
"version": "12.8.0",
"version": "13.0.0",
"description": "Write your Node.js server using pure functions",

@@ -5,0 +5,0 @@ "license": "MIT",

@@ -11,11 +11,15 @@ # server [![npm package](https://img.shields.io/npm/v/@jsenv/server.svg?logo=npm&label=package)](https://www.npmjs.com/package/@jsenv/server)

port: 8080,
requestToResponse: () => {
return {
status: 200,
headers: {
"content-type": "text/plain",
services: [
{
handleRequest: () => {
return {
status: 200,
headers: {
"content-type": "text/plain",
},
body: "Hello world",
}
},
body: "Hello world",
}
},
},
],
})

@@ -33,11 +37,15 @@ ```

const server = await startServer({
requestToResponse: () => {
return {
status: 200,
headers: {
"content-type": "text/plain",
services: [
{
handleRequest: () => {
return {
status: 200,
headers: {
"content-type": "text/plain",
},
body: "Hello world",
}
},
body: "Hello world",
}
},
},
],
})

@@ -62,18 +70,20 @@

const indexService = (request) => {
if (request.ressource === "/") {
return { status: 200 }
}
return null // means "I don't handle that request"
}
const notFoundService = (request) => {
return { status: 404 }
}
const server = await startServer({
requestToResponse: composeServices({
index: indexService,
otherwise: notFoundService,
}),
services: [
{
name: "index",
handleRequest: (request) => {
if (request.ressource === "/") {
return { status: 200 }
}
return null // means "I don't handle that request"
},
},
{
name: "otherwise",
handleRequest: () => {
return { status: 404 }
},
},
],
})

@@ -100,13 +110,17 @@

allowHttpRequestOnHttps: true,
requestToResponse: (request) => {
const clientUsesHttp = request.origin.startsWith("http:")
services: [
{
handleRequest: (request) => {
const clientUsesHttp = request.origin.startsWith("http:")
return {
status: 200,
headers: {
"content-type": "text/plain",
return {
status: 200,
headers: {
"content-type": "text/plain",
},
body: clientUsesHttp ? `Welcome http user` : `Welcome https user`,
}
},
body: clientUsesHttp ? `Welcome http user` : `Welcome https user`,
}
},
},
],
})

@@ -126,9 +140,13 @@

await startServer({
requestToResponse: async (request) => {
const fileUrl = new URL(request.ressource.slice(1), import.meta.url)
const response = await fetchFileSystem(fileUrl, {
...request,
})
return response
},
services: [
{
handleRequest: async (request) => {
const fileUrl = new URL(request.ressource.slice(1), import.meta.url)
const response = await fetchFileSystem(fileUrl, {
...request,
})
return response
},
},
],
})

@@ -139,4 +157,2 @@ ```

- [https](./docs/https/https.md)
- [Serving files](./docs/serving_files/serving_files.md)
- [Handling requests](./docs/handling_requests/handling_requests.md)

@@ -146,2 +162,4 @@ - [Handling errors](./docs/handling_errors/handling_errors.md)

- [CORS](./docs/cors/cors.md)
- [https](./docs/https/https.md)
- [Serving files](./docs/serving_files/serving_files.md)
- [Content negotiation](./docs/content_negotiation/content_negotiation.md)

@@ -148,0 +166,0 @@ - [Server Sent Events](./docs/sse/sse.md)

@@ -15,3 +15,3 @@ /*

import { timeFunction } from "./server_timing/timing_measure.js"
import { negotiateContentEncoding } from "./content_negotiation/negotiateContentEncoding.js"
import { pickContentEncoding } from "./content_negotiation/pick_content_encoding.js"
import { serveDirectory } from "./serve_directory.js"

@@ -364,3 +364,3 @@

const getCompressedResponse = async ({ sourceUrl, headers }) => {
const acceptedCompressionFormat = negotiateContentEncoding(
const acceptedCompressionFormat = pickContentEncoding(
{ headers },

@@ -367,0 +367,0 @@ Object.keys(availableCompressionFormats),

import { networkInterfaces } from "node:os"
import { lookup } from "node:dns"
export const getServerOrigins = async ({ protocol, ip, port }) => {
const isInternalIp = ip === "127.0.0.1"
import { applyDnsResolution } from "./dns_resolution.js"
export const getServerOrigins = async ({ protocol, host, port }) => {
const isLocal = LOOPBACK_HOSTNAMES.includes(host)
const localhostDnsResolution = await applyDnsResolution("localhost")
const internalOrigin = createServerOrigin({
const localOrigin = createServerOrigin({
protocol,

@@ -15,29 +16,31 @@ hostname:

})
if (isInternalIp) {
return { internal: internalOrigin }
if (isLocal) {
return { local: localOrigin }
}
const isAnyIp = !ip || ip === "::" || ip === "0.0.0.0"
const isAnyIp = WILDCARD_HOSTNAMES.includes(host)
const networkOrigin = createServerOrigin({
protocol,
hostname: isAnyIp ? getExternalIp() : host,
port,
})
return {
internal: internalOrigin,
external: createServerOrigin({
protocol,
hostname: isAnyIp ? getExternalIp(ip) : ip,
port,
}),
local: localOrigin,
network: networkOrigin,
}
}
const applyDnsResolution = async (hostname) => {
const dnsResolution = await new Promise((resolve, reject) => {
lookup(hostname, (error, address, family) => {
if (error) {
reject(error)
} else {
resolve({ address, family })
}
})
})
return dnsResolution
}
const LOOPBACK_HOSTNAMES = [
"localhost",
"127.0.0.1",
"::1",
"0000:0000:0000:0000:0000:0000:0000:0001",
]
const WILDCARD_HOSTNAMES = [
undefined,
"0.0.0.0",
"::",
"0000:0000:0000:0000:0000:0000:0000:0000",
]
const createServerOrigin = ({ protocol, hostname, port }) => {

@@ -58,3 +61,3 @@ const url = new URL("https://127.0.0.1:80")

if (networkAddress.internal) return false
if (networkAddress.family !== "IPv4") return false
if (!isIpV4(networkAddress)) return false
internalIPV4NetworkAddress = networkAddress

@@ -66,1 +69,9 @@ return true

}
const isIpV4 = (networkAddress) => {
// node 18+
if (typeof networkAddress.family === "number") {
return networkAddress.family === 4
}
return networkAddress.family === "IPv4"
}

@@ -9,3 +9,3 @@ import { createServer } from "node:net"

portHint,
ip,
host,
}) => {

@@ -21,7 +21,7 @@ const listeningOperation = Abort.startOperation()

signal: listeningOperation.signal,
ip,
host,
})
}
listeningOperation.throwIfAborted()
port = await startListening({ server, port, ip })
port = await startListening({ server, port, host })
listeningOperation.addAbortCallback(() => stopListening(server))

@@ -40,3 +40,3 @@ listeningOperation.throwIfAborted()

signal = new AbortController().signal,
ip = "127.0.0.1",
host = "127.0.0.1",
min = 1,

@@ -52,5 +52,5 @@ max = 65534,

const testUntil = async (port, ip) => {
const testUntil = async (port, host) => {
findFreePortOperation.throwIfAborted()
const free = await portIsFree(port, ip)
const free = await portIsFree(port, host)
if (free) {

@@ -62,7 +62,9 @@ return port

if (nextPort > max) {
throw new Error(`${ip} has no available port between ${min} and ${max}`)
throw new Error(
`${host} has no available port between ${min} and ${max}`,
)
}
return testUntil(nextPort, ip)
return testUntil(nextPort, host)
}
const freePort = await testUntil(initialPort, ip)
const freePort = await testUntil(initialPort, host)
return freePort

@@ -74,3 +76,3 @@ } finally {

const portIsFree = async (port, ip) => {
const portIsFree = async (port, host) => {
const server = createServer()

@@ -82,3 +84,3 @@

port,
ip,
host,
})

@@ -99,3 +101,3 @@ } catch (error) {

const startListening = ({ server, port, ip }) => {
const startListening = ({ server, port, host }) => {
return new Promise((resolve, reject) => {

@@ -108,3 +110,3 @@ server.on("error", reject)

})
server.listen(port, ip)
server.listen(port, host)
})

@@ -111,0 +113,0 @@ }

@@ -7,4 +7,3 @@ /*

export { startServer } from "./startServer.js"
export { composeServices } from "./service_composition/service_composition.js"
export { startServer } from "./server.js"
export { setupRoutes } from "./service_composition/routing.js"

@@ -22,22 +21,22 @@ export { readRequestBody } from "./readRequestBody.js"

} from "./stopReasons.js"
export { jsenvServiceErrorHandler } from "./services/error_handler/jsenv_service_error_handler.js"
// CORS
export {
pluginCORS,
jsenvServiceCORS,
jsenvAccessControlAllowedHeaders,
jsenvAccessControlAllowedMethods,
} from "./cors/plugin_cors.js"
} from "./services/cors/jsenv_service_cors.js"
// server timings
export { pluginServerTiming } from "./server_timing/plugin_server_timing.js"
// server timing
export { timeFunction, timeStart } from "./server_timing/timing_measure.js"
// SSE
export { createSSERoom } from "./sse/createSSERoom.js"
export { createSSERoom } from "./sse/sse_room.js"
// content-negotiation
export { negotiateContentType } from "./content_negotiation/negotiateContentType.js"
export { negotiateContentEncoding } from "./content_negotiation/negotiateContentEncoding.js"
export { negotiateContentLanguage } from "./content_negotiation/negotiateContentLanguage.js"
export { pluginContentNegotiationCheck } from "./content_negotiation/plugin_content_negotiation_check.js"
export { pickContentType } from "./content_negotiation/pick_content_type.js"
export { pickContentEncoding } from "./content_negotiation/pick_content_encoding.js"
export { pickContentLanguage } from "./content_negotiation/pick_content_language.js"
export { jsenvServiceResponseAcceptanceCheck } from "./services/response_acceptance_check/jsenv_service_response_acceptance_check.js"

@@ -48,4 +47,3 @@ // others

export { composeTwoResponses } from "./internal/response_composition.js"
export { pluginRessourceAliases } from "./ressource_aliases/plugin_ressource_aliases.js"
export { pluginRequestWaitingCheck } from "./plugin_request_waiting_check.js"
export { jsenvServiceRessourceAliases } from "./services/ressource_aliases/jsenv_service_ressource_aliases.js"
export { findFreePort } from "./internal/listen.js"
import { readdirSync } from "node:fs"
import { negotiateContentType } from "./content_negotiation/negotiateContentType.js"
import { pickContentType } from "./content_negotiation/pick_content_type.js"

@@ -60,3 +60,3 @@ export const serveDirectory = (

}
const bestContentType = negotiateContentType(
const bestContentType = pickContentType(
{ headers },

@@ -63,0 +63,0 @@ Object.keys(responseProducers),

SocketSocket SOC 2 Logo

Product

  • Package Alerts
  • Integrations
  • Docs
  • Pricing
  • FAQ
  • Roadmap
  • Changelog

Packages

npm

Stay in touch

Get open source security insights delivered straight into your inbox.


  • Terms
  • Privacy
  • Security

Made with ⚡️ by Socket Inc