UNPKG

@settlemint/sdk-utils

Version:

Shared utilities and helper functions for SettleMint SDK modules

246 lines (240 loc) • 8.07 kB
//#region rolldown:runtime var __create = Object.create; var __defProp = Object.defineProperty; var __getOwnPropDesc = Object.getOwnPropertyDescriptor; var __getOwnPropNames = Object.getOwnPropertyNames; var __getProtoOf = Object.getPrototypeOf; var __hasOwnProp = Object.prototype.hasOwnProperty; var __copyProps = (to, from, except, desc) => { if (from && typeof from === "object" || typeof from === "function") for (var keys = __getOwnPropNames(from), i = 0, n = keys.length, key; i < n; i++) { key = keys[i]; if (!__hasOwnProp.call(to, key) && key !== except) __defProp(to, key, { get: ((k) => from[k]).bind(null, key), enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable }); } return to; }; var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__getProtoOf(mod)) : {}, __copyProps(isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", { value: mod, enumerable: true }) : target, mod)); //#endregion let node_path = require("node:path"); node_path = __toESM(node_path); let find_up = require("find-up"); find_up = __toESM(find_up); let node_fs_promises = require("node:fs/promises"); node_fs_promises = __toESM(node_fs_promises); let glob = require("glob"); glob = __toESM(glob); //#region src/filesystem/project-root.ts /** * Finds the root directory of the current project by locating the nearest package.json file * * @param fallbackToCwd - If true, will return the current working directory if no package.json is found * @param cwd - The directory to start searching for the package.json file from (defaults to process.cwd()) * @returns Promise that resolves to the absolute path of the project root directory * @throws Will throw an error if no package.json is found in the directory tree * @example * import { projectRoot } from "@settlemint/sdk-utils/filesystem"; * * // Get project root path * const rootDir = await projectRoot(); * console.log(`Project root is at: ${rootDir}`); */ async function projectRoot(fallbackToCwd = false, cwd) { const packageJsonPath = await (0, find_up.findUp)("package.json", { cwd }); if (!packageJsonPath) { if (fallbackToCwd) { return process.cwd(); } throw new Error("Unable to find project root (no package.json found)"); } return (0, node_path.dirname)(packageJsonPath); } //#endregion //#region src/filesystem/exists.ts /** * Checks if a file or directory exists at the given path * * @param path - The file system path to check for existence * @returns Promise that resolves to true if the path exists, false otherwise * @example * import { exists } from "@settlemint/sdk-utils/filesystem"; * * // Check if file exists before reading * if (await exists('/path/to/file.txt')) { * // File exists, safe to read * } */ async function exists(path) { try { await (0, node_fs_promises.stat)(path); return true; } catch { return false; } } //#endregion //#region src/json.ts /** * Attempts to parse a JSON string into a typed value, returning a default value if parsing fails. * * @param value - The JSON string to parse * @param defaultValue - The value to return if parsing fails or results in null/undefined * @returns The parsed JSON value as type T, or the default value if parsing fails * * @example * import { tryParseJson } from "@settlemint/sdk-utils"; * * const config = tryParseJson<{ port: number }>( * '{"port": 3000}', * { port: 8080 } * ); * // Returns: { port: 3000 } * * const invalid = tryParseJson<string[]>( * 'invalid json', * [] * ); * // Returns: [] */ function tryParseJson(value, defaultValue = null) { try { const parsed = JSON.parse(value); if (parsed === undefined || parsed === null) { return defaultValue; } return parsed; } catch (_err) { return defaultValue; } } /** * Extracts a JSON object from a string. * * @param value - The string to extract the JSON object from * @returns The parsed JSON object, or null if no JSON object is found * @throws {Error} If the input string is too long (longer than 5000 characters) * @example * import { extractJsonObject } from "@settlemint/sdk-utils"; * * const json = extractJsonObject<{ port: number }>( * 'port info: {"port": 3000}', * ); * // Returns: { port: 3000 } */ function extractJsonObject(value) { if (value.length > 5e3) { throw new Error("Input too long"); } const result = /\{([\s\S]*)\}/.exec(value); if (!result) { return null; } return tryParseJson(result[0]); } /** * Converts a value to a JSON stringifiable format. * * @param value - The value to convert * @returns The JSON stringifiable value * * @example * import { makeJsonStringifiable } from "@settlemint/sdk-utils"; * * const json = makeJsonStringifiable<{ amount: bigint }>({ amount: BigInt(1000) }); * // Returns: '{"amount":"1000"}' */ function makeJsonStringifiable(value) { if (value === undefined || value === null) { return value; } return tryParseJson(JSON.stringify(value, (_, value$1) => typeof value$1 === "bigint" ? value$1.toString() : value$1)); } //#endregion //#region src/filesystem/mono-repo.ts /** * Finds the root directory of a monorepo * * @param startDir - The directory to start searching from * @returns The root directory of the monorepo or null if not found * @example * import { findMonoRepoRoot } from "@settlemint/sdk-utils/filesystem"; * * const root = await findMonoRepoRoot("/path/to/your/project"); * console.log(root); // Output: /path/to/your/project/packages/core */ async function findMonoRepoRoot(startDir) { const lockFilePath = await (0, find_up.findUp)([ "package-lock.json", "yarn.lock", "pnpm-lock.yaml", "bun.lockb", "bun.lock" ], { cwd: startDir }); if (lockFilePath) { const packageJsonPath = (0, node_path.join)((0, node_path.dirname)(lockFilePath), "package.json"); const hasWorkSpaces = await packageJsonHasWorkspaces(packageJsonPath); return hasWorkSpaces ? (0, node_path.dirname)(lockFilePath) : null; } let currentDir = startDir; while (currentDir !== "/") { const packageJsonPath = (0, node_path.join)(currentDir, "package.json"); if (await packageJsonHasWorkspaces(packageJsonPath)) { return currentDir; } const parentDir = (0, node_path.dirname)(currentDir); if (parentDir === currentDir) { break; } currentDir = parentDir; } return null; } /** * Finds all packages in a monorepo * * @param projectDir - The directory to start searching from * @returns An array of package directories * @example * import { findMonoRepoPackages } from "@settlemint/sdk-utils/filesystem"; * * const packages = await findMonoRepoPackages("/path/to/your/project"); * console.log(packages); // Output: ["/path/to/your/project/packages/core", "/path/to/your/project/packages/ui"] */ async function findMonoRepoPackages(projectDir) { try { const monoRepoRoot = await findMonoRepoRoot(projectDir); if (!monoRepoRoot) { return [projectDir]; } const packageJsonPath = (0, node_path.join)(monoRepoRoot, "package.json"); const packageJson = tryParseJson(await (0, node_fs_promises.readFile)(packageJsonPath, "utf-8")); const workspaces = packageJson?.workspaces ?? []; const packagePaths = await Promise.all(workspaces.map(async (workspace) => { const matches = await (0, glob.glob)((0, node_path.join)(monoRepoRoot, workspace, "package.json")); return matches.map((match) => (0, node_path.join)(match, "..")); })); const allPaths = packagePaths.flat(); return allPaths.length === 0 ? [projectDir] : [monoRepoRoot, ...allPaths]; } catch (_error) { return [projectDir]; } } async function packageJsonHasWorkspaces(packageJsonPath) { if (await exists(packageJsonPath)) { const packageJson = tryParseJson(await (0, node_fs_promises.readFile)(packageJsonPath, "utf-8")); if (packageJson?.workspaces && Array.isArray(packageJson?.workspaces) && packageJson?.workspaces.length > 0) { return true; } } return false; } //#endregion exports.exists = exists; exports.findMonoRepoPackages = findMonoRepoPackages; exports.findMonoRepoRoot = findMonoRepoRoot; exports.projectRoot = projectRoot; //# sourceMappingURL=filesystem.cjs.map