@stacksjs/utils 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/bytes.js ADDED
@@ -0,0 +1,55 @@
1
+ const DECIMAL_UNITS = ["B", "KB", "MB", "GB", "TB", "PB", "EB", "ZB", "YB"], BINARY_UNITS = ["B", "KiB", "MiB", "GiB", "TiB", "PiB", "EiB", "ZiB", "YiB"];
2
+ export function formatBytes(bytes, options = {}) {
3
+ const {
4
+ precision = 1,
5
+ binary = !1,
6
+ space = !0,
7
+ locale = "en-US",
8
+ minimumFractionDigits = 0,
9
+ maximumFractionDigits = precision
10
+ } = options;
11
+ if (!Number.isFinite(bytes))
12
+ throw TypeError(`Expected a finite number, got ${typeof bytes}: ${bytes}`);
13
+ const isNegative = bytes < 0, prefix = isNegative ? "-" : "";
14
+ if (isNegative)
15
+ bytes = -bytes;
16
+ if (bytes < 1) {
17
+ const numberString = bytes.toLocaleString(locale, {
18
+ minimumFractionDigits,
19
+ maximumFractionDigits
20
+ });
21
+ return `${prefix}${numberString}${space ? " " : ""}B`;
22
+ }
23
+ const base = binary ? 1024 : 1000, units = binary ? BINARY_UNITS : DECIMAL_UNITS, exponent = Math.min(Math.floor(Math.log(bytes) / Math.log(base)), units.length - 1), numberString = (bytes / base ** exponent).toLocaleString(locale, {
24
+ minimumFractionDigits,
25
+ maximumFractionDigits
26
+ }), unit = units[exponent];
27
+ return `${prefix}${numberString}${space ? " " : ""}${unit}`;
28
+ }
29
+ export function parseBytes(input) {
30
+ const match = input.match(/^(-?[\d.]+)\s*([A-Za-z]+)?$/);
31
+ if (!match)
32
+ throw Error(`Invalid byte string: ${input}`);
33
+ const [, numberStr, unit = "B"] = match;
34
+ if (numberStr === void 0)
35
+ throw Error(`Invalid byte string: ${input}`);
36
+ const number = Number.parseFloat(numberStr);
37
+ if (!Number.isFinite(number))
38
+ throw Error(`Invalid number in byte string: ${numberStr}`);
39
+ const normalizedUnit = unit.toUpperCase(), isBinary = normalizedUnit.endsWith("IB"), base = isBinary ? 1024 : 1000;
40
+ let exponent = 0;
41
+ const units = isBinary ? BINARY_UNITS : DECIMAL_UNITS;
42
+ for (let i = 0;i < units.length; i++)
43
+ if (units[i]?.toUpperCase() === normalizedUnit) {
44
+ exponent = i;
45
+ break;
46
+ }
47
+ return number * base ** exponent;
48
+ }
49
+ export function compareBytes(a, b) {
50
+ const bytesA = typeof a === "string" ? parseBytes(a) : a, bytesB = typeof b === "string" ? parseBytes(b) : b;
51
+ return bytesA - bytesB;
52
+ }
53
+ export const prettyBytes = formatBytes, readableSize = formatBytes;
54
+
55
+ export { formatBytes as default };
package/dist/clean.js ADDED
@@ -0,0 +1,13 @@
1
+ import { path as p } from "@stacksjs/path";
2
+ export async function cleanProject() {
3
+ await Bun.$`rm -rf ${p.projectPath("bun.lock")}`;
4
+ await Bun.$`rm -rf ${p.projectPath("yarn.lock")}`;
5
+ await Bun.$`rm -rf ${p.projectPath("node_modules/")}`;
6
+ await Bun.$`rm -rf ${p.frameworkPath("dist")}`;
7
+ await Bun.$`rm -rf ${p.frameworkPath("node_modules")}`;
8
+ await Bun.$`rm -rf ${p.frameworkPath("**/dist")}`;
9
+ await Bun.$`rm -rf ${p.frameworkPath("**/node_modules")}`;
10
+ await Bun.$`rm -rf ${p.frameworkCloudPath("cdk.out/")}`;
11
+ await Bun.$`rm -rf ${p.frameworkCloudPath("cdk.context.json")}`;
12
+ await Bun.$`rm -rf ${p.cloudPath("dist.zip")}`;
13
+ }
package/dist/colors.js ADDED
@@ -0,0 +1,100 @@
1
+ const isColorSupported = !process.env.NO_COLOR && (process.env.FORCE_COLOR || process.stdout?.isTTY), colors = {
2
+ reset: isColorSupported ? "\x1B[0m" : "",
3
+ black: isColorSupported ? "\x1B[30m" : "",
4
+ red: isColorSupported ? "\x1B[31m" : "",
5
+ green: isColorSupported ? "\x1B[32m" : "",
6
+ yellow: isColorSupported ? "\x1B[33m" : "",
7
+ blue: isColorSupported ? "\x1B[34m" : "",
8
+ magenta: isColorSupported ? "\x1B[35m" : "",
9
+ cyan: isColorSupported ? "\x1B[36m" : "",
10
+ white: isColorSupported ? "\x1B[37m" : "",
11
+ gray: isColorSupported ? "\x1B[90m" : "",
12
+ grey: isColorSupported ? "\x1B[90m" : "",
13
+ lightRed: isColorSupported ? "\x1B[91m" : "",
14
+ lightGreen: isColorSupported ? "\x1B[92m" : "",
15
+ lightYellow: isColorSupported ? "\x1B[93m" : "",
16
+ lightBlue: isColorSupported ? "\x1B[94m" : "",
17
+ lightMagenta: isColorSupported ? "\x1B[95m" : "",
18
+ lightCyan: isColorSupported ? "\x1B[96m" : "",
19
+ lightGray: isColorSupported ? "\x1B[37m" : "",
20
+ lightGrey: isColorSupported ? "\x1B[37m" : "",
21
+ bgBlack: isColorSupported ? "\x1B[40m" : "",
22
+ bgRed: isColorSupported ? "\x1B[41m" : "",
23
+ bgGreen: isColorSupported ? "\x1B[42m" : "",
24
+ bgYellow: isColorSupported ? "\x1B[43m" : "",
25
+ bgBlue: isColorSupported ? "\x1B[44m" : "",
26
+ bgMagenta: isColorSupported ? "\x1B[45m" : "",
27
+ bgCyan: isColorSupported ? "\x1B[46m" : "",
28
+ bgWhite: isColorSupported ? "\x1B[47m" : "",
29
+ bgLightRed: isColorSupported ? "\x1B[101m" : "",
30
+ bgLightGreen: isColorSupported ? "\x1B[102m" : "",
31
+ bgLightYellow: isColorSupported ? "\x1B[103m" : "",
32
+ bgLightBlue: isColorSupported ? "\x1B[104m" : "",
33
+ bgLightMagenta: isColorSupported ? "\x1B[105m" : "",
34
+ bgLightCyan: isColorSupported ? "\x1B[106m" : "",
35
+ bold: isColorSupported ? "\x1B[1m" : "",
36
+ dim: isColorSupported ? "\x1B[2m" : "",
37
+ italic: isColorSupported ? "\x1B[3m" : "",
38
+ underline: isColorSupported ? "\x1B[4m" : "",
39
+ inverse: isColorSupported ? "\x1B[7m" : "",
40
+ hidden: isColorSupported ? "\x1B[8m" : "",
41
+ strikethrough: isColorSupported ? "\x1B[9m" : ""
42
+ };
43
+ function createColorFn(code, endCode = colors.reset) {
44
+ return (text) => {
45
+ if (!isColorSupported)
46
+ return String(text);
47
+ return `${code}${text}${endCode}`;
48
+ };
49
+ }
50
+ export const black = createColorFn(colors.black), red = createColorFn(colors.red), green = createColorFn(colors.green), yellow = createColorFn(colors.yellow), blue = createColorFn(colors.blue), magenta = createColorFn(colors.magenta), cyan = createColorFn(colors.cyan), white = createColorFn(colors.white), gray = createColorFn(colors.gray), grey = gray, lightRed = createColorFn(colors.lightRed), lightGreen = createColorFn(colors.lightGreen), lightYellow = createColorFn(colors.lightYellow), lightBlue = createColorFn(colors.lightBlue), lightMagenta = createColorFn(colors.lightMagenta), lightCyan = createColorFn(colors.lightCyan), lightGray = createColorFn(colors.lightGray), lightGrey = lightGray, bgBlack = createColorFn(colors.bgBlack), bgRed = createColorFn(colors.bgRed), bgGreen = createColorFn(colors.bgGreen), bgYellow = createColorFn(colors.bgYellow), bgBlue = createColorFn(colors.bgBlue), bgMagenta = createColorFn(colors.bgMagenta), bgCyan = createColorFn(colors.bgCyan), bgWhite = createColorFn(colors.bgWhite), bgLightRed = createColorFn(colors.bgLightRed), bgLightGreen = createColorFn(colors.bgLightGreen), bgLightYellow = createColorFn(colors.bgLightYellow), bgLightBlue = createColorFn(colors.bgLightBlue), bgLightMagenta = createColorFn(colors.bgLightMagenta), bgLightCyan = createColorFn(colors.bgLightCyan), bold = createColorFn(colors.bold), dim = createColorFn(colors.dim), italic = createColorFn(colors.italic), underline = createColorFn(colors.underline), inverse = createColorFn(colors.inverse), hidden = createColorFn(colors.hidden), strikethrough = createColorFn(colors.strikethrough), reset = createColorFn(colors.reset, "");
51
+ export function stripColors(text) {
52
+ return text.replace(/\x1B\[\d+m/g, "");
53
+ }
54
+ export function supportsColor() {
55
+ return !!isColorSupported;
56
+ }
57
+ export default {
58
+ black,
59
+ red,
60
+ green,
61
+ yellow,
62
+ blue,
63
+ magenta,
64
+ cyan,
65
+ white,
66
+ gray,
67
+ grey,
68
+ lightRed,
69
+ lightGreen,
70
+ lightYellow,
71
+ lightBlue,
72
+ lightMagenta,
73
+ lightCyan,
74
+ lightGray,
75
+ lightGrey,
76
+ bgBlack,
77
+ bgRed,
78
+ bgGreen,
79
+ bgYellow,
80
+ bgBlue,
81
+ bgMagenta,
82
+ bgCyan,
83
+ bgWhite,
84
+ bgLightRed,
85
+ bgLightGreen,
86
+ bgLightYellow,
87
+ bgLightBlue,
88
+ bgLightMagenta,
89
+ bgLightCyan,
90
+ bold,
91
+ dim,
92
+ italic,
93
+ underline,
94
+ inverse,
95
+ hidden,
96
+ strikethrough,
97
+ reset,
98
+ stripColors,
99
+ supportsColor
100
+ };
package/dist/config.js ADDED
@@ -0,0 +1,23 @@
1
+ export {
2
+ defineApp,
3
+ defineCache,
4
+ defineCdn,
5
+ defineChat,
6
+ defineCli,
7
+ defineDatabase,
8
+ defineDependencies,
9
+ defineDns,
10
+ defineEmail,
11
+ defineEmailConfig,
12
+ defineGit,
13
+ defineHashing,
14
+ defineLibrary,
15
+ defineNotification,
16
+ definePayment,
17
+ defineQueue,
18
+ defineSearchEngine,
19
+ defineServices,
20
+ defineSms,
21
+ defineFilesystems,
22
+ defineUi
23
+ } from "@stacksjs/config";
@@ -0,0 +1,77 @@
1
+ export function debounce(fn, wait = 0, options = {}) {
2
+ const { leading = !1, trailing = !0 } = options;
3
+ let timeout = null, lastArgs = null, lastThis = null, result;
4
+ const invokeFunc = () => {
5
+ if (lastArgs) {
6
+ result = fn.apply(lastThis, lastArgs);
7
+ lastArgs = null;
8
+ lastThis = null;
9
+ }
10
+ return result;
11
+ }, cancel = () => {
12
+ if (timeout) {
13
+ clearTimeout(timeout);
14
+ timeout = null;
15
+ }
16
+ lastArgs = null;
17
+ lastThis = null;
18
+ }, flush = () => {
19
+ if (timeout) {
20
+ clearTimeout(timeout);
21
+ timeout = null;
22
+ return invokeFunc();
23
+ }
24
+ return result;
25
+ }, debounced = function(...args) {
26
+ lastArgs = args;
27
+ lastThis = this;
28
+ const shouldCallNow = leading && !timeout;
29
+ if (timeout)
30
+ clearTimeout(timeout);
31
+ timeout = setTimeout(() => {
32
+ timeout = null;
33
+ if (trailing && lastArgs)
34
+ invokeFunc();
35
+ }, wait);
36
+ if (shouldCallNow)
37
+ return invokeFunc();
38
+ return result;
39
+ };
40
+ debounced.cancel = cancel;
41
+ debounced.flush = flush;
42
+ return debounced;
43
+ }
44
+ export function throttle(fn, wait = 0) {
45
+ let timeout = null, lastRun = 0, lastArgs = null, lastThis = null;
46
+ const invokeFunc = () => {
47
+ if (lastArgs) {
48
+ fn.apply(lastThis, lastArgs);
49
+ lastArgs = null;
50
+ lastThis = null;
51
+ lastRun = Date.now();
52
+ }
53
+ }, cancel = () => {
54
+ if (timeout) {
55
+ clearTimeout(timeout);
56
+ timeout = null;
57
+ }
58
+ lastArgs = null;
59
+ lastThis = null;
60
+ }, throttled = function(...args) {
61
+ lastArgs = args;
62
+ lastThis = this;
63
+ const timeSinceLastRun = Date.now() - lastRun;
64
+ if (timeSinceLastRun >= wait)
65
+ invokeFunc();
66
+ else if (!timeout)
67
+ timeout = setTimeout(() => {
68
+ timeout = null;
69
+ invokeFunc();
70
+ }, wait - timeSinceLastRun);
71
+ };
72
+ throttled.cancel = cancel;
73
+ return throttled;
74
+ }
75
+ export function delay(ms) {
76
+ return new Promise((resolve) => setTimeout(resolve, ms));
77
+ }
package/dist/detect.js ADDED
@@ -0,0 +1,65 @@
1
+ export function detectIndent(text) {
2
+ const lines = text.split(`
3
+ `), indents = [];
4
+ for (const line of lines) {
5
+ if (!line.trim())
6
+ continue;
7
+ const match = line.match(/^(\s+)/);
8
+ if (match && match[1] !== void 0)
9
+ indents.push(match[1]);
10
+ }
11
+ if (indents.length === 0)
12
+ return { amount: 0, type: null, indent: "" };
13
+ const indentCounts = new Map;
14
+ for (const indent of indents)
15
+ indentCounts.set(indent, (indentCounts.get(indent) || 0) + 1);
16
+ let mostCommon = "", maxCount = 0;
17
+ for (const [indent, count] of indentCounts)
18
+ if (count > maxCount) {
19
+ maxCount = count;
20
+ mostCommon = indent;
21
+ }
22
+ if (mostCommon.includes("\t"))
23
+ return {
24
+ amount: mostCommon.length,
25
+ type: "tab",
26
+ indent: mostCommon
27
+ };
28
+ return {
29
+ amount: mostCommon.length,
30
+ type: "space",
31
+ indent: mostCommon
32
+ };
33
+ }
34
+ export function detectNewline(text) {
35
+ if (!text)
36
+ return null;
37
+ if (text.includes(`\r
38
+ `))
39
+ return `\r
40
+ `;
41
+ if (text.includes(`
42
+ `))
43
+ return `
44
+ `;
45
+ if (text.includes("\r"))
46
+ return "\r";
47
+ return null;
48
+ }
49
+ export function detectNewlineGraceful(text, fallback = `
50
+ `) {
51
+ return detectNewline(text) || fallback;
52
+ }
53
+ export function normalizeNewlines(text, newline = `
54
+ `) {
55
+ return text.replace(/\r\n|\r|\n/g, newline);
56
+ }
57
+ export function countNewlines(text) {
58
+ const crlf = (text.match(/\r\n/g) || []).length, cr = (text.match(/\r(?!\n)/g) || []).length, lf = (text.match(/(?<!\r)\n/g) || []).length;
59
+ return {
60
+ crlf,
61
+ lf,
62
+ cr,
63
+ total: crlf + lf + cr
64
+ };
65
+ }
package/dist/equal.js ADDED
@@ -0,0 +1,27 @@
1
+ import { getTypeName } from "@stacksjs/types";
2
+ export function isDeepEqual(value1, value2, seen = new WeakMap) {
3
+ if (value1 === value2)
4
+ return !0;
5
+ if (typeof value1 === "number" && typeof value2 === "number" && Number.isNaN(value1) && Number.isNaN(value2))
6
+ return !0;
7
+ const type1 = getTypeName(value1), type2 = getTypeName(value2);
8
+ if (type1 !== type2)
9
+ return !1;
10
+ if (value1 && typeof value1 === "object") {
11
+ if (seen.get(value1) === value2)
12
+ return !0;
13
+ seen.set(value1, value2);
14
+ }
15
+ if (type1 === "array") {
16
+ if (value1.length !== value2.length)
17
+ return !1;
18
+ return value1.every((item, i) => isDeepEqual(item, value2[i], seen));
19
+ }
20
+ if (type1 === "object") {
21
+ const keyArr = Object.keys(value1);
22
+ if (keyArr.length !== Object.keys(value2).length)
23
+ return !1;
24
+ return keyArr.every((key) => isDeepEqual(value1[key], value2[key], seen));
25
+ }
26
+ return Object.is(value1, value2);
27
+ }
package/dist/errors.js ADDED
@@ -0,0 +1,44 @@
1
+ export function getErrorMessage(e) {
2
+ if (e instanceof Error)
3
+ return e.message;
4
+ if (typeof e === "string")
5
+ return e;
6
+ if (typeof e === "number" || typeof e === "boolean")
7
+ return String(e);
8
+ if (e && typeof e === "object" && "message" in e && typeof e.message === "string")
9
+ return e.message;
10
+ if (e == null)
11
+ return "Unknown error";
12
+ try {
13
+ return String(e);
14
+ } catch {
15
+ return "Unknown error";
16
+ }
17
+ }
18
+ export function getErrorStack(e) {
19
+ if (e instanceof Error)
20
+ return e.stack;
21
+ if (e && typeof e === "object" && "stack" in e && typeof e.stack === "string")
22
+ return e.stack;
23
+ return;
24
+ }
25
+ export function getErrorCode(e) {
26
+ if (e && typeof e === "object" && "code" in e && typeof e.code === "string")
27
+ return e.code;
28
+ return;
29
+ }
30
+ export function getErrorStatusCode(e) {
31
+ if (!e || typeof e !== "object")
32
+ return;
33
+ const obj = e;
34
+ if (typeof obj.statusCode === "number" && Number.isFinite(obj.statusCode))
35
+ return obj.statusCode;
36
+ if (typeof obj.status === "number" && Number.isFinite(obj.status))
37
+ return obj.status;
38
+ return;
39
+ }
40
+ export function toError(e) {
41
+ if (e instanceof Error)
42
+ return e;
43
+ return Error(getErrorMessage(e), { cause: e });
44
+ }
@@ -0,0 +1 @@
1
+ export { getExportsSize } from "./size";
package/dist/find.js ADDED
@@ -0,0 +1,68 @@
1
+ import fs from "node:fs/promises";
2
+ import os from "node:os";
3
+ import path from "node:path";
4
+ import { italic } from "@stacksjs/cli";
5
+ import { log } from "@stacksjs/logging";
6
+ const targetFileName = "buddy", alwaysExcludePatterns = [
7
+ "node_modules",
8
+ "dist",
9
+ "vendor",
10
+ "storage/framework",
11
+ /.*out.*/,
12
+ /.*\/\..*/
13
+ ], homeOnlyExcludePatterns = [
14
+ `${os.homedir()}/Documents`,
15
+ `${os.homedir()}/Pictures`,
16
+ `${os.homedir()}/Library`,
17
+ `${os.homedir()}/.Trash`
18
+ ];
19
+ export async function findStacksProjects(dir, options) {
20
+ const dirWasExplicit = !!dir;
21
+ dir = dir || os.homedir();
22
+ const excludePatterns = dirWasExplicit ? alwaysExcludePatterns : [...alwaysExcludePatterns, ...homeOnlyExcludePatterns];
23
+ if (!options?.quiet) {
24
+ log.info(`Searching for Stacks projects in: ${italic(dir)}`);
25
+ log.info("This may take a few moments...");
26
+ console.log("");
27
+ console.log(italic(" Please note, while Stacks is searching for projects on your machine,"));
28
+ console.log(italic(" you may be asked for permissions to scan certain directories."));
29
+ console.log("");
30
+ log.debug(`Excluding directories: ${excludePatterns.join(", ")}`);
31
+ }
32
+ const foundProjects = await searchDirectory(dir, excludePatterns);
33
+ if (!foundProjects)
34
+ throw Error("No Stacks projects found");
35
+ return foundProjects;
36
+ }
37
+ async function searchDirectory(directory, excludePatterns) {
38
+ const foundProjects = [];
39
+ if (excludePatterns.some((pattern) => typeof pattern === "string" ? directory.includes(pattern) : pattern.test(directory)))
40
+ return foundProjects;
41
+ let items;
42
+ try {
43
+ items = await fs.readdir(directory, { withFileTypes: !0 });
44
+ } catch (error) {
45
+ console.error(`Error reading directory ${directory}:`, error);
46
+ return foundProjects;
47
+ }
48
+ let buddyFileFound = !1, storageDirFound = !1;
49
+ for (const item of items) {
50
+ if (item.isFile() && item.name === targetFileName)
51
+ buddyFileFound = !0;
52
+ if (item.isDirectory()) {
53
+ const fullPath = path.join(directory, item.name);
54
+ if (item.name === "storage") {
55
+ const storagePath = path.join(fullPath, "framework/core/buddy");
56
+ try {
57
+ await fs.access(storagePath);
58
+ storageDirFound = !0;
59
+ } catch {}
60
+ }
61
+ const subDirProjects = await searchDirectory(fullPath, excludePatterns);
62
+ foundProjects.push(...subDirProjects);
63
+ }
64
+ }
65
+ if (buddyFileFound && storageDirFound)
66
+ foundProjects.push(directory);
67
+ return foundProjects;
68
+ }
package/dist/git.js ADDED
@@ -0,0 +1,11 @@
1
+ import { execSync } from "node:child_process";
2
+ import { handleError } from "@stacksjs/error-handling";
3
+ export function isGitClean() {
4
+ try {
5
+ execSync("git diff-index --quiet HEAD --");
6
+ return !0;
7
+ } catch (error) {
8
+ handleError(error);
9
+ return !1;
10
+ }
11
+ }
package/dist/glob.d.ts ADDED
@@ -0,0 +1 @@
1
+ export { glob } from '@stacksjs/storage';
package/dist/glob.js ADDED
@@ -0,0 +1 @@
1
+ export { glob } from "@stacksjs/storage";
package/dist/hash.js ADDED
@@ -0,0 +1,36 @@
1
+ import { config } from "@stacksjs/config";
2
+ import { log } from "@stacksjs/logging";
3
+ import { path } from "@stacksjs/path";
4
+ import { hashPaths } from "@stacksjs/storage";
5
+ export function originRequestFunctionHash() {
6
+ try {
7
+ return hashPaths(path.cloudPath("src/edge"));
8
+ } catch (error) {
9
+ log.error("Are we in a Docker container? Failed to hash paths. Error below:");
10
+ log.error(error);
11
+ return;
12
+ }
13
+ }
14
+ export function websiteSourceHash() {
15
+ const docsSrc = [
16
+ path.projectPath("docs"),
17
+ path.frameworkPath("docs/dist")
18
+ ], websiteSrc = [
19
+ path.projectPath("resources/views"),
20
+ path.projectPath("resources/assets"),
21
+ path.projectPath("resources/lang"),
22
+ path.projectPath("resources/functions"),
23
+ path.projectPath("resources/components"),
24
+ path.projectPath("resources/modules"),
25
+ path.projectPath("resources/stores"),
26
+ path.frameworkPath("views/web")
27
+ ];
28
+ return config.app.docMode === !0 ? hashPaths(docsSrc) : hashPaths(websiteSrc);
29
+ }
30
+ export function docsSourceHash() {
31
+ const docsSrc = [
32
+ path.projectPath("docs"),
33
+ path.frameworkPath("docs/dist")
34
+ ];
35
+ return hashPaths(docsSrc);
36
+ }
@@ -0,0 +1,101 @@
1
+ import { runAction } from "@stacksjs/actions";
2
+ import { log, runCommand } from "@stacksjs/cli";
3
+ import { app, ui } from "@stacksjs/config";
4
+ import { Action } from "@stacksjs/enums";
5
+ import { err, handleError, ok } from "@stacksjs/error-handling";
6
+ import { frameworkPath, projectPath } from "@stacksjs/path";
7
+ import { fs, readJsonFile, readPackageJson, readTextFile, writeTextFile } from "@stacksjs/storage";
8
+ export async function packageManager() {
9
+ const { packageManager } = await readPackageJson(frameworkPath("package.json"));
10
+ return packageManager;
11
+ }
12
+ export async function initProject() {
13
+ if (app.env !== "production")
14
+ log.info("Project not yet initialized, generating application key...");
15
+ else
16
+ handleError("Please run `buddy key:generate` to generate an application key");
17
+ const result = await runAction(Action.KeyGenerate, { cwd: projectPath() });
18
+ if (result.isErr)
19
+ return err(handleError(result.error));
20
+ log.info("Application key generated.");
21
+ return ok(result.value);
22
+ }
23
+ export async function ensureProjectIsInitialized() {
24
+ if (fs.existsSync(projectPath(".env")))
25
+ return await isAppKeySet();
26
+ if (fs.existsSync(projectPath(".env.example")))
27
+ fs.copyFileSync(projectPath(".env.example"), projectPath(".env"));
28
+ else
29
+ console.error("no .env.example file found");
30
+ return await isAppKeySet();
31
+ }
32
+ export async function installIfVersionMismatch() {}
33
+ export async function frameworkVersion() {
34
+ return (await readPackageJson(frameworkPath("package.json"))).version;
35
+ }
36
+ export async function isAppKeySet() {
37
+ const appKey = (await readTextFile(".env", projectPath())).data.split(`
38
+ `).find((line) => line.startsWith("APP_KEY="));
39
+ return !!(appKey && appKey.length > 16);
40
+ }
41
+ export function determineResetPreset(preset) {
42
+ if (preset === void 0 && ui.reset)
43
+ preset = ui.reset;
44
+ if (preset === null)
45
+ return [];
46
+ const resetImport = {
47
+ tailwind: 'import { tailwindPreflight as reset } from "@cwcss/crosswind"',
48
+ preflight: 'import { tailwindPreflight as reset } from "@cwcss/crosswind"',
49
+ forms: 'import { tailwindFormsPreflight as reset } from "@cwcss/crosswind"'
50
+ }[preset ?? "tailwind"];
51
+ return resetImport ? [resetImport] : [];
52
+ }
53
+ export function isManifest(obj) {
54
+ return obj && typeof obj === "object" && isOptionalString(obj.name) && isOptionalString(obj.version) && isOptionalString(obj.description);
55
+ }
56
+ export function isOptionalString(value) {
57
+ const type = typeof value;
58
+ return value === null || type === "undefined" || type === "string";
59
+ }
60
+ export async function setEnvValue(key, value) {
61
+ const file = await readTextFile(projectPath(".env")), escapedKey = key.replace(/[.*+?^${}()|[\]\\]/g, "\\$&"), keyPattern = new RegExp(`^${escapedKey}=.*$`, "m"), nextValue = `${key}=${value}`, data = keyPattern.test(file.data) ? file.data.replace(keyPattern, nextValue) : `${file.data}${file.data.endsWith(`
62
+ `) ? "" : `
63
+ `}${nextValue}
64
+ `;
65
+ await writeTextFile({
66
+ path: projectPath(".env"),
67
+ data
68
+ });
69
+ }
70
+ export async function runNpmScript(script, options) {
71
+ const { data: manifest } = await readJsonFile("package.json", frameworkPath());
72
+ if (isManifest(manifest) && hasScript(manifest, script))
73
+ return await runCommand(`bun run ${script}`, options);
74
+ return err(handleError(`The ${script} script does not exist in the package.json file.`));
75
+ }
76
+ export function hasScript(manifest, script) {
77
+ const scripts = manifest.scripts;
78
+ if (scripts && typeof scripts === "object")
79
+ return Boolean(scripts[script]);
80
+ return !1;
81
+ }
82
+ export function parseYaml(content) {
83
+ return Bun.YAML.parse(content);
84
+ }
85
+ export function determineDebugLevel(options) {
86
+ if (options?.verbose === !0)
87
+ return !0;
88
+ return app.debug === !0;
89
+ }
90
+ export function isIpv6(address) {
91
+ return address.family === "IPv6" || address.family === 6;
92
+ }
93
+ export function dumpYaml(content) {
94
+ const yaml = Bun.YAML;
95
+ if (typeof yaml.stringify === "function")
96
+ return yaml.stringify(content);
97
+ return JSON.stringify(content, null, 2);
98
+ }
99
+ export function loadYaml(content) {
100
+ return Bun.YAML.parse(content);
101
+ }
package/dist/index.js CHANGED
@@ -1,16 +1,23 @@
1
- // @bun
2
- import{path as L}from"@stacksjs/path";async function S$(){await Bun.$`rm -rf ${L.projectPath("bun.lock")}`,await Bun.$`rm -rf ${L.projectPath("yarn.lock")}`,await Bun.$`rm -rf ${L.projectPath("node_modules/")}`,await Bun.$`rm -rf ${L.frameworkPath("dist")}`,await Bun.$`rm -rf ${L.frameworkPath("node_modules")}`,await Bun.$`rm -rf ${L.frameworkPath("**/dist")}`,await Bun.$`rm -rf ${L.frameworkPath("**/node_modules")}`,await Bun.$`rm -rf ${L.frameworkCloudPath("cdk.out/")}`,await Bun.$`rm -rf ${L.frameworkCloudPath("cdk.context.json")}`,await Bun.$`rm -rf ${L.cloudPath("dist.zip")}`}import{defineApp as p$,defineCache as g$,defineCdn as b$,defineChat as m$,defineCli as d$,defineDatabase as u$,defineDependencies as c$,defineDns as n$,defineEmail as i$,defineEmailConfig as s$,defineGit as r$,defineHashing as a$,defineLibrary as o$,defineNotification as l$,definePayment as t$,defineQueue as e$,defineSearchEngine as $T,defineServices as TT,defineSms as fT,defineFilesystems as HT,defineUi as QT}from"@stacksjs/config";import{getTypeName as S}from"@stacksjs/types";function v($,T,f=new WeakMap){if($===T)return!0;if(typeof $==="number"&&typeof T==="number"&&Number.isNaN($)&&Number.isNaN(T))return!0;let H=S($),Q=S(T);if(H!==Q)return!1;if($&&typeof $==="object"){if(f.get($)===T)return!0;f.set($,T)}if(H==="array"){if($.length!==T.length)return!1;return $.every((X,_)=>v(X,T[_],f))}if(H==="object"){let X=Object.keys($);if(X.length!==Object.keys(T).length)return!1;return X.every((_)=>v($[_],T[_],f))}return Object.is($,T)}function $$($){if($ instanceof Error)return $.message;if(typeof $==="string")return $;if(typeof $==="number"||typeof $==="boolean")return String($);if($&&typeof $==="object"&&"message"in $&&typeof $.message==="string")return $.message;if($==null)return"Unknown error";try{return String($)}catch{return"Unknown error"}}function qT($){if($ instanceof Error)return $.stack;if($&&typeof $==="object"&&"stack"in $&&typeof $.stack==="string")return $.stack;return}function VT($){if($&&typeof $==="object"&&"code"in $&&typeof $.code==="string")return $.code;return}function _T($){if(!$||typeof $!=="object")return;let T=$;if(typeof T.statusCode==="number"&&Number.isFinite(T.statusCode))return T.statusCode;if(typeof T.status==="number"&&Number.isFinite(T.status))return T.status;return}function PT($){if($ instanceof Error)return $;return Error($$($),{cause:$})}import{stat as T$}from"fs/promises";var C=["B","KB","MB","GB","TB","PB","EB","ZB","YB"],p=["B","KiB","MiB","GiB","TiB","PiB","EiB","ZiB","YiB"];function I($,T={}){let{precision:f=1,binary:H=!1,space:Q=!0,locale:X="en-US",minimumFractionDigits:_=0,maximumFractionDigits:P=f}=T;if(!Number.isFinite($))throw TypeError(`Expected a finite number, got ${typeof $}: ${$}`);let B=$<0,J=B?"-":"";if(B)$=-$;if($<1){let e=$.toLocaleString(X,{minimumFractionDigits:_,maximumFractionDigits:P});return`${J}${e}${Q?" ":""}B`}let G=H?1024:1000,Y=H?p:C,U=Math.min(Math.floor(Math.log($)/Math.log(G)),Y.length-1),O=($/G**U).toLocaleString(X,{minimumFractionDigits:_,maximumFractionDigits:P}),W=Y[U];return`${J}${O}${Q?" ":""}${W}`}function y($){let T=$.match(/^(-?[\d.]+)\s*([A-Za-z]+)?$/);if(!T)throw Error(`Invalid byte string: ${$}`);let[,f,H="B"]=T;if(f===void 0)throw Error(`Invalid byte string: ${$}`);let Q=Number.parseFloat(f);if(!Number.isFinite(Q))throw Error(`Invalid number in byte string: ${f}`);let X=H.toUpperCase(),_=X.endsWith("IB"),P=_?1024:1000,B=0,J=_?p:C;for(let G=0;G<J.length;G++)if(J[G]?.toUpperCase()===X){B=G;break}return Q*P**B}function GT($,T){let f=typeof $==="string"?y($):$,H=typeof T==="string"?y(T):T;return f-H}var JT=I,UT=I;async function f$($){try{return(await T$($)).size}catch{return 0}}async function H$($){let T=[],f=0;try{let H=await Q$($);for(let Q of H){let X=await f$(Q.path);f+=X,T.push({name:Q.name,size:X,readable:I(X)})}}catch(H){}return{totalSize:f,totalReadable:I(f),exports:T.sort((H,Q)=>Q.size-H.size)}}async function Q$($){let T=[];try{let f=await Bun.$.throws(!1)`find ${$} -type f \\( -name "*.js" -o -name "*.mjs" -o -name "*.cjs" \\)`.text();for(let H of f.split(`
3
- `).filter(Boolean)){let Q=H.replace($,"").replace(/^\//,"");T.push({name:Q,path:H})}}catch{}return T}function X$($){return Math.floor($*0.3)}function Z$($){return Math.floor($*0.25)}function OT($){if($.exports.length===0)return"No exports found";let T=["Export Sizes:",""],f=Math.max(...$.exports.map((H)=>H.name.length));for(let H of $.exports){let Q=H.name.padEnd(f," ");T.push(` ${Q} ${H.readable}`)}return T.push(""),T.push(`Total: ${$.totalReadable}`),T.push(`Estimated gzipped: ${I(X$($.totalSize))}`),T.push(`Estimated brotli: ${I(Z$($.totalSize))}`),T.join(`
4
- `)}import g from"fs/promises";import D from"os";import b from"path";import{italic as R}from"@stacksjs/cli";import{log as z}from"@stacksjs/logging";var q$="buddy",m=["node_modules","dist","vendor","storage/framework",/.*out.*/,/.*\/\..*/],V$=[`${D.homedir()}/Documents`,`${D.homedir()}/Pictures`,`${D.homedir()}/Library`,`${D.homedir()}/.Trash`];async function zT($,T){let f=!!$;$=$||D.homedir();let H=f?m:[...m,...V$];if(!T?.quiet)z.info(`Searching for Stacks projects in: ${R($)}`),z.info("This may take a few moments..."),console.log(""),console.log(R(" Please note, while Stacks is searching for projects on your machine,")),console.log(R(" you may be asked for permissions to scan certain directories.")),console.log(""),z.debug(`Excluding directories: ${H.join(", ")}`);let Q=await d($,H);if(!Q)throw Error("No Stacks projects found");return Q}async function d($,T){let f=[];if(T.some((P)=>typeof P==="string"?$.includes(P):P.test($)))return f;let Q;try{Q=await g.readdir($,{withFileTypes:!0})}catch(P){return console.error(`Error reading directory ${$}:`,P),f}let X=!1,_=!1;for(let P of Q){if(P.isFile()&&P.name===q$)X=!0;if(P.isDirectory()){let B=b.join($,P.name);if(P.name==="storage"){let G=b.join(B,"framework/core/buddy");try{await g.access(G),_=!0}catch{}}let J=await d(B,T);f.push(...J)}}if(X&&_)f.push($);return f}import{execSync as _$}from"child_process";import{handleError as P$}from"@stacksjs/error-handling";function hT(){try{return _$("git diff-index --quiet HEAD --"),!0}catch($){return P$($),!1}}import{config as B$}from"@stacksjs/config";import{log as u}from"@stacksjs/logging";import{path as M}from"@stacksjs/path";import{hashPaths as E}from"@stacksjs/storage";function CT(){try{return E(M.cloudPath("src/edge"))}catch($){u.error("Are we in a Docker container? Failed to hash paths. Error below:"),u.error($);return}}function pT(){let $=[M.projectPath("docs"),M.frameworkPath("docs/dist")],T=[M.projectPath("resources/views"),M.projectPath("resources/assets"),M.projectPath("resources/lang"),M.projectPath("resources/functions"),M.projectPath("resources/components"),M.projectPath("resources/modules"),M.projectPath("resources/stores"),M.frameworkPath("views/web")];return B$.app.docMode===!0?E($):E(T)}function gT(){let $=[M.projectPath("docs"),M.frameworkPath("docs/dist")];return E($)}import{runAction as G$}from"@stacksjs/actions";import{log as c,runCommand as J$}from"@stacksjs/cli";import{app as s,ui as n}from"@stacksjs/config";import{Action as U$}from"@stacksjs/enums";import{err as r,handleError as x,ok as Y$}from"@stacksjs/error-handling";import{frameworkPath as h,projectPath as k}from"@stacksjs/path";import{fs as A,readJsonFile as K$,readPackageJson as a,readTextFile as o,writeTextFile as M$}from"@stacksjs/storage";async function rT(){let{packageManager:$}=await a(h("package.json"));return $}async function aT(){if(s.env!=="production")c.info("Project not yet initialized, generating application key...");else x("Please run `buddy key:generate` to generate an application key");let $=await G$(U$.KeyGenerate,{cwd:k()});if($.isErr)return r(x($.error));return c.info("Application key generated."),Y$($.value)}async function oT(){if(A.existsSync(k(".env")))return await i();if(A.existsSync(k(".env.example")))A.copyFileSync(k(".env.example"),k(".env"));else console.error("no .env.example file found");return await i()}async function lT(){}async function tT(){return(await a(h("package.json"))).version}async function i(){let f=(await o(".env",k())).data.split(`
5
- `).find((H)=>H.startsWith("APP_KEY="));return!!(f&&f.length>16)}function eT($){if($===void 0&&n.reset)$=n.reset;if($===null)return[];let H={tailwind:'import { tailwindPreflight as reset } from "@cwcss/crosswind"',preflight:'import { tailwindPreflight as reset } from "@cwcss/crosswind"',forms:'import { tailwindFormsPreflight as reset } from "@cwcss/crosswind"'}[$??"tailwind"];return H?[H]:[]}function O$($){return $&&typeof $==="object"&&w($.name)&&w($.version)&&w($.description)}function w($){let T=typeof $;return $===null||T==="undefined"||T==="string"}async function $f($,T){let f=await o(k(".env")),H=$.replace(/[.*+?^${}()|[\]\\]/g,"\\$&"),Q=new RegExp(`^${H}=.*$`,"m"),X=`${$}=${T}`,_=Q.test(f.data)?f.data.replace(Q,X):`${f.data}${f.data.endsWith(`
6
- `)?"":`
7
- `}${X}
8
- `;await M$({path:k(".env"),data:_})}async function Tf($,T){let{data:f}=await K$("package.json",h());if(O$(f)&&L$(f,$))return await J$(`bun run ${$}`,T);return r(x(`The ${$} script does not exist in the package.json file.`))}function L$($,T){let f=$.scripts;if(f&&typeof f==="object")return Boolean(f[T]);return!1}function ff($){return Bun.YAML.parse($)}function Hf($){if($?.verbose===!0)return!0;return s.debug===!0}function Qf($){return $.family==="IPv6"||$.family===6}function Xf($){let T=Bun.YAML;if(typeof T.stringify==="function")return T.stringify($);return JSON.stringify($,null,2)}function Zf($){return Bun.YAML.parse($)}class k${static macros=new Map;static macro($,T,f=!1){if(this.macros.has($)&&!f)throw Error(`Macro "${$}" is already registered`);this.macros.set($,T),Object.defineProperty(this.prototype,$,{value:T,writable:!0,configurable:!0,enumerable:!1})}static mixin($,T=!0){let f=Object.getOwnPropertyNames($);for(let H of f){if(H==="constructor")continue;if(this.macros.has(H)&&!T)continue;let Q=Object.getOwnPropertyDescriptor($,H);if(Q&&typeof Q.value==="function")this.macro(H,Q.value,T)}}static hasMacro($){return this.macros.has($)}static flushMacros(){for(let $ of this.macros.keys())delete this.prototype[$];this.macros.clear()}static getMacros(){return Array.from(this.macros.keys())}callMacro($,...T){let f=this.constructor.macros.get($);if(!f)throw Error(`Macro "${$}" is not registered`);return f.apply(this,T)}}function Vf($=class{}){return class extends ${static macros=new Map;static macro(T,f,H=!1){if(this.macros.has(T)&&!H)throw Error(`Macro "${T}" is already registered`);this.macros.set(T,f),Object.defineProperty(this.prototype,T,{value:f,writable:!0,configurable:!0,enumerable:!1})}static mixin(T,f=!0){let H=Object.getOwnPropertyNames(T);for(let Q of H){if(Q==="constructor")continue;if(this.macros.has(Q)&&!f)continue;let X=Object.getOwnPropertyDescriptor(T,Q);if(X&&typeof X.value==="function")this.macro(Q,X.value,f)}}static hasMacro(T){return this.macros.has(T)}static flushMacros(){for(let T of this.macros.keys())delete this.prototype[T];this.macros.clear()}static getMacros(){return Array.from(this.macros.keys())}}}function _f($){let T=new Map;return $.macro=function(f,H,Q=!1){if(T.has(f)&&!Q)throw Error(`Macro "${f}" is already registered`);T.set(f,H),Object.defineProperty($.prototype,f,{value:H,writable:!0,configurable:!0,enumerable:!1})},$.mixin=function(f,H=!0){let Q=Object.getOwnPropertyNames(f);for(let X of Q){if(X==="constructor")continue;if(T.has(X)&&!H)continue;let _=Object.getOwnPropertyDescriptor(f,X);if(_&&typeof _.value==="function")$.macro(X,_.value,H)}},$.hasMacro=function(f){return T.has(f)},$.flushMacros=function(){for(let f of T.keys())delete $.prototype[f];T.clear()},$.getMacros=function(){return Array.from(T.keys())},$}function Jf($,T){if(typeof $!=="string"||$.length===0)return T;try{return JSON.parse($)}catch{return T}}function Uf($){if(typeof $!=="string")return{ok:!1,reason:"not-string"};if($.length===0)return{ok:!1,reason:"empty"};try{return{ok:!0,value:JSON.parse($)}}catch(T){return{ok:!1,reason:"malformed",error:T}}}function Yf($,T){let f=new WeakSet;return JSON.stringify($,(H,Q)=>{if(typeof Q==="bigint")return Q.toString();if(Q&&typeof Q==="object"){if(f.has(Q))return"[Circular]";f.add(Q)}return Q},T)}var W$="0.70.87";var Lf=Bun.semver;function kf($,T){return Bun.semver.order($,T)===1}function If($,T){return Bun.semver.order($,T)===-1}function Wf($,T){return Bun.semver.order($,T)===0}function Df($,T){return Bun.semver.order($,T)>=0}function Ef($,T){return Bun.semver.order($,T)<=0}function N(...$){let T={};for(let f of $){if(!f||typeof f!=="object")continue;for(let H in f){let Q=f[H],X=T[H];if(Q===void 0)continue;if(Array.isArray(Q))T[H]=Array.isArray(X)?[...X,...Q]:[...Q];else if(Q&&typeof Q==="object"&&!E$(Q))T[H]=N(X||{},Q);else T[H]=Q}}return T}function Rf($){return(...T)=>{return N($,...T)}}function D$($,...T){return N({},...T,$)}function E$($){if($ instanceof Date)return!0;if($ instanceof RegExp)return!0;if($ instanceof Error)return!0;if($ instanceof Promise)return!0;if($ instanceof Map)return!0;if($ instanceof Set)return!0;if($ instanceof WeakMap)return!0;if($ instanceof WeakSet)return!0;if(ArrayBuffer.isView($))return!0;return!1}var zf=D$,Af=N;function xf($){let T=$.split(`
9
- `),f=[];for(let P of T){if(!P.trim())continue;let B=P.match(/^(\s+)/);if(B&&B[1]!==void 0)f.push(B[1])}if(f.length===0)return{amount:0,type:null,indent:""};let H=new Map;for(let P of f)H.set(P,(H.get(P)||0)+1);let Q="",X=0;for(let[P,B]of H)if(B>X)X=B,Q=P;if(Q.includes("\t"))return{amount:Q.length,type:"tab",indent:Q};return{amount:Q.length,type:"space",indent:Q}}function N$($){if(!$)return null;if($.includes(`\r
10
- `))return`\r
11
- `;if($.includes(`
12
- `))return`
13
- `;if($.includes("\r"))return"\r";return null}function hf($,T=`
14
- `){return N$($)||T}function Ff($,T=`
15
- `){return $.replace(/\r\n|\r|\n/g,T)}function jf($){let T=($.match(/\r\n/g)||[]).length,f=($.match(/\r(?!\n)/g)||[]).length,H=($.match(/(?<!\r)\n/g)||[]).length;return{crlf:T,lf:H,cr:f,total:T+H+f}}function vf($,T=0,f={}){let{leading:H=!1,trailing:Q=!0}=f,X=null,_=null,P=null,B,J=()=>{if(_)B=$.apply(P,_),_=null,P=null;return B},G=()=>{if(X)clearTimeout(X),X=null;_=null,P=null},Y=()=>{if(X)return clearTimeout(X),X=null,J();return B},U=function(...K){_=K,P=this;let O=H&&!X;if(X)clearTimeout(X);if(X=setTimeout(()=>{if(X=null,Q&&_)J()},T),O)return J();return B};return U.cancel=G,U.flush=Y,U}function yf($,T=0){let f=null,H=0,Q=null,X=null,_=()=>{if(Q)$.apply(X,Q),Q=null,X=null,H=Date.now()},P=()=>{if(f)clearTimeout(f),f=null;Q=null,X=null},B=function(...J){Q=J,X=this;let Y=Date.now()-H;if(Y>=T)_();else if(!f)f=setTimeout(()=>{f=null,_()},T-Y)};return B.cancel=P,B}function Cf($){return new Promise((T)=>setTimeout(T,$))}var Z=!process.env.NO_COLOR&&(process.env.FORCE_COLOR||process.stdout?.isTTY),q={reset:Z?"\x1B[0m":"",black:Z?"\x1B[30m":"",red:Z?"\x1B[31m":"",green:Z?"\x1B[32m":"",yellow:Z?"\x1B[33m":"",blue:Z?"\x1B[34m":"",magenta:Z?"\x1B[35m":"",cyan:Z?"\x1B[36m":"",white:Z?"\x1B[37m":"",gray:Z?"\x1B[90m":"",grey:Z?"\x1B[90m":"",lightRed:Z?"\x1B[91m":"",lightGreen:Z?"\x1B[92m":"",lightYellow:Z?"\x1B[93m":"",lightBlue:Z?"\x1B[94m":"",lightMagenta:Z?"\x1B[95m":"",lightCyan:Z?"\x1B[96m":"",lightGray:Z?"\x1B[37m":"",lightGrey:Z?"\x1B[37m":"",bgBlack:Z?"\x1B[40m":"",bgRed:Z?"\x1B[41m":"",bgGreen:Z?"\x1B[42m":"",bgYellow:Z?"\x1B[43m":"",bgBlue:Z?"\x1B[44m":"",bgMagenta:Z?"\x1B[45m":"",bgCyan:Z?"\x1B[46m":"",bgWhite:Z?"\x1B[47m":"",bgLightRed:Z?"\x1B[101m":"",bgLightGreen:Z?"\x1B[102m":"",bgLightYellow:Z?"\x1B[103m":"",bgLightBlue:Z?"\x1B[104m":"",bgLightMagenta:Z?"\x1B[105m":"",bgLightCyan:Z?"\x1B[106m":"",bold:Z?"\x1B[1m":"",dim:Z?"\x1B[2m":"",italic:Z?"\x1B[3m":"",underline:Z?"\x1B[4m":"",inverse:Z?"\x1B[7m":"",hidden:Z?"\x1B[8m":"",strikethrough:Z?"\x1B[9m":""};function V($,T=q.reset){return(f)=>{if(!Z)return String(f);return`${$}${f}${T}`}}var gf=V(q.black),bf=V(q.red),mf=V(q.green),df=V(q.yellow),uf=V(q.blue),cf=V(q.magenta),nf=V(q.cyan),sf=V(q.white),R$=V(q.gray),rf=R$,af=V(q.lightRed),of=V(q.lightGreen),lf=V(q.lightYellow),tf=V(q.lightBlue),ef=V(q.lightMagenta),$0=V(q.lightCyan),z$=V(q.lightGray),T0=z$,f0=V(q.bgBlack),H0=V(q.bgRed),Q0=V(q.bgGreen),X0=V(q.bgYellow),Z0=V(q.bgBlue),q0=V(q.bgMagenta),V0=V(q.bgCyan),_0=V(q.bgWhite),P0=V(q.bgLightRed),B0=V(q.bgLightGreen),G0=V(q.bgLightYellow),J0=V(q.bgLightBlue),U0=V(q.bgLightMagenta),Y0=V(q.bgLightCyan),K0=V(q.bold),M0=V(q.dim),O0=V(q.italic),L0=V(q.underline),k0=V(q.inverse),I0=V(q.hidden),W0=V(q.strikethrough),D0=V(q.reset,"");function E0($){return $.replace(/\x1B\[\d+m/g,"")}function N0(){return!!Z}function A$($,T={}){let{align:f=[],padding:H=!0,delimiter:Q="|",delimiterStart:X=!0,delimiterEnd:_=!0,alignDelimiter:P="-"}=T;if(!$||$.length===0)return"";let B=$.map((U)=>U.map((K)=>{if(K===null||K===void 0)return"";return String(K)})),J=Math.max(...B.map((U)=>U.length)),G=Array.from({length:J}).fill(0);for(let U of B)for(let K=0;K<U.length;K++){let O=U[K]?.length??0;if(O>(G[K]??0))G[K]=O}let Y=[];if(B.length>0){let U=B[0]??[];Y.push(F(U,G,H,Q,X,_));let K=G.map((O,W)=>{let j=x$(f[W]);return w$(O,j,P)});Y.push(F(K,G,H,Q,X,_));for(let O=1;O<B.length;O++){let W=B[O]??[];Y.push(F(W,G,H,Q,X,_))}}return Y.join(`
16
- `)}function F($,T,f,H,Q,X){let _=$.map((J,G)=>{let Y=T[G]??0;return J.padEnd(Y," ")}),P=f?" ":"",B=_.map((J)=>`${P}${J}${P}`).join(H);if(Q)B=H+B;if(X)B=B+H;return B}function w$($,T,f){let H=T==="center"?3:T?2:1;if($<H)$=H;let Q=f.repeat($);if(T==="left")Q=`:${Q.slice(1)}`;else if(T==="right")Q=Q.slice(0,-1)+":";else if(T==="center")Q=`:${Q.slice(2)}:`;return Q}function x$($){if(!$)return null;switch($){case"l":case"left":return"left";case"c":case"center":return"center";case"r":case"right":return"right";default:return null}}function z0($,T={}){if(!$||$.length===0)return"";let f=Array.from(new Set($.flatMap((Q)=>Object.keys(Q)))),H=[f,...$.map((Q)=>f.map((X)=>Q[X]))];return A$(H,T)}function h$(){return typeof window<"u"&&"ResizeObserver"in window}function l(){if(h$())return window.ResizeObserver;return class{callback;observedElements=new Set;rafId=null;constructor(T){this.callback=T}observe(T){if(!this.observedElements.has(T))this.observedElements.add(T),this.scheduleCheck()}unobserve(T){if(this.observedElements.delete(T),this.observedElements.size===0&&this.rafId!==null)(typeof cancelAnimationFrame<"u"?cancelAnimationFrame:clearTimeout)(this.rafId),this.rafId=null}disconnect(){if(this.observedElements.clear(),this.rafId!==null)(typeof cancelAnimationFrame<"u"?cancelAnimationFrame:clearTimeout)(this.rafId),this.rafId=null}scheduleCheck(){if(this.rafId!==null)return;let T=typeof requestAnimationFrame<"u"?requestAnimationFrame:setTimeout;this.rafId=T(()=>{if(this.check(),this.rafId=null,this.observedElements.size>0)this.scheduleCheck()})}check(){let T=[];for(let f of this.observedElements){let H=f.getBoundingClientRect(),Q={target:f,contentRect:H,borderBoxSize:[{inlineSize:H.width,blockSize:H.height}],contentBoxSize:[{inlineSize:H.width,blockSize:H.height}],devicePixelContentBoxSize:[{inlineSize:H.width,blockSize:H.height}]};T.push(Q)}if(T.length>0)this.callback(T,this)}}}function F$($,T){let H=new(l())($),Q=Array.isArray(T)?T:[T];for(let X of Q)H.observe(X);return()=>{H.disconnect()}}function w0($,T){return F$((f)=>{let H=f.find((Q)=>Q.target===$);if(H)T(H)},$)}var x0=l();class t{passable;pipes=[];method="handle";static send($){let T=new t;return T.passable=$,T}through($){return this.pipes=$,this}pipe(...$){return this.pipes.push(...$),this}via($){return this.method=$,this}then($){return this.pipes.reduceRight((f,H)=>{return(Q)=>{if(typeof H==="function")return H(Q,f);let X=H[this.method];if(typeof X==="function")return X.call(H,Q,f);return f(Q)}},$)(this.passable)}thenReturn(){return this.then(($)=>$)}}export{df as yellow,sf as white,pT as websiteSourceHash,W$ as version,l0 as useOnline,L0 as underline,PT as toError,yf as throttle,N0 as supportsColor,E0 as stripColors,W0 as strikethrough,$f as setEnvValue,Lf as semver,Yf as safeJsonStringify,Uf as safeJsonParseResult,Jf as safeJsonParse,Tf as runNpmScript,o0 as retry,D0 as reset,bf as red,UT as readableSize,JT as prettyBytes,ff as parseYaml,y as parseBytes,rT as packageManager,CT as originRequestFunctionHash,w0 as observeElementSize,a0 as notNullish,Ff as normalizeNewlines,D$ as mergeDefaults,N as merge,z0 as markdownTableFromObjects,A$ as markdownTable,cf as magenta,_f as macroable,Zf as loadYaml,lf as lightYellow,af as lightRed,ef as lightMagenta,T0 as lightGrey,of as lightGreen,z$ as lightGray,$0 as lightCyan,tf as lightBlue,O0 as italic,Ef as isVersionLessThanOrEqual,If as isVersionLessThan,Df as isVersionGreaterThanOrEqual,kf as isVersionGreaterThan,Wf as isVersionEqual,h$ as isResizeObserverSupported,w as isOptionalString,O$ as isManifest,Qf as isIpv6,hT as isGitClean,v as isDeepEqual,i as isAppKeySet,k0 as inverse,lT as installIfVersionMismatch,aT as initProject,I0 as hidden,L$ as hasScript,rf as grey,mf as green,R$ as gray,l as getResizeObserver,f$ as getFileSize,H$ as getExportsSize,_T as getErrorStatusCode,qT as getErrorStack,$$ as getErrorMessage,VT as getErrorCode,tT as frameworkVersion,OT as formatExportSizes,I as formatBytes,zT as findStacksProjects,X$ as estimateGzipSize,Z$ as estimateBrotliSize,oT as ensureProjectIsInitialized,Xf as dumpYaml,gT as docsSourceHash,M0 as dim,eT as determineResetPreset,Hf as determineDebugLevel,hf as detectNewlineGraceful,N$ as detectNewline,xf as detectIndent,Cf as delay,Af as defuArrayFn,zf as defu,QT as defineUi,fT as defineSms,TT as defineServices,$T as defineSearchEngine,e$ as defineQueue,t$ as definePayment,l$ as defineNotification,o$ as defineLibrary,a$ as defineHashing,r$ as defineGit,HT as defineFilesystems,s$ as defineEmailConfig,i$ as defineEmail,n$ as defineDns,c$ as defineDependencies,u$ as defineDatabase,d$ as defineCli,m$ as defineChat,b$ as defineCdn,g$ as defineCache,p$ as defineApp,vf as debounce,nf as cyan,F$ as createResizeObserver,Rf as createMerger,Vf as createMacroable,jf as countNewlines,GT as compareBytes,S$ as cleanProject,r0 as clamp,i0 as browserUtils,K0 as bold,uf as blue,gf as black,X0 as bgYellow,_0 as bgWhite,H0 as bgRed,q0 as bgMagenta,G0 as bgLightYellow,P0 as bgLightRed,U0 as bgLightMagenta,B0 as bgLightGreen,Y0 as bgLightCyan,J0 as bgLightBlue,Q0 as bgGreen,V0 as bgCyan,Z0 as bgBlue,f0 as bgBlack,x0 as ResizeObserver,t as Pipeline,k$ as Macroable};
1
+ export * from "./clean";
2
+ export * from "./config";
3
+ export * from "./equal";
4
+ export * from "./errors";
5
+ export * from "./export-size";
6
+ export * from "./find";
7
+ export * from "./git";
8
+ export * from "./hash";
9
+ export * from "./helpers";
10
+ export * from "./macroable";
11
+ export * from "./safe-json";
12
+ export * from "./versions";
13
+ export * as browserUtils from "@stacksjs/browser";
14
+ export { clamp, notNullish, retry, useOnline } from "@stacksjs/browser";
15
+ export * from "./merge";
16
+ export * from "./detect";
17
+ export * from "./debounce";
18
+ export * from "./bytes";
19
+ export * from "./colors";
20
+ export * from "./markdown";
21
+ export * from "./size";
22
+ export * from "./observer";
23
+ export * from "./pipeline";
@@ -0,0 +1,121 @@
1
+ export class Macroable {
2
+ static macros = new Map;
3
+ static macro(name, fn, replace = !1) {
4
+ if (this.macros.has(name) && !replace)
5
+ throw Error(`Macro "${name}" is already registered`);
6
+ this.macros.set(name, fn);
7
+ Object.defineProperty(this.prototype, name, {
8
+ value: fn,
9
+ writable: !0,
10
+ configurable: !0,
11
+ enumerable: !1
12
+ });
13
+ }
14
+ static mixin(obj, replace = !0) {
15
+ const methods = Object.getOwnPropertyNames(obj);
16
+ for (const method of methods) {
17
+ if (method === "constructor")
18
+ continue;
19
+ if (this.macros.has(method) && !replace)
20
+ continue;
21
+ const descriptor = Object.getOwnPropertyDescriptor(obj, method);
22
+ if (descriptor && typeof descriptor.value === "function")
23
+ this.macro(method, descriptor.value, replace);
24
+ }
25
+ }
26
+ static hasMacro(name) {
27
+ return this.macros.has(name);
28
+ }
29
+ static flushMacros() {
30
+ for (const name of this.macros.keys())
31
+ delete this.prototype[name];
32
+ this.macros.clear();
33
+ }
34
+ static getMacros() {
35
+ return Array.from(this.macros.keys());
36
+ }
37
+ callMacro(name, ...args) {
38
+ const macro = this.constructor.macros.get(name);
39
+ if (!macro)
40
+ throw Error(`Macro "${name}" is not registered`);
41
+ return macro.apply(this, args);
42
+ }
43
+ }
44
+ export function createMacroable(BaseClass = class {
45
+ }) {
46
+ return class extends BaseClass {
47
+ static macros = new Map;
48
+ static macro(name, fn, replace = !1) {
49
+ if (this.macros.has(name) && !replace)
50
+ throw Error(`Macro "${name}" is already registered`);
51
+ this.macros.set(name, fn);
52
+ Object.defineProperty(this.prototype, name, {
53
+ value: fn,
54
+ writable: !0,
55
+ configurable: !0,
56
+ enumerable: !1
57
+ });
58
+ }
59
+ static mixin(obj, replace = !0) {
60
+ const methods = Object.getOwnPropertyNames(obj);
61
+ for (const method of methods) {
62
+ if (method === "constructor")
63
+ continue;
64
+ if (this.macros.has(method) && !replace)
65
+ continue;
66
+ const descriptor = Object.getOwnPropertyDescriptor(obj, method);
67
+ if (descriptor && typeof descriptor.value === "function")
68
+ this.macro(method, descriptor.value, replace);
69
+ }
70
+ }
71
+ static hasMacro(name) {
72
+ return this.macros.has(name);
73
+ }
74
+ static flushMacros() {
75
+ for (const name of this.macros.keys())
76
+ delete this.prototype[name];
77
+ this.macros.clear();
78
+ }
79
+ static getMacros() {
80
+ return Array.from(this.macros.keys());
81
+ }
82
+ };
83
+ }
84
+ export function macroable(target) {
85
+ const macros = new Map;
86
+ target.macro = function(name, fn, replace = !1) {
87
+ if (macros.has(name) && !replace)
88
+ throw Error(`Macro "${name}" is already registered`);
89
+ macros.set(name, fn);
90
+ Object.defineProperty(target.prototype, name, {
91
+ value: fn,
92
+ writable: !0,
93
+ configurable: !0,
94
+ enumerable: !1
95
+ });
96
+ };
97
+ target.mixin = function(obj, replace = !0) {
98
+ const methods = Object.getOwnPropertyNames(obj);
99
+ for (const method of methods) {
100
+ if (method === "constructor")
101
+ continue;
102
+ if (macros.has(method) && !replace)
103
+ continue;
104
+ const descriptor = Object.getOwnPropertyDescriptor(obj, method);
105
+ if (descriptor && typeof descriptor.value === "function")
106
+ target.macro(method, descriptor.value, replace);
107
+ }
108
+ };
109
+ target.hasMacro = function(name) {
110
+ return macros.has(name);
111
+ };
112
+ target.flushMacros = function() {
113
+ for (const name of macros.keys())
114
+ delete target.prototype[name];
115
+ macros.clear();
116
+ };
117
+ target.getMacros = function() {
118
+ return Array.from(macros.keys());
119
+ };
120
+ return target;
121
+ }
@@ -0,0 +1,92 @@
1
+ export function markdownTable(table, options = {}) {
2
+ const {
3
+ align = [],
4
+ padding = !0,
5
+ delimiter = "|",
6
+ delimiterStart = !0,
7
+ delimiterEnd = !0,
8
+ alignDelimiter = "-"
9
+ } = options;
10
+ if (!table || table.length === 0)
11
+ return "";
12
+ const normalized = table.map((row) => row.map((cell) => {
13
+ if (cell === null || cell === void 0)
14
+ return "";
15
+ return String(cell);
16
+ })), columnCount = Math.max(...normalized.map((row) => row.length)), columnWidths = Array.from({ length: columnCount }).fill(0);
17
+ for (const row of normalized)
18
+ for (let i = 0;i < row.length; i++) {
19
+ const cellLength = row[i]?.length ?? 0;
20
+ if (cellLength > (columnWidths[i] ?? 0))
21
+ columnWidths[i] = cellLength;
22
+ }
23
+ const rows = [];
24
+ if (normalized.length > 0) {
25
+ const header = normalized[0] ?? [];
26
+ rows.push(buildRow(header, columnWidths, padding, delimiter, delimiterStart, delimiterEnd));
27
+ const separatorCells = columnWidths.map((width, index) => {
28
+ const alignment = normalizeAlignment(align[index]);
29
+ return buildSeparator(width, alignment, alignDelimiter);
30
+ });
31
+ rows.push(buildRow(separatorCells, columnWidths, padding, delimiter, delimiterStart, delimiterEnd));
32
+ for (let i = 1;i < normalized.length; i++) {
33
+ const dataRow = normalized[i] ?? [];
34
+ rows.push(buildRow(dataRow, columnWidths, padding, delimiter, delimiterStart, delimiterEnd));
35
+ }
36
+ }
37
+ return rows.join(`
38
+ `);
39
+ }
40
+ function buildRow(cells, columnWidths, padding, delimiter, delimiterStart, delimiterEnd) {
41
+ const paddedCells = cells.map((cell, index) => {
42
+ const width = columnWidths[index] ?? 0;
43
+ return cell.padEnd(width, " ");
44
+ }), space = padding ? " " : "";
45
+ let row = paddedCells.map((cell) => `${space}${cell}${space}`).join(delimiter);
46
+ if (delimiterStart)
47
+ row = delimiter + row;
48
+ if (delimiterEnd)
49
+ row = row + delimiter;
50
+ return row;
51
+ }
52
+ function buildSeparator(width, alignment, char) {
53
+ const minWidth = alignment === "center" ? 3 : alignment ? 2 : 1;
54
+ if (width < minWidth)
55
+ width = minWidth;
56
+ let separator = char.repeat(width);
57
+ if (alignment === "left")
58
+ separator = `:${separator.slice(1)}`;
59
+ else if (alignment === "right")
60
+ separator = separator.slice(0, -1) + ":";
61
+ else if (alignment === "center")
62
+ separator = `:${separator.slice(2)}:`;
63
+ return separator;
64
+ }
65
+ function normalizeAlignment(align) {
66
+ if (!align)
67
+ return null;
68
+ switch (align) {
69
+ case "l":
70
+ case "left":
71
+ return "left";
72
+ case "c":
73
+ case "center":
74
+ return "center";
75
+ case "r":
76
+ case "right":
77
+ return "right";
78
+ default:
79
+ return null;
80
+ }
81
+ }
82
+ export function markdownTableFromObjects(objects, options = {}) {
83
+ if (!objects || objects.length === 0)
84
+ return "";
85
+ const keys = Array.from(new Set(objects.flatMap((obj) => Object.keys(obj)))), table = [
86
+ keys,
87
+ ...objects.map((obj) => keys.map((key) => obj[key]))
88
+ ];
89
+ return markdownTable(table, options);
90
+ }
91
+
92
+ export { markdownTable as default };
package/dist/merge.js ADDED
@@ -0,0 +1,51 @@
1
+ export function merge(...objects) {
2
+ const result = {};
3
+ for (const obj of objects) {
4
+ if (!obj || typeof obj !== "object")
5
+ continue;
6
+ for (const key in obj) {
7
+ const value = obj[key], existing = result[key];
8
+ if (value === void 0)
9
+ continue;
10
+ if (Array.isArray(value))
11
+ result[key] = Array.isArray(existing) ? [...existing, ...value] : [...value];
12
+ else if (value && typeof value === "object" && !isSpecialObject(value))
13
+ result[key] = merge(existing || {}, value);
14
+ else
15
+ result[key] = value;
16
+ }
17
+ }
18
+ return result;
19
+ }
20
+ export function createMerger(defaults) {
21
+ return (...objects) => {
22
+ return merge(defaults, ...objects);
23
+ };
24
+ }
25
+ export function mergeDefaults(obj, ...defaults) {
26
+ return merge({}, ...defaults, obj);
27
+ }
28
+ function isSpecialObject(obj) {
29
+ if (obj instanceof Date)
30
+ return !0;
31
+ if (obj instanceof RegExp)
32
+ return !0;
33
+ if (obj instanceof Error)
34
+ return !0;
35
+ if (obj instanceof Promise)
36
+ return !0;
37
+ if (obj instanceof Map)
38
+ return !0;
39
+ if (obj instanceof Set)
40
+ return !0;
41
+ if (obj instanceof WeakMap)
42
+ return !0;
43
+ if (obj instanceof WeakSet)
44
+ return !0;
45
+ if (ArrayBuffer.isView(obj))
46
+ return !0;
47
+ return !1;
48
+ }
49
+ export const defu = mergeDefaults, defuArrayFn = merge;
50
+
51
+ export { merge as default };
@@ -0,0 +1,78 @@
1
+ export function isResizeObserverSupported() {
2
+ return typeof window < "u" && "ResizeObserver" in window;
3
+ }
4
+ export function getResizeObserver() {
5
+ if (isResizeObserverSupported())
6
+ return window.ResizeObserver;
7
+ return class ResizeObserverPolyfill {
8
+ callback;
9
+ observedElements = new Set;
10
+ rafId = null;
11
+ constructor(callback) {
12
+ this.callback = callback;
13
+ }
14
+ observe(target) {
15
+ if (!this.observedElements.has(target)) {
16
+ this.observedElements.add(target);
17
+ this.scheduleCheck();
18
+ }
19
+ }
20
+ unobserve(target) {
21
+ this.observedElements.delete(target);
22
+ if (this.observedElements.size === 0 && this.rafId !== null) {
23
+ (typeof cancelAnimationFrame < "u" ? cancelAnimationFrame : clearTimeout)(this.rafId);
24
+ this.rafId = null;
25
+ }
26
+ }
27
+ disconnect() {
28
+ this.observedElements.clear();
29
+ if (this.rafId !== null) {
30
+ (typeof cancelAnimationFrame < "u" ? cancelAnimationFrame : clearTimeout)(this.rafId);
31
+ this.rafId = null;
32
+ }
33
+ }
34
+ scheduleCheck() {
35
+ if (this.rafId !== null)
36
+ return;
37
+ const raf = typeof requestAnimationFrame < "u" ? requestAnimationFrame : setTimeout;
38
+ this.rafId = raf(() => {
39
+ this.check();
40
+ this.rafId = null;
41
+ if (this.observedElements.size > 0)
42
+ this.scheduleCheck();
43
+ });
44
+ }
45
+ check() {
46
+ const entries = [];
47
+ for (const element of this.observedElements) {
48
+ const rect = element.getBoundingClientRect(), entry = {
49
+ target: element,
50
+ contentRect: rect,
51
+ borderBoxSize: [{ inlineSize: rect.width, blockSize: rect.height }],
52
+ contentBoxSize: [{ inlineSize: rect.width, blockSize: rect.height }],
53
+ devicePixelContentBoxSize: [{ inlineSize: rect.width, blockSize: rect.height }]
54
+ };
55
+ entries.push(entry);
56
+ }
57
+ if (entries.length > 0)
58
+ this.callback(entries, this);
59
+ }
60
+ };
61
+ }
62
+ export function createResizeObserver(callback, target) {
63
+ const observer = new (getResizeObserver())(callback), targets = Array.isArray(target) ? target : [target];
64
+ for (const element of targets)
65
+ observer.observe(element);
66
+ return () => {
67
+ observer.disconnect();
68
+ };
69
+ }
70
+ export function observeElementSize(element, callback) {
71
+ return createResizeObserver((entries) => {
72
+ const entry = entries.find((e) => e.target === element);
73
+ if (entry)
74
+ callback(entry);
75
+ }, element);
76
+ }
77
+ export const ResizeObserver = getResizeObserver();
78
+ export default ResizeObserver;
@@ -0,0 +1,37 @@
1
+ export class Pipeline {
2
+ passable;
3
+ pipes = [];
4
+ method = "handle";
5
+ static send(passable) {
6
+ const pipeline = new Pipeline;
7
+ pipeline.passable = passable;
8
+ return pipeline;
9
+ }
10
+ through(pipes) {
11
+ this.pipes = pipes;
12
+ return this;
13
+ }
14
+ pipe(...pipes) {
15
+ this.pipes.push(...pipes);
16
+ return this;
17
+ }
18
+ via(method) {
19
+ this.method = method;
20
+ return this;
21
+ }
22
+ then(destination) {
23
+ return this.pipes.reduceRight((next, pipe) => {
24
+ return (passable) => {
25
+ if (typeof pipe === "function")
26
+ return pipe(passable, next);
27
+ const handler = pipe[this.method];
28
+ if (typeof handler === "function")
29
+ return handler.call(pipe, passable, next);
30
+ return next(passable);
31
+ };
32
+ }, destination)(this.passable);
33
+ }
34
+ thenReturn() {
35
+ return this.then((passable) => passable);
36
+ }
37
+ }
@@ -0,0 +1,33 @@
1
+ export function safeJsonParse(text, defaultValue) {
2
+ if (typeof text !== "string" || text.length === 0)
3
+ return defaultValue;
4
+ try {
5
+ return JSON.parse(text);
6
+ } catch {
7
+ return defaultValue;
8
+ }
9
+ }
10
+ export function safeJsonParseResult(text) {
11
+ if (typeof text !== "string")
12
+ return { ok: !1, reason: "not-string" };
13
+ if (text.length === 0)
14
+ return { ok: !1, reason: "empty" };
15
+ try {
16
+ return { ok: !0, value: JSON.parse(text) };
17
+ } catch (err) {
18
+ return { ok: !1, reason: "malformed", error: err };
19
+ }
20
+ }
21
+ export function safeJsonStringify(value, space) {
22
+ const seen = new WeakSet;
23
+ return JSON.stringify(value, (_key, v) => {
24
+ if (typeof v === "bigint")
25
+ return v.toString();
26
+ if (v && typeof v === "object") {
27
+ if (seen.has(v))
28
+ return "[Circular]";
29
+ seen.add(v);
30
+ }
31
+ return v;
32
+ }, space);
33
+ }
package/dist/size.js ADDED
@@ -0,0 +1,66 @@
1
+ import { stat } from "node:fs/promises";
2
+ import { join } from "node:path";
3
+ import { formatBytes } from "./bytes";
4
+ export async function getFileSize(filePath) {
5
+ try {
6
+ return (await stat(filePath)).size;
7
+ } catch {
8
+ return 0;
9
+ }
10
+ }
11
+ export async function getExportsSize(distPath) {
12
+ const exports = [];
13
+ let totalSize = 0;
14
+ try {
15
+ const files = await getAllJsFiles(distPath);
16
+ for (const file of files) {
17
+ const size = await getFileSize(file.path);
18
+ totalSize += size;
19
+ exports.push({
20
+ name: file.name,
21
+ size,
22
+ readable: formatBytes(size)
23
+ });
24
+ }
25
+ } catch (error) {}
26
+ return {
27
+ totalSize,
28
+ totalReadable: formatBytes(totalSize),
29
+ exports: exports.sort((a, b) => b.size - a.size)
30
+ };
31
+ }
32
+ async function getAllJsFiles(dir) {
33
+ const files = [];
34
+ try {
35
+ const entries = await Bun.$.throws(!1)`find ${dir} -type f \\( -name "*.js" -o -name "*.mjs" -o -name "*.cjs" \\)`.text();
36
+ for (const entry of entries.split(`
37
+ `).filter(Boolean)) {
38
+ const name = entry.replace(dir, "").replace(/^\//, "");
39
+ files.push({ name, path: entry });
40
+ }
41
+ } catch {}
42
+ return files;
43
+ }
44
+ export function estimateGzipSize(size) {
45
+ return Math.floor(size * 0.3);
46
+ }
47
+ export function estimateBrotliSize(size) {
48
+ return Math.floor(size * 0.25);
49
+ }
50
+ export function formatExportSizes(result) {
51
+ if (result.exports.length === 0)
52
+ return "No exports found";
53
+ const lines = ["Export Sizes:", ""], maxNameLength = Math.max(...result.exports.map((e) => e.name.length));
54
+ for (const exp of result.exports) {
55
+ const name = exp.name.padEnd(maxNameLength, " ");
56
+ lines.push(` ${name} ${exp.readable}`);
57
+ }
58
+ lines.push("");
59
+ lines.push(`Total: ${result.totalReadable}`);
60
+ lines.push(`Estimated gzipped: ${formatBytes(estimateGzipSize(result.totalSize))}`);
61
+ lines.push(`Estimated brotli: ${formatBytes(estimateBrotliSize(result.totalSize))}`);
62
+ return lines.join(`
63
+ `);
64
+ }
65
+
66
+ export { getExportsSize as default };
@@ -0,0 +1,2 @@
1
+ export declare const components: string[];
2
+ export declare const functions: string[];
package/dist/utils.js ADDED
@@ -0,0 +1,6 @@
1
+ var __dirname = "";
2
+ import { resolve } from "@stacksjs/path";
3
+ import { fs } from "@stacksjs/storage";
4
+ import { kebabCase } from "@stacksjs/strings";
5
+ const ignore = ["readme-md"];
6
+ export const components = fs.readdirSync(resolve(__dirname, "./resources/components")).map((item) => kebabCase(item.replace(/\.(stx|vue)/g, ""))).filter((item) => !ignore.includes(item)), functions = fs.readdirSync(resolve(__dirname, "./resources/functions")).map((item) => kebabCase(item.replace(/.ts/g, ""))).filter((item) => !ignore.includes(item));
@@ -0,0 +1,19 @@
1
+ import { version } from "../package.json";
2
+ export const semver = Bun.semver;
3
+ export function isVersionGreaterThan(version, compareVersion) {
4
+ return Bun.semver.order(version, compareVersion) === 1;
5
+ }
6
+ export function isVersionLessThan(version, compareVersion) {
7
+ return Bun.semver.order(version, compareVersion) === -1;
8
+ }
9
+ export function isVersionEqual(version, compareVersion) {
10
+ return Bun.semver.order(version, compareVersion) === 0;
11
+ }
12
+ export function isVersionGreaterThanOrEqual(version, compareVersion) {
13
+ return Bun.semver.order(version, compareVersion) >= 0;
14
+ }
15
+ export function isVersionLessThanOrEqual(version, compareVersion) {
16
+ return Bun.semver.order(version, compareVersion) <= 0;
17
+ }
18
+
19
+ export { version };
package/package.json CHANGED
@@ -2,7 +2,7 @@
2
2
  "name": "@stacksjs/utils",
3
3
  "type": "module",
4
4
  "sideEffects": false,
5
- "version": "0.70.87",
5
+ "version": "0.70.90",
6
6
  "description": "The Stacks helper functions.",
7
7
  "author": "Chris Breuer",
8
8
  "contributors": [
@@ -58,20 +58,20 @@
58
58
  "size": "bun scripts/export-size.ts"
59
59
  },
60
60
  "dependencies": {
61
- "@stacksjs/browser": "0.70.87"
61
+ "@stacksjs/browser": "0.70.90"
62
62
  },
63
63
  "devDependencies": {
64
- "@stacksjs/actions": "0.70.87",
65
- "@stacksjs/arrays": "0.70.87",
66
- "@stacksjs/cli": "0.70.87",
67
- "@stacksjs/config": "0.70.87",
64
+ "@stacksjs/actions": "0.70.90",
65
+ "@stacksjs/arrays": "0.70.90",
66
+ "@stacksjs/cli": "0.70.90",
67
+ "@stacksjs/config": "0.70.90",
68
68
  "better-dx": "^0.2.16",
69
69
  "filesize": "^11.0.22",
70
70
  "markdown-table": "^3.0.4",
71
- "@stacksjs/lint": "0.70.87",
72
- "@stacksjs/path": "0.70.87",
73
- "@stacksjs/storage": "0.70.87",
74
- "@stacksjs/strings": "0.70.87",
75
- "@stacksjs/types": "0.70.87"
71
+ "@stacksjs/lint": "0.70.90",
72
+ "@stacksjs/path": "0.70.90",
73
+ "@stacksjs/storage": "0.70.90",
74
+ "@stacksjs/strings": "0.70.90",
75
+ "@stacksjs/types": "0.70.90"
76
76
  }
77
77
  }