Skip to content

Commit 7ff31e4

Browse files
committed
Simplify types & improve type docs
1 parent 7873d93 commit 7ff31e4

File tree

5 files changed

+92
-33
lines changed

5 files changed

+92
-33
lines changed

packages/server/src/handlers/BaseHandler.ts

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
import EventEmitter from 'node:events'
22

3-
import type {ServerOptions, WithRequired} from '../types'
3+
import type {ServerOptions} from '../types'
44
import type {DataStore, CancellationContext} from '../models'
55
import type http from 'node:http'
66
import stream from 'node:stream'
@@ -11,10 +11,10 @@ const reForwardedHost = /host="?([^";]+)/
1111
const reForwardedProto = /proto=(https?)/
1212

1313
export class BaseHandler extends EventEmitter {
14-
options: WithRequired<ServerOptions, 'locker'>
14+
options: ServerOptions
1515
store: DataStore
1616

17-
constructor(store: DataStore, options: WithRequired<ServerOptions, 'locker'>) {
17+
constructor(store: DataStore, options: ServerOptions) {
1818
super()
1919
if (!store) {
2020
throw new Error('Store must be defined')

packages/server/src/handlers/PostHandler.ts

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -13,10 +13,9 @@ const log = debug('tus-node-server:handlers:post')
1313

1414
export class PostHandler extends BaseHandler {
1515
// Overriding the `BaseHandler` type. We always set `namingFunction` in the constructor.
16-
options!: Required<Pick<ServerOptions, 'namingFunction' | 'locker'>> &
17-
Omit<ServerOptions, 'namingFunction' | 'locker'>
16+
options!: WithRequired<ServerOptions, 'namingFunction'>
1817

19-
constructor(store: DataStore, options: WithRequired<ServerOptions, 'locker'>) {
18+
constructor(store: DataStore, options: ServerOptions) {
2019
if (options.namingFunction && typeof options.namingFunction !== 'function') {
2120
throw new Error("'namingFunction' must be a function")
2221
}

packages/server/src/server.ts

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,7 @@ import {
2020
} from './constants'
2121

2222
import type stream from 'node:stream'
23-
import type {ServerOptions, RouteHandler, WithRequired} from './types'
23+
import type {ServerOptions, RouteHandler, WithOptional} from './types'
2424
import type {DataStore, Upload, CancellationContext} from './models'
2525
import {MemoryLocker} from './lockers'
2626

@@ -77,9 +77,9 @@ const log = debug('tus-node-server')
7777
export class Server extends EventEmitter {
7878
datastore: DataStore
7979
handlers: Handlers
80-
options: WithRequired<ServerOptions, 'locker'>
80+
options: ServerOptions
8181

82-
constructor(options: ServerOptions & {datastore: DataStore}) {
82+
constructor(options: WithOptional<ServerOptions, 'locker'> & {datastore: DataStore}) {
8383
super()
8484

8585
if (!options) {
@@ -99,7 +99,7 @@ export class Server extends EventEmitter {
9999
}
100100

101101
const {datastore, ...rest} = options
102-
this.options = rest as WithRequired<ServerOptions, 'locker'>
102+
this.options = rest as ServerOptions
103103
this.datastore = datastore
104104
this.handlers = {
105105
// GET handlers should be written in the implementations

packages/server/src/types.ts

Lines changed: 82 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -2,57 +2,115 @@ import type http from 'node:http'
22

33
import type {Locker, Upload} from './models'
44

5+
/**
6+
* Represents the configuration options for a server.
7+
*/
58
export type ServerOptions = {
6-
// The route to accept requests.
9+
/**
10+
* The route to accept requests.
11+
*/
712
path: string
8-
// Return a relative URL as the `Location` header.
13+
14+
/**
15+
* Return a relative URL as the `Location` header.
16+
*/
917
relativeLocation?: boolean
10-
// Allow `Forwarded`, `X-Forwarded-Proto`, and `X-Forwarded-Host` headers
11-
// to override the `Location` header returned by the server.
18+
19+
/**
20+
* Allow `Forwarded`, `X-Forwarded-Proto`, and `X-Forwarded-Host` headers
21+
* to override the `Location` header returned by the server.
22+
*/
1223
respectForwardedHeaders?: boolean
13-
// adds custom headers sent in `Access-Control-Allow-Headers`.
24+
25+
/**
26+
* Additional headers sent in `Access-Control-Allow-Headers`.
27+
*/
1428
allowedHeaders?: string[]
15-
// Control how the upload url is generated
29+
30+
/**
31+
* Control how the upload URL is generated.
32+
* @param req - The incoming HTTP request.
33+
* @param options - Options for generating the URL.
34+
*/
1635
generateUrl?: (
1736
req: http.IncomingMessage,
1837
options: {proto: string; host: string; baseUrl: string; path: string; id: string}
1938
) => string
20-
// Control how the Upload-ID is extracted from the request
39+
40+
/**
41+
* Control how the Upload-ID is extracted from the request.
42+
* @param req - The incoming HTTP request.
43+
*/
2144
getFileIdFromRequest?: (req: http.IncomingMessage) => string | void
22-
// Control how you want to name files.
23-
// It is important to make these unique to prevent data loss. Only use it if you really need to.
24-
// Default uses `crypto.randomBytes(16).toString('hex')`.
45+
46+
/**
47+
* Control how you want to name files.
48+
* It is important to make these unique to prevent data loss.
49+
* Only use it if you really need to.
50+
* Default uses `crypto.randomBytes(16).toString('hex')`.
51+
* @param req - The incoming HTTP request.
52+
*/
2553
namingFunction?: (req: http.IncomingMessage) => string
26-
// locker implementation to support distributed locks
27-
locker?:
54+
55+
/**
56+
* The Lock interface defines methods for implementing a locking mechanism.
57+
* It is primarily used to ensure exclusive access to resources, such as uploads and their metadata.
58+
*/
59+
locker:
2860
| Locker
2961
| Promise<Locker>
3062
| ((req: http.IncomingMessage) => Locker | Promise<Locker>)
31-
// `onUploadCreate` will be invoked before a new upload is created.
32-
// If the function returns the (modified) response, the upload will be created.
33-
// If an error is thrown, the HTTP request will be aborted and the provided `body` and `status_code` (or their fallbacks)
34-
// will be sent to the client. This can be used to implement validation of upload metadata or add headers.
63+
64+
/**
65+
* `onUploadCreate` will be invoked before a new upload is created.
66+
* If the function returns the (modified) response, the upload will be created.
67+
* If an error is thrown, the HTTP request will be aborted, and the provided `body` and `status_code`
68+
* (or their fallbacks) will be sent to the client. This can be used to implement validation of upload
69+
* metadata or add headers.
70+
* @param req - The incoming HTTP request.
71+
* @param res - The HTTP response.
72+
* @param upload - The Upload object.
73+
*/
3574
onUploadCreate?: (
3675
req: http.IncomingMessage,
3776
res: http.ServerResponse,
3877
upload: Upload
3978
) => Promise<http.ServerResponse>
40-
// `onUploadFinish` will be invoked after an upload is completed but before a response is returned to the client.
41-
// If the function returns the (modified) response, the upload will finish.
42-
// If an error is thrown, the HTTP request will be aborted and the provided `body` and `status_code` (or their fallbacks)
43-
// will be sent to the client. This can be used to implement post-processing validation.
79+
80+
/**
81+
* `onUploadFinish` will be invoked after an upload is completed but before a response is returned to the client.
82+
* If the function returns the (modified) response, the upload will finish.
83+
* If an error is thrown, the HTTP request will be aborted, and the provided `body` and `status_code`
84+
* (or their fallbacks) will be sent to the client. This can be used to implement post-processing validation.
85+
* @param req - The incoming HTTP request.
86+
* @param res - The HTTP response.
87+
* @param upload - The Upload object.
88+
*/
4489
onUploadFinish?: (
4590
req: http.IncomingMessage,
4691
res: http.ServerResponse,
4792
upload: Upload
4893
) => Promise<http.ServerResponse>
94+
95+
/**
96+
* `onIncomingRequest` will be invoked when an incoming request is received.
97+
* @param req - The incoming HTTP request.
98+
* @param res - The HTTP response.
99+
* @param uploadId - The ID of the upload.
100+
*/
49101
onIncomingRequest?: (
50102
req: http.IncomingMessage,
51103
res: http.ServerResponse,
52104
uploadId: string
53105
) => Promise<void>
54-
// `onResponseError` will be invoked when an error response is about to be sent by the server.
55-
// you use this function to map custom errors to tus errors or for custom observability.
106+
107+
/**
108+
* `onResponseError` will be invoked when an error response is about to be sent by the server.
109+
* Use this function to map custom errors to tus errors or for custom observability.
110+
* @param req - The incoming HTTP request.
111+
* @param res - The HTTP response.
112+
* @param err - The error object or response.
113+
*/
56114
onResponseError?: (
57115
req: http.IncomingMessage,
58116
res: http.ServerResponse,
@@ -65,4 +123,6 @@ export type ServerOptions = {
65123

66124
export type RouteHandler = (req: http.IncomingMessage, res: http.ServerResponse) => void
67125

126+
export type WithOptional<T, K extends keyof T> = Omit<T, K> & {[P in K]+?: T[P]}
127+
68128
export type WithRequired<T, K extends keyof T> = T & {[P in K]-?: T[P]}

packages/server/test/utils.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,7 @@ export function addPipableStreamBody<T extends httpMocks.MockRequest<unknown>>(
1313
})
1414

1515
// Add the pipe method to the mockRequest
16-
// @ts-ignore
16+
// @ts-expect-error pipe exists
1717
mockRequest.pipe = function (dest: stream.Writable) {
1818
bodyStream.pipe(dest)
1919
}

0 commit comments

Comments
 (0)