Build utilities for Now (Vercel) serverless platform runtime development
—
Quality
Pending
Does it follow best practices?
Impact
Pending
No eval scenarios have been run
Three specialized file classes for representing different types of file storage and enabling seamless file operations.
Represents a file stored remotely with a content digest, typically in cloud storage.
/**
* File stored remotely with content digest
*/
class FileRef implements File {
public type: 'FileRef';
public mode: number;
public digest: string;
public contentType: string | undefined;
constructor(options: FileRefOptions);
toStream(): NodeJS.ReadableStream;
toStreamAsync(): Promise<NodeJS.ReadableStream>;
}
interface FileRefOptions {
/** File mode/permissions (default: 0o100644) */
mode?: number;
/** Content digest in format "sha:hash" or "sha+ephemeral:hash" */
digest: string;
/** MIME content type */
contentType?: string;
/** Whether file contents can change (affects caching) */
mutable?: boolean;
}Usage Examples:
import { FileRef } from "@now/build-utils";
// Create reference to cached file
const cachedFile = new FileRef({
digest: "sha:a1b2c3d4e5f6789...",
contentType: "application/javascript",
mode: 0o100644
});
// Create reference to ephemeral file
const tempFile = new FileRef({
digest: "sha+ephemeral:x9y8z7w6v5u4321...",
contentType: "text/plain",
mutable: true
});
// Stream file contents
const stream = cachedFile.toStream();
stream.pipe(process.stdout);
// Async streaming
const asyncStream = await cachedFile.toStreamAsync();Represents a file in the local filesystem with direct access to the file path.
/**
* File in the local filesystem
*/
class FileFsRef implements File {
public type: 'FileFsRef';
public mode: number;
public fsPath: string;
public contentType: string | undefined;
constructor(options: FileFsRefOptions);
static fromFsPath(options: FileFsRefOptions): Promise<FileFsRef>;
static fromStream(options: FromStreamOptions): Promise<FileFsRef>;
toStream(): NodeJS.ReadableStream;
toStreamAsync(): Promise<NodeJS.ReadableStream>;
}
interface FileFsRefOptions {
/** File mode/permissions (default: 0o100644) */
mode?: number;
/** MIME content type */
contentType?: string;
/** Absolute path to file in filesystem */
fsPath: string;
}
interface FromStreamOptions {
/** File mode/permissions (default: 0o100644) */
mode?: number;
/** MIME content type */
contentType?: string;
/** Input stream to read from */
stream: NodeJS.ReadableStream;
/** Destination path to write stream to */
fsPath: string;
}Usage Examples:
import { FileFsRef } from "@now/build-utils";
// Create from existing file
const existingFile = new FileFsRef({
fsPath: "/path/to/file.js",
contentType: "application/javascript"
});
// Create from file path with automatic mode detection
const autoModeFile = await FileFsRef.fromFsPath({
fsPath: "/path/to/script.py",
contentType: "text/x-python"
});
// Create from stream (downloads and saves)
const streamFile = await FileFsRef.fromStream({
stream: someReadableStream,
fsPath: "/tmp/downloaded-file.txt",
mode: 0o100644
});
// Stream file contents
const stream = existingFile.toStream();Represents a file stored in memory as a string or Buffer.
/**
* File stored in memory as string or Buffer
*/
class FileBlob implements File {
public type: 'FileBlob';
public mode: number;
public data: string | Buffer;
public contentType: string | undefined;
constructor(options: FileBlobOptions);
static fromStream(options: FromStreamOptions): Promise<FileBlob>;
toStream(): NodeJS.ReadableStream;
}
interface FileBlobOptions {
/** File mode/permissions (default: 0o100644) */
mode?: number;
/** MIME content type */
contentType?: string;
/** File content as string or Buffer */
data: string | Buffer;
}
interface FromStreamOptions {
/** File mode/permissions (default: 0o100644) */
mode?: number;
/** MIME content type */
contentType?: string;
/** Input stream to read into memory */
stream: NodeJS.ReadableStream;
}Usage Examples:
import { FileBlob } from "@now/build-utils";
// Create from string
const textFile = new FileBlob({
data: "console.log('Hello, World!');",
contentType: "application/javascript",
mode: 0o100644
});
// Create from Buffer
const binaryFile = new FileBlob({
data: Buffer.from([0x89, 0x50, 0x4E, 0x47]), // PNG header
contentType: "image/png"
});
// Create from stream (loads into memory)
const streamBlob = await FileBlob.fromStream({
stream: someReadableStream,
contentType: "text/plain"
});
// Stream file contents
const stream = textFile.toStream();
stream.pipe(process.stdout); // Outputs: console.log('Hello, World!');
// Access data directly
console.log(textFile.data); // "console.log('Hello, World!');"All file classes implement the common File interface:
interface File {
/** File type identifier */
type: string;
/** File mode/permissions */
mode: number;
/** MIME content type */
contentType?: string;
/** Convert file to readable stream */
toStream(): NodeJS.ReadableStream;
/** Absolute filesystem path (FileFsRef only) */
fsPath?: string;
}
interface Files {
[filePath: string]: File;
}import { FileFsRef, FileBlob, download } from "@now/build-utils";
// Typical build pipeline
const sourceFiles = {
"src/index.ts": new FileFsRef({ fsPath: "/project/src/index.ts" }),
"package.json": new FileFsRef({ fsPath: "/project/package.json" })
};
// Download files to build directory
const workFiles = await download(sourceFiles, "/tmp/build");
// Generate additional files during build
const outputFiles = {
...workFiles,
"dist/index.js": new FileBlob({
data: "// Compiled JavaScript code...",
contentType: "application/javascript"
}),
"build-info.json": new FileBlob({
data: JSON.stringify({
timestamp: Date.now(),
version: "1.0.0"
}),
contentType: "application/json"
})
};
// Create Lambda from mixed file types
const lambda = await createLambda({
files: outputFiles,
handler: "dist/index.handler",
runtime: "nodejs14.x"
});Use FileRef when:
Use FileFsRef when:
Use FileBlob when:
All file classes provide consistent streaming interfaces:
// Consistent streaming across file types
async function processFile(file: File) {
const stream = file.toStream();
// Pipe to destination
stream.pipe(destinationStream);
// Or collect data
const chunks: Buffer[] = [];
stream.on('data', chunk => chunks.push(chunk));
stream.on('end', () => {
const content = Buffer.concat(chunks);
console.log('File size:', content.length);
});
}// Transform files between types
import { FileFsRef, FileBlob } from "@now/build-utils";
// FileFsRef -> FileBlob (load into memory)
const fsFile = new FileFsRef({ fsPath: "/path/to/file.txt" });
const blobFile = await FileBlob.fromStream({
stream: fsFile.toStream(),
contentType: fsFile.contentType
});
// FileBlob -> FileFsRef (save to disk)
const memoryFile = new FileBlob({ data: "Hello World" });
const diskFile = await FileFsRef.fromStream({
stream: memoryFile.toStream(),
fsPath: "/tmp/output.txt"
});Choose the appropriate file type based on your performance and storage requirements.
Install with Tessl CLI
npx tessl i tessl/npm-now--build-utils