path-class 0.8.1 → 0.8.3
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/lib/path-class/Path.d.ts +6 -1
- package/dist/lib/path-class/chunks/{chunk-NONMAGMS.js → chunk-3W742CSF.js} +19 -1
- package/dist/lib/path-class/chunks/chunk-3W742CSF.js.map +7 -0
- package/dist/lib/path-class/index.js +1 -1
- package/dist/lib/path-class/modifiedNodeTypes.d.ts +1 -11
- package/dist/lib/path-class/sync/index.d.ts +3 -1
- package/dist/lib/path-class/sync/index.js +11 -2
- package/dist/lib/path-class/sync/index.js.map +2 -2
- package/package.json +1 -1
- package/src/Path.test.ts +19 -0
- package/src/Path.ts +23 -0
- package/src/modifiedNodeTypes.ts +2 -17
- package/src/sync/index.ts +22 -2
- package/src/sync/sync.test.ts +17 -0
- package/dist/lib/path-class/chunks/chunk-NONMAGMS.js.map +0 -7
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { cp, mkdir, rm, symlink, writeFile } from "node:fs/promises";
|
|
1
|
+
import { appendFile, cp, mkdir, rm, symlink, writeFile } from "node:fs/promises";
|
|
2
2
|
import type { lstatType, readDirType, readFileType, statType } from "./modifiedNodeTypes";
|
|
3
3
|
type WritableData = Parameters<typeof writeFile>[1] | ReadableStream | Response;
|
|
4
4
|
export declare class Path {
|
|
@@ -77,6 +77,10 @@ export declare class Path {
|
|
|
77
77
|
readJSON<T = any>(options?: {
|
|
78
78
|
fallback?: T;
|
|
79
79
|
}): Promise<T>;
|
|
80
|
+
/**
|
|
81
|
+
* Returns the original `Path` (for chaining).
|
|
82
|
+
*/
|
|
83
|
+
appendFile(data: Parameters<typeof appendFile>[1], options?: Parameters<typeof appendFile>[2]): Promise<Path>;
|
|
80
84
|
/** Creates intermediate directories if they do not exist.
|
|
81
85
|
*
|
|
82
86
|
* Returns the original `Path` (for chaining).
|
|
@@ -97,6 +101,7 @@ export declare class Path {
|
|
|
97
101
|
readDir: typeof readDirType;
|
|
98
102
|
/** Returns the destination path. */
|
|
99
103
|
symlink(target: string | URL | Path, type?: Parameters<typeof symlink>[2]): Promise<Path>;
|
|
104
|
+
realpath(): Promise<Path>;
|
|
100
105
|
stat: typeof statType;
|
|
101
106
|
lstat: typeof lstatType;
|
|
102
107
|
static get homedir(): Path;
|
|
@@ -1,11 +1,13 @@
|
|
|
1
1
|
// src/Path.ts
|
|
2
2
|
import {
|
|
3
|
+
appendFile,
|
|
3
4
|
cp,
|
|
4
5
|
lstat,
|
|
5
6
|
mkdir,
|
|
6
7
|
mkdtemp,
|
|
7
8
|
readdir,
|
|
8
9
|
readFile,
|
|
10
|
+
realpath,
|
|
9
11
|
rename,
|
|
10
12
|
rm,
|
|
11
13
|
stat,
|
|
@@ -260,6 +262,13 @@ var Path = class _Path {
|
|
|
260
262
|
throw e;
|
|
261
263
|
}
|
|
262
264
|
}
|
|
265
|
+
/**
|
|
266
|
+
* Returns the original `Path` (for chaining).
|
|
267
|
+
*/
|
|
268
|
+
async appendFile(data, options) {
|
|
269
|
+
await appendFile(this.#path, data, options);
|
|
270
|
+
return this;
|
|
271
|
+
}
|
|
263
272
|
/** Creates intermediate directories if they do not exist.
|
|
264
273
|
*
|
|
265
274
|
* Returns the original `Path` (for chaining).
|
|
@@ -303,6 +312,15 @@ var Path = class _Path {
|
|
|
303
312
|
);
|
|
304
313
|
return targetPath;
|
|
305
314
|
}
|
|
315
|
+
// I don't think `lstat` is a great name, but it does match the
|
|
316
|
+
// well-established canonical commandline name. So in this case we keep the
|
|
317
|
+
// name instead of using `realPath`.
|
|
318
|
+
//
|
|
319
|
+
// Note: There are no options in our API, because the only option is an
|
|
320
|
+
// encoding. We set the encoding to construct the returned `Path`.
|
|
321
|
+
async realpath() {
|
|
322
|
+
return new _Path(await realpath(this.#path, "utf-8"));
|
|
323
|
+
}
|
|
306
324
|
// biome-ignore lint/suspicious/noExplicitAny: Needed to wrangle the types.
|
|
307
325
|
stat = (...options) => stat(this.#path, ...options);
|
|
308
326
|
// I don't think `lstat` is a great name, but it does match the
|
|
@@ -363,4 +381,4 @@ export {
|
|
|
363
381
|
stringifyIfPath,
|
|
364
382
|
mustNotHaveTrailingSlash
|
|
365
383
|
};
|
|
366
|
-
//# sourceMappingURL=chunk-
|
|
384
|
+
//# sourceMappingURL=chunk-3W742CSF.js.map
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
{
|
|
2
|
+
"version": 3,
|
|
3
|
+
"sources": ["../../../../src/Path.ts"],
|
|
4
|
+
"sourcesContent": ["import {\n appendFile,\n cp,\n lstat,\n mkdir,\n mkdtemp,\n readdir,\n readFile,\n realpath,\n rename,\n rm,\n stat,\n symlink,\n writeFile,\n} from \"node:fs/promises\";\nimport { homedir, tmpdir } from \"node:os\";\nimport { basename, dirname, extname, join } from \"node:path\";\nimport { Readable } from \"node:stream\";\nimport { fileURLToPath, pathToFileURL } from \"node:url\";\nimport {\n xdgCache,\n xdgConfig,\n xdgData,\n xdgRuntime,\n xdgState,\n} from \"xdg-basedir\";\nimport type {\n lstatType,\n readDirType,\n readFileType,\n statType,\n} from \"./modifiedNodeTypes\";\n\n// Note that (non-static) functions in this file are defined using `function(\u2026)\n// { \u2026 }` rather than arrow functions, specifically because we want `this` to\n// operate on the `Path` instance.\n\ntype WritableData = Parameters<typeof writeFile>[1] | ReadableStream | Response;\nasync function wrangleWritableData(\n data: WritableData | Promise<WritableData>,\n): Promise<Parameters<typeof writeFile>[1]> {\n data = await data;\n if (data instanceof Response) {\n data = data.body ? Readable.fromWeb(data.body) : new Uint8Array(0);\n }\n if (data instanceof ReadableStream) {\n data = Readable.fromWeb(data);\n }\n return data;\n}\n\nexport class Path {\n // @ts-expect-error ts(2564): False positive. https://github.com/microsoft/TypeScript/issues/32194\n #path: string;\n /**\n * If `path` is a string starting with `file:///`, it will be parsed as a file URL.\n */\n constructor(path: string | URL | Path) {\n this.#setNormalizedPath(Path.#pathlikeToString(path));\n }\n\n /**\n * Similar to `new URL(path, base)`, but accepting and returning `Path` objects.\n * Note that `base` must be one of:\n *\n * - a valid second argument to `new URL(\u2026)`.\n * - a `Path` representing an absolute path.\n *\n */\n static resolve(path: string | URL | Path, base: string | URL | Path): Path {\n const baseURL = (() => {\n if (!(base instanceof Path)) {\n return base;\n }\n if (!base.isAbsolutePath()) {\n throw new Error(\n \"The `base` arg to `Path.resolve(\u2026)` must be an absolute path.\",\n );\n }\n return pathToFileURL(base.#path);\n })();\n return new Path(new URL(Path.#pathlikeToString(path), baseURL));\n }\n\n static #pathlikeToString(path: string | URL | Path): string {\n if (path instanceof Path) {\n return path.#path;\n }\n if (path instanceof URL) {\n return fileURLToPath(path);\n }\n if (typeof path === \"string\") {\n // TODO: allow turning off this heuristic?\n if (path.startsWith(\"file:///\")) {\n return fileURLToPath(path);\n }\n return path;\n }\n throw new Error(\"Invalid path\");\n }\n\n #setNormalizedPath(path: string): void {\n this.#path = join(path);\n }\n\n isAbsolutePath(): boolean {\n return this.#path.startsWith(\"/\");\n }\n\n toFileURL(): URL {\n if (!this.isAbsolutePath()) {\n throw new Error(\n \"Tried to convert to file URL when the path is not absolute.\",\n );\n }\n return pathToFileURL(this.#path);\n }\n\n /**\n * The `Path` can have a trailing slash, indicating that it represents a\n * directory. (If there is no trailing slash, it can represent either a file\n * or a directory.)\n *\n * Some operations will refuse to treat a directory path as a file path. This\n * function identifies such paths.\n */\n hasTrailingSlash(): boolean {\n // TODO: handle Windows semantically\n return this.#path.endsWith(\"/\");\n }\n\n /**\n * Same as `.toString()`, but more concise.\n */\n get path() {\n return this.#path;\n }\n\n toString(): string {\n return this.#path;\n }\n\n /** Constructs a new path by appending the given path segments.\n * This follows `node` semantics for absolute paths: leading slashes in the given descendant segments are ignored.\n */\n join(...segments: (string | Path)[]): Path {\n const segmentStrings = segments.map((segment) =>\n segment instanceof Path ? segment.path : segment,\n );\n return new Path(join(this.#path, ...segmentStrings));\n }\n\n extendBasename(suffix: string): Path {\n const joinedSuffix = join(suffix);\n if (joinedSuffix !== basename(joinedSuffix)) {\n throw new Error(\"Invalid suffix to extend file name.\");\n }\n // TODO: join basename and dirname instead?\n return new Path(this.#path + joinedSuffix);\n }\n\n get parent(): Path {\n return new Path(dirname(this.#path));\n }\n\n // Normally I'd stick with `node`'s name, but I think `.dirname` is a\n // particularly poor name. So we support `.dirname` for discovery but mark it\n // as deprecated, even if it will never be removed.\n /** @deprecated Alias for `.parent`. */\n get dirname(): Path {\n return this.parent;\n }\n\n get basename(): Path {\n return new Path(basename(this.#path));\n }\n\n get extension(): string {\n mustNotHaveTrailingSlash(this);\n return extname(this.#path);\n }\n\n // Normally I'd stick with `node`'s name, but I think `.extname` is a\n // particularly poor name. So we support `.extname` for discovery but mark it\n // as deprecated, even if it will never be removed.\n /** @deprecated Alias for `.extension`. */\n get extname(): string {\n return this.extension;\n }\n\n // TODO: find a neat way to dedup with the sync version?\n async exists(constraints?: {\n mustBe: \"file\" | \"directory\";\n }): Promise<boolean> {\n let stats: Awaited<ReturnType<typeof stat>>;\n try {\n stats = await stat(this.#path);\n // biome-ignore lint/suspicious/noExplicitAny: TypeScript limitation\n } catch (e: any) {\n if (e.code === \"ENOENT\") {\n return false;\n }\n throw e;\n }\n if (!constraints?.mustBe) {\n return true;\n }\n switch (constraints?.mustBe) {\n case \"file\": {\n mustNotHaveTrailingSlash(this);\n if (stats.isFile()) {\n return true;\n }\n throw new Error(`Path exists but is not a file: ${this.#path}`);\n }\n case \"directory\": {\n if (stats.isDirectory()) {\n return true;\n }\n throw new Error(`Path exists but is not a directory: ${this.#path}`);\n }\n default: {\n throw new Error(\"Invalid path type constraint\");\n }\n }\n }\n\n async existsAsFile(): Promise<boolean> {\n return this.exists({ mustBe: \"file\" });\n }\n\n async existsAsDir(): Promise<boolean> {\n return this.exists({ mustBe: \"directory\" });\n }\n\n // I don't think `mkdir` is a great name, but it does match the\n // well-established canonical commandline name. So in this case we keep the\n // awkward abbreviation.\n /** Defaults to `recursive: true`. */\n async mkdir(options?: Parameters<typeof mkdir>[1]): Promise<Path> {\n const optionsObject = (() => {\n if (typeof options === \"string\" || typeof options === \"number\") {\n return { mode: options };\n }\n return options ?? {};\n })();\n await mkdir(this.#path, { recursive: true, ...optionsObject });\n return this;\n }\n\n // TODO: check idempotency semantics when the destination exists and is a folder.\n /** Returns the destination path. */\n async cp(\n destination: string | URL | Path,\n options?: Parameters<typeof cp>[2],\n ): Promise<Path> {\n await cp(this.#path, new Path(destination).#path, options);\n return new Path(destination);\n }\n\n // TODO: check idempotency semantics when the destination exists and is a folder.\n async rename(destination: string | URL | Path): Promise<void> {\n await rename(this.#path, new Path(destination).#path);\n }\n\n /** Create a temporary dir inside the global temp dir for the current user. */\n static async makeTempDir(prefix?: string): Promise<Path> {\n return new Path(\n await mkdtemp(new Path(tmpdir()).join(prefix ?? \"js-temp-\").toString()),\n );\n }\n\n async rm(options?: Parameters<typeof rm>[1]): Promise<void> {\n await rm(this.#path, options);\n }\n\n /**\n * Equivalent to:\n *\n * .rm({ recursive: true, force: true, ...(options ?? {}) })\n *\n */\n async rm_rf(options?: Parameters<typeof rm>[1]): Promise<void> {\n await this.rm({ recursive: true, force: true, ...(options ?? {}) });\n }\n\n read: typeof readFileType = (options) =>\n // biome-ignore lint/suspicious/noExplicitAny: Needed to wrangle the types.\n readFile(this.#path, options as any) as any;\n\n async readText(): Promise<string> {\n return readFile(this.#path, \"utf-8\");\n }\n\n /**\n * Reads JSON from the given file and parses it. No validation is performed\n * (beyond JSON parsing).\n *\n * An optional `fallback` value can be specified. It will be used if (and only\n * if) the file does not exist.\n *\n */\n\n // biome-ignore lint/suspicious/noExplicitAny: Allow a default of `any` to match `JSON.parse(\u2026)`.\n async readJSON<T = any>(options?: { fallback?: T }): Promise<T> {\n try {\n return JSON.parse(await this.readText());\n } catch (e) {\n if (\n (e as { code?: string }).code === \"ENOENT\" &&\n options &&\n \"fallback\" in options\n ) {\n return options.fallback as T;\n }\n throw e;\n }\n }\n\n /**\n * Returns the original `Path` (for chaining).\n */\n async appendFile(\n data: Parameters<typeof appendFile>[1],\n options?: Parameters<typeof appendFile>[2],\n ): Promise<Path> {\n await appendFile(this.#path, data, options);\n return this;\n }\n\n /** Creates intermediate directories if they do not exist.\n *\n * Returns the original `Path` (for chaining).\n */\n async write(\n data: WritableData | Promise<WritableData>,\n options?: Parameters<typeof writeFile>[2],\n ): Promise<Path> {\n await this.parent.mkdir();\n await writeFile(this.#path, await wrangleWritableData(data), options);\n return this;\n }\n\n /**\n * If only `data` is provided, this is equivalent to:\n *\n * .write(JSON.stringify(data, null, \" \"));\n *\n * `replacer` and `space` can also be specified, making this equivalent to:\n *\n * .write(JSON.stringify(data, replacer, space));\n *\n * Returns the original `Path` (for chaining).\n */\n async writeJSON<T>(\n data: T,\n replacer: Parameters<typeof JSON.stringify>[1] = null,\n space: Parameters<typeof JSON.stringify>[2] = \" \",\n ): Promise<Path> {\n await this.write(JSON.stringify(data, replacer, space));\n return this;\n }\n\n // Normally we'd add a `@deprecated` alias named `.readdir`, but that would\n // differ only by capitalization of a single non-leading character. This can\n // be a bit confusing, especially when autocompleting. So for this function in\n // particular we don't include an alias.\n readDir: typeof readDirType = (options) =>\n // biome-ignore lint/suspicious/noExplicitAny: Needed to wrangle the types.\n readdir(this.#path, options as any) as any;\n\n /** Returns the destination path. */\n async symlink(\n target: string | URL | Path,\n type?: Parameters<typeof symlink>[2],\n ): Promise<Path> {\n const targetPath = new Path(target);\n await symlink(\n this.path,\n targetPath.path,\n type as Exclude<Parameters<typeof symlink>[2], undefined>, // \uD83E\uDD37\n );\n return targetPath;\n }\n\n // I don't think `lstat` is a great name, but it does match the\n // well-established canonical commandline name. So in this case we keep the\n // name instead of using `realPath`.\n //\n // Note: There are no options in our API, because the only option is an\n // encoding. We set the encoding to construct the returned `Path`.\n async realpath(): Promise<Path> {\n return new Path(await realpath(this.#path, \"utf-8\"));\n }\n\n // biome-ignore lint/suspicious/noExplicitAny: Needed to wrangle the types.\n stat: typeof statType = (...options) => stat(this.#path, ...options) as any;\n\n // I don't think `lstat` is a great name, but it does match the\n // well-established canonical system call. So in this case we keep the\n // awkward abbreviation.\n lstat: typeof lstatType = (...options) =>\n // biome-ignore lint/suspicious/noExplicitAny: Needed to wrangle the types.\n lstat(this.#path, ...options) as any;\n\n static get homedir(): Path {\n return new Path(homedir());\n }\n\n static xdg = {\n cache: new Path(xdgCache ?? Path.homedir.join(\".cache\")),\n config: new Path(xdgConfig ?? Path.homedir.join(\".config\")),\n data: new Path(xdgData ?? Path.homedir.join(\".local/share\")),\n state: new Path(xdgState ?? Path.homedir.join(\".local/state\")),\n /**\n * {@link Path.xdg.runtime} does not have a default value. Consider\n * {@link Path.xdg.runtimeWithStateFallback} if you need a fallback but do not have a particular fallback in mind.\n */\n runtime: xdgRuntime ? new Path(xdgRuntime) : undefined,\n runtimeWithStateFallback: xdgRuntime\n ? new Path(xdgRuntime)\n : new Path(xdgState ?? Path.homedir.join(\".local/state\")),\n };\n\n /** Chainable function to print the path. Prints the same as:\n *\n * if (args.length > 0) {\n * console.log(...args);\n * }\n * console.log(this.path);\n *\n */\n // biome-ignore lint/suspicious/noExplicitAny: This is the correct type, based on `console.log(\u2026)`.\n debugPrint(...args: any[]): Path {\n if (args.length > 0) {\n console.log(...args);\n }\n console.log(this.#path);\n return this;\n }\n}\n\n/**\n * This function is useful to serialize any `Path`s in a structure to pass on to\n * functions that do not know about the `Path` class, e.g.\n *\n * function process(args: (string | Path)[]) {\n * const argsAsStrings = args.map(stringifyIfPath);\n * }\n *\n */\nexport function stringifyIfPath<T>(value: T | Path): T | string {\n if (value instanceof Path) {\n return value.toString();\n }\n return value;\n}\n\nexport function mustNotHaveTrailingSlash(path: Path): void {\n if (path.hasTrailingSlash()) {\n throw new Error(\n \"Path ends with a slash, which cannot be treated as a file.\",\n );\n }\n}\n"],
|
|
5
|
+
"mappings": "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",
|
|
6
|
+
"names": []
|
|
7
|
+
}
|
|
@@ -33,17 +33,6 @@ export declare function readFileType(options: ({
|
|
|
33
33
|
export declare function readFileType(options?: (ObjectEncodingOptions & Abortable & {
|
|
34
34
|
flag?: OpenMode | undefined;
|
|
35
35
|
}) | BufferEncoding | null): Promise<string | Buffer>;
|
|
36
|
-
export declare function lstatType(opts?: StatOptions & {
|
|
37
|
-
bigint?: false | undefined;
|
|
38
|
-
}): Promise<Stats>;
|
|
39
|
-
export declare function lstatType(opts: StatOptions & {
|
|
40
|
-
bigint: true;
|
|
41
|
-
}): Promise<BigIntStats>;
|
|
42
|
-
export declare function lstatType(opts?: StatOptions): Promise<Stats | BigIntStats>;
|
|
43
|
-
/**
|
|
44
|
-
* @since v10.0.0
|
|
45
|
-
* @return Fulfills with the {fs.Stats} object for the given `path`.
|
|
46
|
-
*/
|
|
47
36
|
export declare function statType(opts?: StatOptions & {
|
|
48
37
|
bigint?: false | undefined;
|
|
49
38
|
}): Promise<Stats>;
|
|
@@ -51,3 +40,4 @@ export declare function statType(opts: StatOptions & {
|
|
|
51
40
|
bigint: true;
|
|
52
41
|
}): Promise<BigIntStats>;
|
|
53
42
|
export declare function statType(opts?: StatOptions): Promise<Stats | BigIntStats>;
|
|
43
|
+
export declare const lstatType: typeof statType;
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { cpSync, mkdirSync, rmSync, symlinkSync, writeFileSync } from "node:fs";
|
|
1
|
+
import { appendFileSync, cpSync, mkdirSync, rmSync, symlinkSync, writeFileSync } from "node:fs";
|
|
2
2
|
import "./static";
|
|
3
3
|
import type { lstatSyncType, readDirSyncType, readFileSyncType, statSyncType } from "./modifiedNodeTypes";
|
|
4
4
|
declare module "../Path" {
|
|
@@ -18,11 +18,13 @@ declare module "../Path" {
|
|
|
18
18
|
readJSONSync<T>(options?: {
|
|
19
19
|
fallback?: T;
|
|
20
20
|
}): T;
|
|
21
|
+
appendFileSync(data: Parameters<typeof appendFileSync>[1], options?: Parameters<typeof appendFileSync>[2]): Path;
|
|
21
22
|
writeSync(data: Parameters<typeof writeFileSync>[1], options?: Parameters<typeof writeFileSync>[2] | undefined): Path;
|
|
22
23
|
writeJSONSync<T>(data: T, replacer?: Parameters<typeof JSON.stringify>[1], space?: Parameters<typeof JSON.stringify>[2]): Path;
|
|
23
24
|
readDirSync: typeof readDirSyncType;
|
|
24
25
|
/** Returns the destination path. */
|
|
25
26
|
symlinkSync(target: string | URL | Path, type?: Parameters<typeof symlinkSync>[2]): Path;
|
|
27
|
+
realpathSync(): Path;
|
|
26
28
|
statSync: typeof statSyncType;
|
|
27
29
|
lstatSync: typeof lstatSyncType;
|
|
28
30
|
}
|
|
@@ -1,15 +1,17 @@
|
|
|
1
1
|
import {
|
|
2
2
|
Path,
|
|
3
3
|
mustNotHaveTrailingSlash
|
|
4
|
-
} from "../chunks/chunk-
|
|
4
|
+
} from "../chunks/chunk-3W742CSF.js";
|
|
5
5
|
|
|
6
6
|
// src/sync/index.ts
|
|
7
7
|
import {
|
|
8
|
+
appendFileSync,
|
|
8
9
|
cpSync,
|
|
9
10
|
lstatSync,
|
|
10
11
|
mkdirSync,
|
|
11
12
|
readdirSync,
|
|
12
13
|
readFileSync,
|
|
14
|
+
realpathSync,
|
|
13
15
|
renameSync,
|
|
14
16
|
rmSync,
|
|
15
17
|
statSync,
|
|
@@ -102,6 +104,10 @@ Path.prototype.readJSONSync = function(options) {
|
|
|
102
104
|
throw e;
|
|
103
105
|
}
|
|
104
106
|
};
|
|
107
|
+
Path.prototype.appendFileSync = function(data, options) {
|
|
108
|
+
appendFileSync(this.path, data, options);
|
|
109
|
+
return this;
|
|
110
|
+
};
|
|
105
111
|
Path.prototype.writeSync = function(data, options) {
|
|
106
112
|
this.parent.mkdirSync();
|
|
107
113
|
writeFileSync(this.path, data, options);
|
|
@@ -115,7 +121,7 @@ Path.prototype.writeJSONSync = function(data, replacer = null, space = " ") {
|
|
|
115
121
|
Path.prototype.readDirSync = function(options) {
|
|
116
122
|
return readdirSync(this.path, options);
|
|
117
123
|
};
|
|
118
|
-
Path.prototype.symlinkSync = function
|
|
124
|
+
Path.prototype.symlinkSync = function(target, type) {
|
|
119
125
|
const targetPath = new Path(target);
|
|
120
126
|
symlinkSync(
|
|
121
127
|
this.path,
|
|
@@ -125,6 +131,9 @@ Path.prototype.symlinkSync = function symlink(target, type) {
|
|
|
125
131
|
);
|
|
126
132
|
return targetPath;
|
|
127
133
|
};
|
|
134
|
+
Path.prototype.realpathSync = function() {
|
|
135
|
+
return new Path(realpathSync(this.path));
|
|
136
|
+
};
|
|
128
137
|
Path.prototype.statSync = function(options) {
|
|
129
138
|
return statSync(this.path, options);
|
|
130
139
|
};
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"version": 3,
|
|
3
3
|
"sources": ["../../../../src/sync/index.ts", "../../../../src/sync/static.ts"],
|
|
4
|
-
"sourcesContent": ["import {\n cpSync,\n lstatSync,\n mkdirSync,\n readdirSync,\n readFileSync,\n renameSync,\n rmSync,\n statSync,\n symlinkSync,\n writeFileSync,\n} from \"node:fs\";\nimport { mustNotHaveTrailingSlash, Path } from \"../Path\";\nimport \"./static\";\nimport type {\n lstatSyncType,\n readDirSyncType,\n readFileSyncType,\n statSyncType,\n} from \"./modifiedNodeTypes\";\n\n// Note that (non-static) functions in this file are defined using `function(\u2026)\n// { \u2026 }` rather than arrow functions, specifically because we want `this` to\n// operate on the `Path` instance.\n\ndeclare module \"../Path\" {\n interface Path {\n existsSync(constraints?: { mustBe: \"file\" | \"directory\" }): boolean;\n existsAsFileSync(): boolean;\n existsAsDirSync(): boolean;\n\n mkdirSync(options?: Parameters<typeof mkdirSync>[1]): Path;\n cpSync(\n destination: string | URL | Path,\n options?: Parameters<typeof cpSync>[2],\n ): Path;\n renameSync(destination: string | URL | Path): void;\n\n rmSync(options?: Parameters<typeof rmSync>[1]): void;\n rm_rfSync(options?: Parameters<typeof rmSync>[1]): void;\n\n readSync: typeof readFileSyncType;\n readTextSync(): string;\n readJSONSync<T>(options?: { fallback?: T }): T;\n\n writeSync(\n data: Parameters<typeof writeFileSync>[1],\n options?: Parameters<typeof writeFileSync>[2] | undefined,\n ): Path;\n writeJSONSync<T>(\n data: T,\n replacer?: Parameters<typeof JSON.stringify>[1],\n space?: Parameters<typeof JSON.stringify>[2],\n ): Path;\n\n readDirSync: typeof readDirSyncType;\n\n /** Returns the destination path. */\n symlinkSync(\n target: string | URL | Path,\n type?: Parameters<typeof symlinkSync>[2],\n ): Path;\n\n statSync: typeof statSyncType;\n lstatSync: typeof lstatSyncType;\n }\n}\n\n// TODO: find a neat way to dedup with the async version
|
|
5
|
-
"mappings": ";;;;;;AAAA;AAAA,EACE;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,OACK;;;
|
|
4
|
+
"sourcesContent": ["import {\n appendFileSync,\n cpSync,\n lstatSync,\n mkdirSync,\n readdirSync,\n readFileSync,\n realpathSync,\n renameSync,\n rmSync,\n statSync,\n symlinkSync,\n writeFileSync,\n} from \"node:fs\";\nimport { mustNotHaveTrailingSlash, Path } from \"../Path\";\nimport \"./static\";\nimport type {\n lstatSyncType,\n readDirSyncType,\n readFileSyncType,\n statSyncType,\n} from \"./modifiedNodeTypes\";\n\n// Note that (non-static) functions in this file are defined using `function(\u2026)\n// { \u2026 }` rather than arrow functions, specifically because we want `this` to\n// operate on the `Path` instance.\n\ndeclare module \"../Path\" {\n interface Path {\n existsSync(constraints?: { mustBe: \"file\" | \"directory\" }): boolean;\n existsAsFileSync(): boolean;\n existsAsDirSync(): boolean;\n\n mkdirSync(options?: Parameters<typeof mkdirSync>[1]): Path;\n cpSync(\n destination: string | URL | Path,\n options?: Parameters<typeof cpSync>[2],\n ): Path;\n renameSync(destination: string | URL | Path): void;\n\n rmSync(options?: Parameters<typeof rmSync>[1]): void;\n rm_rfSync(options?: Parameters<typeof rmSync>[1]): void;\n\n readSync: typeof readFileSyncType;\n readTextSync(): string;\n readJSONSync<T>(options?: { fallback?: T }): T;\n\n appendFileSync(\n data: Parameters<typeof appendFileSync>[1],\n options?: Parameters<typeof appendFileSync>[2],\n ): Path;\n\n writeSync(\n data: Parameters<typeof writeFileSync>[1],\n options?: Parameters<typeof writeFileSync>[2] | undefined,\n ): Path;\n writeJSONSync<T>(\n data: T,\n replacer?: Parameters<typeof JSON.stringify>[1],\n space?: Parameters<typeof JSON.stringify>[2],\n ): Path;\n\n readDirSync: typeof readDirSyncType;\n\n /** Returns the destination path. */\n symlinkSync(\n target: string | URL | Path,\n type?: Parameters<typeof symlinkSync>[2],\n ): Path;\n realpathSync(): Path;\n\n statSync: typeof statSyncType;\n lstatSync: typeof lstatSyncType;\n }\n}\n\n// TODO: find a neat way to dedup with the async version? // lint-sync-code-expect-error\nPath.prototype.existsSync = function (constraints?: {\n mustBe: \"file\" | \"directory\";\n}): boolean {\n let stats: ReturnType<typeof statSync>;\n try {\n stats = statSync(this.path);\n // biome-ignore lint/suspicious/noExplicitAny: TypeScript limitation\n } catch (e: any) {\n if (e.code === \"ENOENT\") {\n return false;\n }\n throw e;\n }\n if (!constraints?.mustBe) {\n return true;\n }\n switch (constraints?.mustBe) {\n case \"file\": {\n mustNotHaveTrailingSlash(this);\n if (stats.isFile()) {\n return true;\n }\n throw new Error(`Path exists but is not a file: ${this.path}`);\n }\n case \"directory\": {\n if (stats.isDirectory()) {\n return true;\n }\n throw new Error(`Path exists but is not a directory: ${this.path}`);\n }\n default: {\n throw new Error(\"Invalid path type constraint\");\n }\n }\n};\n\nPath.prototype.existsAsFileSync = function (): boolean {\n return this.existsSync({ mustBe: \"file\" });\n};\n\nPath.prototype.existsAsDirSync = function (): boolean {\n return this.existsSync({ mustBe: \"directory\" });\n};\n\nPath.prototype.mkdirSync = function (\n options?: Parameters<typeof mkdirSync>[1],\n): Path {\n const optionsObject = (() => {\n if (typeof options === \"string\" || typeof options === \"number\") {\n return { mode: options };\n }\n return options ?? {};\n })();\n mkdirSync(this.path, { recursive: true, ...optionsObject });\n return this;\n};\n\nPath.prototype.cpSync = function (\n destination: string | URL | Path,\n options?: Parameters<typeof cpSync>[2],\n): Path {\n cpSync(this.path, new Path(destination).path, options);\n return new Path(destination);\n};\n\nPath.prototype.renameSync = function (destination: string | URL | Path): void {\n renameSync(this.path, new Path(destination).path);\n};\n\nPath.prototype.rmSync = function (\n options?: Parameters<typeof rmSync>[1],\n): void {\n rmSync(this.path, options);\n};\n\nPath.prototype.rm_rfSync = function (\n options?: Parameters<typeof rmSync>[1],\n): void {\n this.rmSync({ recursive: true, force: true, ...(options ?? {}) });\n};\n\nPath.prototype.readSync = function () {\n /** @ts-expect-error ts(2683) */\n return readFileSync(this.path);\n} as typeof readFileSyncType;\n\nPath.prototype.readTextSync = function (): string {\n return readFileSync(this.path, \"utf-8\");\n};\n\nPath.prototype.readJSONSync = function <T>(options?: { fallback?: T }): T {\n try {\n return JSON.parse(this.readTextSync());\n } catch (e) {\n if (\n (e as { code?: string }).code === \"ENOENT\" &&\n options &&\n \"fallback\" in options\n ) {\n return options.fallback as T;\n }\n throw e;\n }\n};\n\nPath.prototype.appendFileSync = function (\n data: Parameters<typeof appendFileSync>[1],\n options?: Parameters<typeof appendFileSync>[2],\n): Path {\n appendFileSync(this.path, data, options);\n return this;\n};\n\nPath.prototype.writeSync = function (\n data: Parameters<typeof writeFileSync>[1],\n options?: Parameters<typeof writeFileSync>[2],\n): Path {\n this.parent.mkdirSync();\n writeFileSync(this.path, data, options);\n return this;\n};\n\nPath.prototype.writeJSONSync = function <T>(\n data: T,\n replacer: Parameters<typeof JSON.stringify>[1] = null,\n space: Parameters<typeof JSON.stringify>[2] = \" \",\n): Path {\n this.parent.mkdirSync();\n this.writeSync(JSON.stringify(data, replacer, space));\n return this;\n};\n\n/** @ts-expect-error ts(2322): Wrangle types */\nPath.prototype.readDirSync = function (options) {\n // biome-ignore lint/suspicious/noExplicitAny: Needed to wrangle the types.\n return readdirSync(this.path, options as any);\n};\n\nPath.prototype.symlinkSync = function (\n target: string | URL | Path,\n type?: Parameters<typeof symlinkSync>[2],\n): Path {\n const targetPath = new Path(target);\n symlinkSync(\n this.path,\n targetPath.path,\n type as Exclude<Parameters<typeof symlinkSync>[2], undefined>, // \uD83E\uDD37\n );\n return targetPath;\n};\n\nPath.prototype.realpathSync = function (): Path {\n return new Path(realpathSync(this.path));\n};\n\n/** @ts-expect-error ts(2322): Wrangle types */\nPath.prototype.statSync = function (\n options?: Parameters<typeof statSync>[1],\n): ReturnType<typeof statSync> {\n return statSync(this.path, options);\n};\n\n/** @ts-expect-error ts(2322): Wrangle types */\nPath.prototype.lstatSync = function (\n options?: Parameters<typeof lstatSync>[1],\n): ReturnType<typeof lstatSync> {\n return lstatSync(this.path, options);\n};\n", "import { mkdtempSync } from \"node:fs\";\nimport { tmpdir } from \"node:os\";\nimport { Path } from \"../Path\";\n\ndeclare module \"../Path\" {\n namespace Path {\n export function makeTempDirSync(prefix?: string): Path;\n }\n}\n\nPath.makeTempDirSync = (prefix?: string): Path =>\n new Path(\n mkdtempSync(new Path(tmpdir()).join(prefix ?? \"js-temp-\").toString()),\n );\n"],
|
|
5
|
+
"mappings": "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",
|
|
6
6
|
"names": []
|
|
7
7
|
}
|
package/package.json
CHANGED
package/src/Path.test.ts
CHANGED
|
@@ -320,6 +320,14 @@ test(".writeJSON(…)", async () => {
|
|
|
320
320
|
expect(await file.readJSON()).toEqual<Record<string, string>>({ foo: "bar" });
|
|
321
321
|
});
|
|
322
322
|
|
|
323
|
+
test(".appendFile(…)", async () => {
|
|
324
|
+
const file = (await Path.makeTempDir()).join("file.txt");
|
|
325
|
+
await file.appendFile("test\n");
|
|
326
|
+
expect(await file.readText()).toEqual("test\n");
|
|
327
|
+
await file.appendFile("more\n");
|
|
328
|
+
expect(await file.readText()).toEqual("test\nmore\n");
|
|
329
|
+
});
|
|
330
|
+
|
|
323
331
|
test(".readDir(…)", async () => {
|
|
324
332
|
const dir = await Path.makeTempDir();
|
|
325
333
|
await dir.join("file.txt").write("hello");
|
|
@@ -346,6 +354,17 @@ test(".symlink(…)", async () => {
|
|
|
346
354
|
expect(await target.readText()).toEqual("hello");
|
|
347
355
|
});
|
|
348
356
|
|
|
357
|
+
test(".realpath(…)", async () => {
|
|
358
|
+
const tempDir = await Path.makeTempDir();
|
|
359
|
+
const source = tempDir.join("foo.txt");
|
|
360
|
+
await source.write("hello world!");
|
|
361
|
+
const target = tempDir.join("bar.txt");
|
|
362
|
+
await source.symlink(target);
|
|
363
|
+
expect((await source.realpath()).path).toEqual(
|
|
364
|
+
(await target.realpath()).path,
|
|
365
|
+
);
|
|
366
|
+
});
|
|
367
|
+
|
|
349
368
|
test(".stat(…)", async () => {
|
|
350
369
|
const file = (await Path.makeTempDir()).join("foo.txt");
|
|
351
370
|
await file.write("hello");
|
package/src/Path.ts
CHANGED
|
@@ -1,10 +1,12 @@
|
|
|
1
1
|
import {
|
|
2
|
+
appendFile,
|
|
2
3
|
cp,
|
|
3
4
|
lstat,
|
|
4
5
|
mkdir,
|
|
5
6
|
mkdtemp,
|
|
6
7
|
readdir,
|
|
7
8
|
readFile,
|
|
9
|
+
realpath,
|
|
8
10
|
rename,
|
|
9
11
|
rm,
|
|
10
12
|
stat,
|
|
@@ -315,6 +317,17 @@ export class Path {
|
|
|
315
317
|
}
|
|
316
318
|
}
|
|
317
319
|
|
|
320
|
+
/**
|
|
321
|
+
* Returns the original `Path` (for chaining).
|
|
322
|
+
*/
|
|
323
|
+
async appendFile(
|
|
324
|
+
data: Parameters<typeof appendFile>[1],
|
|
325
|
+
options?: Parameters<typeof appendFile>[2],
|
|
326
|
+
): Promise<Path> {
|
|
327
|
+
await appendFile(this.#path, data, options);
|
|
328
|
+
return this;
|
|
329
|
+
}
|
|
330
|
+
|
|
318
331
|
/** Creates intermediate directories if they do not exist.
|
|
319
332
|
*
|
|
320
333
|
* Returns the original `Path` (for chaining).
|
|
@@ -370,6 +383,16 @@ export class Path {
|
|
|
370
383
|
return targetPath;
|
|
371
384
|
}
|
|
372
385
|
|
|
386
|
+
// I don't think `lstat` is a great name, but it does match the
|
|
387
|
+
// well-established canonical commandline name. So in this case we keep the
|
|
388
|
+
// name instead of using `realPath`.
|
|
389
|
+
//
|
|
390
|
+
// Note: There are no options in our API, because the only option is an
|
|
391
|
+
// encoding. We set the encoding to construct the returned `Path`.
|
|
392
|
+
async realpath(): Promise<Path> {
|
|
393
|
+
return new Path(await realpath(this.#path, "utf-8"));
|
|
394
|
+
}
|
|
395
|
+
|
|
373
396
|
// biome-ignore lint/suspicious/noExplicitAny: Needed to wrangle the types.
|
|
374
397
|
stat: typeof statType = (...options) => stat(this.#path, ...options) as any;
|
|
375
398
|
|
package/src/modifiedNodeTypes.ts
CHANGED
|
@@ -84,23 +84,6 @@ export declare function readFileType(
|
|
|
84
84
|
| null,
|
|
85
85
|
): Promise<string | Buffer>;
|
|
86
86
|
|
|
87
|
-
export declare function lstatType(
|
|
88
|
-
opts?: StatOptions & {
|
|
89
|
-
bigint?: false | undefined;
|
|
90
|
-
},
|
|
91
|
-
): Promise<Stats>;
|
|
92
|
-
export declare function lstatType(
|
|
93
|
-
opts: StatOptions & {
|
|
94
|
-
bigint: true;
|
|
95
|
-
},
|
|
96
|
-
): Promise<BigIntStats>;
|
|
97
|
-
export declare function lstatType(
|
|
98
|
-
opts?: StatOptions,
|
|
99
|
-
): Promise<Stats | BigIntStats>;
|
|
100
|
-
/**
|
|
101
|
-
* @since v10.0.0
|
|
102
|
-
* @return Fulfills with the {fs.Stats} object for the given `path`.
|
|
103
|
-
*/
|
|
104
87
|
export declare function statType(
|
|
105
88
|
opts?: StatOptions & {
|
|
106
89
|
bigint?: false | undefined;
|
|
@@ -114,3 +97,5 @@ export declare function statType(
|
|
|
114
97
|
export declare function statType(
|
|
115
98
|
opts?: StatOptions,
|
|
116
99
|
): Promise<Stats | BigIntStats>;
|
|
100
|
+
|
|
101
|
+
export declare const lstatType: typeof statType;
|
package/src/sync/index.ts
CHANGED
|
@@ -1,9 +1,11 @@
|
|
|
1
1
|
import {
|
|
2
|
+
appendFileSync,
|
|
2
3
|
cpSync,
|
|
3
4
|
lstatSync,
|
|
4
5
|
mkdirSync,
|
|
5
6
|
readdirSync,
|
|
6
7
|
readFileSync,
|
|
8
|
+
realpathSync,
|
|
7
9
|
renameSync,
|
|
8
10
|
rmSync,
|
|
9
11
|
statSync,
|
|
@@ -43,6 +45,11 @@ declare module "../Path" {
|
|
|
43
45
|
readTextSync(): string;
|
|
44
46
|
readJSONSync<T>(options?: { fallback?: T }): T;
|
|
45
47
|
|
|
48
|
+
appendFileSync(
|
|
49
|
+
data: Parameters<typeof appendFileSync>[1],
|
|
50
|
+
options?: Parameters<typeof appendFileSync>[2],
|
|
51
|
+
): Path;
|
|
52
|
+
|
|
46
53
|
writeSync(
|
|
47
54
|
data: Parameters<typeof writeFileSync>[1],
|
|
48
55
|
options?: Parameters<typeof writeFileSync>[2] | undefined,
|
|
@@ -60,13 +67,14 @@ declare module "../Path" {
|
|
|
60
67
|
target: string | URL | Path,
|
|
61
68
|
type?: Parameters<typeof symlinkSync>[2],
|
|
62
69
|
): Path;
|
|
70
|
+
realpathSync(): Path;
|
|
63
71
|
|
|
64
72
|
statSync: typeof statSyncType;
|
|
65
73
|
lstatSync: typeof lstatSyncType;
|
|
66
74
|
}
|
|
67
75
|
}
|
|
68
76
|
|
|
69
|
-
// TODO: find a neat way to dedup with the async version?
|
|
77
|
+
// TODO: find a neat way to dedup with the async version? // lint-sync-code-expect-error
|
|
70
78
|
Path.prototype.existsSync = function (constraints?: {
|
|
71
79
|
mustBe: "file" | "directory";
|
|
72
80
|
}): boolean {
|
|
@@ -172,6 +180,14 @@ Path.prototype.readJSONSync = function <T>(options?: { fallback?: T }): T {
|
|
|
172
180
|
}
|
|
173
181
|
};
|
|
174
182
|
|
|
183
|
+
Path.prototype.appendFileSync = function (
|
|
184
|
+
data: Parameters<typeof appendFileSync>[1],
|
|
185
|
+
options?: Parameters<typeof appendFileSync>[2],
|
|
186
|
+
): Path {
|
|
187
|
+
appendFileSync(this.path, data, options);
|
|
188
|
+
return this;
|
|
189
|
+
};
|
|
190
|
+
|
|
175
191
|
Path.prototype.writeSync = function (
|
|
176
192
|
data: Parameters<typeof writeFileSync>[1],
|
|
177
193
|
options?: Parameters<typeof writeFileSync>[2],
|
|
@@ -197,7 +213,7 @@ Path.prototype.readDirSync = function (options) {
|
|
|
197
213
|
return readdirSync(this.path, options as any);
|
|
198
214
|
};
|
|
199
215
|
|
|
200
|
-
Path.prototype.symlinkSync = function
|
|
216
|
+
Path.prototype.symlinkSync = function (
|
|
201
217
|
target: string | URL | Path,
|
|
202
218
|
type?: Parameters<typeof symlinkSync>[2],
|
|
203
219
|
): Path {
|
|
@@ -210,6 +226,10 @@ Path.prototype.symlinkSync = function symlink(
|
|
|
210
226
|
return targetPath;
|
|
211
227
|
};
|
|
212
228
|
|
|
229
|
+
Path.prototype.realpathSync = function (): Path {
|
|
230
|
+
return new Path(realpathSync(this.path));
|
|
231
|
+
};
|
|
232
|
+
|
|
213
233
|
/** @ts-expect-error ts(2322): Wrangle types */
|
|
214
234
|
Path.prototype.statSync = function (
|
|
215
235
|
options?: Parameters<typeof statSync>[1],
|
package/src/sync/sync.test.ts
CHANGED
|
@@ -193,6 +193,14 @@ test(".writeJSONSync(…)", () => {
|
|
|
193
193
|
expect(file.readJSONSync()).toEqual<Record<string, string>>({ foo: "bar" });
|
|
194
194
|
});
|
|
195
195
|
|
|
196
|
+
test(".appendFileSync(…)", () => {
|
|
197
|
+
const file = Path.makeTempDirSync().join("file.txt");
|
|
198
|
+
file.appendFileSync("test\n");
|
|
199
|
+
expect(file.readTextSync()).toEqual("test\n");
|
|
200
|
+
file.appendFileSync("more\n");
|
|
201
|
+
expect(file.readTextSync()).toEqual("test\nmore\n");
|
|
202
|
+
});
|
|
203
|
+
|
|
196
204
|
test(".readDirSync(…)", () => {
|
|
197
205
|
const dir = Path.makeTempDirSync();
|
|
198
206
|
dir.join("file.txt").writeSync("hello");
|
|
@@ -219,6 +227,15 @@ test(".symlinkSync(…)", () => {
|
|
|
219
227
|
expect(target.readTextSync()).toEqual("hello");
|
|
220
228
|
});
|
|
221
229
|
|
|
230
|
+
test(".realpathSync(…)", () => {
|
|
231
|
+
const tempDir = Path.makeTempDirSync();
|
|
232
|
+
const source = tempDir.join("foo.txt");
|
|
233
|
+
source.writeSync("hello world!");
|
|
234
|
+
const target = tempDir.join("bar.txt");
|
|
235
|
+
source.symlinkSync(target);
|
|
236
|
+
expect(source.realpathSync().path).toEqual(target.realpathSync().path);
|
|
237
|
+
});
|
|
238
|
+
|
|
222
239
|
test(".statSync(…)", () => {
|
|
223
240
|
const file = Path.makeTempDirSync().join("foo.txt");
|
|
224
241
|
file.writeSync("hello");
|
|
@@ -1,7 +0,0 @@
|
|
|
1
|
-
{
|
|
2
|
-
"version": 3,
|
|
3
|
-
"sources": ["../../../../src/Path.ts"],
|
|
4
|
-
"sourcesContent": ["import {\n cp,\n lstat,\n mkdir,\n mkdtemp,\n readdir,\n readFile,\n rename,\n rm,\n stat,\n symlink,\n writeFile,\n} from \"node:fs/promises\";\nimport { homedir, tmpdir } from \"node:os\";\nimport { basename, dirname, extname, join } from \"node:path\";\nimport { Readable } from \"node:stream\";\nimport { fileURLToPath, pathToFileURL } from \"node:url\";\nimport {\n xdgCache,\n xdgConfig,\n xdgData,\n xdgRuntime,\n xdgState,\n} from \"xdg-basedir\";\nimport type {\n lstatType,\n readDirType,\n readFileType,\n statType,\n} from \"./modifiedNodeTypes\";\n\n// Note that (non-static) functions in this file are defined using `function(\u2026)\n// { \u2026 }` rather than arrow functions, specifically because we want `this` to\n// operate on the `Path` instance.\n\ntype WritableData = Parameters<typeof writeFile>[1] | ReadableStream | Response;\nasync function wrangleWritableData(\n data: WritableData | Promise<WritableData>,\n): Promise<Parameters<typeof writeFile>[1]> {\n data = await data;\n if (data instanceof Response) {\n data = data.body ? Readable.fromWeb(data.body) : new Uint8Array(0);\n }\n if (data instanceof ReadableStream) {\n data = Readable.fromWeb(data);\n }\n return data;\n}\n\nexport class Path {\n // @ts-expect-error ts(2564): False positive. https://github.com/microsoft/TypeScript/issues/32194\n #path: string;\n /**\n * If `path` is a string starting with `file:///`, it will be parsed as a file URL.\n */\n constructor(path: string | URL | Path) {\n this.#setNormalizedPath(Path.#pathlikeToString(path));\n }\n\n /**\n * Similar to `new URL(path, base)`, but accepting and returning `Path` objects.\n * Note that `base` must be one of:\n *\n * - a valid second argument to `new URL(\u2026)`.\n * - a `Path` representing an absolute path.\n *\n */\n static resolve(path: string | URL | Path, base: string | URL | Path): Path {\n const baseURL = (() => {\n if (!(base instanceof Path)) {\n return base;\n }\n if (!base.isAbsolutePath()) {\n throw new Error(\n \"The `base` arg to `Path.resolve(\u2026)` must be an absolute path.\",\n );\n }\n return pathToFileURL(base.#path);\n })();\n return new Path(new URL(Path.#pathlikeToString(path), baseURL));\n }\n\n static #pathlikeToString(path: string | URL | Path): string {\n if (path instanceof Path) {\n return path.#path;\n }\n if (path instanceof URL) {\n return fileURLToPath(path);\n }\n if (typeof path === \"string\") {\n // TODO: allow turning off this heuristic?\n if (path.startsWith(\"file:///\")) {\n return fileURLToPath(path);\n }\n return path;\n }\n throw new Error(\"Invalid path\");\n }\n\n #setNormalizedPath(path: string): void {\n this.#path = join(path);\n }\n\n isAbsolutePath(): boolean {\n return this.#path.startsWith(\"/\");\n }\n\n toFileURL(): URL {\n if (!this.isAbsolutePath()) {\n throw new Error(\n \"Tried to convert to file URL when the path is not absolute.\",\n );\n }\n return pathToFileURL(this.#path);\n }\n\n /**\n * The `Path` can have a trailing slash, indicating that it represents a\n * directory. (If there is no trailing slash, it can represent either a file\n * or a directory.)\n *\n * Some operations will refuse to treat a directory path as a file path. This\n * function identifies such paths.\n */\n hasTrailingSlash(): boolean {\n // TODO: handle Windows semantically\n return this.#path.endsWith(\"/\");\n }\n\n /**\n * Same as `.toString()`, but more concise.\n */\n get path() {\n return this.#path;\n }\n\n toString(): string {\n return this.#path;\n }\n\n /** Constructs a new path by appending the given path segments.\n * This follows `node` semantics for absolute paths: leading slashes in the given descendant segments are ignored.\n */\n join(...segments: (string | Path)[]): Path {\n const segmentStrings = segments.map((segment) =>\n segment instanceof Path ? segment.path : segment,\n );\n return new Path(join(this.#path, ...segmentStrings));\n }\n\n extendBasename(suffix: string): Path {\n const joinedSuffix = join(suffix);\n if (joinedSuffix !== basename(joinedSuffix)) {\n throw new Error(\"Invalid suffix to extend file name.\");\n }\n // TODO: join basename and dirname instead?\n return new Path(this.#path + joinedSuffix);\n }\n\n get parent(): Path {\n return new Path(dirname(this.#path));\n }\n\n // Normally I'd stick with `node`'s name, but I think `.dirname` is a\n // particularly poor name. So we support `.dirname` for discovery but mark it\n // as deprecated, even if it will never be removed.\n /** @deprecated Alias for `.parent`. */\n get dirname(): Path {\n return this.parent;\n }\n\n get basename(): Path {\n return new Path(basename(this.#path));\n }\n\n get extension(): string {\n mustNotHaveTrailingSlash(this);\n return extname(this.#path);\n }\n\n // Normally I'd stick with `node`'s name, but I think `.extname` is a\n // particularly poor name. So we support `.extname` for discovery but mark it\n // as deprecated, even if it will never be removed.\n /** @deprecated Alias for `.extension`. */\n get extname(): string {\n return this.extension;\n }\n\n // TODO: find a neat way to dedup with the sync version?\n async exists(constraints?: {\n mustBe: \"file\" | \"directory\";\n }): Promise<boolean> {\n let stats: Awaited<ReturnType<typeof stat>>;\n try {\n stats = await stat(this.#path);\n // biome-ignore lint/suspicious/noExplicitAny: TypeScript limitation\n } catch (e: any) {\n if (e.code === \"ENOENT\") {\n return false;\n }\n throw e;\n }\n if (!constraints?.mustBe) {\n return true;\n }\n switch (constraints?.mustBe) {\n case \"file\": {\n mustNotHaveTrailingSlash(this);\n if (stats.isFile()) {\n return true;\n }\n throw new Error(`Path exists but is not a file: ${this.#path}`);\n }\n case \"directory\": {\n if (stats.isDirectory()) {\n return true;\n }\n throw new Error(`Path exists but is not a directory: ${this.#path}`);\n }\n default: {\n throw new Error(\"Invalid path type constraint\");\n }\n }\n }\n\n async existsAsFile(): Promise<boolean> {\n return this.exists({ mustBe: \"file\" });\n }\n\n async existsAsDir(): Promise<boolean> {\n return this.exists({ mustBe: \"directory\" });\n }\n\n // I don't think `mkdir` is a great name, but it does match the\n // well-established canonical commandline name. So in this case we keep the\n // awkward abbreviation.\n /** Defaults to `recursive: true`. */\n async mkdir(options?: Parameters<typeof mkdir>[1]): Promise<Path> {\n const optionsObject = (() => {\n if (typeof options === \"string\" || typeof options === \"number\") {\n return { mode: options };\n }\n return options ?? {};\n })();\n await mkdir(this.#path, { recursive: true, ...optionsObject });\n return this;\n }\n\n // TODO: check idempotency semantics when the destination exists and is a folder.\n /** Returns the destination path. */\n async cp(\n destination: string | URL | Path,\n options?: Parameters<typeof cp>[2],\n ): Promise<Path> {\n await cp(this.#path, new Path(destination).#path, options);\n return new Path(destination);\n }\n\n // TODO: check idempotency semantics when the destination exists and is a folder.\n async rename(destination: string | URL | Path): Promise<void> {\n await rename(this.#path, new Path(destination).#path);\n }\n\n /** Create a temporary dir inside the global temp dir for the current user. */\n static async makeTempDir(prefix?: string): Promise<Path> {\n return new Path(\n await mkdtemp(new Path(tmpdir()).join(prefix ?? \"js-temp-\").toString()),\n );\n }\n\n async rm(options?: Parameters<typeof rm>[1]): Promise<void> {\n await rm(this.#path, options);\n }\n\n /**\n * Equivalent to:\n *\n * .rm({ recursive: true, force: true, ...(options ?? {}) })\n *\n */\n async rm_rf(options?: Parameters<typeof rm>[1]): Promise<void> {\n await this.rm({ recursive: true, force: true, ...(options ?? {}) });\n }\n\n read: typeof readFileType = (options) =>\n // biome-ignore lint/suspicious/noExplicitAny: Needed to wrangle the types.\n readFile(this.#path, options as any) as any;\n\n async readText(): Promise<string> {\n return readFile(this.#path, \"utf-8\");\n }\n\n /**\n * Reads JSON from the given file and parses it. No validation is performed\n * (beyond JSON parsing).\n *\n * An optional `fallback` value can be specified. It will be used if (and only\n * if) the file does not exist.\n *\n */\n\n // biome-ignore lint/suspicious/noExplicitAny: Allow a default of `any` to match `JSON.parse(\u2026)`.\n async readJSON<T = any>(options?: { fallback?: T }): Promise<T> {\n try {\n return JSON.parse(await this.readText());\n } catch (e) {\n if (\n (e as { code?: string }).code === \"ENOENT\" &&\n options &&\n \"fallback\" in options\n ) {\n return options.fallback as T;\n }\n throw e;\n }\n }\n\n /** Creates intermediate directories if they do not exist.\n *\n * Returns the original `Path` (for chaining).\n */\n async write(\n data: WritableData | Promise<WritableData>,\n options?: Parameters<typeof writeFile>[2],\n ): Promise<Path> {\n await this.parent.mkdir();\n await writeFile(this.#path, await wrangleWritableData(data), options);\n return this;\n }\n\n /**\n * If only `data` is provided, this is equivalent to:\n *\n * .write(JSON.stringify(data, null, \" \"));\n *\n * `replacer` and `space` can also be specified, making this equivalent to:\n *\n * .write(JSON.stringify(data, replacer, space));\n *\n * Returns the original `Path` (for chaining).\n */\n async writeJSON<T>(\n data: T,\n replacer: Parameters<typeof JSON.stringify>[1] = null,\n space: Parameters<typeof JSON.stringify>[2] = \" \",\n ): Promise<Path> {\n await this.write(JSON.stringify(data, replacer, space));\n return this;\n }\n\n // Normally we'd add a `@deprecated` alias named `.readdir`, but that would\n // differ only by capitalization of a single non-leading character. This can\n // be a bit confusing, especially when autocompleting. So for this function in\n // particular we don't include an alias.\n readDir: typeof readDirType = (options) =>\n // biome-ignore lint/suspicious/noExplicitAny: Needed to wrangle the types.\n readdir(this.#path, options as any) as any;\n\n /** Returns the destination path. */\n async symlink(\n target: string | URL | Path,\n type?: Parameters<typeof symlink>[2],\n ): Promise<Path> {\n const targetPath = new Path(target);\n await symlink(\n this.path,\n targetPath.path,\n type as Exclude<Parameters<typeof symlink>[2], undefined>, // \uD83E\uDD37\n );\n return targetPath;\n }\n\n // biome-ignore lint/suspicious/noExplicitAny: Needed to wrangle the types.\n stat: typeof statType = (...options) => stat(this.#path, ...options) as any;\n\n // I don't think `lstat` is a great name, but it does match the\n // well-established canonical system call. So in this case we keep the\n // awkward abbreviation.\n lstat: typeof lstatType = (...options) =>\n // biome-ignore lint/suspicious/noExplicitAny: Needed to wrangle the types.\n lstat(this.#path, ...options) as any;\n\n static get homedir(): Path {\n return new Path(homedir());\n }\n\n static xdg = {\n cache: new Path(xdgCache ?? Path.homedir.join(\".cache\")),\n config: new Path(xdgConfig ?? Path.homedir.join(\".config\")),\n data: new Path(xdgData ?? Path.homedir.join(\".local/share\")),\n state: new Path(xdgState ?? Path.homedir.join(\".local/state\")),\n /**\n * {@link Path.xdg.runtime} does not have a default value. Consider\n * {@link Path.xdg.runtimeWithStateFallback} if you need a fallback but do not have a particular fallback in mind.\n */\n runtime: xdgRuntime ? new Path(xdgRuntime) : undefined,\n runtimeWithStateFallback: xdgRuntime\n ? new Path(xdgRuntime)\n : new Path(xdgState ?? Path.homedir.join(\".local/state\")),\n };\n\n /** Chainable function to print the path. Prints the same as:\n *\n * if (args.length > 0) {\n * console.log(...args);\n * }\n * console.log(this.path);\n *\n */\n // biome-ignore lint/suspicious/noExplicitAny: This is the correct type, based on `console.log(\u2026)`.\n debugPrint(...args: any[]): Path {\n if (args.length > 0) {\n console.log(...args);\n }\n console.log(this.#path);\n return this;\n }\n}\n\n/**\n * This function is useful to serialize any `Path`s in a structure to pass on to\n * functions that do not know about the `Path` class, e.g.\n *\n * function process(args: (string | Path)[]) {\n * const argsAsStrings = args.map(stringifyIfPath);\n * }\n *\n */\nexport function stringifyIfPath<T>(value: T | Path): T | string {\n if (value instanceof Path) {\n return value.toString();\n }\n return value;\n}\n\nexport function mustNotHaveTrailingSlash(path: Path): void {\n if (path.hasTrailingSlash()) {\n throw new Error(\n \"Path ends with a slash, which cannot be treated as a file.\",\n );\n }\n}\n"],
|
|
5
|
-
"mappings": ";AAAA;AAAA,EACE;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,OACK;AACP,SAAS,SAAS,cAAc;AAChC,SAAS,UAAU,SAAS,SAAS,YAAY;AACjD,SAAS,gBAAgB;AACzB,SAAS,eAAe,qBAAqB;AAC7C;AAAA,EACE;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,OACK;AAaP,eAAe,oBACb,MAC0C;AAC1C,SAAO,MAAM;AACb,MAAI,gBAAgB,UAAU;AAC5B,WAAO,KAAK,OAAO,SAAS,QAAQ,KAAK,IAAI,IAAI,IAAI,WAAW,CAAC;AAAA,EACnE;AACA,MAAI,gBAAgB,gBAAgB;AAClC,WAAO,SAAS,QAAQ,IAAI;AAAA,EAC9B;AACA,SAAO;AACT;AAEO,IAAM,OAAN,MAAM,MAAK;AAAA;AAAA,EAEhB;AAAA;AAAA;AAAA;AAAA,EAIA,YAAY,MAA2B;AACrC,SAAK,mBAAmB,MAAK,kBAAkB,IAAI,CAAC;AAAA,EACtD;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAUA,OAAO,QAAQ,MAA2B,MAAiC;AACzE,UAAM,WAAW,MAAM;AACrB,UAAI,EAAE,gBAAgB,QAAO;AAC3B,eAAO;AAAA,MACT;AACA,UAAI,CAAC,KAAK,eAAe,GAAG;AAC1B,cAAM,IAAI;AAAA,UACR;AAAA,QACF;AAAA,MACF;AACA,aAAO,cAAc,KAAK,KAAK;AAAA,IACjC,GAAG;AACH,WAAO,IAAI,MAAK,IAAI,IAAI,MAAK,kBAAkB,IAAI,GAAG,OAAO,CAAC;AAAA,EAChE;AAAA,EAEA,OAAO,kBAAkB,MAAmC;AAC1D,QAAI,gBAAgB,OAAM;AACxB,aAAO,KAAK;AAAA,IACd;AACA,QAAI,gBAAgB,KAAK;AACvB,aAAO,cAAc,IAAI;AAAA,IAC3B;AACA,QAAI,OAAO,SAAS,UAAU;AAE5B,UAAI,KAAK,WAAW,UAAU,GAAG;AAC/B,eAAO,cAAc,IAAI;AAAA,MAC3B;AACA,aAAO;AAAA,IACT;AACA,UAAM,IAAI,MAAM,cAAc;AAAA,EAChC;AAAA,EAEA,mBAAmB,MAAoB;AACrC,SAAK,QAAQ,KAAK,IAAI;AAAA,EACxB;AAAA,EAEA,iBAA0B;AACxB,WAAO,KAAK,MAAM,WAAW,GAAG;AAAA,EAClC;AAAA,EAEA,YAAiB;AACf,QAAI,CAAC,KAAK,eAAe,GAAG;AAC1B,YAAM,IAAI;AAAA,QACR;AAAA,MACF;AAAA,IACF;AACA,WAAO,cAAc,KAAK,KAAK;AAAA,EACjC;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAUA,mBAA4B;AAE1B,WAAO,KAAK,MAAM,SAAS,GAAG;AAAA,EAChC;AAAA;AAAA;AAAA;AAAA,EAKA,IAAI,OAAO;AACT,WAAO,KAAK;AAAA,EACd;AAAA,EAEA,WAAmB;AACjB,WAAO,KAAK;AAAA,EACd;AAAA;AAAA;AAAA;AAAA,EAKA,QAAQ,UAAmC;AACzC,UAAM,iBAAiB,SAAS;AAAA,MAAI,CAAC,YACnC,mBAAmB,QAAO,QAAQ,OAAO;AAAA,IAC3C;AACA,WAAO,IAAI,MAAK,KAAK,KAAK,OAAO,GAAG,cAAc,CAAC;AAAA,EACrD;AAAA,EAEA,eAAe,QAAsB;AACnC,UAAM,eAAe,KAAK,MAAM;AAChC,QAAI,iBAAiB,SAAS,YAAY,GAAG;AAC3C,YAAM,IAAI,MAAM,qCAAqC;AAAA,IACvD;AAEA,WAAO,IAAI,MAAK,KAAK,QAAQ,YAAY;AAAA,EAC3C;AAAA,EAEA,IAAI,SAAe;AACjB,WAAO,IAAI,MAAK,QAAQ,KAAK,KAAK,CAAC;AAAA,EACrC;AAAA;AAAA;AAAA;AAAA;AAAA,EAMA,IAAI,UAAgB;AAClB,WAAO,KAAK;AAAA,EACd;AAAA,EAEA,IAAI,WAAiB;AACnB,WAAO,IAAI,MAAK,SAAS,KAAK,KAAK,CAAC;AAAA,EACtC;AAAA,EAEA,IAAI,YAAoB;AACtB,6BAAyB,IAAI;AAC7B,WAAO,QAAQ,KAAK,KAAK;AAAA,EAC3B;AAAA;AAAA;AAAA;AAAA;AAAA,EAMA,IAAI,UAAkB;AACpB,WAAO,KAAK;AAAA,EACd;AAAA;AAAA,EAGA,MAAM,OAAO,aAEQ;AACnB,QAAI;AACJ,QAAI;AACF,cAAQ,MAAM,KAAK,KAAK,KAAK;AAAA,IAE/B,SAAS,GAAQ;AACf,UAAI,EAAE,SAAS,UAAU;AACvB,eAAO;AAAA,MACT;AACA,YAAM;AAAA,IACR;AACA,QAAI,CAAC,aAAa,QAAQ;AACxB,aAAO;AAAA,IACT;AACA,YAAQ,aAAa,QAAQ;AAAA,MAC3B,KAAK,QAAQ;AACX,iCAAyB,IAAI;AAC7B,YAAI,MAAM,OAAO,GAAG;AAClB,iBAAO;AAAA,QACT;AACA,cAAM,IAAI,MAAM,kCAAkC,KAAK,KAAK,EAAE;AAAA,MAChE;AAAA,MACA,KAAK,aAAa;AAChB,YAAI,MAAM,YAAY,GAAG;AACvB,iBAAO;AAAA,QACT;AACA,cAAM,IAAI,MAAM,uCAAuC,KAAK,KAAK,EAAE;AAAA,MACrE;AAAA,MACA,SAAS;AACP,cAAM,IAAI,MAAM,8BAA8B;AAAA,MAChD;AAAA,IACF;AAAA,EACF;AAAA,EAEA,MAAM,eAAiC;AACrC,WAAO,KAAK,OAAO,EAAE,QAAQ,OAAO,CAAC;AAAA,EACvC;AAAA,EAEA,MAAM,cAAgC;AACpC,WAAO,KAAK,OAAO,EAAE,QAAQ,YAAY,CAAC;AAAA,EAC5C;AAAA;AAAA;AAAA;AAAA;AAAA,EAMA,MAAM,MAAM,SAAsD;AAChE,UAAM,iBAAiB,MAAM;AAC3B,UAAI,OAAO,YAAY,YAAY,OAAO,YAAY,UAAU;AAC9D,eAAO,EAAE,MAAM,QAAQ;AAAA,MACzB;AACA,aAAO,WAAW,CAAC;AAAA,IACrB,GAAG;AACH,UAAM,MAAM,KAAK,OAAO,EAAE,WAAW,MAAM,GAAG,cAAc,CAAC;AAC7D,WAAO;AAAA,EACT;AAAA;AAAA;AAAA,EAIA,MAAM,GACJ,aACA,SACe;AACf,UAAM,GAAG,KAAK,OAAO,IAAI,MAAK,WAAW,EAAE,OAAO,OAAO;AACzD,WAAO,IAAI,MAAK,WAAW;AAAA,EAC7B;AAAA;AAAA,EAGA,MAAM,OAAO,aAAiD;AAC5D,UAAM,OAAO,KAAK,OAAO,IAAI,MAAK,WAAW,EAAE,KAAK;AAAA,EACtD;AAAA;AAAA,EAGA,aAAa,YAAY,QAAgC;AACvD,WAAO,IAAI;AAAA,MACT,MAAM,QAAQ,IAAI,MAAK,OAAO,CAAC,EAAE,KAAK,UAAU,UAAU,EAAE,SAAS,CAAC;AAAA,IACxE;AAAA,EACF;AAAA,EAEA,MAAM,GAAG,SAAmD;AAC1D,UAAM,GAAG,KAAK,OAAO,OAAO;AAAA,EAC9B;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAQA,MAAM,MAAM,SAAmD;AAC7D,UAAM,KAAK,GAAG,EAAE,WAAW,MAAM,OAAO,MAAM,GAAI,WAAW,CAAC,EAAG,CAAC;AAAA,EACpE;AAAA,EAEA,OAA4B,CAAC;AAAA;AAAA,IAE3B,SAAS,KAAK,OAAO,OAAc;AAAA;AAAA,EAErC,MAAM,WAA4B;AAChC,WAAO,SAAS,KAAK,OAAO,OAAO;AAAA,EACrC;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAYA,MAAM,SAAkB,SAAwC;AAC9D,QAAI;AACF,aAAO,KAAK,MAAM,MAAM,KAAK,SAAS,CAAC;AAAA,IACzC,SAAS,GAAG;AACV,UACG,EAAwB,SAAS,YAClC,WACA,cAAc,SACd;AACA,eAAO,QAAQ;AAAA,MACjB;AACA,YAAM;AAAA,IACR;AAAA,EACF;AAAA;AAAA;AAAA;AAAA;AAAA,EAMA,MAAM,MACJ,MACA,SACe;AACf,UAAM,KAAK,OAAO,MAAM;AACxB,UAAM,UAAU,KAAK,OAAO,MAAM,oBAAoB,IAAI,GAAG,OAAO;AACpE,WAAO;AAAA,EACT;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAaA,MAAM,UACJ,MACA,WAAiD,MACjD,QAA8C,MAC/B;AACf,UAAM,KAAK,MAAM,KAAK,UAAU,MAAM,UAAU,KAAK,CAAC;AACtD,WAAO;AAAA,EACT;AAAA;AAAA;AAAA;AAAA;AAAA,EAMA,UAA8B,CAAC;AAAA;AAAA,IAE7B,QAAQ,KAAK,OAAO,OAAc;AAAA;AAAA;AAAA,EAGpC,MAAM,QACJ,QACA,MACe;AACf,UAAM,aAAa,IAAI,MAAK,MAAM;AAClC,UAAM;AAAA,MACJ,KAAK;AAAA,MACL,WAAW;AAAA,MACX;AAAA;AAAA,IACF;AACA,WAAO;AAAA,EACT;AAAA;AAAA,EAGA,OAAwB,IAAI,YAAY,KAAK,KAAK,OAAO,GAAG,OAAO;AAAA;AAAA;AAAA;AAAA,EAKnE,QAA0B,IAAI;AAAA;AAAA,IAE5B,MAAM,KAAK,OAAO,GAAG,OAAO;AAAA;AAAA,EAE9B,WAAW,UAAgB;AACzB,WAAO,IAAI,MAAK,QAAQ,CAAC;AAAA,EAC3B;AAAA,EAEA,OAAO,MAAM;AAAA,IACX,OAAO,IAAI,MAAK,YAAY,MAAK,QAAQ,KAAK,QAAQ,CAAC;AAAA,IACvD,QAAQ,IAAI,MAAK,aAAa,MAAK,QAAQ,KAAK,SAAS,CAAC;AAAA,IAC1D,MAAM,IAAI,MAAK,WAAW,MAAK,QAAQ,KAAK,cAAc,CAAC;AAAA,IAC3D,OAAO,IAAI,MAAK,YAAY,MAAK,QAAQ,KAAK,cAAc,CAAC;AAAA;AAAA;AAAA;AAAA;AAAA,IAK7D,SAAS,aAAa,IAAI,MAAK,UAAU,IAAI;AAAA,IAC7C,0BAA0B,aACtB,IAAI,MAAK,UAAU,IACnB,IAAI,MAAK,YAAY,MAAK,QAAQ,KAAK,cAAc,CAAC;AAAA,EAC5D;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAWA,cAAc,MAAmB;AAC/B,QAAI,KAAK,SAAS,GAAG;AACnB,cAAQ,IAAI,GAAG,IAAI;AAAA,IACrB;AACA,YAAQ,IAAI,KAAK,KAAK;AACtB,WAAO;AAAA,EACT;AACF;AAWO,SAAS,gBAAmB,OAA6B;AAC9D,MAAI,iBAAiB,MAAM;AACzB,WAAO,MAAM,SAAS;AAAA,EACxB;AACA,SAAO;AACT;AAEO,SAAS,yBAAyB,MAAkB;AACzD,MAAI,KAAK,iBAAiB,GAAG;AAC3B,UAAM,IAAI;AAAA,MACR;AAAA,IACF;AAAA,EACF;AACF;",
|
|
6
|
-
"names": []
|
|
7
|
-
}
|