mirror of
https://github.com/denoland/std.git
synced 2024-11-21 20:50:22 +00:00
docs(archive): complete documentation (#5636)
* docs(archive): complete documentation * work * work * work * work * fixes
This commit is contained in:
parent
701b6df3df
commit
d6fde648e2
@ -28,6 +28,7 @@ type DocNodeWithJsDoc<T = DocNodeBase> = T & {
|
||||
};
|
||||
|
||||
const ENTRY_POINTS = [
|
||||
"../archive/mod.ts",
|
||||
"../assert/mod.ts",
|
||||
"../async/mod.ts",
|
||||
"../bytes/mod.ts",
|
||||
|
@ -34,7 +34,7 @@
|
||||
* archive file, while untar is the inverse utility to extract the files from an
|
||||
* archive. Files are not compressed, only collected into the archive.
|
||||
*
|
||||
* ```ts
|
||||
* ```ts no-eval
|
||||
* import { Tar } from "@std/archive/tar";
|
||||
* import { Buffer } from "@std/io/buffer";
|
||||
* import { copy } from "@std/io/copy";
|
||||
|
@ -221,8 +221,8 @@ export interface TarDataWithSource extends TarData {
|
||||
* * Filenames (including path) cannot contain non-ASCII characters
|
||||
* * Sparse files are not supported
|
||||
*
|
||||
* @example
|
||||
* ```ts
|
||||
* @example Usage
|
||||
* ```ts no-eval
|
||||
* import { Tar } from "@std/archive/tar";
|
||||
* import { Buffer } from "@std/io/buffer";
|
||||
* import { copy } from "@std/io/copy";
|
||||
@ -275,6 +275,35 @@ export class Tar {
|
||||
* `test.txt`. Use slash for directory separators.
|
||||
* @param source Details of the source of the content including the
|
||||
* reference to the content itself and potentially any related metadata.
|
||||
*
|
||||
* @example Usage
|
||||
* ```ts no-eval
|
||||
* import { Tar } from "@std/archive/tar";
|
||||
* import { Buffer } from "@std/io/buffer";
|
||||
* import { copy } from "@std/io/copy";
|
||||
*
|
||||
* const tar = new Tar();
|
||||
*
|
||||
* // Now that we've created our tar, let's add some files to it:
|
||||
*
|
||||
* const content = new TextEncoder().encode("Some arbitrary content");
|
||||
* await tar.append("deno.txt", {
|
||||
* reader: new Buffer(content),
|
||||
* contentSize: content.byteLength,
|
||||
* });
|
||||
*
|
||||
* // This file is sourced from the filesystem (and renamed in the archive)
|
||||
* await tar.append("filename_in_archive.txt", {
|
||||
* filePath: "./filename_on_filesystem.txt",
|
||||
* });
|
||||
*
|
||||
* // Now let's write the tar (with it's two files) to the filesystem
|
||||
* // use tar.getReader() to read the contents.
|
||||
*
|
||||
* const writer = await Deno.open("./out.tar", { write: true, create: true });
|
||||
* await copy(tar.getReader(), writer);
|
||||
* writer.close();
|
||||
* ```
|
||||
*/
|
||||
async append(filenameInArchive: string, source: TarOptions) {
|
||||
if (typeof filenameInArchive !== "string") {
|
||||
@ -389,7 +418,38 @@ export class Tar {
|
||||
}
|
||||
|
||||
/**
|
||||
* Get a Reader instance for this tar archive.
|
||||
* Get a {@linkcode Reader} instance for this tar archive.
|
||||
*
|
||||
* @returns A reader instance for the tar archive.
|
||||
*
|
||||
* @example Usage
|
||||
* ```ts no-eval
|
||||
* import { Tar } from "@std/archive/tar";
|
||||
* import { Buffer } from "@std/io/buffer";
|
||||
* import { copy } from "@std/io/copy";
|
||||
*
|
||||
* const tar = new Tar();
|
||||
*
|
||||
* // Now that we've created our tar, let's add some files to it:
|
||||
*
|
||||
* const content = new TextEncoder().encode("Some arbitrary content");
|
||||
* await tar.append("deno.txt", {
|
||||
* reader: new Buffer(content),
|
||||
* contentSize: content.byteLength,
|
||||
* });
|
||||
*
|
||||
* // This file is sourced from the filesystem (and renamed in the archive)
|
||||
* await tar.append("filename_in_archive.txt", {
|
||||
* filePath: "./filename_on_filesystem.txt",
|
||||
* });
|
||||
*
|
||||
* // Now let's write the tar (with it's two files) to the filesystem
|
||||
* // use tar.getReader() to read the contents.
|
||||
*
|
||||
* const writer = await Deno.open("./out.tar", { write: true, create: true });
|
||||
* await copy(tar.getReader(), writer);
|
||||
* writer.close();
|
||||
* ```
|
||||
*/
|
||||
getReader(): Reader {
|
||||
const readers: Reader[] = [];
|
||||
|
205
archive/untar.ts
205
archive/untar.ts
@ -40,6 +40,8 @@ import {
|
||||
import { readAll } from "@std/io/read-all";
|
||||
import type { Reader } from "@std/io/types";
|
||||
|
||||
export type { Reader };
|
||||
|
||||
/**
|
||||
* Extend TarMeta with the `linkName` property so that readers can access
|
||||
* symbolic link values without polluting the world of archive writers.
|
||||
@ -104,6 +106,27 @@ function parseHeader(buffer: Uint8Array): TarHeader {
|
||||
* > **UNSTABLE**: New API, yet to be vetted.
|
||||
*
|
||||
* @experimental
|
||||
*
|
||||
* @example Usage
|
||||
* ```ts no-assert
|
||||
* import { TarEntry } from "@std/archive/untar";
|
||||
* import { Buffer } from "@std/io/buffer";
|
||||
*
|
||||
* const content = new TextEncoder().encode("hello tar world!");
|
||||
* const reader = new Buffer(content);
|
||||
* const tarMeta = {
|
||||
* fileName: "archive/",
|
||||
* fileSize: 0,
|
||||
* fileMode: 509,
|
||||
* mtime: 1591800767,
|
||||
* uid: 1001,
|
||||
* gid: 1001,
|
||||
* owner: "deno",
|
||||
* group: "deno",
|
||||
* type: "directory",
|
||||
* };
|
||||
* const tarEntry: TarEntry = new TarEntry(tarMeta, reader);
|
||||
* ```
|
||||
*/
|
||||
export interface TarEntry extends TarMetaWithLinkName {}
|
||||
|
||||
@ -114,6 +137,27 @@ export interface TarEntry extends TarMetaWithLinkName {}
|
||||
* > **UNSTABLE**: New API, yet to be vetted.
|
||||
*
|
||||
* @experimental
|
||||
*
|
||||
* @example Usage
|
||||
* ```ts no-assert
|
||||
* import { TarEntry } from "@std/archive/untar";
|
||||
* import { Buffer } from "@std/io/buffer";
|
||||
*
|
||||
* const content = new TextEncoder().encode("hello tar world!");
|
||||
* const reader = new Buffer(content);
|
||||
* const tarMeta = {
|
||||
* fileName: "archive/",
|
||||
* fileSize: 0,
|
||||
* fileMode: 509,
|
||||
* mtime: 1591800767,
|
||||
* uid: 1001,
|
||||
* gid: 1001,
|
||||
* owner: "deno",
|
||||
* group: "deno",
|
||||
* type: "directory",
|
||||
* };
|
||||
* const tarEntry: TarEntry = new TarEntry(tarMeta, reader);
|
||||
* ```
|
||||
*/
|
||||
export class TarEntry implements Reader {
|
||||
#reader: Reader | (Reader & Deno.Seeker);
|
||||
@ -122,7 +166,12 @@ export class TarEntry implements Reader {
|
||||
#consumed = false;
|
||||
#entrySize: number;
|
||||
|
||||
/** Constructs a new instance. */
|
||||
/**
|
||||
* Constructs a new instance.
|
||||
*
|
||||
* @param meta The metadata of the entry.
|
||||
* @param reader The reader to read the entry from.
|
||||
*/
|
||||
constructor(
|
||||
meta: TarMetaWithLinkName,
|
||||
reader: Reader | (Reader & Deno.Seeker),
|
||||
@ -137,7 +186,35 @@ export class TarEntry implements Reader {
|
||||
this.#entrySize = blocks * HEADER_LENGTH;
|
||||
}
|
||||
|
||||
/** Returns whether the entry has already been consumed. */
|
||||
/**
|
||||
* Returns whether the entry has already been consumed.
|
||||
*
|
||||
* @returns Whether the entry has already been consumed.
|
||||
*
|
||||
* @example Usage
|
||||
* ```ts
|
||||
* import { TarEntry } from "@std/archive/untar";
|
||||
* import { Buffer } from "@std/io/buffer";
|
||||
* import { assertEquals } from "@std/assert/equals";
|
||||
*
|
||||
* const content = new TextEncoder().encode("hello tar world!");
|
||||
* const reader = new Buffer(content);
|
||||
* const tarMeta = {
|
||||
* fileName: "archive/",
|
||||
* fileSize: 0,
|
||||
* fileMode: 509,
|
||||
* mtime: 1591800767,
|
||||
* uid: 1001,
|
||||
* gid: 1001,
|
||||
* owner: "deno",
|
||||
* group: "deno",
|
||||
* type: "directory",
|
||||
* };
|
||||
* const tarEntry: TarEntry = new TarEntry(tarMeta, reader);
|
||||
*
|
||||
* assertEquals(tarEntry.consumed, false);
|
||||
* ```
|
||||
*/
|
||||
get consumed(): boolean {
|
||||
return this.#consumed;
|
||||
}
|
||||
@ -149,6 +226,32 @@ export class TarEntry implements Reader {
|
||||
* all of `p` as scratch space during the call. If some data is available but
|
||||
* not `p.byteLength bytes`, read() conventionally resolves to what is available
|
||||
* instead of waiting for more.
|
||||
*
|
||||
* @param p The buffer to read the entry into.
|
||||
* @returns The number of bytes read (`0 < n <= p.byteLength`) or `null` if
|
||||
* there are no more bytes to read.
|
||||
*
|
||||
* @example Usage
|
||||
* ```ts
|
||||
* import { Tar, Untar } from "@std/archive";
|
||||
* import { assertEquals } from "@std/assert/equals";
|
||||
* import { Buffer } from "@std/io/buffer";
|
||||
*
|
||||
* const content = new TextEncoder().encode("hello tar world!");
|
||||
*
|
||||
* const tar = new Tar();
|
||||
* tar.append("test.txt", {
|
||||
* reader: new Buffer(content),
|
||||
* contentSize: content.byteLength,
|
||||
* });
|
||||
*
|
||||
* const untar = new Untar(tar.getReader());
|
||||
* const entry = await untar.extract();
|
||||
* const buffer = new Uint8Array(1024);
|
||||
* const n = await entry!.read(buffer);
|
||||
*
|
||||
* assertEquals(buffer.subarray(0, n!), content);
|
||||
* ```
|
||||
*/
|
||||
async read(p: Uint8Array): Promise<number | null> {
|
||||
// Bytes left for entry
|
||||
@ -181,7 +284,36 @@ export class TarEntry implements Reader {
|
||||
return offset < 0 ? n - Math.abs(offset) : offset;
|
||||
}
|
||||
|
||||
/** Discords the current entry. */
|
||||
/**
|
||||
* Discords the current entry.
|
||||
*
|
||||
* @example Usage
|
||||
* ```ts
|
||||
* import { Buffer } from "@std/io/buffer";
|
||||
* import { TarEntry } from "@std/archive/untar";
|
||||
* import { assertEquals } from "@std/assert/equals";
|
||||
*
|
||||
* const text = "Hello, world!";
|
||||
*
|
||||
* const reader = new Buffer(new TextEncoder().encode(text));
|
||||
* const tarMeta = {
|
||||
* fileName: "text",
|
||||
* fileSize: 0,
|
||||
* fileMode: 509,
|
||||
* mtime: 1591800767,
|
||||
* uid: 1001,
|
||||
* gid: 1001,
|
||||
* owner: "deno",
|
||||
* group: "deno",
|
||||
* type: "file",
|
||||
* };
|
||||
*
|
||||
* const tarEntry: TarEntry = new TarEntry(tarMeta, reader);
|
||||
* await tarEntry.discard();
|
||||
*
|
||||
* assertEquals(tarEntry.consumed, true);
|
||||
* ```
|
||||
*/
|
||||
async discard() {
|
||||
// Discard current entry
|
||||
if (this.#consumed) return;
|
||||
@ -220,8 +352,8 @@ export class TarEntry implements Reader {
|
||||
* This utility does not support decompression which must be done before extracting
|
||||
* the files.
|
||||
*
|
||||
* @example
|
||||
* ```ts
|
||||
* @example Usage
|
||||
* ```ts no-eval
|
||||
* import { Untar } from "@std/archive/untar";
|
||||
* import { ensureFile } from "@std/fs/ensure-file";
|
||||
* import { ensureDir } from "@std/fs/ensure-dir";
|
||||
@ -257,7 +389,11 @@ export class Untar {
|
||||
#block: Uint8Array;
|
||||
#entry: TarEntry | undefined;
|
||||
|
||||
/** Constructs a new instance. */
|
||||
/**
|
||||
* Constructs a new instance.
|
||||
*
|
||||
* @param reader The reader to extract from.
|
||||
*/
|
||||
constructor(reader: Reader) {
|
||||
this.#reader = reader;
|
||||
this.#block = new Uint8Array(HEADER_LENGTH);
|
||||
@ -340,8 +476,35 @@ export class Untar {
|
||||
/**
|
||||
* Extract the next entry of the tar archive.
|
||||
*
|
||||
* @returns A TarEntry with header metadata and a reader to the entry's
|
||||
* body, or null if there are no more entries to extract.
|
||||
* @returns A TarEntry with header metadata and a reader to the entry's body,
|
||||
* or null if there are no more entries to extract.
|
||||
*
|
||||
* @example Usage
|
||||
* ```ts
|
||||
* import { Tar, Untar } from "@std/archive";
|
||||
* import { Buffer } from "@std/io/buffer";
|
||||
* import { readAll } from "@std/io/read-all";
|
||||
* import { assertEquals, assertNotEquals } from "@std/assert";
|
||||
*
|
||||
* const content = new TextEncoder().encode("hello tar world!");
|
||||
*
|
||||
* // Create a tar archive
|
||||
* const tar = new Tar();
|
||||
* await tar.append("output.txt", {
|
||||
* reader: new Buffer(content),
|
||||
* contentSize: content.byteLength,
|
||||
* });
|
||||
*
|
||||
* // Read data from a tar archive
|
||||
* const untar = new Untar(tar.getReader());
|
||||
* const result = await untar.extract();
|
||||
*
|
||||
* assertNotEquals(result, null);
|
||||
* assertEquals(result!.fileName, "output.txt");
|
||||
* assertEquals(result!.fileSize, content.byteLength);
|
||||
* assertEquals(result!.type, "file");
|
||||
* assertEquals(await readAll(result!), content);
|
||||
* ```
|
||||
*/
|
||||
async extract(): Promise<TarEntry | null> {
|
||||
if (this.#entry && !this.#entry.consumed) {
|
||||
@ -364,6 +527,32 @@ export class Untar {
|
||||
* Iterate over all entries of the tar archive.
|
||||
*
|
||||
* @yields A TarEntry with tar header metadata and a reader to the entry's body.
|
||||
* @returns An async iterator.
|
||||
*
|
||||
* @example Usage
|
||||
* ```ts no-eval
|
||||
* import { Untar } from "@std/archive/untar";
|
||||
* import { ensureFile } from "@std/fs/ensure-file";
|
||||
* import { ensureDir } from "@std/fs/ensure-dir";
|
||||
* import { copy } from "@std/io/copy";
|
||||
*
|
||||
* using reader = await Deno.open("./out.tar", { read: true });
|
||||
* const untar = new Untar(reader);
|
||||
*
|
||||
* for await (const entry of untar) {
|
||||
* console.log(entry); // metadata
|
||||
*
|
||||
* if (entry.type === "directory") {
|
||||
* await ensureDir(entry.fileName);
|
||||
* continue;
|
||||
* }
|
||||
*
|
||||
* await ensureFile(entry.fileName);
|
||||
* using file = await Deno.open(entry.fileName, { write: true });
|
||||
* // <entry> is a reader.
|
||||
* await copy(entry, file);
|
||||
* }
|
||||
* ```
|
||||
*/
|
||||
async *[Symbol.asyncIterator](): AsyncIterableIterator<TarEntry> {
|
||||
while (true) {
|
||||
|
Loading…
Reference in New Issue
Block a user