🎩 You're Invited:Meet the Socket team at Black Hat in Las Vegas, August 3-6.RSVP
Sign In

@standardserver/core

Package Overview
Dependencies
Maintainers
1
Versions
38
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

@standardserver/core

Source
npmnpm
Version
0.4.2
Version published
Weekly downloads
6.8K
46.93%
Maintainers
1
Weekly downloads
 
Created
Source

@standardserver/core

codecov weekly downloads MIT License Discord Ask DeepWiki

@standardserver/core is the shared contract package for Standard Server.

Standard Server provides a unified interface for client-server communication across HTTP and message-based transports. It lets you keep handler and client code transport-agnostic by working with the same request, response, body, and streaming abstractions whether the transport is Fetch, Node.js HTTP, or a peer-style message channel.

This package is the foundation of that model. It defines the core request and response types, shared runtime validators, small utility helpers, and event stream (SSE) helpers.

Entry Points

Entry pointPurpose
@standardserver/coreShared request/response types, utilities, and validators

Request and response types

The main entry point exposes four transport-agnostic shapes:

ExportDescription
StandardRequestEager request object with a parsed body
StandardLazyRequestRequest object with resolveBody(hint?) for lazy body parsing
StandardResponseEager response object with a parsed body
StandardLazyResponseResponse object with resolveBody(hint?) for lazy body parsing

Supporting primitives:

ExportDescription
StandardMethodCommon HTTP verbs plus any custom string value
StandardUrlA request URL that must start with / and exclude the origin
StandardHeadersRecord<string, string | string[] | undefined>
StandardBodyHintParsing hint for lazy body resolution
StandardBodyShared body union used by requests and responses

By convention, adapters normalize headers to lowercase keys. signal is part of StandardRequest only and is used to propagate request cancellation.

import type { StandardLazyRequest, StandardResponse } from '@standardserver/core'

export async function handle(request: StandardLazyRequest): Promise<StandardResponse> {
  const body = await request.resolveBody()

  return {
    status: 200,
    headers: { 'content-type': 'application/json' },
    body: {
      ok: true,
      method: request.method,
      url: request.url,
      received: body,
    },
  }
}

Body hints and body values

StandardBodyHint and StandardBody describe the shared body contract used across adapters:

HintStandardBody valueTypical content typeNotes
jsonunknownapplication/jsonPrimitives, objects, and arrays
form-dataFormDatamultipart/form-dataMultipart form submissions
url-search-paramsURLSearchParamsapplication/x-www-form-urlencodedURL-encoded forms
event-streamAsyncIteratorObject<unknown>text/event-streamServer-Sent Events (SSE)
octet-streamReadableStream<Uint8Array>anyBinary payloads
fileFileanyFixed-size binary payloads for both File and Blob
noneundefinedEmpty body

Resolving Body

resolveBody(hint?) determines how to parse the body using the following priority:

  • If hint? is provided, use it as the StandardBodyHint.
  • Otherwise, if the standard-server header is present, use it as the StandardBodyHint.
  • Otherwise, if content-type is one of the common types, parse accordingly.
  • Otherwise, if content-length exists, treat the body as file; if not, treat it as octet-stream.

For efficient communication, set the standard-server header to explicitly hint the body type, especially for file or binary streaming. For example, if you upload a file with a common content-type such as application/json but omit the standard-server header, the server may interpret it as JSON and parse it unexpectedly.

const response = await fetch('/upload', {
  method: 'POST',
  headers: {
    'content-type': 'application/json',
    'standard-server': 'file', // <- hint the body type to avoid misinterpretation
  },
  body: new Blob(['{"message": "Hello, world!"}'], { type: 'application/json' }),
})

Utilities

The main entry point also exports a small set of helpers for common header and URL operations.

Content-Disposition helpers

Use generateContentDisposition() to produce a safe Content-Disposition value and getFilenameFromContentDisposition() to read a filename back from an existing header.

import {
  generateContentDisposition,
  getFilenameFromContentDisposition,
} from '@standardserver/core'

const disposition = generateContentDisposition('report "Q2".csv')
// inline; filename="report \"Q2\".csv"; filename*=utf-8''report%20%22Q2%22.csv

const filename = getFilenameFromContentDisposition(disposition)
// 'report "Q2".csv'

generateContentDisposition() preserves an ASCII-safe filename="..." value and also emits filename*= for UTF-8 aware clients.

Header helpers

mergeStandardHeaders() combines two StandardHeaders objects while preserving duplicate values, and flattenStandardHeader() turns a single header value into a plain string when needed.

import {
  flattenStandardHeader,
  mergeStandardHeaders,
} from '@standardserver/core'

const headers = mergeStandardHeaders(
  { 'accept': 'application/json', 'set-cookie': ['a=1'] },
  { 'set-cookie': 'b=2', 'vary': 'accept', 'warning': undefined },
)
// {
//   accept: 'application/json',
//   'set-cookie': ['a=1', 'b=2'],
//   vary: 'accept',
// }

const cookieHeader = flattenStandardHeader(headers['set-cookie'])
// 'a=1, b=2'

URL parsing

parseStandardUrl() splits a StandardUrl into [pathname, search, hash] without requiring a full origin.

import { parseStandardUrl } from '@standardserver/core'

const [pathname, search, hash] = parseStandardUrl('/users/123?tab=settings#profile')
// pathname => '/users/123'
// search => '?tab=settings'
// hash => '#profile'

Validators

Runtime type guards are useful when requests or responses cross process, transport, or message boundaries.

ExportChecks
isStandardMethod()Any string value
isStandardUrl()A string starting with /
isStandardHeaders()Object values are string, string[], or undefined
isStandardRequest()
isStandardResponse()
import { isStandardRequest } from '@standardserver/core'

export function expectStandardRequest(input: unknown) {
  if (!isStandardRequest(input)) {
    throw new TypeError('Expected a StandardRequest-compatible value')
  }

  return input
}

Event-Stream Helpers

Use Event-Stream Helpers when you need explicit SSE encoding, decoding, or metadata handling.

Message types and codecs

The event-stream entry point exposes:

  • EventMeta for id, retry, and comments
  • EventStreamMessage for complete SSE messages
  • encodeEventStreamMessage() and decodeEventStreamMessage() for single-message codec operations
  • EventStreamDecoder and EventStreamDecoderStream for chunked stream decoding
import {
  decodeEventStreamMessage,
  encodeEventStreamMessage,
} from '@standardserver/core'

const encoded = encodeEventStreamMessage({
  comments: ['bootstrap'],
  event: 'message',
  id: '42',
  retry: 3000,
  data: 'hello\nworld',
})

const decoded = decodeEventStreamMessage(encoded)
// {
//   comments: ['bootstrap'],
//   event: 'message',
//   id: '42',
//   retry: 3000,
//   data: 'hello\nworld',
// }

For streaming decode, pipe text chunks through EventStreamDecoderStream:

import { EventStreamDecoderStream } from '@standardserver/core'

const messages = response.body!
  .pipeThrough(new TextDecoderStream())
  .pipeThrough(new EventStreamDecoderStream())

Iterator metadata helpers

StandardBody uses async iterators for event-stream bodies. To attach SSE metadata to a yielded value without changing its visible shape, use withEventMeta().

import type { StandardResponse } from '@standardserver/core'
import { getEventMeta, unwrapEvent, withEventMeta } from '@standardserver/core'

const event = withEventMeta(
  { message: 'hello' },
  { id: '1', retry: 3000, comments: ['bootstrap'] },
)

const [data, meta] = unwrapEvent(event)
// data => { message: 'hello' }
// meta => { id: '1', retry: 3000, comments: ['bootstrap'] }

const extractedMeta = getEventMeta(event)
// { id: '1', retry: 3000, comments: ['bootstrap'] }

const response: StandardResponse = {
  status: 200,
  headers: {},
  async* body() {
    yield event
  },
}

[!WARNING] Metadata is validated before it is attached: id, event, and comments must not contain line breaks, and retry must be a non-negative integer.

Errors and low-level assertions

The subpath also exports:

  • EventStreamEncoderError for invalid outbound SSE messages
  • EventStreamDecoderError for incomplete or invalid inbound stream decoding
  • ErrorEvent for wrapping structured event-stream error payloads in an Error
  • assertEventStreamMessageId(), assertEventStreamMessageName(), assertEventStreamMessageRetry(), and assertEventStreamMessageComment() for low-level validation when building custom SSE tooling
import { ErrorEvent } from '@standardserver/core'

const error = new ErrorEvent(
  { code: 'E_STREAM', detail: 'Connection lost' },
  { message: 'stream error' },
)

error.message
// 'stream error'

error.data
// { code: 'E_STREAM', detail: 'Connection lost' }

Learn more

For the higher-level project overview, see the root Standard Server README.

Sponsors

Like what we build over at middleapi? You can help keep it going here: GitHub Sponsors. Every bit helps! 🚀

🏆 Platinum Sponsor

ScreenshotOne.com
ScreenshotOne.com

🥈 Silver Sponsor

村上さん
村上さん

Generous Sponsors

LN Markets
LN Markets

Sponsors

Reece McDonald
Reece McDonald
nk
nk
supastarter
supastarter
Dexter Miguel
Dexter Miguel
herrfugbaum
herrfugbaum
Ryota Murakami
Ryota Murakami
David Cramer
David Cramer
Valerii Petryniak
Valerii Petryniak
Valerii Strilets
Valerii Strilets
Kyle Mistele
Kyle Mistele
Andrew Peters
Andrew Peters
Ryan Vogel
Ryan Vogel
christ12938
christ12938
Ryan Soderberg
Ryan Soderberg
shota
shota

Backers

David Walsh
David Walsh
Nicholas
Nicholas
Robbe Vaes
Robbe Vaes
Aidan Sunbury
Aidan Sunbury
soonoo
soonoo
Kevin Porten
Kevin Porten
Denis
Denis
Christopher Kapic
Christopher Kapic
Tom Ballinger
Tom Ballinger
Sam
Sam
Titoine
Titoine
Igor Makowski
Igor Makowski
hanayashiki
hanayashiki
Lev Dubinets
Lev Dubinets
Kelly Peilin Chan
Kelly Peilin Chan
Alex
Alex
Andrey Gubanov
Andrey Gubanov

Past Sponsors

Maxie Stijn Timmer あわわわとーにゅ Zuplo motopods Francisco Hermida Théo LUDWIG Abhay Ramesh shr.ink oü 0x4e32 Ryuz happyboy yicchi Saksham Roman Hrynevych rokitg Omar Khatib Yu-Sabo Bapusaheb Patil grim Nelson Lai Lê Cao Nguyên Robert Soriano SKostyukovich Peter Adam Fabworks Novak Antonijevic Laduni Estu Syalwa Chen, Zhi-Yuan Illarion Koperski Anees Iqbal Sefa Eyeoglu natt Adam Tkaczyk plancraft

FAQs

Package last updated on 13 Jul 2026

Did you know?

Socket

Socket for GitHub automatically highlights issues in each pull request and monitors the health of all your open source dependencies. Discover the contents of your packages and block harmful activity before you install or update your dependencies.

Install

Related posts