Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
86 changes: 86 additions & 0 deletions eslint.config.js
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
import tseslint from 'typescript-eslint'
import jsdoc from 'eslint-plugin-jsdoc'
import preferLet from 'eslint-plugin-prefer-let'

/** @type {import('eslint').Linter.Config[]} */
Expand All @@ -7,6 +8,7 @@ export default [
ignores: [
'**/*.d.ts',
'**/dist/**',
'**/docs/**',
'**/coverage/**',
'**/bench/**',
'**/examples/**',
Expand Down Expand Up @@ -85,4 +87,88 @@ export default [
'no-var': 'error',
},
},
{
files: ['packages/**/*.{ts,tsx}'],
ignores: ['packages/**/*.test.ts'],
plugins: { jsdoc },
settings: {
jsdoc: {
// Set our own contexts at the root to identify the types of things we care
// to enforce JSDoc rules on. Mostly we care about:
// - exported public APIs
// - not private class methods
// - not private class properties
// - not anything marked `@private` (`ignorePrivate` setting)
contexts: [
// function foo() {}
'ClassDeclaration',
// function foo() {}
'FunctionDeclaration',
// let foo = function () {}
':not(MethodDefinition) > FunctionExpression',
// Class{ foo() {} } but not Class{ #foo() {} } or Class { get foo() {} }
'MethodDefinition:not([kind=get]):not([key.type=PrivateIdentifier]) FunctionExpression',
// let foo = () => {}
':not(PropertyDefinition) > ArrowFunctionExpression',
// Class{ foo = () => {} } but not Class{ #foo = () => {} }
'PropertyDefinition:not([key.type=PrivateIdentifier]) ArrowFunctionExpression',
],
ignorePrivate: true,
tagNamePreference: {
// TODO: Temporarily allow both `@returns` and `@return`, but
// eventually we can find/replace to the standard `@returns` and
// remove this setting
return: 'return',
},
},
},
rules: {
// Using modified base rulesets from:
// https://github.com/gajus/eslint-plugin-jsdoc?tab=readme-ov-file#granular-flat-configs

// Modified version of jsdoc/flat/contents-typescript-error
'jsdoc/informative-docs': 'off',
'jsdoc/match-description': 'off',
'jsdoc/no-blank-block-descriptions': 'error',
'jsdoc/no-blank-blocks': 'error',
'jsdoc/text-escaping': 'off',

// Modified version of jsdoc/flat/logical-typescript-error
'jsdoc/check-access': 'error',
'jsdoc/check-param-names': 'error',
'jsdoc/check-property-names': 'error',
'jsdoc/check-syntax': 'error',
'jsdoc/check-tag-names': ['error'],
'jsdoc/check-template-names': 'error',
'jsdoc/check-types': 'error',
'jsdoc/check-values': 'error',
'jsdoc/empty-tags': 'error',
'jsdoc/escape-inline-tags': 'error',
'jsdoc/implements-on-classes': 'error',
'jsdoc/require-returns-check': 'error',
'jsdoc/require-yields-check': 'error',
'jsdoc/no-bad-blocks': 'error',
'jsdoc/no-defaults': 'error',
'jsdoc/no-types': 'error',
'jsdoc/no-undefined-types': 'error',
'jsdoc/valid-types': 'error',

// Modified version of jsdoc/flat/stylistic-typescript-error
'jsdoc/check-alignment': 'error',
'jsdoc/check-line-alignment': 'error',
'jsdoc/lines-before-block': 'off',
'jsdoc/multiline-blocks': 'error',
'jsdoc/no-multi-asterisks': 'error',
'jsdoc/require-asterisk-prefix': 'error',
'jsdoc/require-hyphen-before-param-description': ['error', 'never'],
'jsdoc/tag-lines': 'off',

// Additional rules we manually added
'jsdoc/require-param': 'error',
'jsdoc/require-param-description': 'error',
'jsdoc/require-param-name': 'error',
'jsdoc/require-returns': 'error',
'jsdoc/require-returns-description': 'error',
},
},
]
1 change: 1 addition & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@
"dependencies": {
"@typescript/native-preview": "catalog:",
"eslint": "^9.33.0",
"eslint-plugin-jsdoc": "^61.5.0",
"eslint-plugin-prefer-let": "^4.0.0",
"prettier": "^3.3.3",
"tsx": "catalog:",
Expand Down
4 changes: 2 additions & 2 deletions packages/async-context-middleware/src/lib/async-context.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ const storage = new AsyncLocalStorage<RequestContext>()
* Middleware that stores the request context in `AsyncLocalStorage` so it is available
* to all functions in the same async execution context.
*
* @return A middleware function that stores the request context in `AsyncLocalStorage`
* @returns A middleware function that stores the request context in `AsyncLocalStorage`
*/
export function asyncContext(): Middleware {
return (context, next) => storage.run(context, next)
Expand All @@ -17,7 +17,7 @@ export function asyncContext(): Middleware {
/**
* Get the request context from `AsyncLocalStorage`.
*
* @return The request context
* @returns The request context
*/
export function getContext(): RequestContext {
let context = storage.getStore()
Expand Down
6 changes: 3 additions & 3 deletions packages/cookie/src/lib/cookie.ts
Original file line number Diff line number Diff line change
Expand Up @@ -154,7 +154,7 @@ export class Cookie implements CookieProperties {
* Extracts the value of this cookie from a `Cookie` header value.
*
* @param headerValue The `Cookie` header to parse
* @return The value of this cookie, or `null` if it's not present
* @returns The value of this cookie, or `null` if it's not present
*/
async parse(headerValue: string | null): Promise<string | null> {
if (!headerValue) return null
Expand Down Expand Up @@ -218,7 +218,7 @@ export class Cookie implements CookieProperties {
*
* @param value The value to serialize
* @param props Additional properties to use when serializing the cookie
* @return The `Set-Cookie` header value for this cookie
* @returns The `Set-Cookie` header value for this cookie
*/
async serialize(value: string, props?: CookieProperties): Promise<string> {
let header = new SetCookieHeader({
Expand Down Expand Up @@ -251,7 +251,7 @@ export class Cookie implements CookieProperties {
*
* @param name The name of the cookie
* @param options Options for the cookie
* @return A new `Cookie` object
* @returns A new `Cookie` object
*/
export function createCookie(name: string, options?: CookieOptions): Cookie {
return new Cookie(name, options)
Expand Down
4 changes: 2 additions & 2 deletions packages/fetch-proxy/src/lib/fetch-proxy.ts
Original file line number Diff line number Diff line change
Expand Up @@ -38,7 +38,7 @@ export interface FetchProxyOptions {
*
* @param input The URL or request to forward
* @param init Optional request init options
* @return A promise that resolves to the proxied response
* @returns A promise that resolves to the proxied response
*/
export interface FetchProxy {
(input: URL | RequestInfo, init?: RequestInit): Promise<Response>
Expand All @@ -49,7 +49,7 @@ export interface FetchProxy {
*
* @param target The URL of the server to proxy requests to
* @param options Options to customize the behavior of the proxy
* @return A fetch function that forwards requests to the target server
* @returns A fetch function that forwards requests to the target server
*/
export function createFetchProxy(target: string | URL, options?: FetchProxyOptions): FetchProxy {
let localFetch = options?.fetch ?? globalThis.fetch
Expand Down
6 changes: 3 additions & 3 deletions packages/fetch-router/src/lib/app-storage.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ export class AppStorage {
* Check if a value is stored for the given key.
*
* @param key The key to check
* @return `true` if a value is stored for the given key, `false` otherwise
* @returns `true` if a value is stored for the given key, `false` otherwise
*/
has<key extends StorageKey<any>>(key: key): boolean {
return this.#map.has(key)
Expand All @@ -18,7 +18,7 @@ export class AppStorage {
* Get a value from storage.
*
* @param key The key to get
* @return The value for the given key
* @returns The value for the given key
*/
get<key extends StorageKey<any>>(key: key): StorageValue<key> {
if (!this.#map.has(key)) {
Expand Down Expand Up @@ -47,7 +47,7 @@ export class AppStorage {
* Create a storage key with an optional default value.
*
* @param defaultValue The default value for the storage key
* @return The new storage key
* @returns The new storage key
*/
export function createStorageKey<T>(defaultValue?: T): StorageKey<T> {
return { defaultValue }
Expand Down
2 changes: 1 addition & 1 deletion packages/fetch-router/src/lib/controller.ts
Original file line number Diff line number Diff line change
Expand Up @@ -63,7 +63,7 @@ export type BuildAction<method extends RequestMethod | 'ANY', route extends stri
* A request handler function that returns some kind of response.
*
* @param context The request context
* @return The response
* @returns The response
*/
export interface RequestHandler<
method extends RequestMethod | 'ANY' = RequestMethod | 'ANY',
Expand Down
4 changes: 2 additions & 2 deletions packages/fetch-router/src/lib/middleware.ts
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ import type { RequestMethod } from './request-methods.ts'
*
* @param context The request context
* @param next A function that invokes the next middleware or handler in the chain
* @return A response to short-circuit the chain, or `undefined`/`void` to continue
* @returns A response to short-circuit the chain, or `undefined`/`void` to continue
*/
export interface Middleware<
method extends RequestMethod | 'ANY' = RequestMethod | 'ANY',
Expand All @@ -24,7 +24,7 @@ export interface Middleware<
/**
* A function that invokes the next middleware or handler in the chain.
*
* @return The response from the downstream handler
* @returns The response from the downstream handler
*/
export type NextFunction = () => Promise<Response>

Expand Down
2 changes: 1 addition & 1 deletion packages/fetch-router/src/lib/route-helpers/form.ts
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,7 @@ export interface FormOptions {
*
* @param pattern The route pattern to use for the form and its submit action
* @param options Options to configure the form action routes
* @return The route map with `index` and `action` routes
* @returns The route map with `index` and `action` routes
*/
export function createFormRoutes<pattern extends string, const options extends FormOptions>(
pattern: pattern | RoutePattern<pattern>,
Expand Down
2 changes: 1 addition & 1 deletion packages/fetch-router/src/lib/route-helpers/resource.ts
Original file line number Diff line number Diff line change
Expand Up @@ -45,7 +45,7 @@ export type ResourceOptions = {
*
* @param base The base route pattern to use for the resource
* @param options Options to configure the resource routes
* @return The route map with CRUD routes
* @returns The route map with CRUD routes
*/
export function createResourceRoutes<base extends string, const options extends ResourceOptions>(
base: base | RoutePattern<base>,
Expand Down
2 changes: 1 addition & 1 deletion packages/fetch-router/src/lib/route-helpers/resources.ts
Original file line number Diff line number Diff line change
Expand Up @@ -52,7 +52,7 @@ export type ResourcesOptions = {
*
* @param base The base route pattern to use for the resources
* @param options Options to configure the resource routes
* @return The route map with CRUD routes
* @returns The route map with CRUD routes
*/
export function createResourcesRoutes<base extends string, const options extends ResourcesOptions>(
base: base | RoutePattern<base>,
Expand Down
10 changes: 5 additions & 5 deletions packages/fetch-router/src/lib/route-map.ts
Original file line number Diff line number Diff line change
Expand Up @@ -41,7 +41,7 @@ export class Route<
* Build a URL href for this route using the given parameters.
*
* @param args The parameters to use for building the href
* @return The built URL href
* @returns The built URL href
*/
href(...args: HrefBuilderArgs<pattern>): string {
return this.pattern.href(...args)
Expand All @@ -51,7 +51,7 @@ export class Route<
* Match a URL against this route's pattern.
*
* @param url The URL to match
* @return The match result, or `null` if the URL doesn't match
* @returns The match result, or `null` if the URL doesn't match
*/
match(url: string | URL): RouteMatch<pattern> | null {
return this.pattern.match(url)
Expand All @@ -71,15 +71,15 @@ export type BuildRoute<method extends RequestMethod | 'ANY', pattern extends str
* Create a route map from a set of route definitions.
*
* @param defs The route definitions
* @return The route map
* @returns The route map
*/
export function createRoutes<const defs extends RouteDefs>(defs: defs): BuildRouteMap<'/', defs>
/**
* Create a route map from a set of route definitions with a base pattern.
*
* @param base The base pattern for all routes
* @param defs The route definitions
* @return The route map
* @returns The route map
*/
export function createRoutes<base extends string, const defs extends RouteDefs>(
base: base | RoutePattern<base>,
Expand Down Expand Up @@ -128,7 +128,7 @@ export type BuildRouteMap<base extends string, defs extends RouteDefs> = Simplif
}>

// prettier-ignore
type BuildRouteWithBase<base extends string, def extends RouteDef> =
type BuildRouteWithBase<base extends string, def extends RouteDef> =
def extends string ? Route<'ANY', Join<base, def>> :
def extends RoutePattern<infer pattern extends string> ? Route<'ANY', Join<base, pattern>> :
def extends { method: infer method extends RequestMethod | 'ANY', pattern: infer pattern } ? (
Expand Down
4 changes: 2 additions & 2 deletions packages/fetch-router/src/lib/router.ts
Original file line number Diff line number Diff line change
Expand Up @@ -71,7 +71,7 @@ export interface Router {
*
* @param input The request input to fetch
* @param init The request init options
* @return The response from the route that matched the request
* @returns The response from the route that matched the request
*/
fetch(input: string | URL | Request, init?: RequestInit): Promise<Response>
/**
Expand Down Expand Up @@ -177,7 +177,7 @@ function noMatchHandler({ url }: RequestContext): Response {
* Create a new router.
*
* @param options Options to configure the router
* @return The new router
* @returns The new router
*/
export function createRouter(options?: RouterOptions): Router {
let defaultHandler = options?.defaultHandler ?? noMatchHandler
Expand Down
8 changes: 4 additions & 4 deletions packages/file-storage/src/lib/file-storage.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,14 +6,14 @@ export interface FileStorage {
* Get a [`File`](https://developer.mozilla.org/en-US/docs/Web/API/File) at the given key.
*
* @param key The key to look up
* @return The file with the given key, or `null` if no such key exists
* @returns The file with the given key, or `null` if no such key exists
*/
get(key: string): File | null | Promise<File | null>
/**
* Check if a file with the given key exists.
*
* @param key The key to look up
* @return `true` if a file with the given key exists, `false` otherwise
* @returns `true` if a file with the given key exists, `false` otherwise
*/
has(key: string): boolean | Promise<boolean>
/**
Expand Down Expand Up @@ -73,7 +73,7 @@ export interface FileStorage {
* Use the `limit` option to limit how many results you get back in the `files` array.
*
* @param options Options for the list operation
* @return An object with an array of `files` and an optional `cursor` property
* @returns An object with an array of `files` and an optional `cursor` property
*/
list<T extends ListOptions>(options?: T): ListResult<T> | Promise<ListResult<T>>
/**
Expand All @@ -82,7 +82,7 @@ export interface FileStorage {
*
* @param key The key to store the file under
* @param file The file to store
* @return A new `File` object backed by this storage
* @returns A new `File` object backed by this storage
*/
put(key: string, file: File): File | Promise<File>
/**
Expand Down
2 changes: 1 addition & 1 deletion packages/form-data-middleware/src/lib/form-data.ts
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,7 @@ export interface FormDataOptions extends ParseFormDataOptions {
* Middleware that parses `FormData` from the request body and populates `context.formData`.
*
* @param options Options for parsing form data
* @return A middleware function that parses form data
* @returns A middleware function that parses form data
*/
export function formData(options?: FormDataOptions): Middleware {
let suppressErrors = options?.suppressErrors ?? false
Expand Down
6 changes: 3 additions & 3 deletions packages/form-data-parser/src/lib/form-data.ts
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,7 @@ export class MaxFilesExceededError extends FormDataParseError {
*/
export class FileUpload extends File {
/**
* The name of the <input> field used to upload the file.
* The name of the `<input>` field used to upload the file.
*/
readonly fieldName: string

Expand All @@ -47,7 +47,7 @@ export class FileUpload extends File {
* A function used for handling file uploads.
*
* @param file The uploaded file
* @return A value to store in `FormData`, or `void`/`null` to skip
* @returns A value to store in `FormData`, or `void`/`null` to skip
*/
export interface FileUploadHandler {
(file: FileUpload): void | null | string | Blob | Promise<void | null | string | Blob>
Expand Down Expand Up @@ -84,7 +84,7 @@ export interface ParseFormDataOptions extends MultipartParserOptions {
* @param request The `Request` object to parse
* @param options Options for the parser
* @param uploadHandler A function that handles file uploads. It receives a `File` object and may return any value that is valid in a `FormData` object
* @return A `Promise` that resolves to a `FormData` object containing the parsed data
* @returns A `Promise` that resolves to a `FormData` object containing the parsed data
*/
export async function parseFormData(
request: Request,
Expand Down
Loading