@stacksjs/storage 0.70.87 → 0.70.90

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/files.js ADDED
@@ -0,0 +1,126 @@
1
+ import { contains } from "@stacksjs/arrays";
2
+ import { log } from "@stacksjs/logging";
3
+ import { dirname, join, path as p } from "@stacksjs/path";
4
+ import { detectIndent, detectNewline } from "@stacksjs/strings";
5
+ import { createFolder, isFolder } from "./folders";
6
+ import { existsSync, fs } from "./fs";
7
+ export async function readJsonFile(name, cwd) {
8
+ const file = await readTextFile(name, cwd);
9
+ let data;
10
+ try {
11
+ data = JSON.parse(file.data);
12
+ } catch (error) {
13
+ throw Error(`Failed to parse JSON file "${name}": ${error.message}`);
14
+ }
15
+ const indent = detectIndent(file.data).indent, newline = detectNewline(file.data);
16
+ return { ...file, data, indent, newline };
17
+ }
18
+ export async function readPackageJson(name, cwd) {
19
+ return (await readJsonFile(name, cwd)).data;
20
+ }
21
+ export async function writeFile(path, data) {
22
+ if (typeof path === "string") {
23
+ const dirPath = dirname(path);
24
+ if (!await existsSync(dirPath))
25
+ await createFolder(dirPath);
26
+ return await Bun.write(Bun.file(path), data);
27
+ }
28
+ return await Bun.write(path, data);
29
+ }
30
+ export async function writeJsonFile(file) {
31
+ let json = JSON.stringify(file.data, void 0, file.indent);
32
+ if (file.newline)
33
+ json += file.newline;
34
+ return writeTextFile({ ...file, data: json });
35
+ }
36
+ export function readTextFile(name, cwd) {
37
+ return new Promise((resolve, reject) => {
38
+ let filePath;
39
+ if (cwd)
40
+ filePath = join(cwd, name);
41
+ else
42
+ filePath = name;
43
+ fs.readFile(filePath, "utf8", (err, text) => {
44
+ if (err)
45
+ reject(err);
46
+ else
47
+ resolve({
48
+ path: filePath,
49
+ data: text
50
+ });
51
+ });
52
+ });
53
+ }
54
+ export async function writeTextFile(file) {
55
+ return await Bun.write(file.path, file.data);
56
+ }
57
+ function isFile(path) {
58
+ return fs.existsSync(path);
59
+ }
60
+ export function doesExist(path) {
61
+ return isFile(path) || isFolder(path);
62
+ }
63
+ export function doesNotExist(path) {
64
+ return !isFile(path) && !isFolder(path);
65
+ }
66
+ export function hasFiles(folder) {
67
+ try {
68
+ return fs.readdirSync(folder).length > 0;
69
+ } catch (err) {
70
+ log.debug(`Error reading folder: ${folder}`, err);
71
+ return !1;
72
+ }
73
+ }
74
+ export function hasComponents() {
75
+ return hasFiles(p.componentsPath());
76
+ }
77
+ export function hasFunctions() {
78
+ return hasFiles(p.functionsPath());
79
+ }
80
+ export function deleteFiles(dir, exclude = []) {
81
+ if (fs.existsSync(dir))
82
+ fs.readdirSync(dir).forEach((file) => {
83
+ const p = join(dir, file);
84
+ if (fs.statSync(p).isDirectory())
85
+ if (fs.readdirSync(p).length === 0)
86
+ fs.rmSync(p, { recursive: !0, force: !0 });
87
+ else
88
+ deleteFiles(p, exclude);
89
+ else if (!contains(p, exclude))
90
+ fs.rmSync(p);
91
+ });
92
+ }
93
+ export function getFiles(dir, exclude = []) {
94
+ let results = [];
95
+ fs.readdirSync(dir).forEach((file) => {
96
+ file = join(dir, file);
97
+ if (fs.statSync(file).isDirectory())
98
+ results = results.concat(getFiles(file, exclude));
99
+ else if (!contains(file, exclude))
100
+ results.push(file);
101
+ });
102
+ return results;
103
+ }
104
+ export function put(path, contents) {
105
+ const dirPath = dirname(path);
106
+ if (!fs.existsSync(dirPath))
107
+ fs.mkdirSync(dirPath, { recursive: !0 });
108
+ fs.writeFileSync(path, contents, "utf-8");
109
+ }
110
+ export async function get(path) {
111
+ return Bun.file(path).text();
112
+ }
113
+ export const files = {
114
+ readJsonFile,
115
+ readPackageJson,
116
+ readTextFile,
117
+ writeJsonFile,
118
+ writeTextFile,
119
+ hasFiles,
120
+ hasComponents,
121
+ hasFunctions,
122
+ deleteFiles,
123
+ getFiles,
124
+ put,
125
+ get
126
+ };
@@ -0,0 +1,36 @@
1
+ import { join } from "@stacksjs/path";
2
+ import { fs } from "./fs";
3
+ export function isFolder(path) {
4
+ try {
5
+ return fs.statSync(path).isDirectory();
6
+ } catch {
7
+ return !1;
8
+ }
9
+ }
10
+ export function isDir(path) {
11
+ return isFolder(path);
12
+ }
13
+ export function doesFolderExist(path) {
14
+ return fs.existsSync(path);
15
+ }
16
+ export function createFolder(dir) {
17
+ return new Promise((resolve, reject) => {
18
+ try {
19
+ fs.mkdirSync(dir, { recursive: !0 });
20
+ resolve();
21
+ } catch (err) {
22
+ reject(err);
23
+ }
24
+ });
25
+ }
26
+ export function getFolders(dir) {
27
+ return fs.readdirSync(dir).filter((file) => {
28
+ return fs.statSync(join(dir, file)).isDirectory();
29
+ });
30
+ }
31
+ export const folders = {
32
+ isFolder,
33
+ doesFolderExist,
34
+ createFolder,
35
+ getFolders
36
+ };
package/dist/fs.js ADDED
@@ -0,0 +1,7 @@
1
+ import * as fs from "node:fs";
2
+ import { existsSync, watch as fsWatch, mkdirSync, readFileSync, watchFile, writeFileSync } from "node:fs";
3
+ export function exists(path) {
4
+ return existsSync(path);
5
+ }
6
+
7
+ export { existsSync, fsWatch, mkdirSync, readFileSync, watchFile, writeFileSync, fs };
package/dist/glob.js ADDED
@@ -0,0 +1,40 @@
1
+ import { Glob as BunGlob } from "bun";
2
+ function isEnoent(err) {
3
+ return !!err && typeof err === "object" && err.code === "ENOENT";
4
+ }
5
+ export function globSync(patterns, options) {
6
+ const patternArray = typeof patterns === "string" ? [patterns] : patterns, results = [];
7
+ for (const pattern of patternArray)
8
+ try {
9
+ const matches = new BunGlob(pattern).scanSync({
10
+ cwd: options?.cwd,
11
+ absolute: options?.absolute,
12
+ dot: options?.dot,
13
+ onlyFiles: options?.onlyFiles
14
+ });
15
+ for (const match of matches)
16
+ results.push(match);
17
+ } catch (err) {
18
+ if (!isEnoent(err))
19
+ throw err;
20
+ }
21
+ return results;
22
+ }
23
+ export async function glob(patterns, options) {
24
+ const patternArray = typeof patterns === "string" ? [patterns] : patterns, results = [];
25
+ for (const pattern of patternArray)
26
+ try {
27
+ const matches = new BunGlob(pattern).scan({
28
+ cwd: options?.cwd,
29
+ absolute: options?.absolute,
30
+ dot: options?.dot,
31
+ onlyFiles: options?.onlyFiles
32
+ });
33
+ for await (const match of matches)
34
+ results.push(match);
35
+ } catch (err) {
36
+ if (!isEnoent(err))
37
+ throw err;
38
+ }
39
+ return results;
40
+ }
package/dist/hash.js ADDED
@@ -0,0 +1,33 @@
1
+ import { createHash } from "node:crypto";
2
+ import { path as p } from "@stacksjs/path";
3
+ import { fs } from "./fs";
4
+ export function hashFileOrDirectory(path, hash) {
5
+ if (!fs.existsSync(path)) {
6
+ console.error(`Path does not exist: ${path}`);
7
+ return;
8
+ }
9
+ if (fs.statSync(path).isDirectory()) {
10
+ const files = fs.readdirSync(path);
11
+ for (const file of files) {
12
+ const filePath = p.join(path, file);
13
+ hashFileOrDirectory(filePath, hash);
14
+ }
15
+ } else
16
+ hash.update(fs.readFileSync(path));
17
+ }
18
+ export function hashDirectory(directory) {
19
+ const hash = createHash("sha256");
20
+ hashFileOrDirectory(directory, hash);
21
+ return hash.digest("hex");
22
+ }
23
+ export function hashPath(path) {
24
+ const hash = createHash("sha256");
25
+ hashFileOrDirectory(path, hash);
26
+ return hash.digest("hex");
27
+ }
28
+ export function hashPaths(paths) {
29
+ const hash = createHash("sha256"), pathsArray = Array.isArray(paths) ? paths : [paths];
30
+ for (const path of pathsArray)
31
+ hashFileOrDirectory(path, hash);
32
+ return hash.digest("hex");
33
+ }
@@ -0,0 +1,28 @@
1
+ var __dirname = "";
2
+ import { fileURLToPath } from "node:url";
3
+ import { dirname } from "@stacksjs/path";
4
+ import { fs } from "./fs";
5
+ export const _dirname = typeof __dirname < "u" ? __dirname : dirname(fileURLToPath(import.meta.url));
6
+ export function updateConfigFile(filePath, newConfig) {
7
+ return new Promise((resolve, reject) => {
8
+ let config;
9
+ try {
10
+ config = JSON.parse(fs.readFileSync(filePath, "utf8"));
11
+ } catch (error) {
12
+ reject(Error(`Failed to parse config file "${filePath}": ${error.message}`));
13
+ return;
14
+ }
15
+ for (const key in newConfig)
16
+ config[key] = newConfig[key];
17
+ try {
18
+ fs.writeFileSync(filePath, JSON.stringify(config, null, 2));
19
+ resolve();
20
+ } catch (error) {
21
+ reject(error);
22
+ }
23
+ });
24
+ }
25
+ export const helpers = {
26
+ _dirname,
27
+ updateConfigFile
28
+ };
package/dist/image.js CHANGED
@@ -1,8 +1,4 @@
1
- // @bun
2
- var __require = import.meta.require;
3
-
4
- // src/image.ts
5
- var cachedSharp = null;
1
+ let cachedSharp = null;
6
2
  async function loadSharp() {
7
3
  if (cachedSharp)
8
4
  return cachedSharp;
@@ -11,33 +7,23 @@ async function loadSharp() {
11
7
  cachedSharp = mod.default ?? mod;
12
8
  return cachedSharp;
13
9
  } catch (err) {
14
- throw new Error(`[storage/image] \`sharp\` is not installed. Image transforms require it as a peer dependency.
10
+ throw Error(`[storage/image] \`sharp\` is not installed. Image transforms require it as a peer dependency.
15
11
  Install with: \`bun add sharp\`
16
12
  Original load error: ${err instanceof Error ? err.message : String(err)}`);
17
13
  }
18
14
  }
19
- function transform(pipeline) {
15
+ export function transform(pipeline) {
20
16
  return async (input) => {
21
- const sharp = await loadSharp();
22
- const bytes = input instanceof ArrayBuffer ? new Uint8Array(input) : input;
23
- const buf = Buffer.isBuffer(bytes) ? bytes : Buffer.from(bytes);
24
- const img = sharp(buf);
25
- const piped = await pipeline(img);
26
- return piped.toBuffer();
17
+ const sharp = await loadSharp(), bytes = input instanceof ArrayBuffer ? new Uint8Array(input) : input, buf = Buffer.isBuffer(bytes) ? bytes : Buffer.from(bytes), img = sharp(buf);
18
+ return (await pipeline(img)).toBuffer();
27
19
  };
28
20
  }
29
- function avatar(size = 512, quality = 85) {
21
+ export function avatar(size = 512, quality = 85) {
30
22
  return transform((img) => img.resize(size, size, { fit: "cover" }).webp({ quality }));
31
23
  }
32
- function resize(width, height, fit = "inside") {
24
+ export function resize(width, height, fit = "inside") {
33
25
  return transform((img) => img.resize(width, height, { fit }));
34
26
  }
35
- function stripMetadata() {
27
+ export function stripMetadata() {
36
28
  return transform((img) => img);
37
29
  }
38
- export {
39
- transform,
40
- stripMetadata,
41
- resize,
42
- avatar
43
- };