Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

fix(types): make definitions nodenext compatible #396

Merged
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
265 changes: 151 additions & 114 deletions index.d.ts
@@ -1,92 +1,111 @@
import { Busboy, BusboyConfig, BusboyFileStream } from "@fastify/busboy";
import { FastifyPluginCallback } from "fastify";
import { Readable } from 'stream';
import { Readable } from "stream";
import { FastifyErrorConstructor } from "@fastify/error";

type MultipartHandler = (
field: string,
file: BusboyFileStream,
filename: string,
encoding: string,
mimetype: string,
) => void;

interface BodyEntry {
data: Buffer,
filename: string,
encoding: string,
mimetype: string,
limit: false
}

export interface MultipartFields {
[fieldname: string]: Multipart | Multipart[] | undefined;
declare module "fastify" {
interface FastifyRequest {
isMultipart: () => boolean;

// promise api
parts: (
options?: Omit<BusboyConfig, "headers">
) => AsyncIterableIterator<fastifyMultipart.Multipart>;

// legacy
multipart: (
handler: MultipartHandler,
next: (err: Error) => void,
options?: Omit<BusboyConfig, "headers">
) => Busboy;

// Stream mode
file: (
options?: Omit<BusboyConfig, "headers">
) => Promise<fastifyMultipart.MultipartFile | undefined>;
files: (
options?: Omit<BusboyConfig, "headers">
) => AsyncIterableIterator<fastifyMultipart.MultipartFile>;

// Disk mode
saveRequestFiles: (
options?: Omit<BusboyConfig, "headers"> & { tmpdir?: string }
) => Promise<Array<fastifyMultipart.SavedMultipartFile>>;
cleanRequestFiles: () => Promise<void>;
tmpUploads: Array<string> | null;
}

interface FastifyInstance {
multipartErrors: MultipartErrors;
}
}

export type Multipart = MultipartFile | MultipartValue;
type FastifyMultipartPlugin = FastifyPluginCallback<
| fastifyMultipart.FastifyMultipartBaseOptions
| fastifyMultipart.FastifyMultipartOptions
| fastifyMultipart.FastifyMultipartAttachFieldsToBodyOptions
>;

export interface MultipartFile {
toBuffer: () => Promise<Buffer>,
type MultipartHandler = (
field: string,
file: BusboyFileStream,
fieldname: string,
filename: string,
encoding: string,
mimetype: string,
fields: MultipartFields
}

export interface SavedMultipartFile extends MultipartFile {
/**
* Path to the temporary file
*/
filepath: string,
}
mimetype: string
) => void;

export interface MultipartValue<T = unknown> {
value: T;
fieldname: string;
mimetype: string;
interface BodyEntry {
data: Buffer;
filename: string;
encoding: string;
fieldnameTruncated: boolean;
valueTruncated: boolean;
fields: MultipartFields;
mimetype: string;
limit: false;
}

interface MultipartErrors {
PartsLimitError: FastifyErrorConstructor,
FilesLimitError: FastifyErrorConstructor,
FieldsLimitError: FastifyErrorConstructor,
PrototypeViolationError: FastifyErrorConstructor,
InvalidMultipartContentTypeError: FastifyErrorConstructor,
RequestFileTooLargeError: FastifyErrorConstructor
PartsLimitError: FastifyErrorConstructor;
FilesLimitError: FastifyErrorConstructor;
FieldsLimitError: FastifyErrorConstructor;
PrototypeViolationError: FastifyErrorConstructor;
InvalidMultipartContentTypeError: FastifyErrorConstructor;
RequestFileTooLargeError: FastifyErrorConstructor;
}

declare module "fastify" {
interface FastifyRequest {
isMultipart: () => boolean;

// promise api
parts: (options?: Omit<BusboyConfig, 'headers'>) => AsyncIterableIterator<Multipart>

// legacy
multipart: (handler: MultipartHandler, next: (err: Error) => void, options?: Omit<BusboyConfig, 'headers'>) => Busboy;

// Stream mode
file: (options?: Omit<BusboyConfig, 'headers'>) => Promise<MultipartFile | undefined>
files: (options?: Omit<BusboyConfig, 'headers'>) => AsyncIterableIterator<MultipartFile>

// Disk mode
saveRequestFiles: (options?: Omit<BusboyConfig, 'headers'> & { tmpdir?: string }) => Promise<Array<SavedMultipartFile>>
cleanRequestFiles: () => Promise<void>
tmpUploads: Array<string> | null
}

interface FastifyInstance {
multipartErrors: MultipartErrors
}
}
declare namespace fastifyMultipart {
export interface SavedMultipartFile extends MultipartFile {
/**
* Path to the temporary file
*/
filepath: string;
}

export type Multipart = MultipartFile | MultipartValue;

export interface MultipartFile {
toBuffer: () => Promise<Buffer>;
file: BusboyFileStream;
fieldname: string;
filename: string;
encoding: string;
mimetype: string;
fields: MultipartFields;
}

export interface MultipartValue<T = unknown> {
value: T;
fieldname: string;
mimetype: string;
encoding: string;
fieldnameTruncated: boolean;
valueTruncated: boolean;
fields: MultipartFields;
}

export interface MultipartFields {
[fieldname: string]: Multipart | Multipart[] | undefined;
}

export interface FastifyMultipartBaseOptions {
export interface FastifyMultipartBaseOptions {
/**
* Append the multipart parameters to the body object
*/
Expand All @@ -100,7 +119,7 @@ export interface FastifyMultipartBaseOptions {
/**
* Allow throwing error when file size limit reached.
*/
throwFileSizeLimit?: boolean
throwFileSizeLimit?: boolean;

/**
* Detect if a Part is a file.
Expand All @@ -111,64 +130,82 @@ export interface FastifyMultipartBaseOptions {
*
* Modify this to handle e.g. Blobs.
*/
isPartAFile?: (fieldName: string | undefined, contentType: string | undefined, fileName: string | undefined) => boolean;
isPartAFile?: (
fieldName: string | undefined,
contentType: string | undefined,
fileName: string | undefined
) => boolean;

limits?: {
/**
* Max field name size in bytes
*/
fieldNameSize?: number;

/**
* Max field value size in bytes
*/
fieldSize?: number;

/**
* Max number of non-file fields
*/
fields?: number;

/**
* For multipart forms, the max file size
*/
fileSize?: number;

/**
* Max number of file fields
*/
files?: number;

/**
* Max number of header key=>value pairs
*/
headerPairs?: number;
}
}

export interface FastifyMultipartOptions extends FastifyMultipartBaseOptions {
/**
* Max field name size in bytes
*/
fieldNameSize?: number;

/**
* Max field value size in bytes
*/
fieldSize?: number;

/**
* Max number of non-file fields
*/
fields?: number;

/**
* For multipart forms, the max file size
*/
fileSize?: number;

/**
* Max number of file fields
*/
files?: number;

/**
* Max number of header key=>value pairs
*/
headerPairs?: number;
};
}

export interface FastifyMultipartOptions extends FastifyMultipartBaseOptions {
/**
* Only valid in the promise api. Append the multipart parameters to the body object.
*/
attachFieldsToBody?: false
attachFieldsToBody?: false;

/**
* Manage the file stream like you need
*/
onFile?: (fieldName: string, stream: Readable, filename: string, encoding: string, mimetype: string, body: Record<string, BodyEntry>) => void | Promise<void>;
}

export interface FastifyMultipartAttactFieldsToBodyOptions extends FastifyMultipartBaseOptions {
onFile?: (
fieldName: string,
stream: Readable,
filename: string,
encoding: string,
mimetype: string,
body: Record<string, BodyEntry>
) => void | Promise<void>;
}

export interface FastifyMultipartAttachFieldsToBodyOptions
extends FastifyMultipartBaseOptions {
/**
* Only valid in the promise api. Append the multipart parameters to the body object.
*/
attachFieldsToBody: true | 'keyValues';
attachFieldsToBody: true | "keyValues";

/**
* Manage the file stream like you need
*/
onFile?: (part: MultipartFile) => void | Promise<void>;
}

export const fastifyMultipart: FastifyMultipartPlugin;
export { fastifyMultipart as default };
}
declare function fastifyMultipart(
...params: Parameters<FastifyMultipartPlugin>
): ReturnType<FastifyMultipartPlugin>;

declare const fastifyMultipart: FastifyPluginCallback<FastifyMultipartOptions | FastifyMultipartAttactFieldsToBodyOptions>;
export default fastifyMultipart;
export = fastifyMultipart;