extra-filesystem 0.5.0 → 0.5.2

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.
Files changed (57) hide show
  1. package/README.md +5 -0
  2. package/lib/index.d.ts +1 -0
  3. package/lib/index.js +1 -0
  4. package/lib/index.js.map +1 -1
  5. package/lib/path-equals.d.ts +1 -0
  6. package/lib/path-equals.js +5 -0
  7. package/lib/path-equals.js.map +1 -0
  8. package/package.json +3 -2
  9. package/src/checksum-file.ts +14 -0
  10. package/src/copy-sync.ts +7 -0
  11. package/src/copy.ts +10 -0
  12. package/src/create-temp-dir-sync.ts +8 -0
  13. package/src/create-temp-dir.ts +8 -0
  14. package/src/create-temp-file-sync.ts +8 -0
  15. package/src/create-temp-file.ts +8 -0
  16. package/src/create-temp-name-sync.ts +5 -0
  17. package/src/create-temp-name.ts +5 -0
  18. package/src/empty-dir-sync.ts +8 -0
  19. package/src/empty-dir.ts +9 -0
  20. package/src/ensure-dir-sync.ts +5 -0
  21. package/src/ensure-dir.ts +5 -0
  22. package/src/ensure-file-sync.ts +14 -0
  23. package/src/ensure-file.ts +15 -0
  24. package/src/find-all-dirnames.ts +22 -0
  25. package/src/find-all-filenames.ts +20 -0
  26. package/src/find-up-package-filename-sync.ts +14 -0
  27. package/src/find-up-package-filename.ts +14 -0
  28. package/src/get-long-extension.ts +13 -0
  29. package/src/get-short-basename.ts +6 -0
  30. package/src/index.ts +48 -0
  31. package/src/is-directory-sync.ts +6 -0
  32. package/src/is-directory.ts +6 -0
  33. package/src/is-file-sync.ts +6 -0
  34. package/src/is-file.ts +6 -0
  35. package/src/is-readable.ts +11 -0
  36. package/src/is-sub-path-of.ts +9 -0
  37. package/src/is-writable.ts +11 -0
  38. package/src/move-sync.ts +7 -0
  39. package/src/move.ts +7 -0
  40. package/src/path-equals.ts +5 -0
  41. package/src/path-exists-sync.ts +13 -0
  42. package/src/path-exists.ts +13 -0
  43. package/src/read-file-line-by-line-sync.ts +25 -0
  44. package/src/read-file-line-by-line.ts +14 -0
  45. package/src/read-json-file-sync.ts +9 -0
  46. package/src/read-json-file.ts +9 -0
  47. package/src/read-ndjson-file-sync.ts +14 -0
  48. package/src/read-ndjson-file.ts +14 -0
  49. package/src/read-yaml-file-sync.ts +11 -0
  50. package/src/read-yaml-file.ts +11 -0
  51. package/src/remove-sync.ts +5 -0
  52. package/src/remove.ts +5 -0
  53. package/src/write-iterable-to-file.ts +12 -0
  54. package/src/write-json-file-sync.ts +10 -0
  55. package/src/write-json-file.ts +10 -0
  56. package/src/write-yaml-file-sync.ts +7 -0
  57. package/src/write-yaml-file.ts +7 -0
package/README.md CHANGED
@@ -284,3 +284,8 @@ function findUpPackageFilename(pathname: string): Promise<string | undefined>
284
284
  ```ts
285
285
  function findUpPackageFilenameSync(pathname: string): string | undefined
286
286
  ```
287
+
288
+ ### pathEquals
289
+ ```ts
290
+ function pathEquals(a: string, b: string): boolean
291
+ ```
package/lib/index.d.ts CHANGED
@@ -45,3 +45,4 @@ export * from './is-sub-path-of.js';
45
45
  export * from './checksum-file.js';
46
46
  export * from './find-up-package-filename.js';
47
47
  export * from './find-up-package-filename-sync.js';
48
+ export * from './path-equals.js';
package/lib/index.js CHANGED
@@ -45,4 +45,5 @@ export * from './is-sub-path-of.js';
45
45
  export * from './checksum-file.js';
46
46
  export * from './find-up-package-filename.js';
47
47
  export * from './find-up-package-filename-sync.js';
48
+ export * from './path-equals.js';
48
49
  //# sourceMappingURL=index.js.map
package/lib/index.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,cAAc,sBAAsB,CAAA;AACpC,cAAc,2BAA2B,CAAA;AACzC,cAAc,uBAAuB,CAAA;AACrC,cAAc,4BAA4B,CAAA;AAC1C,cAAc,uBAAuB,CAAA;AACrC,cAAc,4BAA4B,CAAA;AAC1C,cAAc,gBAAgB,CAAA;AAC9B,cAAc,qBAAqB,CAAA;AACnC,cAAc,iBAAiB,CAAA;AAC/B,cAAc,sBAAsB,CAAA;AACpC,cAAc,kBAAkB,CAAA;AAChC,cAAc,uBAAuB,CAAA;AACrC,cAAc,kBAAkB,CAAA;AAChC,cAAc,uBAAuB,CAAA;AACrC,cAAc,uBAAuB,CAAA;AACrC,cAAc,4BAA4B,CAAA;AAC1C,cAAc,qBAAqB,CAAA;AACnC,cAAc,0BAA0B,CAAA;AACxC,cAAc,qBAAqB,CAAA;AACnC,cAAc,0BAA0B,CAAA;AACxC,cAAc,sBAAsB,CAAA;AACpC,cAAc,2BAA2B,CAAA;AACzC,cAAc,sBAAsB,CAAA;AACpC,cAAc,2BAA2B,CAAA;AACzC,cAAc,6BAA6B,CAAA;AAC3C,cAAc,6BAA6B,CAAA;AAC3C,cAAc,kCAAkC,CAAA;AAChD,cAAc,WAAW,CAAA;AACzB,cAAc,gBAAgB,CAAA;AAC9B,cAAc,WAAW,CAAA;AACzB,cAAc,gBAAgB,CAAA;AAC9B,cAAc,aAAa,CAAA;AAC3B,cAAc,kBAAkB,CAAA;AAChC,cAAc,yBAAyB,CAAA;AACvC,cAAc,wBAAwB,CAAA;AACtC,cAAc,yBAAyB,CAAA;AACvC,cAAc,yBAAyB,CAAA;AACvC,cAAc,mBAAmB,CAAA;AACjC,cAAc,wBAAwB,CAAA;AACtC,cAAc,cAAc,CAAA;AAC5B,cAAc,mBAAmB,CAAA;AACjC,cAAc,kBAAkB,CAAA;AAChC,cAAc,kBAAkB,CAAA;AAChC,cAAc,qBAAqB,CAAA;AACnC,cAAc,oBAAoB,CAAA;AAClC,cAAc,+BAA+B,CAAA;AAC7C,cAAc,oCAAoC,CAAA"}
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,cAAc,sBAAsB,CAAA;AACpC,cAAc,2BAA2B,CAAA;AACzC,cAAc,uBAAuB,CAAA;AACrC,cAAc,4BAA4B,CAAA;AAC1C,cAAc,uBAAuB,CAAA;AACrC,cAAc,4BAA4B,CAAA;AAC1C,cAAc,gBAAgB,CAAA;AAC9B,cAAc,qBAAqB,CAAA;AACnC,cAAc,iBAAiB,CAAA;AAC/B,cAAc,sBAAsB,CAAA;AACpC,cAAc,kBAAkB,CAAA;AAChC,cAAc,uBAAuB,CAAA;AACrC,cAAc,kBAAkB,CAAA;AAChC,cAAc,uBAAuB,CAAA;AACrC,cAAc,uBAAuB,CAAA;AACrC,cAAc,4BAA4B,CAAA;AAC1C,cAAc,qBAAqB,CAAA;AACnC,cAAc,0BAA0B,CAAA;AACxC,cAAc,qBAAqB,CAAA;AACnC,cAAc,0BAA0B,CAAA;AACxC,cAAc,sBAAsB,CAAA;AACpC,cAAc,2BAA2B,CAAA;AACzC,cAAc,sBAAsB,CAAA;AACpC,cAAc,2BAA2B,CAAA;AACzC,cAAc,6BAA6B,CAAA;AAC3C,cAAc,6BAA6B,CAAA;AAC3C,cAAc,kCAAkC,CAAA;AAChD,cAAc,WAAW,CAAA;AACzB,cAAc,gBAAgB,CAAA;AAC9B,cAAc,WAAW,CAAA;AACzB,cAAc,gBAAgB,CAAA;AAC9B,cAAc,aAAa,CAAA;AAC3B,cAAc,kBAAkB,CAAA;AAChC,cAAc,yBAAyB,CAAA;AACvC,cAAc,wBAAwB,CAAA;AACtC,cAAc,yBAAyB,CAAA;AACvC,cAAc,yBAAyB,CAAA;AACvC,cAAc,mBAAmB,CAAA;AACjC,cAAc,wBAAwB,CAAA;AACtC,cAAc,cAAc,CAAA;AAC5B,cAAc,mBAAmB,CAAA;AACjC,cAAc,kBAAkB,CAAA;AAChC,cAAc,kBAAkB,CAAA;AAChC,cAAc,qBAAqB,CAAA;AACnC,cAAc,oBAAoB,CAAA;AAClC,cAAc,+BAA+B,CAAA;AAC7C,cAAc,oCAAoC,CAAA;AAClD,cAAc,kBAAkB,CAAA"}
@@ -0,0 +1 @@
1
+ export declare function pathEquals(a: string, b: string): boolean;
@@ -0,0 +1,5 @@
1
+ import path from 'path';
2
+ export function pathEquals(a, b) {
3
+ return path.relative(a, b) === '';
4
+ }
5
+ //# sourceMappingURL=path-equals.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"path-equals.js","sourceRoot":"","sources":["../src/path-equals.ts"],"names":[],"mappings":"AAAA,OAAO,IAAI,MAAM,MAAM,CAAA;AAEvB,MAAM,UAAU,UAAU,CAAC,CAAS,EAAE,CAAS;IAC7C,OAAO,IAAI,CAAC,QAAQ,CAAC,CAAC,EAAE,CAAC,CAAC,KAAK,EAAE,CAAA;AACnC,CAAC"}
package/package.json CHANGED
@@ -1,10 +1,11 @@
1
1
  {
2
2
  "name": "extra-filesystem",
3
- "version": "0.5.0",
3
+ "version": "0.5.2",
4
4
  "description": "",
5
5
  "keywords": [],
6
6
  "files": [
7
- "lib"
7
+ "lib",
8
+ "src"
8
9
  ],
9
10
  "type": "module",
10
11
  "main": "lib/index.js",
@@ -0,0 +1,14 @@
1
+ import crypto from 'crypto'
2
+ import fs from 'fs'
3
+
4
+ export async function checksumFile(
5
+ algorithm: string
6
+ , filename: string
7
+ ): Promise<string> {
8
+ const hash = crypto.createHash(algorithm)
9
+ const stream = fs.createReadStream(filename)
10
+ for await (const chunk of stream) {
11
+ hash.update(chunk)
12
+ }
13
+ return hash.digest('hex')
14
+ }
@@ -0,0 +1,7 @@
1
+ import fs from 'fs-extra'
2
+
3
+ export function copySync(sourcePath: string, destinationPath: string): void {
4
+ fs.copySync(sourcePath, destinationPath, {
5
+ overwrite: true
6
+ })
7
+ }
package/src/copy.ts ADDED
@@ -0,0 +1,10 @@
1
+ import fs from 'fs-extra'
2
+
3
+ export async function copy(
4
+ sourcePath: string
5
+ , destinationPath: string
6
+ ): Promise<void> {
7
+ await fs.copy(sourcePath, destinationPath, {
8
+ overwrite: true
9
+ })
10
+ }
@@ -0,0 +1,8 @@
1
+ import { ensureDirSync } from './ensure-dir-sync.js'
2
+ import { createTempNameSync } from './create-temp-name-sync.js'
3
+
4
+ export function createTempDirSync(): string {
5
+ const dirname = createTempNameSync()
6
+ ensureDirSync(dirname)
7
+ return dirname
8
+ }
@@ -0,0 +1,8 @@
1
+ import { ensureDir } from './ensure-dir.js'
2
+ import { createTempName } from './create-temp-name.js'
3
+
4
+ export async function createTempDir(): Promise<string> {
5
+ const dirname = await createTempName()
6
+ await ensureDir(dirname)
7
+ return dirname
8
+ }
@@ -0,0 +1,8 @@
1
+ import { ensureFileSync } from './ensure-file-sync.js'
2
+ import { createTempNameSync } from './create-temp-name-sync.js'
3
+
4
+ export function createTempFileSync(): string {
5
+ const filename = createTempNameSync()
6
+ ensureFileSync(filename)
7
+ return filename
8
+ }
@@ -0,0 +1,8 @@
1
+ import { ensureFile } from './ensure-file.js'
2
+ import { createTempName } from './create-temp-name.js'
3
+
4
+ export async function createTempFile(): Promise<string> {
5
+ const filename = await createTempName()
6
+ await ensureFile(filename)
7
+ return filename
8
+ }
@@ -0,0 +1,5 @@
1
+ import { tmpNameSync } from 'tmp-promise'
2
+
3
+ export function createTempNameSync(): string {
4
+ return tmpNameSync()
5
+ }
@@ -0,0 +1,5 @@
1
+ import { tmpName } from 'tmp-promise'
2
+
3
+ export async function createTempName(): Promise<string> {
4
+ return await tmpName()
5
+ }
@@ -0,0 +1,8 @@
1
+ import fs from 'fs'
2
+ import { removeSync } from './remove-sync.js'
3
+ import path from 'path'
4
+
5
+ export function emptyDirSync(dirname: string): void {
6
+ const names = fs.readdirSync(dirname)
7
+ names.forEach(name => removeSync(path.join(dirname, name)))
8
+ }
@@ -0,0 +1,9 @@
1
+ import fs from 'fs/promises'
2
+ import { remove } from './remove.js'
3
+ import { each } from 'extra-promise'
4
+ import path from 'path'
5
+
6
+ export async function emptyDir(dirname: string): Promise<void> {
7
+ const names = await fs.readdir(dirname)
8
+ await each(names, name => remove(path.join(dirname, name)))
9
+ }
@@ -0,0 +1,5 @@
1
+ import fs from 'fs'
2
+
3
+ export function ensureDirSync(dirname: string): void {
4
+ fs.mkdirSync(dirname, { recursive: true })
5
+ }
@@ -0,0 +1,5 @@
1
+ import fs from 'fs/promises'
2
+
3
+ export async function ensureDir(dirname: string): Promise<void> {
4
+ await fs.mkdir(dirname, { recursive: true })
5
+ }
@@ -0,0 +1,14 @@
1
+ import { ensureDirSync } from './ensure-dir-sync.js'
2
+ import path from 'path'
3
+ import fs from 'fs'
4
+ import { pass } from '@blackglory/prelude'
5
+
6
+ export function ensureFileSync(filename: string): void {
7
+ const dir = path.dirname(filename)
8
+ ensureDirSync(dir)
9
+ try {
10
+ fs.closeSync(fs.openSync(filename, 'wx'))
11
+ } catch {
12
+ pass()
13
+ }
14
+ }
@@ -0,0 +1,15 @@
1
+ import { ensureDir } from './ensure-dir.js'
2
+ import path from 'path'
3
+ import fs from 'fs/promises'
4
+ import { pass } from '@blackglory/prelude'
5
+
6
+ export async function ensureFile(filename: string): Promise<void> {
7
+ const dir = path.dirname(filename)
8
+ await ensureDir(dir)
9
+ try {
10
+ const handle = await fs.open(filename, 'wx')
11
+ await handle.close()
12
+ } catch {
13
+ pass()
14
+ }
15
+ }
@@ -0,0 +1,22 @@
1
+ import fs from 'fs/promises'
2
+ import path from 'path'
3
+
4
+ export async function* findAllDirnames(
5
+ dirname: string
6
+ , predicate: (dirname: string) => boolean = _ => true
7
+ ): AsyncIterableIterator<string> {
8
+ const subDirnames = await getSubDirnames(dirname)
9
+ for (const dirname of subDirnames) {
10
+ if (predicate(dirname)) {
11
+ yield dirname
12
+ yield* findAllDirnames(dirname, predicate)
13
+ }
14
+ }
15
+ }
16
+
17
+ async function getSubDirnames(dirname: string): Promise<string[]> {
18
+ const dirents = await fs.readdir(dirname, { withFileTypes: true })
19
+ return dirents
20
+ .filter(x => x.isDirectory())
21
+ .map(x => path.join(dirname, x.name))
22
+ }
@@ -0,0 +1,20 @@
1
+ import fs from 'fs/promises'
2
+ import path from 'path'
3
+
4
+ export async function* findAllFilenames(
5
+ dirname: string
6
+ , predicate: (dirname: string) => boolean = _ => true
7
+ ): AsyncIterableIterator<string> {
8
+ const dirents = await fs.readdir(dirname, { withFileTypes: true })
9
+ for (const dirent of dirents) {
10
+ if (dirent.isDirectory()) {
11
+ const subDirname = path.join(dirname, dirent.name)
12
+ if (predicate(subDirname)) {
13
+ yield* findAllFilenames(subDirname, predicate)
14
+ }
15
+ } else {
16
+ const filename = path.join(dirname, dirent.name)
17
+ yield filename
18
+ }
19
+ }
20
+ }
@@ -0,0 +1,14 @@
1
+ import path from 'path'
2
+ import { pathExistsSync } from './path-exists-sync.js'
3
+
4
+ export function findUpPackageFilenameSync(pathname: string): string | undefined {
5
+ pathname = path.resolve(pathname)
6
+ while (true) {
7
+ const filename = path.resolve(pathname, 'package.json')
8
+ if (pathExistsSync(filename)) return filename
9
+
10
+ const newpathname = path.resolve(pathname, '..')
11
+ if (newpathname === pathname) return
12
+ pathname = newpathname
13
+ }
14
+ }
@@ -0,0 +1,14 @@
1
+ import path from 'path'
2
+ import { pathExists } from './path-exists.js'
3
+
4
+ export async function findUpPackageFilename(pathname: string): Promise<string | undefined> {
5
+ pathname = path.resolve(pathname)
6
+ while (true) {
7
+ const filename = path.resolve(pathname, 'package.json')
8
+ if (await pathExists(filename)) return filename
9
+
10
+ const newpathname = path.resolve(pathname, '..')
11
+ if (newpathname === pathname) return
12
+ pathname = newpathname
13
+ }
14
+ }
@@ -0,0 +1,13 @@
1
+ import path from 'path'
2
+
3
+ export function getLongExtension(filename: string): string {
4
+ let result = ''
5
+ let remainder = filename
6
+ while (true) {
7
+ const extension = path.extname(remainder)
8
+ if (!extension) break
9
+ remainder = path.basename(remainder, extension)
10
+ result = extension + result
11
+ }
12
+ return result
13
+ }
@@ -0,0 +1,6 @@
1
+ import path from 'path'
2
+ import { getLongExtension } from './get-long-extension.js'
3
+
4
+ export function getShortBasename(filename: string): string {
5
+ return path.basename(filename, getLongExtension(filename))
6
+ }
package/src/index.ts ADDED
@@ -0,0 +1,48 @@
1
+ export * from './create-temp-dir.js'
2
+ export * from './create-temp-dir-sync.js'
3
+ export * from './create-temp-file.js'
4
+ export * from './create-temp-file-sync.js'
5
+ export * from './create-temp-name.js'
6
+ export * from './create-temp-name-sync.js'
7
+ export * from './empty-dir.js'
8
+ export * from './empty-dir-sync.js'
9
+ export * from './ensure-dir.js'
10
+ export * from './ensure-dir-sync.js'
11
+ export * from './ensure-file.js'
12
+ export * from './ensure-file-sync.js'
13
+ export * from './path-exists.js'
14
+ export * from './path-exists-sync.js'
15
+ export * from './read-ndjson-file.js'
16
+ export * from './read-ndjson-file-sync.js'
17
+ export * from './read-json-file.js'
18
+ export * from './read-json-file-sync.js'
19
+ export * from './read-yaml-file.js'
20
+ export * from './read-yaml-file-sync.js'
21
+ export * from './write-json-file.js'
22
+ export * from './write-json-file-sync.js'
23
+ export * from './write-yaml-file.js'
24
+ export * from './write-yaml-file-sync.js'
25
+ export * from './write-iterable-to-file.js'
26
+ export * from './read-file-line-by-line.js'
27
+ export * from './read-file-line-by-line-sync.js'
28
+ export * from './move.js'
29
+ export * from './move-sync.js'
30
+ export * from './copy.js'
31
+ export * from './copy-sync.js'
32
+ export * from './remove.js'
33
+ export * from './remove-sync.js'
34
+ export * from './find-all-filenames.js'
35
+ export * from './find-all-dirnames.js'
36
+ export * from './get-long-extension.js'
37
+ export * from './get-short-basename.js'
38
+ export * from './is-directory.js'
39
+ export * from './is-directory-sync.js'
40
+ export * from './is-file.js'
41
+ export * from './is-file-sync.js'
42
+ export * from './is-readable.js'
43
+ export * from './is-writable.js'
44
+ export * from './is-sub-path-of.js'
45
+ export * from './checksum-file.js'
46
+ export * from './find-up-package-filename.js'
47
+ export * from './find-up-package-filename-sync.js'
48
+ export * from './path-equals.js'
@@ -0,0 +1,6 @@
1
+ import fs from 'fs'
2
+
3
+ export function isDirectorySync(path: string): boolean {
4
+ const stat = fs.statSync(path)
5
+ return stat.isDirectory()
6
+ }
@@ -0,0 +1,6 @@
1
+ import fs from 'fs/promises'
2
+
3
+ export async function isDirectory(path: string): Promise<boolean> {
4
+ const stat = await fs.stat(path)
5
+ return stat.isDirectory()
6
+ }
@@ -0,0 +1,6 @@
1
+ import fs from 'fs'
2
+
3
+ export function isFileSync(path: string): boolean {
4
+ const stat = fs.statSync(path)
5
+ return stat.isFile()
6
+ }
package/src/is-file.ts ADDED
@@ -0,0 +1,6 @@
1
+ import fs from 'fs/promises'
2
+
3
+ export async function isFile(path: string): Promise<boolean> {
4
+ const stat = await fs.stat(path)
5
+ return stat.isFile()
6
+ }
@@ -0,0 +1,11 @@
1
+ import fs from 'fs/promises'
2
+ import { constants } from 'fs'
3
+
4
+ export async function isReadable(path: string): Promise<boolean> {
5
+ try {
6
+ await fs.access(path, constants.R_OK)
7
+ return true
8
+ } catch {
9
+ return false
10
+ }
11
+ }
@@ -0,0 +1,9 @@
1
+ import path from 'path'
2
+
3
+ // Source: https://stackoverflow.com/a/45242825/5462167
4
+ export function isSubPathOf(subject: string, object: string): boolean {
5
+ const relative = path.relative(object, subject)
6
+ return relative !== '' // not equal
7
+ && !relative.startsWith('..')
8
+ && !path.isAbsolute(relative)
9
+ }
@@ -0,0 +1,11 @@
1
+ import fs from 'fs/promises'
2
+ import { constants } from 'fs'
3
+
4
+ export async function isWritable(path: string): Promise<boolean> {
5
+ try {
6
+ await fs.access(path, constants.W_OK)
7
+ return true
8
+ } catch {
9
+ return false
10
+ }
11
+ }
@@ -0,0 +1,7 @@
1
+ import fs from 'fs-extra'
2
+
3
+ export function moveSync(oldPath: string, newPath: string): void {
4
+ fs.moveSync(oldPath, newPath, {
5
+ overwrite: true
6
+ })
7
+ }
package/src/move.ts ADDED
@@ -0,0 +1,7 @@
1
+ import fs from 'fs-extra'
2
+
3
+ export async function move(oldPath: string, newPath: string): Promise<void> {
4
+ await fs.move(oldPath, newPath, {
5
+ overwrite: true
6
+ })
7
+ }
@@ -0,0 +1,5 @@
1
+ import path from 'path'
2
+
3
+ export function pathEquals(a: string, b: string): boolean {
4
+ return path.relative(a, b) === ''
5
+ }
@@ -0,0 +1,13 @@
1
+ import fs from 'fs'
2
+
3
+ /**
4
+ * Note: Combining pathExists with other fs functions will introduce race conditions.
5
+ */
6
+ export function pathExistsSync(path: string): boolean {
7
+ try {
8
+ fs.accessSync(path)
9
+ return true
10
+ } catch {
11
+ return false
12
+ }
13
+ }
@@ -0,0 +1,13 @@
1
+ import fs from 'fs/promises'
2
+
3
+ /**
4
+ * Note: Combining pathExists with other fs functions will introduce race conditions.
5
+ */
6
+ export async function pathExists(path: string): Promise<boolean> {
7
+ try {
8
+ await fs.access(path)
9
+ return true
10
+ } catch {
11
+ return false
12
+ }
13
+ }
@@ -0,0 +1,25 @@
1
+ import fs from 'fs'
2
+
3
+ export function* readFileLineByLineSync(
4
+ filename: string
5
+ , encoding: BufferEncoding = 'utf-8'
6
+ ): IterableIterator<string> {
7
+ const fd = fs.openSync(filename, 'r')
8
+ const bufferSize = 1024 * 64
9
+ const buffer = Buffer.alloc(bufferSize)
10
+
11
+ let bytesRead: number
12
+ let remainingLine = ''
13
+ while ((bytesRead = fs.readSync(fd, buffer, 0, bufferSize, null)) !== 0) {
14
+ const str = buffer.toString(encoding, 0, bytesRead)
15
+ const lines = str.split(/\r?\n/)
16
+ lines[0] = remainingLine + lines[0]
17
+ while (lines.length > 1) {
18
+ yield lines.shift()!
19
+ }
20
+ remainingLine = lines.shift()!
21
+ }
22
+ if (remainingLine) yield remainingLine
23
+
24
+ fs.closeSync(fd)
25
+ }
@@ -0,0 +1,14 @@
1
+ import fs from 'fs'
2
+ import readline from 'readline'
3
+
4
+ export function readFileLineByLine(
5
+ filename: string
6
+ , encoding: BufferEncoding = 'utf-8'
7
+ ): AsyncIterable<string> {
8
+ const fileStream = fs.createReadStream(filename, { encoding })
9
+
10
+ return readline.createInterface({
11
+ input: fileStream
12
+ , crlfDelay: Infinity
13
+ })
14
+ }
@@ -0,0 +1,9 @@
1
+ import fs from 'fs'
2
+
3
+ export function readJSONFileSync<T>(
4
+ filename: string
5
+ , encoding: BufferEncoding = 'utf-8'
6
+ ): T {
7
+ const text = fs.readFileSync(filename, encoding)
8
+ return JSON.parse(text)
9
+ }
@@ -0,0 +1,9 @@
1
+ import fs from 'fs/promises'
2
+
3
+ export async function readJSONFile<T>(
4
+ filename: string
5
+ , encoding: BufferEncoding = 'utf-8'
6
+ ): Promise<T> {
7
+ const text = await fs.readFile(filename, encoding)
8
+ return JSON.parse(text)
9
+ }
@@ -0,0 +1,14 @@
1
+ import { filter, map } from 'iterable-operator'
2
+ import { readFileLineByLineSync } from './read-file-line-by-line-sync.js'
3
+ import { pipe } from 'extra-utils'
4
+
5
+ export function readNDJSONFileSync<T>(
6
+ filename: string
7
+ , encoding: BufferEncoding = 'utf-8'
8
+ ): IterableIterator<T> {
9
+ return pipe(
10
+ readFileLineByLineSync(filename, encoding)
11
+ , iter => filter(iter, line => line.trim() !== '')
12
+ , iter => map(iter, line => JSON.parse(line))
13
+ )
14
+ }
@@ -0,0 +1,14 @@
1
+ import { filterAsync, mapAsync } from 'iterable-operator'
2
+ import { readFileLineByLine } from './read-file-line-by-line.js'
3
+ import { pipe } from 'extra-utils'
4
+
5
+ export function readNDJSONFile<T>(
6
+ filename: string
7
+ , encoding: BufferEncoding = 'utf-8'
8
+ ): AsyncIterableIterator<T> {
9
+ return pipe(
10
+ readFileLineByLine(filename, encoding)
11
+ , iter => filterAsync(iter, line => line.trim() !== '')
12
+ , iter => mapAsync(iter, line => JSON.parse(line))
13
+ )
14
+ }
@@ -0,0 +1,11 @@
1
+ import fs from 'fs'
2
+ import YAML from 'js-yaml'
3
+
4
+ export function readYAMLFileSync<T>(
5
+ filename: string
6
+ , encoding: BufferEncoding = 'utf-8'
7
+ ): T {
8
+ const text = fs.readFileSync(filename, encoding)
9
+ const data = YAML.load(text)
10
+ return data as T
11
+ }
@@ -0,0 +1,11 @@
1
+ import fs from 'fs/promises'
2
+ import YAML from 'js-yaml'
3
+
4
+ export async function readYAMLFile<T>(
5
+ filename: string
6
+ , encoding: BufferEncoding = 'utf-8'
7
+ ): Promise<T> {
8
+ const text = await fs.readFile(filename, encoding)
9
+ const data = YAML.load(text)
10
+ return data as T
11
+ }
@@ -0,0 +1,5 @@
1
+ import fs from 'fs'
2
+
3
+ export function removeSync(path: string): void {
4
+ fs.rmSync(path, { recursive: true, force: true })
5
+ }
package/src/remove.ts ADDED
@@ -0,0 +1,5 @@
1
+ import fs from 'fs/promises'
2
+
3
+ export async function remove(path: string): Promise<void> {
4
+ await fs.rm(path, { recursive: true, force: true })
5
+ }
@@ -0,0 +1,12 @@
1
+ import fs from 'fs'
2
+ import stream from 'stream'
3
+ import { pipeline } from 'stream/promises'
4
+
5
+ export async function writeIterableToFile(
6
+ filename: string
7
+ , iterable: Iterable<string> | AsyncIterable<string>
8
+ ): Promise<void> {
9
+ const readStream = stream.Readable.from(iterable)
10
+ const writeStream = fs.createWriteStream(filename)
11
+ await pipeline(readStream, writeStream)
12
+ }
@@ -0,0 +1,10 @@
1
+ import fs from 'fs'
2
+
3
+ export function writeJSONFileSync(
4
+ filename: string
5
+ , data: unknown
6
+ , options: { spaces?: number } = {}
7
+ ): void {
8
+ const text = JSON.stringify(data, undefined, options.spaces)
9
+ fs.writeFileSync(filename, text, 'utf-8')
10
+ }
@@ -0,0 +1,10 @@
1
+ import fs from 'fs/promises'
2
+
3
+ export async function writeJSONFile(
4
+ filename: string
5
+ , data: unknown
6
+ , options: { spaces?: number } = {}
7
+ ): Promise<void> {
8
+ const text = JSON.stringify(data, undefined, options.spaces)
9
+ await fs.writeFile(filename, text, 'utf-8')
10
+ }
@@ -0,0 +1,7 @@
1
+ import fs from 'fs'
2
+ import YAML from 'js-yaml'
3
+
4
+ export function writeYAMLFileSync(filename: string, data: unknown): void {
5
+ const text = YAML.dump(data)
6
+ fs.writeFileSync(filename, text, 'utf-8')
7
+ }
@@ -0,0 +1,7 @@
1
+ import fs from 'fs/promises'
2
+ import YAML from 'js-yaml'
3
+
4
+ export async function writeYAMLFile(filename: string, data: unknown): Promise<void> {
5
+ const text = YAML.dump(data)
6
+ await fs.writeFile(filename, text, 'utf-8')
7
+ }