design-math
Advanced tools
+109
| const { join, dirname } = require("path"); | ||
| const detectLibc = require("detect-libc"); | ||
| const PLATFORM_PACKAGES = [ | ||
| { | ||
| "os": "darwin", | ||
| "cpu": "arm64", | ||
| "libc": null, | ||
| "packageName": "design-math-bin-darwin-arm64", | ||
| "binaryName": "design-math" | ||
| }, | ||
| { | ||
| "os": "darwin", | ||
| "cpu": "x64", | ||
| "libc": null, | ||
| "packageName": "design-math-bin-darwin-x64", | ||
| "binaryName": "design-math" | ||
| }, | ||
| { | ||
| "os": "linux", | ||
| "cpu": "arm64", | ||
| "libc": "glibc", | ||
| "packageName": "design-math-bin-linux-arm64-gnu", | ||
| "binaryName": "design-math" | ||
| }, | ||
| { | ||
| "os": "linux", | ||
| "cpu": "arm64", | ||
| "libc": "musl", | ||
| "packageName": "design-math-bin-linux-arm64-musl", | ||
| "binaryName": "design-math" | ||
| }, | ||
| { | ||
| "os": "linux", | ||
| "cpu": "x64", | ||
| "libc": "glibc", | ||
| "packageName": "design-math-bin-linux-x64-gnu", | ||
| "binaryName": "design-math" | ||
| }, | ||
| { | ||
| "os": "linux", | ||
| "cpu": "x64", | ||
| "libc": "musl", | ||
| "packageName": "design-math-bin-linux-x64-musl", | ||
| "binaryName": "design-math" | ||
| }, | ||
| { | ||
| "os": "win32", | ||
| "cpu": "x64", | ||
| "libc": null, | ||
| "packageName": "design-math-bin-win32-x64", | ||
| "binaryName": "design-math.exe" | ||
| } | ||
| ]; | ||
| function currentLibc() { | ||
| if (process.platform !== "linux") { | ||
| return null; | ||
| } | ||
| const family = detectLibc.familySync(); | ||
| return family === detectLibc.MUSL ? "musl" : "glibc"; | ||
| } | ||
| function currentPlatformKey() { | ||
| return { | ||
| os: process.platform, | ||
| cpu: process.arch, | ||
| libc: currentLibc(), | ||
| }; | ||
| } | ||
| function resolvePlatformPackage() { | ||
| const current = currentPlatformKey(); | ||
| const match = PLATFORM_PACKAGES.find((candidate) => { | ||
| if (candidate.os !== current.os || candidate.cpu !== current.cpu) { | ||
| return false; | ||
| } | ||
| if (candidate.libc && candidate.libc !== current.libc) { | ||
| return false; | ||
| } | ||
| return true; | ||
| }); | ||
| if (!match) { | ||
| const currentLabel = [current.os, current.cpu, current.libc].filter(Boolean).join("/"); | ||
| throw new Error( | ||
| "design-math does not ship a prebuilt npm binary for " + currentLabel + "." | ||
| ); | ||
| } | ||
| let packageJsonPath; | ||
| try { | ||
| packageJsonPath = require.resolve(match.packageName + "/package.json"); | ||
| } catch (error) { | ||
| throw new Error( | ||
| "The npm package " + | ||
| match.packageName + | ||
| " was not installed. Re-run npm install without --omit=optional." | ||
| ); | ||
| } | ||
| return { | ||
| ...match, | ||
| packageDir: dirname(packageJsonPath), | ||
| binaryPath: join(dirname(packageJsonPath), "bin", match.binaryName), | ||
| }; | ||
| } | ||
| module.exports = { resolvePlatformPackage }; |
| #!/usr/bin/env node | ||
| const { resolvePlatformPackage } = require("./platform"); | ||
| try { | ||
| resolvePlatformPackage(); | ||
| } catch (error) { | ||
| console.error(error.message); | ||
| process.exit(1); | ||
| } |
+30
-117
| { | ||
| "artifactDownloadUrls": [ | ||
| "https://github.com/eric8810/design-math/releases/download/v0.1.1" | ||
| ], | ||
| "bin": { | ||
| "design-math": "run-design-math.js" | ||
| }, | ||
| "dependencies": { | ||
| "axios": "^1.13.5", | ||
| "axios-proxy-builder": "^0.1.2", | ||
| "console.table": "^0.10.0", | ||
| "detect-libc": "^2.1.2", | ||
| "rimraf": "^6.1.3" | ||
| }, | ||
| "name": "design-math", | ||
| "version": "0.1.2", | ||
| "description": "Agent-friendly design math CLI for color, typography, and shadow systems.", | ||
| "devDependencies": { | ||
| "prettier": "^3.8.1" | ||
| "license": "MIT", | ||
| "homepage": "https://github.com/eric8810/design-math", | ||
| "repository": { | ||
| "type": "git", | ||
| "url": "git+https://github.com/eric8810/design-math.git" | ||
| }, | ||
| "engines": { | ||
| "node": ">=14", | ||
| "npm": ">=6" | ||
| }, | ||
| "glibcMinimum": { | ||
| "major": 2, | ||
| "series": 35 | ||
| }, | ||
| "homepage": "https://github.com/eric8810/design-math", | ||
| "keywords": [ | ||
| "command-line-utilities", | ||
| "graphics", | ||
| "design", | ||
@@ -37,95 +18,27 @@ "color", | ||
| ], | ||
| "license": "MIT", | ||
| "name": "design-math", | ||
| "preferUnplugged": true, | ||
| "repository": "https://github.com/eric8810/design-math", | ||
| "bin": { | ||
| "design-math": "run-design-math.js" | ||
| }, | ||
| "files": [ | ||
| "platform.js", | ||
| "run-design-math.js", | ||
| "postinstall.js", | ||
| "README.md" | ||
| ], | ||
| "scripts": { | ||
| "fmt": "prettier --write **/*.js", | ||
| "fmt:check": "prettier --check **/*.js", | ||
| "postinstall": "node ./install.js" | ||
| "postinstall": "node ./postinstall.js" | ||
| }, | ||
| "supportedPlatforms": { | ||
| "aarch64-apple-darwin": { | ||
| "artifactName": "design-math-aarch64-apple-darwin.tar.xz", | ||
| "bins": { | ||
| "design-math": "design-math" | ||
| }, | ||
| "zipExt": ".tar.xz" | ||
| }, | ||
| "aarch64-pc-windows-msvc": { | ||
| "artifactName": "design-math-x86_64-pc-windows-msvc.zip", | ||
| "bins": { | ||
| "design-math": "design-math.exe" | ||
| }, | ||
| "zipExt": ".zip" | ||
| }, | ||
| "aarch64-unknown-linux-gnu": { | ||
| "artifactName": "design-math-aarch64-unknown-linux-gnu.tar.xz", | ||
| "bins": { | ||
| "design-math": "design-math" | ||
| }, | ||
| "zipExt": ".tar.xz" | ||
| }, | ||
| "aarch64-unknown-linux-musl-dynamic": { | ||
| "artifactName": "design-math-aarch64-unknown-linux-musl.tar.xz", | ||
| "bins": { | ||
| "design-math": "design-math" | ||
| }, | ||
| "zipExt": ".tar.xz" | ||
| }, | ||
| "aarch64-unknown-linux-musl-static": { | ||
| "artifactName": "design-math-aarch64-unknown-linux-musl.tar.xz", | ||
| "bins": { | ||
| "design-math": "design-math" | ||
| }, | ||
| "zipExt": ".tar.xz" | ||
| }, | ||
| "x86_64-apple-darwin": { | ||
| "artifactName": "design-math-x86_64-apple-darwin.tar.xz", | ||
| "bins": { | ||
| "design-math": "design-math" | ||
| }, | ||
| "zipExt": ".tar.xz" | ||
| }, | ||
| "x86_64-pc-windows-gnu": { | ||
| "artifactName": "design-math-x86_64-pc-windows-msvc.zip", | ||
| "bins": { | ||
| "design-math": "design-math.exe" | ||
| }, | ||
| "zipExt": ".zip" | ||
| }, | ||
| "x86_64-pc-windows-msvc": { | ||
| "artifactName": "design-math-x86_64-pc-windows-msvc.zip", | ||
| "bins": { | ||
| "design-math": "design-math.exe" | ||
| }, | ||
| "zipExt": ".zip" | ||
| }, | ||
| "x86_64-unknown-linux-gnu": { | ||
| "artifactName": "design-math-x86_64-unknown-linux-gnu.tar.xz", | ||
| "bins": { | ||
| "design-math": "design-math" | ||
| }, | ||
| "zipExt": ".tar.xz" | ||
| }, | ||
| "x86_64-unknown-linux-musl-dynamic": { | ||
| "artifactName": "design-math-x86_64-unknown-linux-musl.tar.xz", | ||
| "bins": { | ||
| "design-math": "design-math" | ||
| }, | ||
| "zipExt": ".tar.xz" | ||
| }, | ||
| "x86_64-unknown-linux-musl-static": { | ||
| "artifactName": "design-math-x86_64-unknown-linux-musl.tar.xz", | ||
| "bins": { | ||
| "design-math": "design-math" | ||
| }, | ||
| "zipExt": ".tar.xz" | ||
| } | ||
| "dependencies": { | ||
| "detect-libc": "^2.1.2" | ||
| }, | ||
| "version": "0.1.1", | ||
| "volta": { | ||
| "node": "18.14.1", | ||
| "npm": "9.5.0" | ||
| } | ||
| } | ||
| "optionalDependencies": { | ||
| "design-math-bin-darwin-arm64": "0.1.2", | ||
| "design-math-bin-darwin-x64": "0.1.2", | ||
| "design-math-bin-linux-arm64-gnu": "0.1.2", | ||
| "design-math-bin-linux-arm64-musl": "0.1.2", | ||
| "design-math-bin-linux-x64-gnu": "0.1.2", | ||
| "design-math-bin-linux-x64-musl": "0.1.2", | ||
| "design-math-bin-win32-x64": "0.1.2" | ||
| }, | ||
| "preferUnplugged": true | ||
| } |
+10
-52
| # design-math | ||
| Agent-friendly design math CLI built in Rust. | ||
| Agent-friendly design math CLI. | ||
| `design-math` focuses on deterministic design calculations that are easy for humans to inspect and easy for agents, scripts, and CI to consume. | ||
| Version: `0.1.2` | ||
| ## What it does | ||
| Bundled platform packages: | ||
| - Color conversion, contrast, palette, and scheme generation | ||
| - Typography scale and fluid type calculations | ||
| - Shadow token generation for light and dark surfaces | ||
| - JSON, CSS, HTML, and PNG export paths for automation workflows | ||
| ## Install | ||
| ### Cargo | ||
| ```bash | ||
| cargo install design-math | ||
| ``` | ||
| If you build from source and want PNG export support: | ||
| ```bash | ||
| cargo install design-math --features image | ||
| ``` | ||
| ### npm | ||
| ```bash | ||
| npx design-math color convert "#c96442" --json | ||
| ``` | ||
| ### Homebrew | ||
| ```bash | ||
| brew install eric8810/design-math/design-math | ||
| ``` | ||
| ## Quick examples | ||
| ```bash | ||
| design-math color convert "#c96442" --json | ||
| design-math color contrast "rgba(255,255,255,0.72)" "#111111" --json | ||
| design-math color palette --bg "#f5f4ed" --fg "#141413" --brand "#c96442" --format css | ||
| design-math type scale --base 16 --ratio major-third --json | ||
| design-math shadow generate --levels 5 --json | ||
| ``` | ||
| ## Packages | ||
| - `design-math`: end-user CLI crate | ||
| - `design-math-core`: shared Rust library used by the CLI and future bindings | ||
| ## Status | ||
| Core calculation milestones through M6 are implemented. The current focus is packaging, release automation, and bindings for agent-first workflows. | ||
| - `design-math-bin-darwin-arm64` (aarch64-apple-darwin) | ||
| - `design-math-bin-darwin-x64` (x86_64-apple-darwin) | ||
| - `design-math-bin-linux-arm64-gnu` (aarch64-unknown-linux-gnu) | ||
| - `design-math-bin-linux-arm64-musl` (aarch64-unknown-linux-musl) | ||
| - `design-math-bin-linux-x64-gnu` (x86_64-unknown-linux-gnu) | ||
| - `design-math-bin-linux-x64-musl` (x86_64-unknown-linux-musl) | ||
| - `design-math-bin-win32-x64` (x86_64-pc-windows-msvc) |
+15
-2
| #!/usr/bin/env node | ||
| const { spawnSync } = require("child_process"); | ||
| const { resolvePlatformPackage } = require("./platform"); | ||
| const { run } = require("./binary"); | ||
| run("design-math"); | ||
| try { | ||
| const platformPackage = resolvePlatformPackage(); | ||
| const result = spawnSync(platformPackage.binaryPath, process.argv.slice(2), { | ||
| stdio: "inherit", | ||
| }); | ||
| if (result.error) { | ||
| throw result.error; | ||
| } | ||
| process.exit(result.status ?? 0); | ||
| } catch (error) { | ||
| console.error(error.message); | ||
| process.exit(1); | ||
| } |
| /node_modules | ||
| const { createWriteStream, existsSync, mkdirSync, mkdtemp } = require("fs"); | ||
| const { join, sep } = require("path"); | ||
| const { spawnSync } = require("child_process"); | ||
| const { tmpdir } = require("os"); | ||
| const axios = require("axios"); | ||
| const rimraf = require("rimraf"); | ||
| const tmpDir = tmpdir(); | ||
| const error = (msg) => { | ||
| console.error(msg); | ||
| process.exit(1); | ||
| }; | ||
| class Package { | ||
| constructor(platform, name, url, filename, zipExt, binaries) { | ||
| let errors = []; | ||
| if (typeof url !== "string") { | ||
| errors.push("url must be a string"); | ||
| } else { | ||
| try { | ||
| new URL(url); | ||
| } catch (e) { | ||
| errors.push(e); | ||
| } | ||
| } | ||
| if (name && typeof name !== "string") { | ||
| errors.push("package name must be a string"); | ||
| } | ||
| if (!name) { | ||
| errors.push("You must specify the name of your package"); | ||
| } | ||
| if (binaries && typeof binaries !== "object") { | ||
| errors.push("binaries must be a string => string map"); | ||
| } | ||
| if (!binaries) { | ||
| errors.push("You must specify the binaries in the package"); | ||
| } | ||
| if (errors.length > 0) { | ||
| let errorMsg = | ||
| "One or more of the parameters you passed to the Binary constructor are invalid:\n"; | ||
| errors.forEach((error) => { | ||
| errorMsg += error; | ||
| }); | ||
| errorMsg += | ||
| '\n\nCorrect usage: new Package("my-binary", "https://example.com/binary/download.tar.gz", {"my-binary": "my-binary"})'; | ||
| error(errorMsg); | ||
| } | ||
| this.platform = platform; | ||
| this.url = url; | ||
| this.name = name; | ||
| this.filename = filename; | ||
| this.zipExt = zipExt; | ||
| this.installDirectory = join(__dirname, "node_modules", ".bin_real"); | ||
| this.binaries = binaries; | ||
| if (!existsSync(this.installDirectory)) { | ||
| mkdirSync(this.installDirectory, { recursive: true }); | ||
| } | ||
| } | ||
| exists() { | ||
| for (const binaryName in this.binaries) { | ||
| const binRelPath = this.binaries[binaryName]; | ||
| const binPath = join(this.installDirectory, binRelPath); | ||
| if (!existsSync(binPath)) { | ||
| return false; | ||
| } | ||
| } | ||
| return true; | ||
| } | ||
| install(fetchOptions, suppressLogs = false) { | ||
| if (this.exists()) { | ||
| if (!suppressLogs) { | ||
| console.error( | ||
| `${this.name} is already installed, skipping installation.`, | ||
| ); | ||
| } | ||
| return Promise.resolve(); | ||
| } | ||
| if (existsSync(this.installDirectory)) { | ||
| rimraf.sync(this.installDirectory); | ||
| } | ||
| mkdirSync(this.installDirectory, { recursive: true }); | ||
| if (!suppressLogs) { | ||
| console.error(`Downloading release from ${this.url}`); | ||
| } | ||
| return axios({ ...fetchOptions, url: this.url, responseType: "stream" }) | ||
| .then((res) => { | ||
| return new Promise((resolve, reject) => { | ||
| mkdtemp(`${tmpDir}${sep}`, (err, directory) => { | ||
| let tempFile = join(directory, this.filename); | ||
| const sink = res.data.pipe(createWriteStream(tempFile)); | ||
| sink.on("error", (err) => reject(err)); | ||
| sink.on("close", () => { | ||
| if (/\.tar\.*/.test(this.zipExt)) { | ||
| const result = spawnSync("tar", [ | ||
| "xf", | ||
| tempFile, | ||
| // The tarballs are stored with a leading directory | ||
| // component; we strip one component in the | ||
| // shell installers too. | ||
| "--strip-components", | ||
| "1", | ||
| "-C", | ||
| this.installDirectory, | ||
| ]); | ||
| if (result.status == 0) { | ||
| resolve(); | ||
| } else if (result.error) { | ||
| reject(result.error); | ||
| } else { | ||
| reject( | ||
| new Error( | ||
| `An error occurred untarring the artifact: stdout: ${result.stdout}; stderr: ${result.stderr}`, | ||
| ), | ||
| ); | ||
| } | ||
| } else if (this.zipExt == ".zip") { | ||
| let result; | ||
| if (this.platform.artifactName.includes("windows")) { | ||
| // Windows does not have "unzip" by default on many installations, instead | ||
| // we use Expand-Archive from powershell | ||
| result = spawnSync("powershell.exe", [ | ||
| "-NoProfile", | ||
| "-NonInteractive", | ||
| "-Command", | ||
| `& { | ||
| param([string]$LiteralPath, [string]$DestinationPath) | ||
| Expand-Archive -LiteralPath $LiteralPath -DestinationPath $DestinationPath -Force | ||
| }`, | ||
| tempFile, | ||
| this.installDirectory, | ||
| ]); | ||
| } else { | ||
| result = spawnSync("unzip", [ | ||
| "-q", | ||
| tempFile, | ||
| "-d", | ||
| this.installDirectory, | ||
| ]); | ||
| } | ||
| if (result.status == 0) { | ||
| resolve(); | ||
| } else if (result.error) { | ||
| reject(result.error); | ||
| } else { | ||
| reject( | ||
| new Error( | ||
| `An error occurred unzipping the artifact: stdout: ${result.stdout}; stderr: ${result.stderr}`, | ||
| ), | ||
| ); | ||
| } | ||
| } else { | ||
| reject( | ||
| new Error(`Unrecognized file extension: ${this.zipExt}`), | ||
| ); | ||
| } | ||
| }); | ||
| }); | ||
| }); | ||
| }) | ||
| .then(() => { | ||
| if (!suppressLogs) { | ||
| console.error(`${this.name} has been installed!`); | ||
| } | ||
| }) | ||
| .catch((e) => { | ||
| error(`Error fetching release: ${e.message}`); | ||
| }); | ||
| } | ||
| run(binaryName, fetchOptions) { | ||
| const promise = !this.exists() | ||
| ? this.install(fetchOptions, true) | ||
| : Promise.resolve(); | ||
| promise | ||
| .then(() => { | ||
| const [, , ...args] = process.argv; | ||
| const options = { cwd: process.cwd(), stdio: "inherit" }; | ||
| const binRelPath = this.binaries[binaryName]; | ||
| if (!binRelPath) { | ||
| error(`${binaryName} is not a known binary in ${this.name}`); | ||
| } | ||
| const binPath = join(this.installDirectory, binRelPath); | ||
| const result = spawnSync(binPath, args, options); | ||
| if (result.error) { | ||
| error(result.error); | ||
| } | ||
| process.exit(result.status); | ||
| }) | ||
| .catch((e) => { | ||
| error(e.message); | ||
| process.exit(1); | ||
| }); | ||
| } | ||
| } | ||
| module.exports.Package = Package; |
-128
| const { Package } = require("./binary-install"); | ||
| const os = require("os"); | ||
| const cTable = require("console.table"); | ||
| const libc = require("detect-libc"); | ||
| const { configureProxy } = require("axios-proxy-builder"); | ||
| const error = (msg) => { | ||
| console.error(msg); | ||
| process.exit(1); | ||
| }; | ||
| const { | ||
| name, | ||
| artifactDownloadUrls, | ||
| supportedPlatforms, | ||
| glibcMinimum, | ||
| } = require("./package.json"); | ||
| // FIXME: implement NPM installer handling of fallback download URLs | ||
| const artifactDownloadUrl = artifactDownloadUrls[0]; | ||
| const builderGlibcMajorVersion = glibcMinimum.major; | ||
| const builderGlibcMinorVersion = glibcMinimum.series; | ||
| const getPlatform = () => { | ||
| const rawOsType = os.type(); | ||
| const rawArchitecture = os.arch(); | ||
| // We want to use rust-style target triples as the canonical key | ||
| // for a platform, so translate the "os" library's concepts into rust ones | ||
| let osType = ""; | ||
| switch (rawOsType) { | ||
| case "Windows_NT": | ||
| osType = "pc-windows-msvc"; | ||
| break; | ||
| case "Darwin": | ||
| osType = "apple-darwin"; | ||
| break; | ||
| case "Linux": | ||
| osType = "unknown-linux-gnu"; | ||
| break; | ||
| } | ||
| let arch = ""; | ||
| switch (rawArchitecture) { | ||
| case "x64": | ||
| arch = "x86_64"; | ||
| break; | ||
| case "arm64": | ||
| arch = "aarch64"; | ||
| break; | ||
| } | ||
| if (rawOsType === "Linux") { | ||
| if (libc.familySync() == "musl") { | ||
| osType = "unknown-linux-musl-dynamic"; | ||
| } else if (libc.isNonGlibcLinuxSync()) { | ||
| console.warn( | ||
| "Your libc is neither glibc nor musl; trying static musl binary instead", | ||
| ); | ||
| osType = "unknown-linux-musl-static"; | ||
| } else { | ||
| let libcVersion = libc.versionSync(); | ||
| let splitLibcVersion = libcVersion.split("."); | ||
| let libcMajorVersion = splitLibcVersion[0]; | ||
| let libcMinorVersion = splitLibcVersion[1]; | ||
| if ( | ||
| libcMajorVersion != builderGlibcMajorVersion || | ||
| libcMinorVersion < builderGlibcMinorVersion | ||
| ) { | ||
| // We can't run the glibc binaries, but we can run the static musl ones | ||
| // if they exist | ||
| console.warn( | ||
| "Your glibc isn't compatible; trying static musl binary instead", | ||
| ); | ||
| osType = "unknown-linux-musl-static"; | ||
| } | ||
| } | ||
| } | ||
| // Assume the above succeeded and build a target triple to look things up with. | ||
| // If any of it failed, this lookup will fail and we'll handle it like normal. | ||
| let targetTriple = `${arch}-${osType}`; | ||
| let platform = supportedPlatforms[targetTriple]; | ||
| if (!platform) { | ||
| error( | ||
| `Platform with type "${rawOsType}" and architecture "${rawArchitecture}" is not supported by ${name}.\nYour system must be one of the following:\n\n${Object.keys( | ||
| supportedPlatforms, | ||
| ).join(",")}`, | ||
| ); | ||
| } | ||
| return platform; | ||
| }; | ||
| const getPackage = () => { | ||
| const platform = getPlatform(); | ||
| const url = `${artifactDownloadUrl}/${platform.artifactName}`; | ||
| let filename = platform.artifactName; | ||
| let ext = platform.zipExt; | ||
| let binary = new Package(platform, name, url, filename, ext, platform.bins); | ||
| return binary; | ||
| }; | ||
| const install = (suppressLogs) => { | ||
| if (!artifactDownloadUrl || artifactDownloadUrl.length === 0) { | ||
| console.warn("in demo mode, not installing binaries"); | ||
| return; | ||
| } | ||
| const package = getPackage(); | ||
| const proxy = configureProxy(package.url); | ||
| return package.install(proxy, suppressLogs); | ||
| }; | ||
| const run = (binaryName) => { | ||
| const package = getPackage(); | ||
| const proxy = configureProxy(package.url); | ||
| package.run(binaryName, proxy); | ||
| }; | ||
| module.exports = { | ||
| install, | ||
| run, | ||
| getPackage, | ||
| }; |
-26
| # Changelog | ||
| All notable changes to this project will be documented in this file. | ||
| The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.1.0/), | ||
| and this project aims to follow [Semantic Versioning](https://semver.org/spec/v2.0.0.html). | ||
| ## [Unreleased] | ||
| ## [0.1.1] - 2026-04-06 | ||
| ### Fixed | ||
| - Switched the npm package name from a scoped package to plain `design-math` | ||
| - Aligned the release pipeline with the real Homebrew tap repository setup | ||
| ## [0.1.0] - 2026-04-06 | ||
| ### Added | ||
| - Rust workspace with `design-math-core` and `design-math` CLI crates | ||
| - Color workflows: convert, contrast, manipulate, mix, scale, harmony, palette, and scheme | ||
| - Typography workflows: scale and fluid type generation | ||
| - Shadow token generation for light and dark surfaces | ||
| - Export support for JSON, CSS, HTML, and PNG | ||
| - GitHub release workflow for cross-platform binaries, npm packages, and Homebrew formula updates |
| #!/usr/bin/env node | ||
| const { install } = require("./binary"); | ||
| install(false); |
| { | ||
| "lockfileVersion": 3, | ||
| "name": "design-math", | ||
| "packages": { | ||
| "": { | ||
| "bin": { | ||
| "design-math": "run-design-math.js" | ||
| }, | ||
| "dependencies": { | ||
| "axios": "^1.13.5", | ||
| "axios-proxy-builder": "^0.1.2", | ||
| "console.table": "^0.10.0", | ||
| "detect-libc": "^2.1.2", | ||
| "rimraf": "^6.1.3" | ||
| }, | ||
| "devDependencies": { | ||
| "prettier": "^3.8.1" | ||
| }, | ||
| "engines": { | ||
| "node": ">=14", | ||
| "npm": ">=6" | ||
| }, | ||
| "hasInstallScript": true, | ||
| "license": "MIT", | ||
| "name": "design-math", | ||
| "version": "0.1.1" | ||
| }, | ||
| "node_modules/@isaacs/cliui": { | ||
| "engines": { | ||
| "node": ">=18" | ||
| }, | ||
| "integrity": "sha512-AokJm4tuBHillT+FpMtxQ60n8ObyXBatq7jD2/JA9dxbDDokKQm8KMht5ibGzLVU9IJDIKK4TPKgMHEYMn3lMg==", | ||
| "license": "BlueOak-1.0.0", | ||
| "resolved": "https://registry.npmjs.org/@isaacs/cliui/-/cliui-9.0.0.tgz", | ||
| "version": "9.0.0" | ||
| }, | ||
| "node_modules/asynckit": { | ||
| "integrity": "sha512-Oei9OH4tRh0YqU3GxhX79dM/mwVgvbZJaSNaRk+bshkj0S5cfHcgYakreBjrHwatXKbz+IoIdYLxrKim2MjW0Q==", | ||
| "license": "MIT", | ||
| "resolved": "https://registry.npmjs.org/asynckit/-/asynckit-0.4.0.tgz", | ||
| "version": "0.4.0" | ||
| }, | ||
| "node_modules/axios": { | ||
| "dependencies": { | ||
| "follow-redirects": "^1.15.11", | ||
| "form-data": "^4.0.5", | ||
| "proxy-from-env": "^1.1.0" | ||
| }, | ||
| "integrity": "sha512-cz4ur7Vb0xS4/KUN0tPWe44eqxrIu31me+fbang3ijiNscE129POzipJJA6zniq2C/Z6sJCjMimjS8Lc/GAs8Q==", | ||
| "license": "MIT", | ||
| "resolved": "https://registry.npmjs.org/axios/-/axios-1.13.5.tgz", | ||
| "version": "1.13.5" | ||
| }, | ||
| "node_modules/axios-proxy-builder": { | ||
| "dependencies": { | ||
| "tunnel": "^0.0.6" | ||
| }, | ||
| "integrity": "sha512-6uBVsBZzkB3tCC8iyx59mCjQckhB8+GQrI9Cop8eC7ybIsvs/KtnNgEBfRMSEa7GqK2VBGUzgjNYMdPIfotyPA==", | ||
| "license": "MIT", | ||
| "resolved": "https://registry.npmjs.org/axios-proxy-builder/-/axios-proxy-builder-0.1.2.tgz", | ||
| "version": "0.1.2" | ||
| }, | ||
| "node_modules/balanced-match": { | ||
| "dependencies": { | ||
| "jackspeak": "^4.2.3" | ||
| }, | ||
| "engines": { | ||
| "node": "20 || >=22" | ||
| }, | ||
| "integrity": "sha512-x0K50QvKQ97fdEz2kPehIerj+YTeptKF9hyYkKf6egnwmMWAkADiO0QCzSp0R5xN8FTZgYaBfSaue46Ej62nMg==", | ||
| "license": "MIT", | ||
| "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-4.0.2.tgz", | ||
| "version": "4.0.2" | ||
| }, | ||
| "node_modules/brace-expansion": { | ||
| "dependencies": { | ||
| "balanced-match": "^4.0.2" | ||
| }, | ||
| "engines": { | ||
| "node": "20 || >=22" | ||
| }, | ||
| "integrity": "sha512-Pdk8c9poy+YhOgVWw1JNN22/HcivgKWwpxKq04M/jTmHyCZn12WPJebZxdjSa5TmBqISrUSgNYU3eRORljfCCw==", | ||
| "license": "MIT", | ||
| "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-5.0.2.tgz", | ||
| "version": "5.0.2" | ||
| }, | ||
| "node_modules/call-bind-apply-helpers": { | ||
| "dependencies": { | ||
| "es-errors": "^1.3.0", | ||
| "function-bind": "^1.1.2" | ||
| }, | ||
| "engines": { | ||
| "node": ">= 0.4" | ||
| }, | ||
| "integrity": "sha512-Sp1ablJ0ivDkSzjcaJdxEunN5/XvksFJ2sMBFfq6x0ryhQV/2b/KwFe21cMpmHtPOSij8K99/wSfoEuTObmuMQ==", | ||
| "license": "MIT", | ||
| "resolved": "https://registry.npmjs.org/call-bind-apply-helpers/-/call-bind-apply-helpers-1.0.2.tgz", | ||
| "version": "1.0.2" | ||
| }, | ||
| "node_modules/clone": { | ||
| "engines": { | ||
| "node": ">=0.8" | ||
| }, | ||
| "integrity": "sha512-JQHZ2QMW6l3aH/j6xCqQThY/9OH4D/9ls34cgkUBiEeocRTU04tHfKPBsUK1PqZCUQM7GiA0IIXJSuXHI64Kbg==", | ||
| "license": "MIT", | ||
| "optional": true, | ||
| "resolved": "https://registry.npmjs.org/clone/-/clone-1.0.4.tgz", | ||
| "version": "1.0.4" | ||
| }, | ||
| "node_modules/combined-stream": { | ||
| "dependencies": { | ||
| "delayed-stream": "~1.0.0" | ||
| }, | ||
| "engines": { | ||
| "node": ">= 0.8" | ||
| }, | ||
| "integrity": "sha512-FQN4MRfuJeHf7cBbBMJFXhKSDq+2kAArBlmRBvcvFE5BB1HZKXtSFASDhdlz9zOYwxh8lDdnvmMOe/+5cdoEdg==", | ||
| "license": "MIT", | ||
| "resolved": "https://registry.npmjs.org/combined-stream/-/combined-stream-1.0.8.tgz", | ||
| "version": "1.0.8" | ||
| }, | ||
| "node_modules/console.table": { | ||
| "dependencies": { | ||
| "easy-table": "1.1.0" | ||
| }, | ||
| "engines": { | ||
| "node": "> 0.10" | ||
| }, | ||
| "integrity": "sha512-dPyZofqggxuvSf7WXvNjuRfnsOk1YazkVP8FdxH4tcH2c37wc79/Yl6Bhr7Lsu00KMgy2ql/qCMuNu8xctZM8g==", | ||
| "license": "MIT", | ||
| "resolved": "https://registry.npmjs.org/console.table/-/console.table-0.10.0.tgz", | ||
| "version": "0.10.0" | ||
| }, | ||
| "node_modules/defaults": { | ||
| "dependencies": { | ||
| "clone": "^1.0.2" | ||
| }, | ||
| "funding": { | ||
| "url": "https://github.com/sponsors/sindresorhus" | ||
| }, | ||
| "integrity": "sha512-eFuaLoy/Rxalv2kr+lqMlUnrDWV+3j4pljOIJgLIhI058IQfWJ7vXhyEIHu+HtC738klGALYxOKDO0bQP3tg8A==", | ||
| "license": "MIT", | ||
| "optional": true, | ||
| "resolved": "https://registry.npmjs.org/defaults/-/defaults-1.0.4.tgz", | ||
| "version": "1.0.4" | ||
| }, | ||
| "node_modules/delayed-stream": { | ||
| "engines": { | ||
| "node": ">=0.4.0" | ||
| }, | ||
| "integrity": "sha512-ZySD7Nf91aLB0RxL4KGrKHBXl7Eds1DAmEdcoVawXnLD7SDhpNgtuII2aAkg7a7QS41jxPSZ17p4VdGnMHk3MQ==", | ||
| "license": "MIT", | ||
| "resolved": "https://registry.npmjs.org/delayed-stream/-/delayed-stream-1.0.0.tgz", | ||
| "version": "1.0.0" | ||
| }, | ||
| "node_modules/detect-libc": { | ||
| "engines": { | ||
| "node": ">=8" | ||
| }, | ||
| "integrity": "sha512-Btj2BOOO83o3WyH59e8MgXsxEQVcarkUOpEYrubB0urwnN10yQ364rsiByU11nZlqWYZm05i/of7io4mzihBtQ==", | ||
| "license": "Apache-2.0", | ||
| "resolved": "https://registry.npmjs.org/detect-libc/-/detect-libc-2.1.2.tgz", | ||
| "version": "2.1.2" | ||
| }, | ||
| "node_modules/dunder-proto": { | ||
| "dependencies": { | ||
| "call-bind-apply-helpers": "^1.0.1", | ||
| "es-errors": "^1.3.0", | ||
| "gopd": "^1.2.0" | ||
| }, | ||
| "engines": { | ||
| "node": ">= 0.4" | ||
| }, | ||
| "integrity": "sha512-KIN/nDJBQRcXw0MLVhZE9iQHmG68qAVIBg9CqmUYjmQIhgij9U5MFvrqkUL5FbtyyzZuOeOt0zdeRe4UY7ct+A==", | ||
| "license": "MIT", | ||
| "resolved": "https://registry.npmjs.org/dunder-proto/-/dunder-proto-1.0.1.tgz", | ||
| "version": "1.0.1" | ||
| }, | ||
| "node_modules/easy-table": { | ||
| "integrity": "sha512-oq33hWOSSnl2Hoh00tZWaIPi1ievrD9aFG82/IgjlycAnW9hHx5PkJiXpxPsgEE+H7BsbVQXFVFST8TEXS6/pA==", | ||
| "license": "MIT", | ||
| "optionalDependencies": { | ||
| "wcwidth": ">=1.0.1" | ||
| }, | ||
| "resolved": "https://registry.npmjs.org/easy-table/-/easy-table-1.1.0.tgz", | ||
| "version": "1.1.0" | ||
| }, | ||
| "node_modules/es-define-property": { | ||
| "engines": { | ||
| "node": ">= 0.4" | ||
| }, | ||
| "integrity": "sha512-e3nRfgfUZ4rNGL232gUgX06QNyyez04KdjFrF+LTRoOXmrOgFKDg4BCdsjW8EnT69eqdYGmRpJwiPVYNrCaW3g==", | ||
| "license": "MIT", | ||
| "resolved": "https://registry.npmjs.org/es-define-property/-/es-define-property-1.0.1.tgz", | ||
| "version": "1.0.1" | ||
| }, | ||
| "node_modules/es-errors": { | ||
| "engines": { | ||
| "node": ">= 0.4" | ||
| }, | ||
| "integrity": "sha512-Zf5H2Kxt2xjTvbJvP2ZWLEICxA6j+hAmMzIlypy4xcBg1vKVnx89Wy0GbS+kf5cwCVFFzdCFh2XSCFNULS6csw==", | ||
| "license": "MIT", | ||
| "resolved": "https://registry.npmjs.org/es-errors/-/es-errors-1.3.0.tgz", | ||
| "version": "1.3.0" | ||
| }, | ||
| "node_modules/es-object-atoms": { | ||
| "dependencies": { | ||
| "es-errors": "^1.3.0" | ||
| }, | ||
| "engines": { | ||
| "node": ">= 0.4" | ||
| }, | ||
| "integrity": "sha512-FGgH2h8zKNim9ljj7dankFPcICIK9Cp5bm+c2gQSYePhpaG5+esrLODihIorn+Pe6FGJzWhXQotPv73jTaldXA==", | ||
| "license": "MIT", | ||
| "resolved": "https://registry.npmjs.org/es-object-atoms/-/es-object-atoms-1.1.1.tgz", | ||
| "version": "1.1.1" | ||
| }, | ||
| "node_modules/es-set-tostringtag": { | ||
| "dependencies": { | ||
| "es-errors": "^1.3.0", | ||
| "get-intrinsic": "^1.2.6", | ||
| "has-tostringtag": "^1.0.2", | ||
| "hasown": "^2.0.2" | ||
| }, | ||
| "engines": { | ||
| "node": ">= 0.4" | ||
| }, | ||
| "integrity": "sha512-j6vWzfrGVfyXxge+O0x5sh6cvxAog0a/4Rdd2K36zCMV5eJ+/+tOAngRO8cODMNWbVRdVlmGZQL2YS3yR8bIUA==", | ||
| "license": "MIT", | ||
| "resolved": "https://registry.npmjs.org/es-set-tostringtag/-/es-set-tostringtag-2.1.0.tgz", | ||
| "version": "2.1.0" | ||
| }, | ||
| "node_modules/follow-redirects": { | ||
| "engines": { | ||
| "node": ">=4.0" | ||
| }, | ||
| "funding": [ | ||
| { | ||
| "type": "individual", | ||
| "url": "https://github.com/sponsors/RubenVerborgh" | ||
| } | ||
| ], | ||
| "integrity": "sha512-deG2P0JfjrTxl50XGCDyfI97ZGVCxIpfKYmfyrQ54n5FO/0gfIES8C/Psl6kWVDolizcaaxZJnTS0QSMxvnsBQ==", | ||
| "license": "MIT", | ||
| "peerDependenciesMeta": { | ||
| "debug": { | ||
| "optional": true | ||
| } | ||
| }, | ||
| "resolved": "https://registry.npmjs.org/follow-redirects/-/follow-redirects-1.15.11.tgz", | ||
| "version": "1.15.11" | ||
| }, | ||
| "node_modules/form-data": { | ||
| "dependencies": { | ||
| "asynckit": "^0.4.0", | ||
| "combined-stream": "^1.0.8", | ||
| "es-set-tostringtag": "^2.1.0", | ||
| "hasown": "^2.0.2", | ||
| "mime-types": "^2.1.12" | ||
| }, | ||
| "engines": { | ||
| "node": ">= 6" | ||
| }, | ||
| "integrity": "sha512-8RipRLol37bNs2bhoV67fiTEvdTrbMUYcFTiy3+wuuOnUog2QBHCZWXDRijWQfAkhBj2Uf5UnVaiWwA5vdd82w==", | ||
| "license": "MIT", | ||
| "resolved": "https://registry.npmjs.org/form-data/-/form-data-4.0.5.tgz", | ||
| "version": "4.0.5" | ||
| }, | ||
| "node_modules/function-bind": { | ||
| "funding": { | ||
| "url": "https://github.com/sponsors/ljharb" | ||
| }, | ||
| "integrity": "sha512-7XHNxH7qX9xG5mIwxkhumTox/MIRNcOgDrxWsMt2pAr23WHp6MrRlN7FBSFpCpr+oVO0F744iUgR82nJMfG2SA==", | ||
| "license": "MIT", | ||
| "resolved": "https://registry.npmjs.org/function-bind/-/function-bind-1.1.2.tgz", | ||
| "version": "1.1.2" | ||
| }, | ||
| "node_modules/get-intrinsic": { | ||
| "dependencies": { | ||
| "call-bind-apply-helpers": "^1.0.2", | ||
| "es-define-property": "^1.0.1", | ||
| "es-errors": "^1.3.0", | ||
| "es-object-atoms": "^1.1.1", | ||
| "function-bind": "^1.1.2", | ||
| "get-proto": "^1.0.1", | ||
| "gopd": "^1.2.0", | ||
| "has-symbols": "^1.1.0", | ||
| "hasown": "^2.0.2", | ||
| "math-intrinsics": "^1.1.0" | ||
| }, | ||
| "engines": { | ||
| "node": ">= 0.4" | ||
| }, | ||
| "funding": { | ||
| "url": "https://github.com/sponsors/ljharb" | ||
| }, | ||
| "integrity": "sha512-9fSjSaos/fRIVIp+xSJlE6lfwhES7LNtKaCBIamHsjr2na1BiABJPo0mOjjz8GJDURarmCPGqaiVg5mfjb98CQ==", | ||
| "license": "MIT", | ||
| "resolved": "https://registry.npmjs.org/get-intrinsic/-/get-intrinsic-1.3.0.tgz", | ||
| "version": "1.3.0" | ||
| }, | ||
| "node_modules/get-proto": { | ||
| "dependencies": { | ||
| "dunder-proto": "^1.0.1", | ||
| "es-object-atoms": "^1.0.0" | ||
| }, | ||
| "engines": { | ||
| "node": ">= 0.4" | ||
| }, | ||
| "integrity": "sha512-sTSfBjoXBp89JvIKIefqw7U2CCebsc74kiY6awiGogKtoSGbgjYE/G/+l9sF3MWFPNc9IcoOC4ODfKHfxFmp0g==", | ||
| "license": "MIT", | ||
| "resolved": "https://registry.npmjs.org/get-proto/-/get-proto-1.0.1.tgz", | ||
| "version": "1.0.1" | ||
| }, | ||
| "node_modules/glob": { | ||
| "dependencies": { | ||
| "minimatch": "^10.2.0", | ||
| "minipass": "^7.1.2", | ||
| "path-scurry": "^2.0.0" | ||
| }, | ||
| "engines": { | ||
| "node": "20 || >=22" | ||
| }, | ||
| "funding": { | ||
| "url": "https://github.com/sponsors/isaacs" | ||
| }, | ||
| "integrity": "sha512-/g3B0mC+4x724v1TgtBlBtt2hPi/EWptsIAmXUx9Z2rvBYleQcsrmaOzd5LyL50jf/Soi83ZDJmw2+XqvH/EeA==", | ||
| "license": "BlueOak-1.0.0", | ||
| "resolved": "https://registry.npmjs.org/glob/-/glob-13.0.3.tgz", | ||
| "version": "13.0.3" | ||
| }, | ||
| "node_modules/gopd": { | ||
| "engines": { | ||
| "node": ">= 0.4" | ||
| }, | ||
| "funding": { | ||
| "url": "https://github.com/sponsors/ljharb" | ||
| }, | ||
| "integrity": "sha512-ZUKRh6/kUFoAiTAtTYPZJ3hw9wNxx+BIBOijnlG9PnrJsCcSjs1wyyD6vJpaYtgnzDrKYRSqf3OO6Rfa93xsRg==", | ||
| "license": "MIT", | ||
| "resolved": "https://registry.npmjs.org/gopd/-/gopd-1.2.0.tgz", | ||
| "version": "1.2.0" | ||
| }, | ||
| "node_modules/has-symbols": { | ||
| "engines": { | ||
| "node": ">= 0.4" | ||
| }, | ||
| "funding": { | ||
| "url": "https://github.com/sponsors/ljharb" | ||
| }, | ||
| "integrity": "sha512-1cDNdwJ2Jaohmb3sg4OmKaMBwuC48sYni5HUw2DvsC8LjGTLK9h+eb1X6RyuOHe4hT0ULCW68iomhjUoKUqlPQ==", | ||
| "license": "MIT", | ||
| "resolved": "https://registry.npmjs.org/has-symbols/-/has-symbols-1.1.0.tgz", | ||
| "version": "1.1.0" | ||
| }, | ||
| "node_modules/has-tostringtag": { | ||
| "dependencies": { | ||
| "has-symbols": "^1.0.3" | ||
| }, | ||
| "engines": { | ||
| "node": ">= 0.4" | ||
| }, | ||
| "funding": { | ||
| "url": "https://github.com/sponsors/ljharb" | ||
| }, | ||
| "integrity": "sha512-NqADB8VjPFLM2V0VvHUewwwsw0ZWBaIdgo+ieHtK3hasLz4qeCRjYcqfB6AQrBggRKppKF8L52/VqdVsO47Dlw==", | ||
| "license": "MIT", | ||
| "resolved": "https://registry.npmjs.org/has-tostringtag/-/has-tostringtag-1.0.2.tgz", | ||
| "version": "1.0.2" | ||
| }, | ||
| "node_modules/hasown": { | ||
| "dependencies": { | ||
| "function-bind": "^1.1.2" | ||
| }, | ||
| "engines": { | ||
| "node": ">= 0.4" | ||
| }, | ||
| "integrity": "sha512-0hJU9SCPvmMzIBdZFqNPXWa6dqh7WdH0cII9y+CyS8rG3nL48Bclra9HmKhVVUHyPWNH5Y7xDwAB7bfgSjkUMQ==", | ||
| "license": "MIT", | ||
| "resolved": "https://registry.npmjs.org/hasown/-/hasown-2.0.2.tgz", | ||
| "version": "2.0.2" | ||
| }, | ||
| "node_modules/jackspeak": { | ||
| "dependencies": { | ||
| "@isaacs/cliui": "^9.0.0" | ||
| }, | ||
| "engines": { | ||
| "node": "20 || >=22" | ||
| }, | ||
| "funding": { | ||
| "url": "https://github.com/sponsors/isaacs" | ||
| }, | ||
| "integrity": "sha512-ykkVRwrYvFm1nb2AJfKKYPr0emF6IiXDYUaFx4Zn9ZuIH7MrzEZ3sD5RlqGXNRpHtvUHJyOnCEFxOlNDtGo7wg==", | ||
| "license": "BlueOak-1.0.0", | ||
| "resolved": "https://registry.npmjs.org/jackspeak/-/jackspeak-4.2.3.tgz", | ||
| "version": "4.2.3" | ||
| }, | ||
| "node_modules/lru-cache": { | ||
| "engines": { | ||
| "node": "20 || >=22" | ||
| }, | ||
| "integrity": "sha512-ESL2CrkS/2wTPfuend7Zhkzo2u0daGJ/A2VucJOgQ/C48S/zB8MMeMHSGKYpXhIjbPxfuezITkaBH1wqv00DDQ==", | ||
| "license": "BlueOak-1.0.0", | ||
| "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-11.2.6.tgz", | ||
| "version": "11.2.6" | ||
| }, | ||
| "node_modules/math-intrinsics": { | ||
| "engines": { | ||
| "node": ">= 0.4" | ||
| }, | ||
| "integrity": "sha512-/IXtbwEk5HTPyEwyKX6hGkYXxM9nbj64B+ilVJnC/R6B0pH5G4V3b0pVbL7DBj4tkhBAppbQUlf6F6Xl9LHu1g==", | ||
| "license": "MIT", | ||
| "resolved": "https://registry.npmjs.org/math-intrinsics/-/math-intrinsics-1.1.0.tgz", | ||
| "version": "1.1.0" | ||
| }, | ||
| "node_modules/mime-db": { | ||
| "engines": { | ||
| "node": ">= 0.6" | ||
| }, | ||
| "integrity": "sha512-sPU4uV7dYlvtWJxwwxHD0PuihVNiE7TyAbQ5SWxDCB9mUYvOgroQOwYQQOKPJ8CIbE+1ETVlOoK1UC2nU3gYvg==", | ||
| "license": "MIT", | ||
| "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.52.0.tgz", | ||
| "version": "1.52.0" | ||
| }, | ||
| "node_modules/mime-types": { | ||
| "dependencies": { | ||
| "mime-db": "1.52.0" | ||
| }, | ||
| "engines": { | ||
| "node": ">= 0.6" | ||
| }, | ||
| "integrity": "sha512-ZDY+bPm5zTTF+YpCrAU9nK0UgICYPT0QtT1NZWFv4s++TNkcgVaT0g6+4R2uI4MjQjzysHB1zxuWL50hzaeXiw==", | ||
| "license": "MIT", | ||
| "resolved": "https://registry.npmjs.org/mime-types/-/mime-types-2.1.35.tgz", | ||
| "version": "2.1.35" | ||
| }, | ||
| "node_modules/minimatch": { | ||
| "dependencies": { | ||
| "brace-expansion": "^5.0.2" | ||
| }, | ||
| "engines": { | ||
| "node": "20 || >=22" | ||
| }, | ||
| "funding": { | ||
| "url": "https://github.com/sponsors/isaacs" | ||
| }, | ||
| "integrity": "sha512-ugkC31VaVg9cF0DFVoADH12k6061zNZkZON+aX8AWsR9GhPcErkcMBceb6znR8wLERM2AkkOxy2nWRLpT9Jq5w==", | ||
| "license": "BlueOak-1.0.0", | ||
| "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-10.2.0.tgz", | ||
| "version": "10.2.0" | ||
| }, | ||
| "node_modules/minipass": { | ||
| "engines": { | ||
| "node": ">=16 || 14 >=14.17" | ||
| }, | ||
| "integrity": "sha512-qOOzS1cBTWYF4BH8fVePDBOO9iptMnGUEZwNc/cMWnTV2nVLZ7VoNWEPHkYczZA0pdoA7dl6e7FL659nX9S2aw==", | ||
| "license": "ISC", | ||
| "resolved": "https://registry.npmjs.org/minipass/-/minipass-7.1.2.tgz", | ||
| "version": "7.1.2" | ||
| }, | ||
| "node_modules/package-json-from-dist": { | ||
| "integrity": "sha512-UEZIS3/by4OC8vL3P2dTXRETpebLI2NiI5vIrjaD/5UtrkFX/tNbwjTSRAGC/+7CAo2pIcBaRgWmcBBHcsaCIw==", | ||
| "license": "BlueOak-1.0.0", | ||
| "resolved": "https://registry.npmjs.org/package-json-from-dist/-/package-json-from-dist-1.0.1.tgz", | ||
| "version": "1.0.1" | ||
| }, | ||
| "node_modules/path-scurry": { | ||
| "dependencies": { | ||
| "lru-cache": "^11.0.0", | ||
| "minipass": "^7.1.2" | ||
| }, | ||
| "engines": { | ||
| "node": "20 || >=22" | ||
| }, | ||
| "funding": { | ||
| "url": "https://github.com/sponsors/isaacs" | ||
| }, | ||
| "integrity": "sha512-oWyT4gICAu+kaA7QWk/jvCHWarMKNs6pXOGWKDTr7cw4IGcUbW+PeTfbaQiLGheFRpjo6O9J0PmyMfQPjH71oA==", | ||
| "license": "BlueOak-1.0.0", | ||
| "resolved": "https://registry.npmjs.org/path-scurry/-/path-scurry-2.0.1.tgz", | ||
| "version": "2.0.1" | ||
| }, | ||
| "node_modules/prettier": { | ||
| "bin": { | ||
| "prettier": "bin/prettier.cjs" | ||
| }, | ||
| "dev": true, | ||
| "engines": { | ||
| "node": ">=14" | ||
| }, | ||
| "funding": { | ||
| "url": "https://github.com/prettier/prettier?sponsor=1" | ||
| }, | ||
| "integrity": "sha512-UOnG6LftzbdaHZcKoPFtOcCKztrQ57WkHDeRD9t/PTQtmT0NHSeWWepj6pS0z/N7+08BHFDQVUrfmfMRcZwbMg==", | ||
| "license": "MIT", | ||
| "resolved": "https://registry.npmjs.org/prettier/-/prettier-3.8.1.tgz", | ||
| "version": "3.8.1" | ||
| }, | ||
| "node_modules/proxy-from-env": { | ||
| "integrity": "sha512-D+zkORCbA9f1tdWRK0RaCR3GPv50cMxcrz4X8k5LTSUD1Dkw47mKJEZQNunItRTkWwgtaUSo1RVFRIG9ZXiFYg==", | ||
| "license": "MIT", | ||
| "resolved": "https://registry.npmjs.org/proxy-from-env/-/proxy-from-env-1.1.0.tgz", | ||
| "version": "1.1.0" | ||
| }, | ||
| "node_modules/rimraf": { | ||
| "bin": { | ||
| "rimraf": "dist/esm/bin.mjs" | ||
| }, | ||
| "dependencies": { | ||
| "glob": "^13.0.3", | ||
| "package-json-from-dist": "^1.0.1" | ||
| }, | ||
| "engines": { | ||
| "node": "20 || >=22" | ||
| }, | ||
| "funding": { | ||
| "url": "https://github.com/sponsors/isaacs" | ||
| }, | ||
| "integrity": "sha512-LKg+Cr2ZF61fkcaK1UdkH2yEBBKnYjTyWzTJT6KNPcSPaiT7HSdhtMXQuN5wkTX0Xu72KQ1l8S42rlmexS2hSA==", | ||
| "license": "BlueOak-1.0.0", | ||
| "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-6.1.3.tgz", | ||
| "version": "6.1.3" | ||
| }, | ||
| "node_modules/tunnel": { | ||
| "engines": { | ||
| "node": ">=0.6.11 <=0.7.0 || >=0.7.3" | ||
| }, | ||
| "integrity": "sha512-1h/Lnq9yajKY2PEbBadPXj3VxsDDu844OnaAo52UVmIzIvwwtBPIuNvkjuzBlTWpfJyUbG3ez0KSBibQkj4ojg==", | ||
| "license": "MIT", | ||
| "resolved": "https://registry.npmjs.org/tunnel/-/tunnel-0.0.6.tgz", | ||
| "version": "0.0.6" | ||
| }, | ||
| "node_modules/wcwidth": { | ||
| "dependencies": { | ||
| "defaults": "^1.0.3" | ||
| }, | ||
| "integrity": "sha512-XHPEwS0q6TaxcvG85+8EYkbiCux2XtWG2mkc47Ng2A77BQu9+DqIOJldST4HgPkuea7dvKSj5VgX3P1d4rW8Tg==", | ||
| "license": "MIT", | ||
| "optional": true, | ||
| "resolved": "https://registry.npmjs.org/wcwidth/-/wcwidth-1.0.1.tgz", | ||
| "version": "1.0.1" | ||
| } | ||
| }, | ||
| "requires": true, | ||
| "version": "0.1.1" | ||
| } |
Install scripts
Supply chain riskInstall scripts are run when the package is installed or built. Malicious packages often use scripts that run automatically to execute payloads or fetch additional code.
Major refactor
Supply chain riskPackage has recently undergone a major refactor. It may be unstable or indicate significant internal changes. Use caution when updating to versions that include significant changes.
Install scripts
Supply chain riskInstall scripts are run when the package is installed or built. Malicious packages often use scripts that run automatically to execute payloads or fetch additional code.
Shrinkwrap
Supply chain riskPackage contains a shrinkwrap file. This may allow the package to bypass normal install procedures.
Major refactor
Supply chain riskPackage has recently undergone a major refactor. It may be unstable or indicate significant internal changes. Use caution when updating to versions that include significant changes.
Filesystem access
Supply chain riskAccesses the file system, and could potentially read sensitive data.
AI-detected potential code anomaly
Supply chain riskAI has identified unusual behaviors that may pose a security risk.
No repository
Supply chain riskPackage does not have a linked source code repository. Without this field, a package will have no reference to the location of the source code use to generate the package.
0
-100%1
-50%0
-100%4742
-86.45%8
60%5
-44.44%125
-85.36%16
-72.41%+ Added
+ Added
+ Added
+ Added
+ Added
+ Added
+ Added
- Removed
- Removed
- Removed
- Removed
- Removed
- Removed
- Removed
- Removed
- Removed
- Removed
- Removed
- Removed
- Removed
- Removed
- Removed
- Removed
- Removed
- Removed
- Removed
- Removed
- Removed
- Removed
- Removed
- Removed
- Removed
- Removed
- Removed
- Removed
- Removed
- Removed
- Removed
- Removed
- Removed
- Removed
- Removed
- Removed
- Removed
- Removed
- Removed
- Removed
- Removed
- Removed
- Removed
- Removed
- Removed