@bouko/fs 0.0.3 → 0.0.4

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.
@@ -1,11 +1,26 @@
1
1
  import { EnsureFileOptions } from "../types/file";
2
+ type ReadFilesOptions<T extends keyof FileReturnMap, K> = {
3
+ folderPath: string;
4
+ ext: T;
5
+ page?: number;
6
+ pageSize?: number;
7
+ formatter?: (x: FileReturnMap[T]) => K;
8
+ cache?: Map<string, K>;
9
+ };
10
+ export declare function readFiles<T extends "mp3" | "json", K = undefined>({ folderPath, ext, page, pageSize, formatter }: ReadFilesOptions<T, K>): Promise<{
11
+ items: (Awaited<K> & ({} | undefined))[];
12
+ page: number;
13
+ totalItems: number;
14
+ totalPages: number;
15
+ }>;
2
16
  export declare function ensureFile(filePath: string, options?: EnsureFileOptions): Promise<void>;
3
17
  export declare function readJson<T>(filePath: string, fallback?: object): Promise<T>;
4
18
  type SpecialFile = {
19
+ path: string;
5
20
  buffer: ArrayBuffer;
6
21
  last_modified: Date;
7
22
  };
8
- type Mp3File = SpecialFile & {
23
+ export type Mp3File = SpecialFile & {
9
24
  duration: number;
10
25
  metadata: {
11
26
  title: string;
@@ -1,7 +1,34 @@
1
1
  import fs from "fs/promises";
2
2
  import path from "path";
3
3
  import * as mm from "music-metadata";
4
- import { sanitizeArrayMap } from "@bouko/ts";
4
+ import { sanitizeArrayMap, byName } from "@bouko/ts";
5
+ export async function readFiles({ folderPath, ext, page = 0, pageSize = 20, formatter }) {
6
+ const entries = await fs.readdir(folderPath, { withFileTypes: true });
7
+ const filePaths = entries
8
+ .filter((e) => e.isFile() && e.name.toLowerCase().endsWith("." + ext))
9
+ .map((e) => path.join(folderPath, e.name))
10
+ .sort(byName);
11
+ const totalItems = filePaths.length;
12
+ const totalPages = Math.max(1, Math.ceil(totalItems / pageSize));
13
+ const safePage = Math.min(Math.max(page, 0), totalPages - 1);
14
+ const start = safePage * pageSize;
15
+ const items = filePaths.slice(start, start + pageSize);
16
+ const raw = await Promise.all(items.map(async (p) => {
17
+ try {
18
+ return await readFile(p).then(formatter);
19
+ }
20
+ catch {
21
+ return null;
22
+ }
23
+ }));
24
+ const final = raw.filter(x => x !== null);
25
+ return {
26
+ items: final,
27
+ page: safePage,
28
+ totalItems,
29
+ totalPages
30
+ };
31
+ }
5
32
  export async function ensureFile(filePath, options) {
6
33
  const dirPath = path.dirname(filePath);
7
34
  await fs.mkdir(dirPath, { recursive: true });
@@ -58,6 +85,7 @@ export async function readFile(filePath, options) {
58
85
  const sanitized = sanitizeArrayMap(parsed);
59
86
  const buffer = await fs.readFile(filePath);
60
87
  return {
88
+ path: filePath,
61
89
  buffer: buffer.buffer.slice(buffer.byteOffset, buffer.byteOffset + buffer.byteLength),
62
90
  last_modified
63
91
  };
@@ -67,6 +95,7 @@ export async function readFile(filePath, options) {
67
95
  const { common, format } = await mm.parseFile(filePath, { duration: true });
68
96
  const pic = common.picture?.[0] ?? null;
69
97
  return {
98
+ path: filePath,
70
99
  buffer: buffer.buffer.slice(buffer.byteOffset, buffer.byteOffset + buffer.byteLength),
71
100
  metadata: {
72
101
  title: common.title ?? path.basename(filePath),
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
 
3
3
  "name": "@bouko/fs",
4
- "version": "0.0.3",
4
+ "version": "0.0.4",
5
5
  "main": "./dist/index.js",
6
6
  "types": "./dist/index.d.ts",
7
7
  "license": "MIT",