docs(archive): complete documentation (#5636)

* docs(archive): complete documentation

* work

* work

* work

* work

* fixes
This commit is contained in:
Asher Gomez 2024-08-20 17:13:54 +10:00 committed by GitHub
parent 701b6df3df
commit d6fde648e2
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
4 changed files with 262 additions and 12 deletions

View File

@ -28,6 +28,7 @@ type DocNodeWithJsDoc<T = DocNodeBase> = T & {
};
const ENTRY_POINTS = [
"../archive/mod.ts",
"../assert/mod.ts",
"../async/mod.ts",
"../bytes/mod.ts",

View File

@ -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";

View File

@ -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[] = [];

View File

@ -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) {