Socket
Socket
Sign inDemoInstall

formdata-node

Package Overview
Dependencies
4
Maintainers
1
Versions
76
Alerts
File Explorer

Advanced tools

Install Socket

Detect and block malicious and high-risk dependencies

Install

Comparing version 3.5.4 to 3.6.0

browser.js

9

@type/fileFromPath.d.ts
import { File, FileOptions } from "./File";
export declare type FileFromPathOptions = Omit<FileOptions, "lastModified">;
/**

@@ -11,4 +12,4 @@ * Creates a `File` referencing the one on a disk by given path. Synchronous version of the `fileFromPath`

export declare function fileFromPathSync(path: string, filename?: string): File;
export declare function fileFromPathSync(path: string, options?: FileOptions): File;
export declare function fileFromPathSync(path: string, filename?: string, options?: FileOptions): File;
export declare function fileFromPathSync(path: string, options?: FileFromPathOptions): File;
export declare function fileFromPathSync(path: string, filename?: string, options?: FileFromPathOptions): File;
/**

@@ -23,3 +24,3 @@ * Creates a `File` referencing the one on a disk by given path.

export declare function fileFromPath(path: string, filename?: string): Promise<File>;
export declare function fileFromPath(path: string, options?: FileOptions): Promise<File>;
export declare function fileFromPath(path: string, filename?: string, options?: FileOptions): Promise<File>;
export declare function fileFromPath(path: string, options?: FileFromPathOptions): Promise<File>;
export declare function fileFromPath(path: string, filename?: string, options?: FileFromPathOptions): Promise<File>;

@@ -32,6 +32,2 @@ /// <reference types="node" />

/**
* Returns a boundary string
*/
readonly boundary: string;
/**
* Returns headers for multipart/form-data

@@ -50,2 +46,3 @@ *

get stream(): Readable;
get boundary(): string;
constructor(entries?: FormDataConstructorEntries);

@@ -151,3 +148,3 @@ /**

*/
[Symbol.asyncIterator](): AsyncGenerator<Buffer, void, unknown>;
[Symbol.asyncIterator](): AsyncGenerator<Uint8Array, void, undefined>;
}

@@ -21,6 +21,5 @@ "use strict";

const path_1 = require("path");
const domexception_1 = __importDefault(require("domexception"));
const node_domexception_1 = __importDefault(require("node-domexception"));
const File_1 = require("./File");
const isPlainObject_1 = __importDefault(require("./util/isPlainObject"));
const getMimeFromFilename_1 = __importDefault(require("./util/getMimeFromFilename"));
const MESSAGE = "The requested file could not be read, "

@@ -36,10 +35,10 @@ + "typically due to permission problems that have occurred after a reference "

class FileFromPath {
constructor(options) {
constructor(input) {
_FileFromPath_path.set(this, void 0);
_FileFromPath_start.set(this, void 0);
__classPrivateFieldSet(this, _FileFromPath_path, options.path, "f");
__classPrivateFieldSet(this, _FileFromPath_start, options.start || 0, "f");
__classPrivateFieldSet(this, _FileFromPath_path, input.path, "f");
__classPrivateFieldSet(this, _FileFromPath_start, input.start || 0, "f");
this.name = path_1.basename(__classPrivateFieldGet(this, _FileFromPath_path, "f"));
this.size = options.size;
this.lastModified = options.lastModified;
this.size = input.size;
this.lastModified = input.lastModified;
}

@@ -58,3 +57,3 @@ slice(start, end) {

// eslint-disable-next-line @typescript-eslint/no-throw-literal
throw new domexception_1.default(MESSAGE, "NotReadableError");
throw new node_domexception_1.default(MESSAGE, "NotReadableError");
}

@@ -84,9 +83,5 @@ if (this.size) {

}
if (!options.lastModified) {
options.lastModified = file.lastModified;
}
if (!options.type) {
options.type = getMimeFromFilename_1.default(filename);
}
return new File_1.File([file], filename, options);
return new File_1.File([file], filename, {
...options, lastModified: file.lastModified
});
}

@@ -93,0 +88,0 @@ function fileFromPathSync(path, filenameOrOptions, options = {}) {

@@ -8,7 +8,2 @@ "use strict";

};
var __classPrivateFieldGet = (this && this.__classPrivateFieldGet) || function (receiver, state, kind, f) {
if (kind === "a" && !f) throw new TypeError("Private accessor was defined without a getter");
if (typeof state === "function" ? receiver !== state || !f : !state.has(receiver)) throw new TypeError("Cannot read private member from an object whose class did not declare it");
return kind === "m" ? f : kind === "a" ? f.call(receiver) : f ? f.value : state.get(receiver);
};
var __classPrivateFieldSet = (this && this.__classPrivateFieldSet) || function (receiver, state, value, kind, f) {

@@ -20,6 +15,11 @@ if (kind === "m") throw new TypeError("Private method is not writable");

};
var __classPrivateFieldGet = (this && this.__classPrivateFieldGet) || function (receiver, state, kind, f) {
if (kind === "a" && !f) throw new TypeError("Private accessor was defined without a getter");
if (typeof state === "function" ? receiver !== state || !f : !state.has(receiver)) throw new TypeError("Cannot read private member from an object whose class did not declare it");
return kind === "m" ? f : kind === "a" ? f.call(receiver) : f ? f.value : state.get(receiver);
};
var __importDefault = (this && this.__importDefault) || function (mod) {
return (mod && mod.__esModule) ? mod : { "default": mod };
};
var _FormData_instances, _FormData_stream, _FormData_content, _FormData_footer, _FormData_getHeader, _FormData_getField, _FormData_setField;
var _FormData_instances, _FormData_stream, _FormData_encoder, _FormData_content, _FormData_setField;
var _a;

@@ -31,2 +31,3 @@ Object.defineProperty(exports, "__esModule", { value: true });

const util_1 = require("util");
const form_data_encoder_1 = require("form-data-encoder");
const File_1 = require("./File");

@@ -41,11 +42,6 @@ const fileFromPath_1 = require("./fileFromPath");

const isFile_1 = __importDefault(require("./util/isFile"));
const getLength_1 = __importDefault(require("./util/getLength"));
const isPlainObject_1 = __importDefault(require("./util/isPlainObject"));
const createBoundary_1 = __importDefault(require("./util/createBoundary"));
const isReadStream_1 = __importDefault(require("./util/isReadStream"));
const getFilename_1 = __importDefault(require("./util/getFilename"));
const { isBuffer } = Buffer;
const DASHES = "-".repeat(2);
const CRLF = "\r\n";
const CRLF_BYTES_LENGTH = Buffer.byteLength(CRLF);
class FormData {

@@ -56,18 +52,8 @@ constructor(entries) {

_FormData_stream.set(this, void 0);
_FormData_encoder.set(this, void 0);
/**
* Returns a boundary string
*/
this.boundary = `NodeJSFormDataStreamBoundary${createBoundary_1.default()}`;
/**
* Stores internal data for every field
*/
_FormData_content.set(this, new Map()
/**
* Returns field's footer
*/
);
/**
* Returns field's footer
*/
_FormData_footer.set(this, `${DASHES}${this.boundary}${DASHES}${CRLF.repeat(2)}`);
_FormData_content.set(this, new Map());
__classPrivateFieldSet(this, _FormData_encoder, new form_data_encoder_1.Encoder(this), "f");
if (entries) {

@@ -98,2 +84,5 @@ entries.forEach(({ name, value, filename, options }) => this.append(name, value, filename, options));

}
get boundary() {
return __classPrivateFieldGet(this, _FormData_encoder, "f").boundary;
}
/**

@@ -105,8 +94,3 @@ * Returns computed length of the FormData content.

getComputedLength() {
let length = 0;
for (const [name, value] of this) {
length += Buffer.byteLength(__classPrivateFieldGet(this, _FormData_instances, "m", _FormData_getHeader).call(this, name, value));
length += getLength_1.default(value) + CRLF_BYTES_LENGTH;
}
return length + Buffer.byteLength(__classPrivateFieldGet(this, _FormData_footer, "f"));
return __classPrivateFieldGet(this, _FormData_encoder, "f").getContentLength();
}

@@ -208,28 +192,3 @@ append(name, value, filenameOrOptions, options) {

*/
[(_FormData_stream = new WeakMap(), _FormData_content = new WeakMap(), _FormData_footer = new WeakMap(), _FormData_instances = new WeakSet(), _FormData_getHeader = function _FormData_getHeader(name, value) {
let header = "";
header += `${DASHES}${this.boundary}${CRLF}`;
header += `Content-Disposition: form-data; name="${name}"`;
if (isFile_1.default(value)) {
header += `; filename="${value.name}"${CRLF}`;
header += `Content-Type: ${value.type || "application/octet-stream"}`;
}
return `${header}${CRLF.repeat(2)}`;
}, _FormData_getField = async function* _FormData_getField() {
// Note to switch back to reading from this.#content if any extra logic will be necessary in a future, because the public FormData API returns values only as `string | File`
for (const [name, value] of this) {
// Set field's header
yield __classPrivateFieldGet(this, _FormData_instances, "m", _FormData_getHeader).call(this, name, value);
if (isFile_1.default(value)) {
yield* value.stream();
}
else {
yield value;
}
// Add trailing carriage
yield CRLF;
}
// Add a footer when all fields ended
yield __classPrivateFieldGet(this, _FormData_footer, "f");
}, _FormData_setField = function _FormData_setField({ name, value, append, filenameOrOptions, options, argsLength }) {
[(_FormData_stream = new WeakMap(), _FormData_encoder = new WeakMap(), _FormData_content = new WeakMap(), _FormData_instances = new WeakSet(), _FormData_setField = function _FormData_setField({ name, value, append, filenameOrOptions, options, argsLength }) {
const methodName = append ? "append" : "set";

@@ -317,5 +276,3 @@ name = String(name);

async *[_a = Symbol.asyncIterator]() {
for await (const ch of __classPrivateFieldGet(this, _FormData_instances, "m", _FormData_getField).call(this)) {
yield isBuffer(ch) ? ch : Buffer.from(String(ch));
}
yield* __classPrivateFieldGet(this, _FormData_encoder, "f").encode();
}

@@ -322,0 +279,0 @@ }

@@ -15,6 +15,5 @@ var __classPrivateFieldSet = (this && this.__classPrivateFieldSet) || function (receiver, state, value, kind, f) {

import { basename } from "path";
import DOMException from "domexception";
import DOMException from "node-domexception";
import { File } from "./File.js";
import isPlainObject from "./util/isPlainObject.js";
import getMime from "./util/getMimeFromFilename.js";
const MESSAGE = "The requested file could not be read, "

@@ -30,10 +29,10 @@ + "typically due to permission problems that have occurred after a reference "

class FileFromPath {
constructor(options) {
constructor(input) {
_FileFromPath_path.set(this, void 0);
_FileFromPath_start.set(this, void 0);
__classPrivateFieldSet(this, _FileFromPath_path, options.path, "f");
__classPrivateFieldSet(this, _FileFromPath_start, options.start || 0, "f");
__classPrivateFieldSet(this, _FileFromPath_path, input.path, "f");
__classPrivateFieldSet(this, _FileFromPath_start, input.start || 0, "f");
this.name = basename(__classPrivateFieldGet(this, _FileFromPath_path, "f"));
this.size = options.size;
this.lastModified = options.lastModified;
this.size = input.size;
this.lastModified = input.lastModified;
}

@@ -77,9 +76,5 @@ slice(start, end) {

}
if (!options.lastModified) {
options.lastModified = file.lastModified;
}
if (!options.type) {
options.type = getMime(filename);
}
return new File([file], filename, options);
return new File([file], filename, {
...options, lastModified: file.lastModified
});
}

@@ -86,0 +81,0 @@ export function fileFromPathSync(path, filenameOrOptions, options = {}) {

@@ -7,7 +7,2 @@ var __decorate = (this && this.__decorate) || function (decorators, target, key, desc) {

};
var __classPrivateFieldGet = (this && this.__classPrivateFieldGet) || function (receiver, state, kind, f) {
if (kind === "a" && !f) throw new TypeError("Private accessor was defined without a getter");
if (typeof state === "function" ? receiver !== state || !f : !state.has(receiver)) throw new TypeError("Cannot read private member from an object whose class did not declare it");
return kind === "m" ? f : kind === "a" ? f.call(receiver) : f ? f.value : state.get(receiver);
};
var __classPrivateFieldSet = (this && this.__classPrivateFieldSet) || function (receiver, state, value, kind, f) {

@@ -19,3 +14,8 @@ if (kind === "m") throw new TypeError("Private method is not writable");

};
var _FormData_instances, _FormData_stream, _FormData_content, _FormData_footer, _FormData_getHeader, _FormData_getField, _FormData_setField;
var __classPrivateFieldGet = (this && this.__classPrivateFieldGet) || function (receiver, state, kind, f) {
if (kind === "a" && !f) throw new TypeError("Private accessor was defined without a getter");
if (typeof state === "function" ? receiver !== state || !f : !state.has(receiver)) throw new TypeError("Cannot read private member from an object whose class did not declare it");
return kind === "m" ? f : kind === "a" ? f.call(receiver) : f ? f.value : state.get(receiver);
};
var _FormData_instances, _FormData_stream, _FormData_encoder, _FormData_content, _FormData_setField;
var _a;

@@ -25,2 +25,3 @@ import { Readable } from "stream";

import { inspect } from "util";
import { Encoder } from "form-data-encoder";
import { File } from "./File.js";

@@ -35,11 +36,6 @@ import { fileFromPathSync } from "./fileFromPath.js";

import isFile from "./util/isFile.js";
import getLength from "./util/getLength.js";
import isPlainObject from "./util/isPlainObject.js";
import createBoundary from "./util/createBoundary.js";
import isReadStream from "./util/isReadStream.js";
import getFilename from "./util/getFilename.js";
const { isBuffer } = Buffer;
const DASHES = "-".repeat(2);
const CRLF = "\r\n";
const CRLF_BYTES_LENGTH = Buffer.byteLength(CRLF);
export class FormData {

@@ -50,18 +46,8 @@ constructor(entries) {

_FormData_stream.set(this, void 0);
_FormData_encoder.set(this, void 0);
/**
* Returns a boundary string
*/
this.boundary = `NodeJSFormDataStreamBoundary${createBoundary()}`;
/**
* Stores internal data for every field
*/
_FormData_content.set(this, new Map()
/**
* Returns field's footer
*/
);
/**
* Returns field's footer
*/
_FormData_footer.set(this, `${DASHES}${this.boundary}${DASHES}${CRLF.repeat(2)}`);
_FormData_content.set(this, new Map());
__classPrivateFieldSet(this, _FormData_encoder, new Encoder(this), "f");
if (entries) {

@@ -92,2 +78,5 @@ entries.forEach(({ name, value, filename, options }) => this.append(name, value, filename, options));

}
get boundary() {
return __classPrivateFieldGet(this, _FormData_encoder, "f").boundary;
}
/**

@@ -99,8 +88,3 @@ * Returns computed length of the FormData content.

getComputedLength() {
let length = 0;
for (const [name, value] of this) {
length += Buffer.byteLength(__classPrivateFieldGet(this, _FormData_instances, "m", _FormData_getHeader).call(this, name, value));
length += getLength(value) + CRLF_BYTES_LENGTH;
}
return length + Buffer.byteLength(__classPrivateFieldGet(this, _FormData_footer, "f"));
return __classPrivateFieldGet(this, _FormData_encoder, "f").getContentLength();
}

@@ -202,28 +186,3 @@ append(name, value, filenameOrOptions, options) {

*/
[(_FormData_stream = new WeakMap(), _FormData_content = new WeakMap(), _FormData_footer = new WeakMap(), _FormData_instances = new WeakSet(), _FormData_getHeader = function _FormData_getHeader(name, value) {
let header = "";
header += `${DASHES}${this.boundary}${CRLF}`;
header += `Content-Disposition: form-data; name="${name}"`;
if (isFile(value)) {
header += `; filename="${value.name}"${CRLF}`;
header += `Content-Type: ${value.type || "application/octet-stream"}`;
}
return `${header}${CRLF.repeat(2)}`;
}, _FormData_getField = async function* _FormData_getField() {
// Note to switch back to reading from this.#content if any extra logic will be necessary in a future, because the public FormData API returns values only as `string | File`
for (const [name, value] of this) {
// Set field's header
yield __classPrivateFieldGet(this, _FormData_instances, "m", _FormData_getHeader).call(this, name, value);
if (isFile(value)) {
yield* value.stream();
}
else {
yield value;
}
// Add trailing carriage
yield CRLF;
}
// Add a footer when all fields ended
yield __classPrivateFieldGet(this, _FormData_footer, "f");
}, _FormData_setField = function _FormData_setField({ name, value, append, filenameOrOptions, options, argsLength }) {
[(_FormData_stream = new WeakMap(), _FormData_encoder = new WeakMap(), _FormData_content = new WeakMap(), _FormData_instances = new WeakSet(), _FormData_setField = function _FormData_setField({ name, value, append, filenameOrOptions, options, argsLength }) {
const methodName = append ? "append" : "set";

@@ -311,5 +270,3 @@ name = String(name);

async *[_a = Symbol.asyncIterator]() {
for await (const ch of __classPrivateFieldGet(this, _FormData_instances, "m", _FormData_getField).call(this)) {
yield isBuffer(ch) ? ch : Buffer.from(String(ch));
}
yield* __classPrivateFieldGet(this, _FormData_encoder, "f").encode();
}

@@ -316,0 +273,0 @@ }

{
"name": "formdata-node",
"version": "3.5.4",
"version": "3.6.0",
"description": "FormData implementation for Node.js",

@@ -19,2 +19,3 @@ "repository": "octet-stream/form-data",

"module": "./lib/esm/index.js",
"browser": "./browser.js",
"types": "./@type/index.d.ts",

@@ -32,2 +33,3 @@ "exports": {

"coverage": "c8 npm test",
"report:html": "c8 -r=html npm test",
"ci": "c8 npm test && c8 report --reporter=json",

@@ -46,15 +48,13 @@ "build:esm": "ttsc --project tsconfig.esm.json",

"@octetstream/eslint-config": "5.0.0",
"@types/domexception": "^2.0.1",
"@types/mime-types": "2.1.0",
"@types/node": "15.12.2",
"@types/node": "16.4.2",
"@types/sinon": "10.0.2",
"@types/supertest": "2.0.11",
"@typescript-eslint/eslint-plugin": "4.27.0",
"@typescript-eslint/parser": "4.27.0",
"@typescript-eslint/eslint-plugin": "4.28.4",
"@typescript-eslint/parser": "4.28.4",
"@zoltu/typescript-transformer-append-js-extension": "1.0.1",
"ava": "3.15.0",
"c8": "7.7.3",
"codecov": "3.8.2",
"dotenv": "^10.0.0",
"eslint": "7.28.0",
"codecov": "3.8.3",
"eslint": "7.31.0",
"eslint-config-airbnb-typescript": "12.3.1",

@@ -64,15 +64,15 @@ "eslint-plugin-ava": "12.0.0",

"eslint-plugin-react": "7.24.0",
"husky": "6.0.0",
"lint-staged": "11.0.0",
"husky": "7.0.1",
"lint-staged": "11.1.1",
"pinst": "2.1.6",
"sinon": "11.1.1",
"ts-node": "10.0.0",
"ts-node": "10.1.0",
"ttypescript": "1.5.12",
"typescript": "4.3.2"
"typescript": "4.3.5"
},
"dependencies": {
"domexception": "2.0.1",
"fetch-blob": "2.1.2",
"mime-types": "2.1.31"
"form-data-encoder": "1.0.1",
"node-domexception": "1.0.0"
}
}

@@ -177,2 +177,75 @@ # FormData

8. You can still use files sourced from any stream, but unlike in v2 you'll need some extra work to achieve that:
```js
import {Readable} from "stream"
import {FormData} from "formdata-node"
class BlobFromStream {
#stream
constructor(stream, size) {
this.#stream = stream
this.size = size
}
stream() {
return this.#stream
}
get [Symbol.toStringTag]() {
return "Blob"
}
}
const content = Buffer.from("Stream content")
const stream = new Readable({
read() {
this.push(content)
this.push(null)
}
})
const fd = new FormData()
fd.set("stream", new BlobFromStream(stream, content.length), "file.txt")
await fetch("https://httpbin.org/post", {method: "post", body: fd})
```
9. Note that if you don't know the length of that stream, you'll also need to handle form-data encoding manually or use [`form-data-encoder`](https://github.com/octet-stream/form-data-encoder) package. This is necessary to control which headers will be sent with your HTTP request:
```js
import {Readable} from "stream"
import {Encoder} from "form-data-encoder"
import {FormData} from "formdata-node"
const fd = new FormData()
// You can use file-shaped or blob-shaped objects as FormData value instead of creating separate class
fd.set("stream", {
type: "text/plain",
name: "file.txt",
[Symbol.toStringTag]: "File",
stream() {
return getStreamFromSomewhere()
}
})
const encoder = new Encoder(fd)
const options = {
method: "post",
headers: {
"content-type": encoder.contentType
},
body: Readable.from(encoder)
}
await fetch("https://httpbin.org/post", {method: "post", body: fd})
```
## API

@@ -328,3 +401,2 @@

- **{object}** [options = {}] - File options.
- **{number}** [options.lastModified = Date.now()] – provides the last modified date of the file as the number of milliseconds since the Unix epoch (January 1, 1970 at midnight). Files without a known last modified date return the current date.
- **{string}** [options.type = ""] - Returns the media type ([`MIME`](https://developer.mozilla.org/en-US/docs/Web/HTTP/Basics_of_HTTP/MIME_types)) of the file represented by a `File` object.

@@ -339,3 +411,2 @@

- **{object}** [options = {}] - File options.
- **{number}** [options.lastModified = Date.now()] – provides the last modified date of the file as the number of milliseconds since the Unix epoch (January 1, 1970 at midnight). Files without a known last modified date return the current date.
- **{string}** [options.type = ""] - Returns the media type ([`MIME`](https://developer.mozilla.org/en-US/docs/Web/HTTP/Basics_of_HTTP/MIME_types)) of the file represented by a `File` object.

@@ -342,0 +413,0 @@

Sorry, the diff of this file is not supported yet

SocketSocket SOC 2 Logo

Product

  • Package Alerts
  • Integrations
  • Docs
  • Pricing
  • FAQ
  • Roadmap

Stay in touch

Get open source security insights delivered straight into your inbox.


  • Terms
  • Privacy
  • Security

Made with ⚡️ by Socket Inc