Skip to content

Commit

Permalink
fix(types): make definitions nodenext compatible (#396)
Browse files Browse the repository at this point in the history
* chore: make definitions nodenext compatible

* chore: add index necessary changes
  • Loading branch information
cesarvspr committed Oct 26, 2022
1 parent 4e21cdc commit 49f3a62
Show file tree
Hide file tree
Showing 3 changed files with 166 additions and 115 deletions.
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;
10 changes: 9 additions & 1 deletion index.js
Expand Up @@ -575,7 +575,15 @@ function fastifyMultipart (fastify, options, done) {
done()
}

module.exports = fp(fastifyMultipart, {
const _fastifyMultipart = fp(fastifyMultipart, {
fastify: '4.x',
name: '@fastify/multipart'
})

/**
* These export configurations enable JS and TS developers
* to consumer fastify in whatever way best suits their needs.
*/
module.exports = _fastifyMultipart
module.exports.fastifyMultipart = _fastifyMultipart
module.exports.default = _fastifyMultipart
6 changes: 6 additions & 0 deletions test/named-import.test-d.ts
@@ -0,0 +1,6 @@
import fastify from "fastify";
import { fastifyMultipart } from "..";

const app = fastify();

app.register(fastifyMultipart);

0 comments on commit 49f3a62

Please sign in to comment.