@unshared/fs 0.0.1
Sign up to get free protection for your applications and to get access to all the features.
- package/LICENSE.md +21 -0
- package/dist/createTemporaryDirectory.cjs +11 -0
- package/dist/createTemporaryDirectory.cjs.map +1 -0
- package/dist/createTemporaryDirectory.d.ts +35 -0
- package/dist/createTemporaryDirectory.js +14 -0
- package/dist/createTemporaryDirectory.js.map +1 -0
- package/dist/createTemporaryFile.cjs +12 -0
- package/dist/createTemporaryFile.cjs.map +1 -0
- package/dist/createTemporaryFile.d.ts +44 -0
- package/dist/createTemporaryFile.js +15 -0
- package/dist/createTemporaryFile.js.map +1 -0
- package/dist/findAncestor.cjs +16 -0
- package/dist/findAncestor.cjs.map +1 -0
- package/dist/findAncestor.d.ts +18 -0
- package/dist/findAncestor.js +19 -0
- package/dist/findAncestor.js.map +1 -0
- package/dist/findAncestors.cjs +20 -0
- package/dist/findAncestors.cjs.map +1 -0
- package/dist/findAncestors.d.ts +21 -0
- package/dist/findAncestors.js +24 -0
- package/dist/findAncestors.js.map +1 -0
- package/dist/glob.cjs +28 -0
- package/dist/glob.cjs.map +1 -0
- package/dist/glob.d.ts +71 -0
- package/dist/glob.js +33 -0
- package/dist/glob.js.map +1 -0
- package/dist/index.cjs +25 -0
- package/dist/index.cjs.map +1 -0
- package/dist/index.d.ts +16 -0
- package/dist/index.js +35 -0
- package/dist/index.js.map +1 -0
- package/dist/loadObject.cjs +187 -0
- package/dist/loadObject.cjs.map +1 -0
- package/dist/loadObject.d.ts +222 -0
- package/dist/loadObject.js +195 -0
- package/dist/loadObject.js.map +1 -0
- package/dist/touch.cjs +15 -0
- package/dist/touch.cjs.map +1 -0
- package/dist/touch.d.ts +36 -0
- package/dist/touch.js +17 -0
- package/dist/touch.js.map +1 -0
- package/dist/updateFile.cjs +8 -0
- package/dist/updateFile.cjs.map +1 -0
- package/dist/updateFile.d.ts +32 -0
- package/dist/updateFile.js +9 -0
- package/dist/updateFile.js.map +1 -0
- package/dist/withTemporaryDirectories.cjs +17 -0
- package/dist/withTemporaryDirectories.cjs.map +1 -0
- package/dist/withTemporaryDirectories.d.ts +18 -0
- package/dist/withTemporaryDirectories.js +18 -0
- package/dist/withTemporaryDirectories.js.map +1 -0
- package/dist/withTemporaryFiles.cjs +17 -0
- package/dist/withTemporaryFiles.cjs.map +1 -0
- package/dist/withTemporaryFiles.d.ts +19 -0
- package/dist/withTemporaryFiles.js +18 -0
- package/dist/withTemporaryFiles.js.map +1 -0
- package/package.json +90 -0
package/LICENSE.md
ADDED
@@ -0,0 +1,21 @@
|
|
1
|
+
The MIT License (MIT)
|
2
|
+
|
3
|
+
Copyright (c) 2024 Stanley Horwood <stanley@hsjm.io>
|
4
|
+
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
7
|
+
in the Software without restriction, including without limitation the rights
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
10
|
+
furnished to do so, subject to the following conditions:
|
11
|
+
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
13
|
+
copies or substantial portions of the Software.
|
14
|
+
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
21
|
+
SOFTWARE.
|
@@ -0,0 +1,11 @@
|
|
1
|
+
"use strict";
|
2
|
+
var node_path = require("node:path"), node_os = require("node:os"), promises = require("node:fs/promises");
|
3
|
+
async function createTemporaryDirectory(options = {}) {
|
4
|
+
const {
|
5
|
+
directory = node_os.tmpdir(),
|
6
|
+
random = () => Math.random().toString(36).slice(2)
|
7
|
+
} = options, name = random(), path = node_path.join(directory, name);
|
8
|
+
return await promises.mkdir(path, { recursive: !0 }), [path, () => promises.rm(path, { force: !0, recursive: !0 })];
|
9
|
+
}
|
10
|
+
exports.createTemporaryDirectory = createTemporaryDirectory;
|
11
|
+
//# sourceMappingURL=createTemporaryDirectory.cjs.map
|
@@ -0,0 +1 @@
|
|
1
|
+
{"version":3,"file":"createTemporaryDirectory.cjs","sources":["../createTemporaryDirectory.ts"],"sourcesContent":["import { join } from 'node:path'\nimport { tmpdir } from 'node:os'\nimport { mkdir, rm } from 'node:fs/promises'\n\nexport interface CreateTemporaryDirectoryOptions {\n /**\n * The directory to create the temporary directory in.\n * Defaults to the system's temporary directory.\n *\n * @default tmpdir()\n */\n directory?: string\n /**\n * A function that generates a random string.\n *\n * @default () => Math.random().toString(36).slice(2)\n */\n random?: () => string\n}\n/**\n * Create a temporary directory with a random name and return\n * an object containing the directory path, and a function to\n * recursively remove the directory.\n *\n * @param options The options to create the temporary directory.\n * @returns A promise that resolves to the temporary directory object.\n * @example\n * // Create a temporary directory.\n * const [path, remove] = await createTemporaryDirectory()\n *\n * // Do something with the directory.\n * exec(`tar -czf ${path}.tar.gz ${path}`)\n *\n * // Remove the directory.\n * await remove()\n */\n\nexport async function createTemporaryDirectory(options: CreateTemporaryDirectoryOptions = {}) {\n const {\n directory = tmpdir(),\n random = () => Math.random().toString(36).slice(2),\n } = options\n\n // --- Generate a random name.\n const name = random()\n const path = join(directory, name)\n\n // --- Create the directory.\n await mkdir(path, { recursive: true })\n\n // --- Return the path and a function to remove the directory.\n const remove = () => rm(path, { force: true, recursive: true })\n return [path, remove] as const\n}\n\n/* v8 ignore start */\nif (import.meta.vitest) {\n const { existsSync, statSync } = await import('node:fs')\n\n test('should create an empty temporary directory in \"/tmp/<random>\"', async() => {\n const [path] = await createTemporaryDirectory()\n const isDirectory = statSync(path).isDirectory()\n expect(path).toMatch(/^\\/tmp\\/[\\da-z]+$/)\n expect (isDirectory).toBeTruthy()\n })\n\n test('should create a temporary directory in the specified directory', async() => {\n const [path] = await createTemporaryDirectory({ directory: '/cache' })\n expect(path).toMatch(/^\\/cache\\/[\\da-z]+$/)\n })\n\n test('should recursively create the specified directory', async() => {\n const [path] = await createTemporaryDirectory({ directory: '/tmp/foo/bar' })\n expect(path).toMatch(/^\\/tmp\\/foo\\/bar\\/[\\da-z]+$/)\n })\n\n test('should create a temporary file with the given random function', async() => {\n const [path] = await createTemporaryDirectory({ random: () => 'foo' })\n expect(path).toMatch(/^\\/tmp\\/foo$/)\n })\n\n test('should remove the temporary file after calling the remove function', async() => {\n const [path, remove] = await createTemporaryDirectory()\n await remove()\n const exists = existsSync(path)\n expect(exists).toBeFalsy()\n })\n}\n"],"names":["tmpdir","join","mkdir","rm"],"mappings":";;AAqCsB,eAAA,yBAAyB,UAA2C,IAAI;AACtF,QAAA;AAAA,IACJ,YAAYA,QAAAA,OAAO;AAAA,IACnB,SAAS,MAAM,KAAK,SAAS,SAAS,EAAE,EAAE,MAAM,CAAC;AAAA,EAAA,IAC/C,SAGE,OAAO,UACP,OAAOC,eAAK,WAAW,IAAI;AAGjC,SAAA,MAAMC,eAAM,MAAM,EAAE,WAAW,GAAK,CAAC,GAI9B,CAAC,MADO,MAAMC,SAAAA,GAAG,MAAM,EAAE,OAAO,IAAM,WAAW,GAAM,CAAA,CAC1C;AACtB;;"}
|
@@ -0,0 +1,35 @@
|
|
1
|
+
interface CreateTemporaryDirectoryOptions {
|
2
|
+
/**
|
3
|
+
* The directory to create the temporary directory in.
|
4
|
+
* Defaults to the system's temporary directory.
|
5
|
+
*
|
6
|
+
* @default tmpdir()
|
7
|
+
*/
|
8
|
+
directory?: string;
|
9
|
+
/**
|
10
|
+
* A function that generates a random string.
|
11
|
+
*
|
12
|
+
* @default () => Math.random().toString(36).slice(2)
|
13
|
+
*/
|
14
|
+
random?: () => string;
|
15
|
+
}
|
16
|
+
/**
|
17
|
+
* Create a temporary directory with a random name and return
|
18
|
+
* an object containing the directory path, and a function to
|
19
|
+
* recursively remove the directory.
|
20
|
+
*
|
21
|
+
* @param options The options to create the temporary directory.
|
22
|
+
* @returns A promise that resolves to the temporary directory object.
|
23
|
+
* @example
|
24
|
+
* // Create a temporary directory.
|
25
|
+
* const [path, remove] = await createTemporaryDirectory()
|
26
|
+
*
|
27
|
+
* // Do something with the directory.
|
28
|
+
* exec(`tar -czf ${path}.tar.gz ${path}`)
|
29
|
+
*
|
30
|
+
* // Remove the directory.
|
31
|
+
* await remove()
|
32
|
+
*/
|
33
|
+
declare function createTemporaryDirectory(options?: CreateTemporaryDirectoryOptions): Promise<readonly [string, () => Promise<void>]>;
|
34
|
+
|
35
|
+
export { type CreateTemporaryDirectoryOptions, createTemporaryDirectory };
|
@@ -0,0 +1,14 @@
|
|
1
|
+
import { join } from "node:path";
|
2
|
+
import { tmpdir } from "node:os";
|
3
|
+
import { mkdir, rm } from "node:fs/promises";
|
4
|
+
async function createTemporaryDirectory(options = {}) {
|
5
|
+
const {
|
6
|
+
directory = tmpdir(),
|
7
|
+
random = () => Math.random().toString(36).slice(2)
|
8
|
+
} = options, name = random(), path = join(directory, name);
|
9
|
+
return await mkdir(path, { recursive: !0 }), [path, () => rm(path, { force: !0, recursive: !0 })];
|
10
|
+
}
|
11
|
+
export {
|
12
|
+
createTemporaryDirectory
|
13
|
+
};
|
14
|
+
//# sourceMappingURL=createTemporaryDirectory.js.map
|
@@ -0,0 +1 @@
|
|
1
|
+
{"version":3,"file":"createTemporaryDirectory.js","sources":["../createTemporaryDirectory.ts"],"sourcesContent":["import { join } from 'node:path'\nimport { tmpdir } from 'node:os'\nimport { mkdir, rm } from 'node:fs/promises'\n\nexport interface CreateTemporaryDirectoryOptions {\n /**\n * The directory to create the temporary directory in.\n * Defaults to the system's temporary directory.\n *\n * @default tmpdir()\n */\n directory?: string\n /**\n * A function that generates a random string.\n *\n * @default () => Math.random().toString(36).slice(2)\n */\n random?: () => string\n}\n/**\n * Create a temporary directory with a random name and return\n * an object containing the directory path, and a function to\n * recursively remove the directory.\n *\n * @param options The options to create the temporary directory.\n * @returns A promise that resolves to the temporary directory object.\n * @example\n * // Create a temporary directory.\n * const [path, remove] = await createTemporaryDirectory()\n *\n * // Do something with the directory.\n * exec(`tar -czf ${path}.tar.gz ${path}`)\n *\n * // Remove the directory.\n * await remove()\n */\n\nexport async function createTemporaryDirectory(options: CreateTemporaryDirectoryOptions = {}) {\n const {\n directory = tmpdir(),\n random = () => Math.random().toString(36).slice(2),\n } = options\n\n // --- Generate a random name.\n const name = random()\n const path = join(directory, name)\n\n // --- Create the directory.\n await mkdir(path, { recursive: true })\n\n // --- Return the path and a function to remove the directory.\n const remove = () => rm(path, { force: true, recursive: true })\n return [path, remove] as const\n}\n\n/* v8 ignore start */\nif (import.meta.vitest) {\n const { existsSync, statSync } = await import('node:fs')\n\n test('should create an empty temporary directory in \"/tmp/<random>\"', async() => {\n const [path] = await createTemporaryDirectory()\n const isDirectory = statSync(path).isDirectory()\n expect(path).toMatch(/^\\/tmp\\/[\\da-z]+$/)\n expect (isDirectory).toBeTruthy()\n })\n\n test('should create a temporary directory in the specified directory', async() => {\n const [path] = await createTemporaryDirectory({ directory: '/cache' })\n expect(path).toMatch(/^\\/cache\\/[\\da-z]+$/)\n })\n\n test('should recursively create the specified directory', async() => {\n const [path] = await createTemporaryDirectory({ directory: '/tmp/foo/bar' })\n expect(path).toMatch(/^\\/tmp\\/foo\\/bar\\/[\\da-z]+$/)\n })\n\n test('should create a temporary file with the given random function', async() => {\n const [path] = await createTemporaryDirectory({ random: () => 'foo' })\n expect(path).toMatch(/^\\/tmp\\/foo$/)\n })\n\n test('should remove the temporary file after calling the remove function', async() => {\n const [path, remove] = await createTemporaryDirectory()\n await remove()\n const exists = existsSync(path)\n expect(exists).toBeFalsy()\n })\n}\n"],"names":[],"mappings":";;;AAqCsB,eAAA,yBAAyB,UAA2C,IAAI;AACtF,QAAA;AAAA,IACJ,YAAY,OAAO;AAAA,IACnB,SAAS,MAAM,KAAK,SAAS,SAAS,EAAE,EAAE,MAAM,CAAC;AAAA,EAAA,IAC/C,SAGE,OAAO,UACP,OAAO,KAAK,WAAW,IAAI;AAGjC,SAAA,MAAM,MAAM,MAAM,EAAE,WAAW,GAAK,CAAC,GAI9B,CAAC,MADO,MAAM,GAAG,MAAM,EAAE,OAAO,IAAM,WAAW,GAAM,CAAA,CAC1C;AACtB;"}
|
@@ -0,0 +1,12 @@
|
|
1
|
+
"use strict";
|
2
|
+
var node_path = require("node:path"), node_os = require("node:os"), promises = require("node:fs/promises");
|
3
|
+
async function createTemporaryFile(content, options = {}) {
|
4
|
+
const {
|
5
|
+
directory = node_os.tmpdir(),
|
6
|
+
extension,
|
7
|
+
random = () => Math.random().toString(36).slice(2)
|
8
|
+
} = options, rand = random(), name = extension ? `${rand}.${extension}` : rand, path = node_path.join(directory, name);
|
9
|
+
return await promises.mkdir(directory, { recursive: !0 }), await promises.writeFile(path, content ?? ""), [path, () => promises.rm(path, { force: !0 })];
|
10
|
+
}
|
11
|
+
exports.createTemporaryFile = createTemporaryFile;
|
12
|
+
//# sourceMappingURL=createTemporaryFile.cjs.map
|
@@ -0,0 +1 @@
|
|
1
|
+
{"version":3,"file":"createTemporaryFile.cjs","sources":["../createTemporaryFile.ts"],"sourcesContent":["import { join } from 'node:path'\nimport { tmpdir } from 'node:os'\nimport { mkdir, rm, writeFile } from 'node:fs/promises'\n\nexport interface CreateTemporaryFileOptions {\n /**\n * The directory to create the temporary file in.\n * Defaults to the system's temporary directory.\n *\n * @default tmpdir()\n */\n directory?: string\n /**\n * The file extension to use for the temporary file.\n *\n * @default ''\n */\n extension?: string\n /**\n * A function that generates a random string.\n *\n * @default () => Math.random().toString(36).slice(2)\n */\n random?: () => string\n}\n\n/**\n * Create a temporary file with a random name and return\n * an object containing the file path, and a function to\n * remove the file.\n *\n * @param content The content to write to the temporary file.\n * @param options The options to create the temporary file.\n * @returns A promise that resolves to the temporary file object.\n * @example\n * // Create a temporary file with the specified content.\n * const [path, remove] = await createTemporaryFile('Hello, world!')\n *\n * // Do something with the file.\n * exec(`openssl sha1 ${path}`)\n *\n * // Remove the file.\n * await remove()\n */\nexport async function createTemporaryFile(content?: Parameters<typeof writeFile>[1], options: CreateTemporaryFileOptions = {}) {\n const {\n directory = tmpdir(),\n extension,\n random = () => Math.random().toString(36).slice(2),\n } = options\n\n // --- Generate a random name.\n const rand = random()\n const name = extension ? `${rand}.${extension}` : rand\n const path = join(directory, name)\n\n // --- Write the content to the file.\n await mkdir(directory, { recursive: true })\n await writeFile(path, content ?? '')\n\n // --- Return the path and a function to remove the file.\n const remove = () => rm(path, { force: true })\n return [path, remove] as const\n}\n\n/* v8 ignore start */\nif (import.meta.vitest) {\n const { existsSync, readFileSync, statSync } = await import('node:fs')\n\n test('should create an empty temporary file in \"/tmp/<random>\"', async() => {\n const [path] = await createTemporaryFile()\n const isFile = statSync(path).isFile()\n const content = readFileSync(path, 'utf8')\n expect(path).toMatch(/^\\/tmp\\/[\\da-z]+$/)\n expect (isFile).toBeTruthy()\n expect(content).toBe('')\n })\n\n test('should create a temporary file with the specified content', async() => {\n const [path] = await createTemporaryFile('Hello, world!')\n const content = readFileSync(path, 'utf8')\n expect(content).toBe('Hello, world!')\n })\n\n test('should create a temporary file in the specified directory', async() => {\n const [path] = await createTemporaryFile(undefined, { directory: '/cache' })\n expect(path).toMatch(/^\\/cache\\/[\\da-z]+$/)\n })\n\n test('should recursively create the specified directory', async() => {\n const [path] = await createTemporaryFile(undefined, { directory: '/tmp/foo/bar' })\n expect(path).toMatch(/^\\/tmp\\/foo\\/bar\\/[\\da-z]+$/)\n })\n\n test('should create a temporary file with the specified extension', async() => {\n const [path] = await createTemporaryFile(undefined, { extension: 'txt' })\n expect(path).toMatch(/^\\/tmp\\/[\\da-z]+\\.txt$/)\n })\n\n test('should create a temporary file with the given random function', async() => {\n const [path] = await createTemporaryFile(undefined, { random: () => 'foo' })\n expect(path).toMatch(/^\\/tmp\\/foo$/)\n })\n\n test('should remove the temporary file after calling the remove function', async() => {\n const [path, remove] = await createTemporaryFile()\n await remove()\n const exists = existsSync(path)\n expect(exists).toBeFalsy()\n })\n}\n"],"names":["tmpdir","join","mkdir","writeFile","rm"],"mappings":";;AA4CA,eAAsB,oBAAoB,SAA2C,UAAsC,IAAI;AACvH,QAAA;AAAA,IACJ,YAAYA,QAAAA,OAAO;AAAA,IACnB;AAAA,IACA,SAAS,MAAM,KAAK,SAAS,SAAS,EAAE,EAAE,MAAM,CAAC;AAAA,EAAA,IAC/C,SAGE,OAAO,OAAO,GACd,OAAO,YAAY,GAAG,IAAI,IAAI,SAAS,KAAK,MAC5C,OAAOC,UAAAA,KAAK,WAAW,IAAI;AAG3B,SAAA,MAAAC,SAAAA,MAAM,WAAW,EAAE,WAAW,IAAM,GAC1C,MAAMC,SAAA,UAAU,MAAM,WAAW,EAAE,GAI5B,CAAC,MADO,MAAMC,YAAG,MAAM,EAAE,OAAO,GAAM,CAAA,CACzB;AACtB;;"}
|
@@ -0,0 +1,44 @@
|
|
1
|
+
import { writeFile } from 'node:fs/promises';
|
2
|
+
|
3
|
+
interface CreateTemporaryFileOptions {
|
4
|
+
/**
|
5
|
+
* The directory to create the temporary file in.
|
6
|
+
* Defaults to the system's temporary directory.
|
7
|
+
*
|
8
|
+
* @default tmpdir()
|
9
|
+
*/
|
10
|
+
directory?: string;
|
11
|
+
/**
|
12
|
+
* The file extension to use for the temporary file.
|
13
|
+
*
|
14
|
+
* @default ''
|
15
|
+
*/
|
16
|
+
extension?: string;
|
17
|
+
/**
|
18
|
+
* A function that generates a random string.
|
19
|
+
*
|
20
|
+
* @default () => Math.random().toString(36).slice(2)
|
21
|
+
*/
|
22
|
+
random?: () => string;
|
23
|
+
}
|
24
|
+
/**
|
25
|
+
* Create a temporary file with a random name and return
|
26
|
+
* an object containing the file path, and a function to
|
27
|
+
* remove the file.
|
28
|
+
*
|
29
|
+
* @param content The content to write to the temporary file.
|
30
|
+
* @param options The options to create the temporary file.
|
31
|
+
* @returns A promise that resolves to the temporary file object.
|
32
|
+
* @example
|
33
|
+
* // Create a temporary file with the specified content.
|
34
|
+
* const [path, remove] = await createTemporaryFile('Hello, world!')
|
35
|
+
*
|
36
|
+
* // Do something with the file.
|
37
|
+
* exec(`openssl sha1 ${path}`)
|
38
|
+
*
|
39
|
+
* // Remove the file.
|
40
|
+
* await remove()
|
41
|
+
*/
|
42
|
+
declare function createTemporaryFile(content?: Parameters<typeof writeFile>[1], options?: CreateTemporaryFileOptions): Promise<readonly [string, () => Promise<void>]>;
|
43
|
+
|
44
|
+
export { type CreateTemporaryFileOptions, createTemporaryFile };
|
@@ -0,0 +1,15 @@
|
|
1
|
+
import { join } from "node:path";
|
2
|
+
import { tmpdir } from "node:os";
|
3
|
+
import { mkdir, writeFile, rm } from "node:fs/promises";
|
4
|
+
async function createTemporaryFile(content, options = {}) {
|
5
|
+
const {
|
6
|
+
directory = tmpdir(),
|
7
|
+
extension,
|
8
|
+
random = () => Math.random().toString(36).slice(2)
|
9
|
+
} = options, rand = random(), name = extension ? `${rand}.${extension}` : rand, path = join(directory, name);
|
10
|
+
return await mkdir(directory, { recursive: !0 }), await writeFile(path, content ?? ""), [path, () => rm(path, { force: !0 })];
|
11
|
+
}
|
12
|
+
export {
|
13
|
+
createTemporaryFile
|
14
|
+
};
|
15
|
+
//# sourceMappingURL=createTemporaryFile.js.map
|
@@ -0,0 +1 @@
|
|
1
|
+
{"version":3,"file":"createTemporaryFile.js","sources":["../createTemporaryFile.ts"],"sourcesContent":["import { join } from 'node:path'\nimport { tmpdir } from 'node:os'\nimport { mkdir, rm, writeFile } from 'node:fs/promises'\n\nexport interface CreateTemporaryFileOptions {\n /**\n * The directory to create the temporary file in.\n * Defaults to the system's temporary directory.\n *\n * @default tmpdir()\n */\n directory?: string\n /**\n * The file extension to use for the temporary file.\n *\n * @default ''\n */\n extension?: string\n /**\n * A function that generates a random string.\n *\n * @default () => Math.random().toString(36).slice(2)\n */\n random?: () => string\n}\n\n/**\n * Create a temporary file with a random name and return\n * an object containing the file path, and a function to\n * remove the file.\n *\n * @param content The content to write to the temporary file.\n * @param options The options to create the temporary file.\n * @returns A promise that resolves to the temporary file object.\n * @example\n * // Create a temporary file with the specified content.\n * const [path, remove] = await createTemporaryFile('Hello, world!')\n *\n * // Do something with the file.\n * exec(`openssl sha1 ${path}`)\n *\n * // Remove the file.\n * await remove()\n */\nexport async function createTemporaryFile(content?: Parameters<typeof writeFile>[1], options: CreateTemporaryFileOptions = {}) {\n const {\n directory = tmpdir(),\n extension,\n random = () => Math.random().toString(36).slice(2),\n } = options\n\n // --- Generate a random name.\n const rand = random()\n const name = extension ? `${rand}.${extension}` : rand\n const path = join(directory, name)\n\n // --- Write the content to the file.\n await mkdir(directory, { recursive: true })\n await writeFile(path, content ?? '')\n\n // --- Return the path and a function to remove the file.\n const remove = () => rm(path, { force: true })\n return [path, remove] as const\n}\n\n/* v8 ignore start */\nif (import.meta.vitest) {\n const { existsSync, readFileSync, statSync } = await import('node:fs')\n\n test('should create an empty temporary file in \"/tmp/<random>\"', async() => {\n const [path] = await createTemporaryFile()\n const isFile = statSync(path).isFile()\n const content = readFileSync(path, 'utf8')\n expect(path).toMatch(/^\\/tmp\\/[\\da-z]+$/)\n expect (isFile).toBeTruthy()\n expect(content).toBe('')\n })\n\n test('should create a temporary file with the specified content', async() => {\n const [path] = await createTemporaryFile('Hello, world!')\n const content = readFileSync(path, 'utf8')\n expect(content).toBe('Hello, world!')\n })\n\n test('should create a temporary file in the specified directory', async() => {\n const [path] = await createTemporaryFile(undefined, { directory: '/cache' })\n expect(path).toMatch(/^\\/cache\\/[\\da-z]+$/)\n })\n\n test('should recursively create the specified directory', async() => {\n const [path] = await createTemporaryFile(undefined, { directory: '/tmp/foo/bar' })\n expect(path).toMatch(/^\\/tmp\\/foo\\/bar\\/[\\da-z]+$/)\n })\n\n test('should create a temporary file with the specified extension', async() => {\n const [path] = await createTemporaryFile(undefined, { extension: 'txt' })\n expect(path).toMatch(/^\\/tmp\\/[\\da-z]+\\.txt$/)\n })\n\n test('should create a temporary file with the given random function', async() => {\n const [path] = await createTemporaryFile(undefined, { random: () => 'foo' })\n expect(path).toMatch(/^\\/tmp\\/foo$/)\n })\n\n test('should remove the temporary file after calling the remove function', async() => {\n const [path, remove] = await createTemporaryFile()\n await remove()\n const exists = existsSync(path)\n expect(exists).toBeFalsy()\n })\n}\n"],"names":[],"mappings":";;;AA4CA,eAAsB,oBAAoB,SAA2C,UAAsC,IAAI;AACvH,QAAA;AAAA,IACJ,YAAY,OAAO;AAAA,IACnB;AAAA,IACA,SAAS,MAAM,KAAK,SAAS,SAAS,EAAE,EAAE,MAAM,CAAC;AAAA,EAAA,IAC/C,SAGE,OAAO,OAAO,GACd,OAAO,YAAY,GAAG,IAAI,IAAI,SAAS,KAAK,MAC5C,OAAO,KAAK,WAAW,IAAI;AAG3B,SAAA,MAAA,MAAM,WAAW,EAAE,WAAW,IAAM,GAC1C,MAAM,UAAU,MAAM,WAAW,EAAE,GAI5B,CAAC,MADO,MAAM,GAAG,MAAM,EAAE,OAAO,GAAM,CAAA,CACzB;AACtB;"}
|
@@ -0,0 +1,16 @@
|
|
1
|
+
"use strict";
|
2
|
+
var node_process = require("node:process"), node_path = require("node:path"), promises = require("node:fs/promises");
|
3
|
+
async function findAncestor(name, from = node_process.cwd()) {
|
4
|
+
for (; from !== ""; ) {
|
5
|
+
const absolutePath = node_path.resolve(from, name);
|
6
|
+
try {
|
7
|
+
return await promises.access(absolutePath, promises.constants.F_OK), absolutePath;
|
8
|
+
} catch {
|
9
|
+
}
|
10
|
+
if (from === "/")
|
11
|
+
break;
|
12
|
+
from = node_path.dirname(from);
|
13
|
+
}
|
14
|
+
}
|
15
|
+
exports.findAncestor = findAncestor;
|
16
|
+
//# sourceMappingURL=findAncestor.cjs.map
|
@@ -0,0 +1 @@
|
|
1
|
+
{"version":3,"file":"findAncestor.cjs","sources":["../findAncestor.ts"],"sourcesContent":["import { cwd } from 'node:process'\nimport { dirname, resolve } from 'node:path'\nimport { access, constants } from 'node:fs/promises'\n\n/**\n * Find the first ancestor of a file from a given path. The search will start\n * from the given path and will continue until the root directory is reached.\n * If the file is not found, will throw an error.\n *\n * @param name The file name to find.\n * @param from The path to start from.\n * @returns The absolute path of the file found.\n * @example\n * // Create a file in the root directory.\n * await writeFile('/home/user/file.txt', 'Hello, world!')\n *\n * // Find the file from a subdirectory.\n * await findAncestor('file.txt', '/home/user/project') // '/home/user/file.txt'\n */\nexport async function findAncestor(name: string, from: string = cwd()): Promise<string | undefined> {\n while (from !== '') {\n const absolutePath = resolve(from, name)\n try {\n await access(absolutePath, constants.F_OK)\n return absolutePath\n }\n catch {\n /** Ignore error. */\n }\n if (from === '/') break\n from = dirname(from)\n }\n}\n\n/* v8 ignore start */\nif (import.meta.vitest) {\n const { vol } = await import('memfs')\n\n test('should resolve ancestor from current directory', async() => {\n vi.mock('node:process', () => ({ cwd: () => '/home/user/project' }))\n vol.fromJSON({ '/home/user/project/.npmrc': '' })\n const result = await findAncestor('.npmrc')\n expect(result).toBe('/home/user/project/.npmrc')\n })\n\n test('should resolve ancestor from given directory', async() => {\n vol.fromJSON({ '/home/user/.npmrc': '' })\n const result = await findAncestor('.npmrc', '/home/user/project')\n expect(result).toBe('/home/user/.npmrc')\n })\n\n test('should resolve ancestor at root directory', async() => {\n vol.fromJSON({ '/.npmrc': '' })\n const result = await findAncestor('.npmrc', '/home/user/project')\n expect(result).toBe('/.npmrc')\n })\n\n test('should resolve the first ancestor', async() => {\n vol.fromJSON({\n '/.npmrc': '',\n '/home/user/.npmrc': '',\n '/home/user/project/.npmrc': '',\n })\n const result = await findAncestor('.npmrc', '/home/user/project')\n expect(result).toBe('/home/user/project/.npmrc')\n })\n\n test('should return undefined if no ancestor was found', async() => {\n vol.fromJSON({})\n const result = await findAncestor('file', '/')\n expect(result).toBeUndefined()\n })\n}\n"],"names":["cwd","resolve","access","constants","dirname"],"mappings":";;AAmBA,eAAsB,aAAa,MAAc,OAAeA,aAAAA,OAAoC;AAClG,SAAO,SAAS,MAAI;AACZ,UAAA,eAAeC,UAAAA,QAAQ,MAAM,IAAI;AACnC,QAAA;AACF,aAAA,MAAMC,SAAO,OAAA,cAAcC,SAAU,UAAA,IAAI,GAClC;AAAA,IAAA,QAEH;AAAA,IAEN;AACA,QAAI,SAAS;AAAK;AAClB,WAAOC,UAAAA,QAAQ,IAAI;AAAA,EACrB;AACF;;"}
|
@@ -0,0 +1,18 @@
|
|
1
|
+
/**
|
2
|
+
* Find the first ancestor of a file from a given path. The search will start
|
3
|
+
* from the given path and will continue until the root directory is reached.
|
4
|
+
* If the file is not found, will throw an error.
|
5
|
+
*
|
6
|
+
* @param name The file name to find.
|
7
|
+
* @param from The path to start from.
|
8
|
+
* @returns The absolute path of the file found.
|
9
|
+
* @example
|
10
|
+
* // Create a file in the root directory.
|
11
|
+
* await writeFile('/home/user/file.txt', 'Hello, world!')
|
12
|
+
*
|
13
|
+
* // Find the file from a subdirectory.
|
14
|
+
* await findAncestor('file.txt', '/home/user/project') // '/home/user/file.txt'
|
15
|
+
*/
|
16
|
+
declare function findAncestor(name: string, from?: string): Promise<string | undefined>;
|
17
|
+
|
18
|
+
export { findAncestor };
|
@@ -0,0 +1,19 @@
|
|
1
|
+
import { cwd } from "node:process";
|
2
|
+
import { resolve, dirname } from "node:path";
|
3
|
+
import { access, constants } from "node:fs/promises";
|
4
|
+
async function findAncestor(name, from = cwd()) {
|
5
|
+
for (; from !== ""; ) {
|
6
|
+
const absolutePath = resolve(from, name);
|
7
|
+
try {
|
8
|
+
return await access(absolutePath, constants.F_OK), absolutePath;
|
9
|
+
} catch {
|
10
|
+
}
|
11
|
+
if (from === "/")
|
12
|
+
break;
|
13
|
+
from = dirname(from);
|
14
|
+
}
|
15
|
+
}
|
16
|
+
export {
|
17
|
+
findAncestor
|
18
|
+
};
|
19
|
+
//# sourceMappingURL=findAncestor.js.map
|
@@ -0,0 +1 @@
|
|
1
|
+
{"version":3,"file":"findAncestor.js","sources":["../findAncestor.ts"],"sourcesContent":["import { cwd } from 'node:process'\nimport { dirname, resolve } from 'node:path'\nimport { access, constants } from 'node:fs/promises'\n\n/**\n * Find the first ancestor of a file from a given path. The search will start\n * from the given path and will continue until the root directory is reached.\n * If the file is not found, will throw an error.\n *\n * @param name The file name to find.\n * @param from The path to start from.\n * @returns The absolute path of the file found.\n * @example\n * // Create a file in the root directory.\n * await writeFile('/home/user/file.txt', 'Hello, world!')\n *\n * // Find the file from a subdirectory.\n * await findAncestor('file.txt', '/home/user/project') // '/home/user/file.txt'\n */\nexport async function findAncestor(name: string, from: string = cwd()): Promise<string | undefined> {\n while (from !== '') {\n const absolutePath = resolve(from, name)\n try {\n await access(absolutePath, constants.F_OK)\n return absolutePath\n }\n catch {\n /** Ignore error. */\n }\n if (from === '/') break\n from = dirname(from)\n }\n}\n\n/* v8 ignore start */\nif (import.meta.vitest) {\n const { vol } = await import('memfs')\n\n test('should resolve ancestor from current directory', async() => {\n vi.mock('node:process', () => ({ cwd: () => '/home/user/project' }))\n vol.fromJSON({ '/home/user/project/.npmrc': '' })\n const result = await findAncestor('.npmrc')\n expect(result).toBe('/home/user/project/.npmrc')\n })\n\n test('should resolve ancestor from given directory', async() => {\n vol.fromJSON({ '/home/user/.npmrc': '' })\n const result = await findAncestor('.npmrc', '/home/user/project')\n expect(result).toBe('/home/user/.npmrc')\n })\n\n test('should resolve ancestor at root directory', async() => {\n vol.fromJSON({ '/.npmrc': '' })\n const result = await findAncestor('.npmrc', '/home/user/project')\n expect(result).toBe('/.npmrc')\n })\n\n test('should resolve the first ancestor', async() => {\n vol.fromJSON({\n '/.npmrc': '',\n '/home/user/.npmrc': '',\n '/home/user/project/.npmrc': '',\n })\n const result = await findAncestor('.npmrc', '/home/user/project')\n expect(result).toBe('/home/user/project/.npmrc')\n })\n\n test('should return undefined if no ancestor was found', async() => {\n vol.fromJSON({})\n const result = await findAncestor('file', '/')\n expect(result).toBeUndefined()\n })\n}\n"],"names":[],"mappings":";;;AAmBA,eAAsB,aAAa,MAAc,OAAe,OAAoC;AAClG,SAAO,SAAS,MAAI;AACZ,UAAA,eAAe,QAAQ,MAAM,IAAI;AACnC,QAAA;AACF,aAAA,MAAM,OAAO,cAAc,UAAU,IAAI,GAClC;AAAA,IAAA,QAEH;AAAA,IAEN;AACA,QAAI,SAAS;AAAK;AAClB,WAAO,QAAQ,IAAI;AAAA,EACrB;AACF;"}
|
@@ -0,0 +1,20 @@
|
|
1
|
+
"use strict";
|
2
|
+
var node_process = require("node:process"), node_path = require("node:path"), promises = require("node:fs/promises"), awaitable = require("@unshared/functions/awaitable");
|
3
|
+
function findAncestors(name, from = node_process.cwd()) {
|
4
|
+
async function* createIterator() {
|
5
|
+
for (; from !== ""; ) {
|
6
|
+
const absolutePath = node_path.resolve(from, name);
|
7
|
+
try {
|
8
|
+
await promises.access(absolutePath, promises.constants.F_OK), yield absolutePath;
|
9
|
+
} catch {
|
10
|
+
}
|
11
|
+
if (from === "/")
|
12
|
+
break;
|
13
|
+
from = node_path.dirname(from);
|
14
|
+
}
|
15
|
+
}
|
16
|
+
const iterator = createIterator();
|
17
|
+
return awaitable.awaitable(iterator);
|
18
|
+
}
|
19
|
+
exports.findAncestors = findAncestors;
|
20
|
+
//# sourceMappingURL=findAncestors.cjs.map
|
@@ -0,0 +1 @@
|
|
1
|
+
{"version":3,"file":"findAncestors.cjs","sources":["../findAncestors.ts"],"sourcesContent":["import { cwd } from 'node:process'\nimport { dirname, resolve } from 'node:path'\nimport { access, constants } from 'node:fs/promises'\nimport { Awaitable, awaitable } from '@unshared/functions/awaitable'\n\n/**\n * Find all ancestors of a file from a given path. The search will start\n * from the given path and will continue until the root directory is reached.\n * If the file is not found, an empty array will be returned.\n *\n * @param name The file name to find.\n * @param from The path to start from.\n * @returns An awaitable iterator of the absolute paths of the files found.\n * @example\n * // Get all ancestors as an array.\n * const ancestors = await findAncestors('file', '/home/user/project')\n *\n * // Or, iterate over the ancestors one by one.\n * const ancestors = findAncestors('file', '/home/user/project')\n * for await (const ancestor of ancestors) console.log(ancestor)\n */\nexport function findAncestors(name: string, from: string = cwd()): Awaitable<AsyncIterable<string>, string[]> {\n async function *createIterator() {\n while (from !== '') {\n const absolutePath = resolve(from, name)\n try {\n await access(absolutePath, constants.F_OK)\n yield absolutePath\n }\n catch {\n /** Ignore error. */\n }\n if (from === '/') break\n from = dirname(from)\n }\n }\n\n // --- Instantiate the iterator and wrap it in an awaitable.\n const iterator = createIterator()\n return awaitable(iterator)\n}\n\n/** v8 ignore start */\nif (import.meta.vitest) {\n const { vol } = await import('memfs')\n\n test('should resolve ancestors from current directory', async() => {\n vi.mock('node:process', () => ({ cwd: () => '/home/user/project' }))\n vol.fromJSON({\n '/file': '',\n '/home/file': '',\n '/home/user/file': '',\n '/home/user/project/file': '',\n })\n const result = await findAncestors('file')\n expect(result).toStrictEqual([\n '/home/user/project/file',\n '/home/user/file',\n '/home/file',\n '/file',\n ])\n })\n\n test('should resolve ancestors at from given directory', async() => {\n vol.fromJSON({\n '/file': '',\n '/home/file': '',\n '/home/user/file': '',\n '/home/user/project/file': '',\n })\n const result = await findAncestors('file', '/home/user/project')\n expect(result).toStrictEqual([\n '/home/user/project/file',\n '/home/user/file',\n '/home/file',\n '/file',\n ])\n })\n\n test('should be iterable', async() => {\n vol.fromJSON({\n '/file': '',\n '/home/file': '',\n '/home/user/file': '',\n '/home/user/project/file': '',\n })\n const result = findAncestors('file', '/home/user/project')\n const items = []\n for await (const item of result) items.push(item)\n expect(items).toStrictEqual([\n '/home/user/project/file',\n '/home/user/file',\n '/home/file',\n '/file',\n ])\n })\n\n test('should return empty array if no ancestors were found', async() => {\n const result = await findAncestors('filename')\n expect(result).toStrictEqual([])\n })\n}\n"],"names":["cwd","resolve","access","constants","dirname","awaitable"],"mappings":";;AAqBO,SAAS,cAAc,MAAc,OAAeA,aAAAA,OAAmD;AAC5G,kBAAgB,iBAAiB;AAC/B,WAAO,SAAS,MAAI;AACZ,YAAA,eAAeC,UAAAA,QAAQ,MAAM,IAAI;AACnC,UAAA;AACF,cAAMC,SAAAA,OAAO,cAAcC,SAAAA,UAAU,IAAI,GACzC,MAAM;AAAA,MAAA,QAEF;AAAA,MAEN;AACA,UAAI,SAAS;AAAK;AAClB,aAAOC,UAAAA,QAAQ,IAAI;AAAA,IACrB;AAAA,EACF;AAGA,QAAM,WAAW;AACjB,SAAOC,UAAAA,UAAU,QAAQ;AAC3B;;"}
|
@@ -0,0 +1,21 @@
|
|
1
|
+
import { Awaitable } from '@unshared/functions/awaitable';
|
2
|
+
|
3
|
+
/**
|
4
|
+
* Find all ancestors of a file from a given path. The search will start
|
5
|
+
* from the given path and will continue until the root directory is reached.
|
6
|
+
* If the file is not found, an empty array will be returned.
|
7
|
+
*
|
8
|
+
* @param name The file name to find.
|
9
|
+
* @param from The path to start from.
|
10
|
+
* @returns An awaitable iterator of the absolute paths of the files found.
|
11
|
+
* @example
|
12
|
+
* // Get all ancestors as an array.
|
13
|
+
* const ancestors = await findAncestors('file', '/home/user/project')
|
14
|
+
*
|
15
|
+
* // Or, iterate over the ancestors one by one.
|
16
|
+
* const ancestors = findAncestors('file', '/home/user/project')
|
17
|
+
* for await (const ancestor of ancestors) console.log(ancestor)
|
18
|
+
*/
|
19
|
+
declare function findAncestors(name: string, from?: string): Awaitable<AsyncIterable<string>, string[]>;
|
20
|
+
|
21
|
+
export { findAncestors };
|
@@ -0,0 +1,24 @@
|
|
1
|
+
import { cwd } from "node:process";
|
2
|
+
import { resolve, dirname } from "node:path";
|
3
|
+
import { access, constants } from "node:fs/promises";
|
4
|
+
import { awaitable } from "@unshared/functions/awaitable";
|
5
|
+
function findAncestors(name, from = cwd()) {
|
6
|
+
async function* createIterator() {
|
7
|
+
for (; from !== ""; ) {
|
8
|
+
const absolutePath = resolve(from, name);
|
9
|
+
try {
|
10
|
+
await access(absolutePath, constants.F_OK), yield absolutePath;
|
11
|
+
} catch {
|
12
|
+
}
|
13
|
+
if (from === "/")
|
14
|
+
break;
|
15
|
+
from = dirname(from);
|
16
|
+
}
|
17
|
+
}
|
18
|
+
const iterator = createIterator();
|
19
|
+
return awaitable(iterator);
|
20
|
+
}
|
21
|
+
export {
|
22
|
+
findAncestors
|
23
|
+
};
|
24
|
+
//# sourceMappingURL=findAncestors.js.map
|
@@ -0,0 +1 @@
|
|
1
|
+
{"version":3,"file":"findAncestors.js","sources":["../findAncestors.ts"],"sourcesContent":["import { cwd } from 'node:process'\nimport { dirname, resolve } from 'node:path'\nimport { access, constants } from 'node:fs/promises'\nimport { Awaitable, awaitable } from '@unshared/functions/awaitable'\n\n/**\n * Find all ancestors of a file from a given path. The search will start\n * from the given path and will continue until the root directory is reached.\n * If the file is not found, an empty array will be returned.\n *\n * @param name The file name to find.\n * @param from The path to start from.\n * @returns An awaitable iterator of the absolute paths of the files found.\n * @example\n * // Get all ancestors as an array.\n * const ancestors = await findAncestors('file', '/home/user/project')\n *\n * // Or, iterate over the ancestors one by one.\n * const ancestors = findAncestors('file', '/home/user/project')\n * for await (const ancestor of ancestors) console.log(ancestor)\n */\nexport function findAncestors(name: string, from: string = cwd()): Awaitable<AsyncIterable<string>, string[]> {\n async function *createIterator() {\n while (from !== '') {\n const absolutePath = resolve(from, name)\n try {\n await access(absolutePath, constants.F_OK)\n yield absolutePath\n }\n catch {\n /** Ignore error. */\n }\n if (from === '/') break\n from = dirname(from)\n }\n }\n\n // --- Instantiate the iterator and wrap it in an awaitable.\n const iterator = createIterator()\n return awaitable(iterator)\n}\n\n/** v8 ignore start */\nif (import.meta.vitest) {\n const { vol } = await import('memfs')\n\n test('should resolve ancestors from current directory', async() => {\n vi.mock('node:process', () => ({ cwd: () => '/home/user/project' }))\n vol.fromJSON({\n '/file': '',\n '/home/file': '',\n '/home/user/file': '',\n '/home/user/project/file': '',\n })\n const result = await findAncestors('file')\n expect(result).toStrictEqual([\n '/home/user/project/file',\n '/home/user/file',\n '/home/file',\n '/file',\n ])\n })\n\n test('should resolve ancestors at from given directory', async() => {\n vol.fromJSON({\n '/file': '',\n '/home/file': '',\n '/home/user/file': '',\n '/home/user/project/file': '',\n })\n const result = await findAncestors('file', '/home/user/project')\n expect(result).toStrictEqual([\n '/home/user/project/file',\n '/home/user/file',\n '/home/file',\n '/file',\n ])\n })\n\n test('should be iterable', async() => {\n vol.fromJSON({\n '/file': '',\n '/home/file': '',\n '/home/user/file': '',\n '/home/user/project/file': '',\n })\n const result = findAncestors('file', '/home/user/project')\n const items = []\n for await (const item of result) items.push(item)\n expect(items).toStrictEqual([\n '/home/user/project/file',\n '/home/user/file',\n '/home/file',\n '/file',\n ])\n })\n\n test('should return empty array if no ancestors were found', async() => {\n const result = await findAncestors('filename')\n expect(result).toStrictEqual([])\n })\n}\n"],"names":[],"mappings":";;;;AAqBO,SAAS,cAAc,MAAc,OAAe,OAAmD;AAC5G,kBAAgB,iBAAiB;AAC/B,WAAO,SAAS,MAAI;AACZ,YAAA,eAAe,QAAQ,MAAM,IAAI;AACnC,UAAA;AACF,cAAM,OAAO,cAAc,UAAU,IAAI,GACzC,MAAM;AAAA,MAAA,QAEF;AAAA,MAEN;AACA,UAAI,SAAS;AAAK;AAClB,aAAO,QAAQ,IAAI;AAAA,IACrB;AAAA,EACF;AAGA,QAAM,WAAW;AACjB,SAAO,UAAU,QAAQ;AAC3B;"}
|
package/dist/glob.cjs
ADDED
@@ -0,0 +1,28 @@
|
|
1
|
+
"use strict";
|
2
|
+
var node_process = require("node:process"), node_path = require("node:path"), promises = require("node:fs/promises"), createPattern = require("@unshared/string/createPattern"), awaitable = require("@unshared/functions/awaitable");
|
3
|
+
function glob(pattern, options = {}) {
|
4
|
+
const {
|
5
|
+
cwd = node_process.cwd(),
|
6
|
+
exclude = [],
|
7
|
+
getRelative = !1,
|
8
|
+
getStats = !1,
|
9
|
+
onlyDirectories = !1,
|
10
|
+
onlyFiles = !1
|
11
|
+
} = options, patterns = (Array.isArray(pattern) ? pattern : [pattern]).map(createPattern.createPattern), excludePatterns = (Array.isArray(exclude) ? exclude : [exclude]).map(createPattern.createPattern), searchPool = [cwd];
|
12
|
+
async function* createIterator() {
|
13
|
+
for (; searchPool.length > 0; ) {
|
14
|
+
const directory = searchPool.pop(), entities = await promises.readdir(directory, { withFileTypes: !0 }).catch(() => []);
|
15
|
+
for (const entity of entities) {
|
16
|
+
const pathAbsolute = node_path.join(directory, entity.name), pathRelative = node_path.relative(cwd, pathAbsolute), isFile = entity.isFile(), isDirectory = entity.isDirectory();
|
17
|
+
if (isDirectory && searchPool.push(pathAbsolute), onlyFiles && !isFile || onlyDirectories && !isDirectory || !patterns.some((pattern2) => pattern2.test(pathRelative)) || excludePatterns.some((pattern2) => pattern2.test(pathRelative)))
|
18
|
+
continue;
|
19
|
+
let result = pathAbsolute;
|
20
|
+
getStats && (result = await promises.stat(pathAbsolute)), getRelative && (result = `./${pathRelative}`), yield result;
|
21
|
+
}
|
22
|
+
}
|
23
|
+
}
|
24
|
+
const iterator = createIterator();
|
25
|
+
return awaitable.awaitable(iterator);
|
26
|
+
}
|
27
|
+
exports.glob = glob;
|
28
|
+
//# sourceMappingURL=glob.cjs.map
|
@@ -0,0 +1 @@
|
|
1
|
+
{"version":3,"file":"glob.cjs","sources":["../glob.ts"],"sourcesContent":["import { cwd as getCwd } from 'node:process'\nimport { join, relative } from 'node:path'\nimport { readdir, stat } from 'node:fs/promises'\nimport { Stats } from 'node:fs'\nimport { MaybeArray } from '@unshared/types'\nimport { createPattern } from '@unshared/string/createPattern'\nimport { Awaitable, awaitable } from '@unshared/functions/awaitable'\n\n/**\n * An entry in the glob result iterator or array.\n */\nexport type GlobEntry = Stats | string\n\n/**\n * The result of a glob operation. If `Stat` is `true` the result will be an\n * array of file stats. Otherwise the result will be an array of file paths.\n */\nexport type GlobResult<T extends boolean = boolean> = T extends true\n ? Awaitable<AsyncIterable<Stats>, Stats[]>\n : Awaitable<AsyncIterable<string>, string[]>\n\nexport interface GlobOptions<Stat extends boolean = boolean> {\n /**\n * The current working directory. Used to determine the base path for the glob\n * pattern.\n *\n * @default process.cwd()\n */\n cwd?: string\n /**\n * A list of patterns to exclude from the result.\n *\n * @default []\n */\n exclude?: MaybeArray<string>\n /**\n * Return the paths relative to the current working directory. Will be ignored\n * if `stats` is `true`.\n *\n * @default false\n */\n getRelative?: boolean\n /**\n * Return the file stats instead of the file path. Allowing you to filter-out\n * files based on their stats.\n *\n * @default false\n */\n getStats?: Stat\n /**\n * If `true` and the glob pattern will only match directories.\n *\n * @default false\n * @example glob('src/**', { onlyDirectories: true }) // ['src/foo', 'src/foo/bar']\n */\n onlyDirectories?: boolean\n /**\n * Only return entries that matches the path of a file.\n *\n * @default false\n * @example glob('src/**', { onlyFiles: true }) // ['src/foo.ts', 'src/foo/bar.ts']\n */\n onlyFiles?: boolean\n}\n\n/**\n * Find files matching a glob pattern.\n *\n * @param pattern The glob pattern.\n * @param options The glob options.\n * @returns An awaitable asyncronous iterator of file paths.\n * @example\n * const files = glob('src/*.ts')\n * for await (const file of files) { ... }\n */\nexport function glob(pattern: MaybeArray<string>, options?: GlobOptions<false>): GlobResult<false>\nexport function glob(pattern: MaybeArray<string>, options?: GlobOptions<true>): GlobResult<true>\nexport function glob<T extends boolean>(pattern: MaybeArray<string>, options?: GlobOptions<T>): GlobResult<T>\nexport function glob(pattern: MaybeArray<string>, options: GlobOptions = {}): GlobResult {\n const {\n cwd = getCwd(),\n exclude = [],\n getRelative = false,\n getStats = false,\n onlyDirectories = false,\n onlyFiles = false,\n } = options\n\n // --- Convert the pattern to an array of RegExp.\n const patternArray = Array.isArray(pattern) ? pattern : [pattern]\n const patterns = patternArray.map(createPattern)\n const exludeArray = Array.isArray(exclude) ? exclude : [exclude]\n const excludePatterns = exludeArray.map(createPattern)\n\n // --- Create an iterator that will yield the matching paths.\n const searchPool: string[] = [cwd]\n async function* createIterator() {\n while (searchPool.length > 0) {\n const directory = searchPool.pop()!\n const entities = await readdir(directory, { withFileTypes: true }).catch(() => [])\n\n for (const entity of entities) {\n const pathAbsolute = join(directory, entity.name)\n const pathRelative = relative(cwd, pathAbsolute)\n const isFile = entity.isFile()\n const isDirectory = entity.isDirectory()\n\n // --- Add the directory to the list of directories to check.\n if (isDirectory) searchPool.push(pathAbsolute)\n\n // --- Filter-out the non-matching entries.\n if (onlyFiles && !isFile) continue\n if (onlyDirectories && !isDirectory) continue\n\n // --- Check if the path matches the pattern(s).\n const isMatch = patterns.some(pattern => pattern.test(pathRelative))\n if (!isMatch) continue\n\n // --- Check if the path matches the exclude pattern(s).\n const isExcluded = excludePatterns.some(pattern => pattern.test(pathRelative))\n if (isExcluded) continue\n\n // --- Return the result.\n let result: GlobEntry = pathAbsolute\n if (getStats) result = await stat(pathAbsolute)\n if (getRelative) result = `./${pathRelative}`\n yield result\n }\n }\n }\n\n // --- Instantiate the iterator.\n const iterator = createIterator()\n\n // --- Return the iterator or the result as an array.\n return awaitable(iterator) as GlobResult\n}\n\n/* v8 ignore next */\nif (import.meta.vitest) {\n const { vol } = await import('memfs')\n\n beforeEach(() => {\n vol.fromJSON({\n '/project/bar.ts': '',\n '/project/baz.ts': '',\n '/project/dist/bar.js': '',\n '/project/dist/baz.js': '',\n '/project/dist/docs/CHANGELOG.md': '',\n '/project/dist/docs/README.md': '',\n '/project/dist/foo.js': '',\n '/project/foo.ts': '',\n '/project/README.md': '',\n })\n })\n\n test('should yield the paths matching a glob pattern', async() => {\n const files = glob('*.ts', { cwd: '/project' })\n const result = []\n for await (const file of files) result.push(file)\n expect(result).toStrictEqual([\n '/project/bar.ts',\n '/project/baz.ts',\n '/project/foo.ts',\n ])\n })\n\n test('should find the absolute path matching a glob pattern', async() => {\n const files = await glob('*.ts', { cwd: '/project' })\n expect(files).toStrictEqual([\n '/project/bar.ts',\n '/project/baz.ts',\n '/project/foo.ts',\n ])\n })\n\n test('should find the relative path matching a glob pattern', async() => {\n const files = await glob('*.ts', { cwd: '/project', getRelative: true })\n expect(files).toStrictEqual([\n './bar.ts',\n './baz.ts',\n './foo.ts',\n ])\n })\n\n test('should find the stats matching a glob pattern', async() => {\n const files = await glob('*.ts', { cwd: '/project', getStats: true })\n const expected = [\n vol.statSync('/project/foo.ts'),\n vol.statSync('/project/bar.ts'),\n vol.statSync('/project/baz.ts'),\n ]\n expect(files.map(x => x.uid)).toStrictEqual(expected.map(x => x.uid))\n })\n\n test('should find the paths matching an exclude pattern', async() => {\n const files = await glob('*.ts', { cwd: '/project', exclude: 'baz.ts' })\n const expected = [\n '/project/bar.ts',\n '/project/foo.ts',\n ]\n expect(files).toStrictEqual(expected)\n })\n\n test('should find nested and non-nested files', async() => {\n const files = await glob('**/*', { cwd: '/project', onlyFiles: true })\n expect(files).toStrictEqual([\n '/project/README.md',\n '/project/bar.ts',\n '/project/baz.ts',\n '/project/foo.ts',\n '/project/dist/bar.js',\n '/project/dist/baz.js',\n '/project/dist/foo.js',\n '/project/dist/docs/CHANGELOG.md',\n '/project/dist/docs/README.md',\n ])\n })\n\n test('should find nested and non-nested directories', async() => {\n const files = await glob('**/*', { cwd: '/project', onlyDirectories: true })\n expect(files).toStrictEqual([\n '/project/dist',\n '/project/dist/docs',\n ])\n })\n\n test('should find files but exclude the dist directory', async() => {\n const files = await glob('*', { cwd: '/project', exclude: 'dist/**' })\n expect(files).toStrictEqual([\n '/project/README.md',\n '/project/bar.ts',\n '/project/baz.ts',\n '/project/foo.ts',\n ])\n })\n\n test('should infer the return type as a collection of `Stats`', () => {\n const files = glob('*.ts', { cwd: '/project', getStats: true })\n expectTypeOf(files).toEqualTypeOf<Awaitable<AsyncIterable<Stats>, Stats[]>>()\n })\n\n test('should infer the return type as a collection of `string`', () => {\n const files = glob('*.ts', { cwd: '/project', getStats: false })\n expectTypeOf(files).toEqualTypeOf<Awaitable<AsyncIterable<string>, string[]>>()\n })\n\n test('should infer the return type as a collection of `Stats` or `string`', () => {\n const files = glob('*.ts', { cwd: '/project', getStats: true as boolean })\n expectTypeOf(files).toEqualTypeOf<Awaitable<AsyncIterable<Stats>, Stats[]> | Awaitable<AsyncIterable<string>, string[]>>()\n })\n}\n"],"names":["getCwd","createPattern","readdir","join","relative","pattern","stat","awaitable"],"mappings":";;AA8EO,SAAS,KAAK,SAA6B,UAAuB,IAAgB;AACjF,QAAA;AAAA,IACJ,MAAMA,aAAAA,IAAO;AAAA,IACb,UAAU,CAAC;AAAA,IACX,cAAc;AAAA,IACd,WAAW;AAAA,IACX,kBAAkB;AAAA,IAClB,YAAY;AAAA,EACV,IAAA,SAIE,YADe,MAAM,QAAQ,OAAO,IAAI,UAAU,CAAC,OAAO,GAClC,IAAIC,cAAa,aAAA,GAEzC,mBADc,MAAM,QAAQ,OAAO,IAAI,UAAU,CAAC,OAAO,GAC3B,IAAIA,cAAAA,aAAa,GAG/C,aAAuB,CAAC,GAAG;AACjC,kBAAgB,iBAAiB;AACxB,WAAA,WAAW,SAAS,KAAG;AAC5B,YAAM,YAAY,WAAW,IACvB,GAAA,WAAW,MAAMC,SAAAA,QAAQ,WAAW,EAAE,eAAe,GAAM,CAAA,EAAE,MAAM,MAAM,CAAE,CAAA;AAEjF,iBAAW,UAAU,UAAU;AAC7B,cAAM,eAAeC,UAAAA,KAAK,WAAW,OAAO,IAAI,GAC1C,eAAeC,mBAAS,KAAK,YAAY,GACzC,SAAS,OAAO,OAChB,GAAA,cAAc,OAAO;AAe3B,YAZI,eAAa,WAAW,KAAK,YAAY,GAGzC,aAAa,CAAC,UACd,mBAAmB,CAAC,eAIpB,CADY,SAAS,KAAK,CAAAC,aAAWA,SAAQ,KAAK,YAAY,CAAC,KAIhD,gBAAgB,KAAK,CAAAA,aAAWA,SAAQ,KAAK,YAAY,CAAC;AAC7D;AAGhB,YAAI,SAAoB;AACpB,qBAAU,SAAS,MAAMC,cAAK,YAAY,IAC1C,gBAAa,SAAS,KAAK,YAAY,KAC3C,MAAM;AAAA,MACR;AAAA,IACF;AAAA,EACF;AAGA,QAAM,WAAW;AAGjB,SAAOC,UAAAA,UAAU,QAAQ;AAC3B;;"}
|
package/dist/glob.d.ts
ADDED
@@ -0,0 +1,71 @@
|
|
1
|
+
import { Stats } from 'node:fs';
|
2
|
+
import { MaybeArray } from '@unshared/types';
|
3
|
+
import { Awaitable } from '@unshared/functions/awaitable';
|
4
|
+
|
5
|
+
/**
|
6
|
+
* An entry in the glob result iterator or array.
|
7
|
+
*/
|
8
|
+
type GlobEntry = Stats | string;
|
9
|
+
/**
|
10
|
+
* The result of a glob operation. If `Stat` is `true` the result will be an
|
11
|
+
* array of file stats. Otherwise the result will be an array of file paths.
|
12
|
+
*/
|
13
|
+
type GlobResult<T extends boolean = boolean> = T extends true ? Awaitable<AsyncIterable<Stats>, Stats[]> : Awaitable<AsyncIterable<string>, string[]>;
|
14
|
+
interface GlobOptions<Stat extends boolean = boolean> {
|
15
|
+
/**
|
16
|
+
* The current working directory. Used to determine the base path for the glob
|
17
|
+
* pattern.
|
18
|
+
*
|
19
|
+
* @default process.cwd()
|
20
|
+
*/
|
21
|
+
cwd?: string;
|
22
|
+
/**
|
23
|
+
* A list of patterns to exclude from the result.
|
24
|
+
*
|
25
|
+
* @default []
|
26
|
+
*/
|
27
|
+
exclude?: MaybeArray<string>;
|
28
|
+
/**
|
29
|
+
* Return the paths relative to the current working directory. Will be ignored
|
30
|
+
* if `stats` is `true`.
|
31
|
+
*
|
32
|
+
* @default false
|
33
|
+
*/
|
34
|
+
getRelative?: boolean;
|
35
|
+
/**
|
36
|
+
* Return the file stats instead of the file path. Allowing you to filter-out
|
37
|
+
* files based on their stats.
|
38
|
+
*
|
39
|
+
* @default false
|
40
|
+
*/
|
41
|
+
getStats?: Stat;
|
42
|
+
/**
|
43
|
+
* If `true` and the glob pattern will only match directories.
|
44
|
+
*
|
45
|
+
* @default false
|
46
|
+
* @example glob('src/**', { onlyDirectories: true }) // ['src/foo', 'src/foo/bar']
|
47
|
+
*/
|
48
|
+
onlyDirectories?: boolean;
|
49
|
+
/**
|
50
|
+
* Only return entries that matches the path of a file.
|
51
|
+
*
|
52
|
+
* @default false
|
53
|
+
* @example glob('src/**', { onlyFiles: true }) // ['src/foo.ts', 'src/foo/bar.ts']
|
54
|
+
*/
|
55
|
+
onlyFiles?: boolean;
|
56
|
+
}
|
57
|
+
/**
|
58
|
+
* Find files matching a glob pattern.
|
59
|
+
*
|
60
|
+
* @param pattern The glob pattern.
|
61
|
+
* @param options The glob options.
|
62
|
+
* @returns An awaitable asyncronous iterator of file paths.
|
63
|
+
* @example
|
64
|
+
* const files = glob('src/*.ts')
|
65
|
+
* for await (const file of files) { ... }
|
66
|
+
*/
|
67
|
+
declare function glob(pattern: MaybeArray<string>, options?: GlobOptions<false>): GlobResult<false>;
|
68
|
+
declare function glob(pattern: MaybeArray<string>, options?: GlobOptions<true>): GlobResult<true>;
|
69
|
+
declare function glob<T extends boolean>(pattern: MaybeArray<string>, options?: GlobOptions<T>): GlobResult<T>;
|
70
|
+
|
71
|
+
export { type GlobEntry, type GlobOptions, type GlobResult, glob };
|
package/dist/glob.js
ADDED
@@ -0,0 +1,33 @@
|
|
1
|
+
import { cwd } from "node:process";
|
2
|
+
import { join, relative } from "node:path";
|
3
|
+
import { readdir, stat } from "node:fs/promises";
|
4
|
+
import { createPattern } from "@unshared/string/createPattern";
|
5
|
+
import { awaitable } from "@unshared/functions/awaitable";
|
6
|
+
function glob(pattern, options = {}) {
|
7
|
+
const {
|
8
|
+
cwd: cwd$1 = cwd(),
|
9
|
+
exclude = [],
|
10
|
+
getRelative = !1,
|
11
|
+
getStats = !1,
|
12
|
+
onlyDirectories = !1,
|
13
|
+
onlyFiles = !1
|
14
|
+
} = options, patterns = (Array.isArray(pattern) ? pattern : [pattern]).map(createPattern), excludePatterns = (Array.isArray(exclude) ? exclude : [exclude]).map(createPattern), searchPool = [cwd$1];
|
15
|
+
async function* createIterator() {
|
16
|
+
for (; searchPool.length > 0; ) {
|
17
|
+
const directory = searchPool.pop(), entities = await readdir(directory, { withFileTypes: !0 }).catch(() => []);
|
18
|
+
for (const entity of entities) {
|
19
|
+
const pathAbsolute = join(directory, entity.name), pathRelative = relative(cwd$1, pathAbsolute), isFile = entity.isFile(), isDirectory = entity.isDirectory();
|
20
|
+
if (isDirectory && searchPool.push(pathAbsolute), onlyFiles && !isFile || onlyDirectories && !isDirectory || !patterns.some((pattern2) => pattern2.test(pathRelative)) || excludePatterns.some((pattern2) => pattern2.test(pathRelative)))
|
21
|
+
continue;
|
22
|
+
let result = pathAbsolute;
|
23
|
+
getStats && (result = await stat(pathAbsolute)), getRelative && (result = `./${pathRelative}`), yield result;
|
24
|
+
}
|
25
|
+
}
|
26
|
+
}
|
27
|
+
const iterator = createIterator();
|
28
|
+
return awaitable(iterator);
|
29
|
+
}
|
30
|
+
export {
|
31
|
+
glob
|
32
|
+
};
|
33
|
+
//# sourceMappingURL=glob.js.map
|
package/dist/glob.js.map
ADDED
@@ -0,0 +1 @@
|
|
1
|
+
{"version":3,"file":"glob.js","sources":["../glob.ts"],"sourcesContent":["import { cwd as getCwd } from 'node:process'\nimport { join, relative } from 'node:path'\nimport { readdir, stat } from 'node:fs/promises'\nimport { Stats } from 'node:fs'\nimport { MaybeArray } from '@unshared/types'\nimport { createPattern } from '@unshared/string/createPattern'\nimport { Awaitable, awaitable } from '@unshared/functions/awaitable'\n\n/**\n * An entry in the glob result iterator or array.\n */\nexport type GlobEntry = Stats | string\n\n/**\n * The result of a glob operation. If `Stat` is `true` the result will be an\n * array of file stats. Otherwise the result will be an array of file paths.\n */\nexport type GlobResult<T extends boolean = boolean> = T extends true\n ? Awaitable<AsyncIterable<Stats>, Stats[]>\n : Awaitable<AsyncIterable<string>, string[]>\n\nexport interface GlobOptions<Stat extends boolean = boolean> {\n /**\n * The current working directory. Used to determine the base path for the glob\n * pattern.\n *\n * @default process.cwd()\n */\n cwd?: string\n /**\n * A list of patterns to exclude from the result.\n *\n * @default []\n */\n exclude?: MaybeArray<string>\n /**\n * Return the paths relative to the current working directory. Will be ignored\n * if `stats` is `true`.\n *\n * @default false\n */\n getRelative?: boolean\n /**\n * Return the file stats instead of the file path. Allowing you to filter-out\n * files based on their stats.\n *\n * @default false\n */\n getStats?: Stat\n /**\n * If `true` and the glob pattern will only match directories.\n *\n * @default false\n * @example glob('src/**', { onlyDirectories: true }) // ['src/foo', 'src/foo/bar']\n */\n onlyDirectories?: boolean\n /**\n * Only return entries that matches the path of a file.\n *\n * @default false\n * @example glob('src/**', { onlyFiles: true }) // ['src/foo.ts', 'src/foo/bar.ts']\n */\n onlyFiles?: boolean\n}\n\n/**\n * Find files matching a glob pattern.\n *\n * @param pattern The glob pattern.\n * @param options The glob options.\n * @returns An awaitable asyncronous iterator of file paths.\n * @example\n * const files = glob('src/*.ts')\n * for await (const file of files) { ... }\n */\nexport function glob(pattern: MaybeArray<string>, options?: GlobOptions<false>): GlobResult<false>\nexport function glob(pattern: MaybeArray<string>, options?: GlobOptions<true>): GlobResult<true>\nexport function glob<T extends boolean>(pattern: MaybeArray<string>, options?: GlobOptions<T>): GlobResult<T>\nexport function glob(pattern: MaybeArray<string>, options: GlobOptions = {}): GlobResult {\n const {\n cwd = getCwd(),\n exclude = [],\n getRelative = false,\n getStats = false,\n onlyDirectories = false,\n onlyFiles = false,\n } = options\n\n // --- Convert the pattern to an array of RegExp.\n const patternArray = Array.isArray(pattern) ? pattern : [pattern]\n const patterns = patternArray.map(createPattern)\n const exludeArray = Array.isArray(exclude) ? exclude : [exclude]\n const excludePatterns = exludeArray.map(createPattern)\n\n // --- Create an iterator that will yield the matching paths.\n const searchPool: string[] = [cwd]\n async function* createIterator() {\n while (searchPool.length > 0) {\n const directory = searchPool.pop()!\n const entities = await readdir(directory, { withFileTypes: true }).catch(() => [])\n\n for (const entity of entities) {\n const pathAbsolute = join(directory, entity.name)\n const pathRelative = relative(cwd, pathAbsolute)\n const isFile = entity.isFile()\n const isDirectory = entity.isDirectory()\n\n // --- Add the directory to the list of directories to check.\n if (isDirectory) searchPool.push(pathAbsolute)\n\n // --- Filter-out the non-matching entries.\n if (onlyFiles && !isFile) continue\n if (onlyDirectories && !isDirectory) continue\n\n // --- Check if the path matches the pattern(s).\n const isMatch = patterns.some(pattern => pattern.test(pathRelative))\n if (!isMatch) continue\n\n // --- Check if the path matches the exclude pattern(s).\n const isExcluded = excludePatterns.some(pattern => pattern.test(pathRelative))\n if (isExcluded) continue\n\n // --- Return the result.\n let result: GlobEntry = pathAbsolute\n if (getStats) result = await stat(pathAbsolute)\n if (getRelative) result = `./${pathRelative}`\n yield result\n }\n }\n }\n\n // --- Instantiate the iterator.\n const iterator = createIterator()\n\n // --- Return the iterator or the result as an array.\n return awaitable(iterator) as GlobResult\n}\n\n/* v8 ignore next */\nif (import.meta.vitest) {\n const { vol } = await import('memfs')\n\n beforeEach(() => {\n vol.fromJSON({\n '/project/bar.ts': '',\n '/project/baz.ts': '',\n '/project/dist/bar.js': '',\n '/project/dist/baz.js': '',\n '/project/dist/docs/CHANGELOG.md': '',\n '/project/dist/docs/README.md': '',\n '/project/dist/foo.js': '',\n '/project/foo.ts': '',\n '/project/README.md': '',\n })\n })\n\n test('should yield the paths matching a glob pattern', async() => {\n const files = glob('*.ts', { cwd: '/project' })\n const result = []\n for await (const file of files) result.push(file)\n expect(result).toStrictEqual([\n '/project/bar.ts',\n '/project/baz.ts',\n '/project/foo.ts',\n ])\n })\n\n test('should find the absolute path matching a glob pattern', async() => {\n const files = await glob('*.ts', { cwd: '/project' })\n expect(files).toStrictEqual([\n '/project/bar.ts',\n '/project/baz.ts',\n '/project/foo.ts',\n ])\n })\n\n test('should find the relative path matching a glob pattern', async() => {\n const files = await glob('*.ts', { cwd: '/project', getRelative: true })\n expect(files).toStrictEqual([\n './bar.ts',\n './baz.ts',\n './foo.ts',\n ])\n })\n\n test('should find the stats matching a glob pattern', async() => {\n const files = await glob('*.ts', { cwd: '/project', getStats: true })\n const expected = [\n vol.statSync('/project/foo.ts'),\n vol.statSync('/project/bar.ts'),\n vol.statSync('/project/baz.ts'),\n ]\n expect(files.map(x => x.uid)).toStrictEqual(expected.map(x => x.uid))\n })\n\n test('should find the paths matching an exclude pattern', async() => {\n const files = await glob('*.ts', { cwd: '/project', exclude: 'baz.ts' })\n const expected = [\n '/project/bar.ts',\n '/project/foo.ts',\n ]\n expect(files).toStrictEqual(expected)\n })\n\n test('should find nested and non-nested files', async() => {\n const files = await glob('**/*', { cwd: '/project', onlyFiles: true })\n expect(files).toStrictEqual([\n '/project/README.md',\n '/project/bar.ts',\n '/project/baz.ts',\n '/project/foo.ts',\n '/project/dist/bar.js',\n '/project/dist/baz.js',\n '/project/dist/foo.js',\n '/project/dist/docs/CHANGELOG.md',\n '/project/dist/docs/README.md',\n ])\n })\n\n test('should find nested and non-nested directories', async() => {\n const files = await glob('**/*', { cwd: '/project', onlyDirectories: true })\n expect(files).toStrictEqual([\n '/project/dist',\n '/project/dist/docs',\n ])\n })\n\n test('should find files but exclude the dist directory', async() => {\n const files = await glob('*', { cwd: '/project', exclude: 'dist/**' })\n expect(files).toStrictEqual([\n '/project/README.md',\n '/project/bar.ts',\n '/project/baz.ts',\n '/project/foo.ts',\n ])\n })\n\n test('should infer the return type as a collection of `Stats`', () => {\n const files = glob('*.ts', { cwd: '/project', getStats: true })\n expectTypeOf(files).toEqualTypeOf<Awaitable<AsyncIterable<Stats>, Stats[]>>()\n })\n\n test('should infer the return type as a collection of `string`', () => {\n const files = glob('*.ts', { cwd: '/project', getStats: false })\n expectTypeOf(files).toEqualTypeOf<Awaitable<AsyncIterable<string>, string[]>>()\n })\n\n test('should infer the return type as a collection of `Stats` or `string`', () => {\n const files = glob('*.ts', { cwd: '/project', getStats: true as boolean })\n expectTypeOf(files).toEqualTypeOf<Awaitable<AsyncIterable<Stats>, Stats[]> | Awaitable<AsyncIterable<string>, string[]>>()\n })\n}\n"],"names":["cwd","getCwd","pattern"],"mappings":";;;;;AA8EO,SAAS,KAAK,SAA6B,UAAuB,IAAgB;AACjF,QAAA;AAAA,IACJA,KAAAA,QAAMC,IAAO;AAAA,IACb,UAAU,CAAC;AAAA,IACX,cAAc;AAAA,IACd,WAAW;AAAA,IACX,kBAAkB;AAAA,IAClB,YAAY;AAAA,EACV,IAAA,SAIE,YADe,MAAM,QAAQ,OAAO,IAAI,UAAU,CAAC,OAAO,GAClC,IAAI,aAAa,GAEzC,mBADc,MAAM,QAAQ,OAAO,IAAI,UAAU,CAAC,OAAO,GAC3B,IAAI,aAAa,GAG/C,aAAuB,CAACD,KAAG;AACjC,kBAAgB,iBAAiB;AACxB,WAAA,WAAW,SAAS,KAAG;AAC5B,YAAM,YAAY,WAAW,IACvB,GAAA,WAAW,MAAM,QAAQ,WAAW,EAAE,eAAe,GAAM,CAAA,EAAE,MAAM,MAAM,CAAE,CAAA;AAEjF,iBAAW,UAAU,UAAU;AAC7B,cAAM,eAAe,KAAK,WAAW,OAAO,IAAI,GAC1C,eAAe,SAASA,OAAK,YAAY,GACzC,SAAS,OAAO,OAChB,GAAA,cAAc,OAAO;AAe3B,YAZI,eAAa,WAAW,KAAK,YAAY,GAGzC,aAAa,CAAC,UACd,mBAAmB,CAAC,eAIpB,CADY,SAAS,KAAK,CAAAE,aAAWA,SAAQ,KAAK,YAAY,CAAC,KAIhD,gBAAgB,KAAK,CAAAA,aAAWA,SAAQ,KAAK,YAAY,CAAC;AAC7D;AAGhB,YAAI,SAAoB;AACpB,qBAAU,SAAS,MAAM,KAAK,YAAY,IAC1C,gBAAa,SAAS,KAAK,YAAY,KAC3C,MAAM;AAAA,MACR;AAAA,IACF;AAAA,EACF;AAGA,QAAM,WAAW;AAGjB,SAAO,UAAU,QAAQ;AAC3B;"}
|
package/dist/index.cjs
ADDED
@@ -0,0 +1,25 @@
|
|
1
|
+
"use strict";
|
2
|
+
var createTemporaryDirectory = require("./createTemporaryDirectory.cjs"), createTemporaryFile = require("./createTemporaryFile.cjs"), findAncestor = require("./findAncestor.cjs"), findAncestors = require("./findAncestors.cjs"), glob = require("./glob.cjs"), loadObject = require("./loadObject.cjs"), touch = require("./touch.cjs"), updateFile = require("./updateFile.cjs"), withTemporaryDirectories = require("./withTemporaryDirectories.cjs"), withTemporaryFiles = require("./withTemporaryFiles.cjs");
|
3
|
+
require("node:path");
|
4
|
+
require("node:os");
|
5
|
+
require("node:fs/promises");
|
6
|
+
require("node:process");
|
7
|
+
require("@unshared/functions/awaitable");
|
8
|
+
require("@unshared/string/createPattern");
|
9
|
+
require("node:fs");
|
10
|
+
require("node:events");
|
11
|
+
require("@unshared/reactivity/reactive");
|
12
|
+
require("@unshared/functions/garbageCollected");
|
13
|
+
require("@unshared/collection/overwrite");
|
14
|
+
exports.createTemporaryDirectory = createTemporaryDirectory.createTemporaryDirectory;
|
15
|
+
exports.createTemporaryFile = createTemporaryFile.createTemporaryFile;
|
16
|
+
exports.findAncestor = findAncestor.findAncestor;
|
17
|
+
exports.findAncestors = findAncestors.findAncestors;
|
18
|
+
exports.glob = glob.glob;
|
19
|
+
exports.FSObject = loadObject.FSObject;
|
20
|
+
exports.loadObject = loadObject.loadObject;
|
21
|
+
exports.touch = touch.touch;
|
22
|
+
exports.updateFile = updateFile.updateFile;
|
23
|
+
exports.withTemporaryDirectories = withTemporaryDirectories.withTemporaryDirectories;
|
24
|
+
exports.withTemporaryFiles = withTemporaryFiles.withTemporaryFiles;
|
25
|
+
//# sourceMappingURL=index.cjs.map
|
@@ -0,0 +1 @@
|
|
1
|
+
{"version":3,"file":"index.cjs","sources":[],"sourcesContent":[],"names":[],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;"}
|
package/dist/index.d.ts
ADDED
@@ -0,0 +1,16 @@
|
|
1
|
+
export { CreateTemporaryDirectoryOptions, createTemporaryDirectory } from './createTemporaryDirectory.js';
|
2
|
+
export { CreateTemporaryFileOptions, createTemporaryFile } from './createTemporaryFile.js';
|
3
|
+
export { findAncestor } from './findAncestor.js';
|
4
|
+
export { findAncestors } from './findAncestors.js';
|
5
|
+
export { GlobEntry, GlobOptions, GlobResult, glob } from './glob.js';
|
6
|
+
export { FSObject, FSObjectEventMap, FSObjectOptions, loadObject } from './loadObject.js';
|
7
|
+
export { TouchOptions, touch } from './touch.js';
|
8
|
+
export { UpdateFileCallback, updateFile } from './updateFile.js';
|
9
|
+
export { withTemporaryDirectories } from './withTemporaryDirectories.js';
|
10
|
+
export { withTemporaryFiles } from './withTemporaryFiles.js';
|
11
|
+
import 'node:fs/promises';
|
12
|
+
import '@unshared/functions/awaitable';
|
13
|
+
import 'node:fs';
|
14
|
+
import '@unshared/types';
|
15
|
+
import 'node:events';
|
16
|
+
import '@unshared/reactivity/reactive';
|