@moontra/moonui-cli
Version:
CLI tool for MoonUI component library
775 lines (769 loc) • 24.5 kB
JavaScript
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 __require = /* @__PURE__ */ ((x) => typeof require !== "undefined" ? require : typeof Proxy !== "undefined" ? new Proxy(x, {
get: (a, b) => (typeof require !== "undefined" ? require : a)[b]
}) : x)(function(x) {
if (typeof require !== "undefined")
return require.apply(this, arguments);
throw new Error('Dynamic require of "' + x + '" is not supported');
});
var __commonJS = (cb, mod) => function __require2() {
return mod || (0, cb[__getOwnPropNames(cb)[0]])((mod = { exports: {} }).exports, mod), mod.exports;
};
var __copyProps = (to, from, except, desc) => {
if (from && typeof from === "object" || typeof from === "function") {
for (let key of __getOwnPropNames(from))
if (!__hasOwnProp.call(to, key) && key !== except)
__defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
}
return to;
};
var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__getProtoOf(mod)) : {}, __copyProps(
// If the importer is in node compatibility mode or this is not an ESM
// file that has been converted to a CommonJS file using a Babel-
// compatible transform (i.e. "__esModule" has not been set), then set
// "default" to the CommonJS "module.exports" for node compatibility.
isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", { value: mod, enumerable: true }) : target,
mod
));
// package.json
var require_package = __commonJS({
"package.json"(exports, module) {
module.exports = {
name: "@moontra/moonui-cli",
version: "2.13.5",
description: "CLI tool for MoonUI component library",
main: "dist/index.js",
types: "dist/index.d.ts",
bin: {
moonui: "./dist/index.js"
},
files: [
"dist",
"src/postcss",
"src/vite",
"src/theme-presets.ts",
"src/utils/theme-generator.ts"
],
exports: {
".": {
types: "./dist/index.d.ts",
import: "./dist/index.js",
require: "./dist/index.cjs"
},
"./postcss/moonui-theme-plugin": {
types: "./src/postcss/moonui-theme-plugin.d.ts",
require: "./src/postcss/moonui-theme-plugin.js"
},
"./vite/moonui-theme-plugin": {
types: "./dist/vite/moonui-theme-plugin.d.ts",
import: "./dist/vite/moonui-theme-plugin.js"
}
},
scripts: {
build: "tsup src/index.ts --format cjs,esm --dts",
dev: "tsup src/index.ts --format cjs,esm --dts --watch --sourcemap",
clean: "rm -rf dist",
lint: 'eslint "src/**/*.ts*"',
test: "jest",
"test:watch": "jest --watch",
"test:coverage": "jest --coverage",
prepublishOnly: "npm run clean && npm run build",
pub: "npm version patch && npm run build && npm publish --access=public",
"pub:minor": "npm version minor && npm run build && npm publish --access=public",
"pub:major": "npm version major && npm run build && npm publish --access=public"
},
keywords: [
"ui",
"components",
"cli",
"moonui"
],
author: "MoonUI",
license: "MIT",
dependencies: {
"@radix-ui/react-primitive": "^2.1.3",
"@types/jsonwebtoken": "^9.0.10",
"@types/node-fetch": "^2.6.12",
"@types/react-syntax-highlighter": "^15.5.13",
"adm-zip": "^0.5.10",
axios: "^1.6.2",
chalk: "^4.1.2",
"class-variance-authority": "^0.7.1",
clsx: "^2.1.1",
commander: "^10.0.1",
"cross-spawn": "^7.0.3",
degit: "^2.8.4",
figlet: "^1.6.0",
"fs-extra": "^11.1.1",
inquirer: "^9.2.14",
jsonwebtoken: "^9.0.2",
"node-fetch": "^3.3.2",
open: "^8.4.2",
ora: "^5.4.1",
prompts: "^2.4.2",
"react-syntax-highlighter": "^15.6.1",
"tailwind-merge": "^3.3.1",
"ts-morph": "^18.0.0",
"validate-npm-package-name": "^5.0.0",
zod: "^3.22.4"
},
devDependencies: {
"@next/bundle-analyzer": "^15.4.6",
"@sentry/nextjs": "^10.3.0",
"@svgr/webpack": "^8.1.0",
"@types/adm-zip": "^0.5.5",
"@types/cross-spawn": "^6.0.6",
"@types/degit": "^2.8.6",
"@types/figlet": "^1.7.0",
"@types/fs-extra": "^11.0.4",
"@types/inquirer": "^9.0.9",
"@types/node": "^18.16.0",
"@types/ora": "^3.1.0",
"@types/prompts": "^2.4.9",
"@types/validate-npm-package-name": "^4.0.2",
autoprefixer: "^10.4.21",
eslint: "^8.39.0",
jest: "^29.5.0",
postcss: "^8.5.6",
tailwindcss: "^4.1.11",
tsup: "^6.7.0",
typescript: "^5.0.4"
}
};
}
});
// src/services/auth-service.ts
import fs from "fs-extra";
import path from "path";
import os2 from "os";
import crypto2 from "crypto";
import chalk from "chalk";
// src/services/device.service.ts
import os from "os";
import crypto from "crypto";
import { networkInterfaces } from "os";
var DeviceService = class {
/**
* Generate a unique device fingerprint based on system attributes
*/
static getDeviceFingerprint() {
const deviceInfo = this.getDeviceInfo();
const fingerprintData = [
deviceInfo.hostname,
deviceInfo.username,
deviceInfo.platform,
deviceInfo.arch,
deviceInfo.cpuModel,
deviceInfo.cpuCount.toString(),
deviceInfo.macAddress || "no-mac"
].join("|");
return crypto.createHash("sha256").update(fingerprintData).digest("hex");
}
/**
* Get detailed device information
*/
static getDeviceInfo() {
const cpus = os.cpus();
const macAddress = this.getMacAddress();
const packageJson = require_package();
const cliVersion = packageJson.version || "unknown";
return {
hostname: os.hostname(),
username: os.userInfo().username,
platform: os.platform(),
arch: os.arch(),
cpuModel: cpus[0]?.model || "unknown",
cpuCount: cpus.length,
totalMemory: os.totalmem(),
nodeVersion: process.version,
cliVersion,
macAddress
};
}
/**
* Get the primary MAC address of the device
*/
static getMacAddress() {
const interfaces = networkInterfaces();
for (const name of Object.keys(interfaces)) {
const iface = interfaces[name];
if (!iface)
continue;
for (const details of iface) {
if (!details.internal && details.mac && details.mac !== "00:00:00:00:00:00") {
return details.mac;
}
}
}
for (const name of Object.keys(interfaces)) {
const iface = interfaces[name];
if (!iface)
continue;
for (const details of iface) {
if (details.mac && details.mac !== "00:00:00:00:00:00") {
return details.mac;
}
}
}
return void 0;
}
/**
* Validate device against API
*/
static async validateDevice(apiKey, deviceId) {
try {
const API_BASE2 = "https://moonui.dev";
const response = await fetch(`${API_BASE2}/api/device/validate`, {
method: "POST",
headers: {
"Content-Type": "application/json",
"Authorization": `Bearer ${apiKey}`,
"X-Device-ID": deviceId
},
body: JSON.stringify({
deviceId,
deviceInfo: this.getDeviceInfo()
})
});
return response.ok;
} catch (error) {
console.error("Device validation error:", error);
return false;
}
}
/**
* Register a new device
*/
static async registerDevice(apiKey) {
try {
const deviceId = this.getDeviceFingerprint();
const deviceInfo = this.getDeviceInfo();
const API_BASE2 = "https://moonui.dev";
const response = await fetch(`${API_BASE2}/api/device/register`, {
method: "POST",
headers: {
"Content-Type": "application/json",
"Authorization": `Bearer ${apiKey}`
},
body: JSON.stringify({
deviceId,
deviceInfo
})
});
if (response.ok) {
return { success: true, deviceId };
} else {
const error = await response.json();
return { success: false, error: error.message || "Failed to register device" };
}
} catch (error) {
return {
success: false,
error: error.message || "Device registration failed"
};
}
}
/**
* List all registered devices for the user
*/
static async listDevices(apiKey) {
try {
const API_BASE2 = "https://moonui.dev";
const response = await fetch(`${API_BASE2}/api/device/list`, {
headers: {
"Authorization": `Bearer ${apiKey}`
}
});
if (response.ok) {
const data = await response.json();
return data.devices || [];
}
return [];
} catch (error) {
console.error("Failed to list devices:", error);
return [];
}
}
/**
* Revoke a device
*/
static async revokeDevice(apiKey, deviceId) {
try {
const API_BASE2 = "https://moonui.dev";
const response = await fetch(`${API_BASE2}/api/device/revoke`, {
method: "POST",
headers: {
"Content-Type": "application/json",
"Authorization": `Bearer ${apiKey}`
},
body: JSON.stringify({ deviceId })
});
return response.ok;
} catch (error) {
console.error("Failed to revoke device:", error);
return false;
}
}
/**
* Get current device status
*/
static async getDeviceStatus(apiKey) {
try {
const deviceId = this.getDeviceFingerprint();
const API_BASE2 = "https://moonui.dev";
const response = await fetch(`${API_BASE2}/api/device/status`, {
headers: {
"Authorization": `Bearer ${apiKey}`,
"X-Device-ID": deviceId
}
});
if (response.ok) {
return await response.json();
}
return null;
} catch (error) {
console.error("Failed to get device status:", error);
return null;
}
}
};
// src/services/auth-service.ts
var API_BASE = "https://moonui.dev";
var CACHE_DURATION = 24 * 60 * 60 * 1e3;
var REFRESH_THRESHOLD = 60 * 60 * 1e3;
var MOONUI_SECRET_KEY = "moonui-2024-auth-encryption-key-v1";
var AuthService = class {
constructor() {
const configDir = path.join(os2.homedir(), ".moonui");
this.authPath = path.join(configDir, "auth.encrypted");
this.encryptionKey = this.getEncryptionKey();
}
static getInstance() {
if (!this.instance) {
this.instance = new AuthService();
}
return this.instance;
}
getDeviceFingerprint() {
const platform = os2.platform();
const hostname = os2.hostname();
const username = os2.userInfo().username;
return `${platform}-${hostname}-${username}`;
}
getEncryptionKey() {
const devicePart = this.getDeviceFingerprint();
return crypto2.pbkdf2Sync(
MOONUI_SECRET_KEY + devicePart,
"moonui-salt-2025",
1e4,
32,
"sha256"
);
}
encrypt(data) {
const iv = crypto2.randomBytes(16);
const cipher = crypto2.createCipheriv("aes-256-cbc", this.encryptionKey, iv);
let encrypted = cipher.update(data, "utf8", "hex");
encrypted += cipher.final("hex");
return iv.toString("hex") + ":" + encrypted;
}
decrypt(data) {
const parts = data.split(":");
const iv = Buffer.from(parts[0], "hex");
const encrypted = parts[1];
const decipher = crypto2.createDecipheriv("aes-256-cbc", this.encryptionKey, iv);
let decrypted = decipher.update(encrypted, "hex", "utf8");
decrypted += decipher.final("utf8");
return decrypted;
}
generateSignature(token) {
const data = JSON.stringify({
accessToken: token.accessToken,
userId: token.user.id,
plan: token.user.plan,
expiresAt: token.expiresAt
});
return crypto2.createHmac("sha256", this.encryptionKey).update(data).digest("hex");
}
verifySignature(token) {
if (!token.signature)
return false;
const expectedSignature = this.generateSignature(token);
return token.signature === expectedSignature;
}
async saveAuth(token) {
try {
token.signature = this.generateSignature(token);
token.lastVerified = (/* @__PURE__ */ new Date()).toISOString();
const deviceFingerprint = this.getDeviceFingerprint();
token.deviceId = deviceFingerprint;
const cache = {
token,
deviceId: deviceFingerprint,
machineId: deviceFingerprint,
encryptedAt: (/* @__PURE__ */ new Date()).toISOString(),
// Extended user info for local auth
userInfo: {
email: token.user.email,
plan: token.user.plan,
hasProAccess: token.user.hasProAccess || token.user.plan !== "free",
expiresAt: token.expiresAt,
features: token.user.features || [],
hasLifetimeAccess: token.user.hasLifetimeAccess
}
};
const encrypted = this.encrypt(JSON.stringify(cache));
const hmac = crypto2.createHmac("sha256", this.encryptionKey);
const [iv, encryptedData] = encrypted.split(":");
hmac.update(encryptedData);
const signature = hmac.digest("hex");
const finalData = `${iv}.${encryptedData}.${signature}`;
const configDir = path.dirname(this.authPath);
await fs.ensureDir(configDir);
await fs.writeFile(this.authPath, finalData, "utf8");
await fs.chmod(this.authPath, 384);
} catch (error) {
throw new Error(`Failed to save auth: ${error.message}`);
}
}
async clearAuth() {
try {
const configDir = path.join(os2.homedir(), ".moonui");
const filesToRemove = [
this.authPath,
path.join(configDir, "auth.json"),
path.join(configDir, "auth.encrypted"),
path.join(configDir, "device.json"),
path.join(configDir, "cache"),
path.join(configDir, ".session"),
path.join(configDir, ".token"),
path.join(configDir, ".refresh"),
path.join(configDir, ".device"),
path.join(configDir, ".fingerprint")
];
for (const file of filesToRemove) {
try {
if (await fs.pathExists(file)) {
await fs.remove(file);
}
} catch {
}
}
const cacheDir = path.join(configDir, "cache");
try {
if (await fs.pathExists(cacheDir)) {
await fs.emptyDir(cacheDir);
}
} catch {
}
} catch (error) {
throw new Error(`Failed to clear auth: ${error.message}`);
}
}
async getAuth() {
try {
if (!await fs.pathExists(this.authPath)) {
return null;
}
const fileContent = await fs.readFile(this.authPath, "utf8");
const parts = fileContent.split(".");
if (parts.length !== 3) {
return null;
}
const [iv, encryptedData, signature] = parts;
const hmac = crypto2.createHmac("sha256", this.encryptionKey);
hmac.update(encryptedData);
const computedSignature = hmac.digest("hex");
if (computedSignature !== signature) {
return null;
}
const encrypted = `${iv}:${encryptedData}`;
const decrypted = this.decrypt(encrypted);
const cache = JSON.parse(decrypted);
const currentDeviceId = this.getDeviceFingerprint();
if (cache.deviceId && cache.deviceId !== currentDeviceId) {
console.warn(chalk.red("\u26A0\uFE0F This license is registered to a different device"));
console.warn(chalk.yellow(" MoonUI Pro licenses are device-specific"));
console.warn(chalk.yellow(" Please login again or contact support for multi-device access"));
await this.clearAuth();
return null;
}
if (!cache.token.deviceId) {
cache.token.deviceId = currentDeviceId;
}
if (!this.verifySignature(cache.token)) {
console.warn(chalk.red("Auth token signature verification failed"));
await this.clearAuth();
return null;
}
const expiresAt = new Date(cache.token.expiresAt);
const now = /* @__PURE__ */ new Date();
if (expiresAt < now) {
if (cache.token.refreshToken) {
try {
const newToken = await this.refreshToken(cache.token.refreshToken);
await this.saveAuth(newToken);
return newToken;
} catch (error) {
return null;
}
}
return null;
}
const lastVerified = new Date(cache.token.lastVerified);
if (now.getTime() - lastVerified.getTime() > REFRESH_THRESHOLD) {
this.backgroundRefresh(cache.token);
}
return cache.token;
} catch (error) {
await this.clearAuth();
return null;
}
}
async backgroundRefresh(token) {
try {
const response = await fetch(`${API_BASE}/api/auth/verify`, {
method: "POST",
headers: {
"Authorization": `Bearer ${token.accessToken}`,
"Content-Type": "application/json"
}
});
if (response.ok) {
const data = await response.json();
token.user = data.user;
token.lastVerified = (/* @__PURE__ */ new Date()).toISOString();
token.signature = this.generateSignature(token);
await this.saveAuth(token);
}
} catch {
}
}
async refreshToken(refreshToken) {
const response = await fetch(`${API_BASE}/api/auth/refresh`, {
method: "POST",
headers: {
"Content-Type": "application/json"
},
body: JSON.stringify({
refresh_token: refreshToken,
grant_type: "refresh_token"
})
});
if (!response.ok) {
throw new Error("Token refresh failed");
}
const data = await response.json();
return {
accessToken: data.access_token,
refreshToken: data.refresh_token,
expiresAt: data.expires_at,
user: data.user,
lastVerified: (/* @__PURE__ */ new Date()).toISOString()
};
}
async isAuthenticated(skipServerValidation = false) {
const auth = await this.getAuth();
if (!auth)
return false;
if (skipServerValidation) {
return true;
}
const isValid = await this.validateTokenWithServer(auth.accessToken);
if (!isValid) {
await this.clearAuth();
return false;
}
return true;
}
async requireAuth() {
const auth = await this.getAuth();
if (!auth) {
console.log(chalk.yellow("\n\u{1F510} Authentication required"));
console.log(chalk.gray("Please login to continue:"));
console.log(chalk.cyan(" moonui login\n"));
process.exit(1);
}
const isValid = await this.validateTokenWithServer(auth.accessToken);
if (!isValid) {
console.log(chalk.red("\n\u274C Your session has been revoked"));
console.log(chalk.yellow("Please login again:"));
console.log(chalk.cyan(" moonui login\n"));
await this.clearAuth();
process.exit(1);
}
return auth;
}
async validateTokenWithServer(token) {
try {
const deviceId = this.getDeviceFingerprint();
const response = await fetch(`${API_BASE}/api/device/validate`, {
method: "POST",
headers: {
"Content-Type": "application/json",
"Authorization": `Bearer ${token}`,
"X-Device-ID": deviceId
},
body: JSON.stringify({ deviceId })
});
if (!response.ok) {
try {
const errorData = await response.json();
if (response.status === 401 && (errorData.error?.includes("revoked") || errorData.error?.includes("Device session revoked"))) {
return false;
}
} catch {
if (response.status === 401) {
return false;
}
}
}
return response.ok;
} catch (error) {
return true;
}
}
async checkProAccess(component) {
const auth = await this.getAuth();
if (!auth) {
return false;
}
if (auth.user.hasLifetimeAccess === true) {
return true;
}
if (auth.user.plan === "pro_lifetime" || auth.user.plan === "lifetime") {
return true;
}
if (component && this.isCriticalComponent(component)) {
try {
const response = await fetch(`${API_BASE}/api/license/verify`, {
method: "POST",
headers: {
"Authorization": `Bearer ${auth.accessToken}`,
"Content-Type": "application/json"
},
body: JSON.stringify({
component,
plan: auth.user.plan
})
});
if (!response.ok) {
return false;
}
const data = await response.json();
if (data.user?.hasLifetimeAccess === true) {
return true;
}
return data.hasAccess && auth.user.plan !== "free";
} catch {
}
}
if (auth.user.hasProAccess === true) {
return true;
}
return auth.user.plan !== "free";
}
isCriticalComponent(component) {
const criticalComponents = [
"data-table",
"advanced-chart",
"dashboard",
"kanban",
"calendar"
];
return criticalComponents.includes(component);
}
async getUserInfo() {
const auth = await this.getAuth();
return auth?.user || null;
}
async makeAuthenticatedRequest(url, options = {}) {
const auth = await this.requireAuth();
const deviceId = this.getDeviceFingerprint();
return fetch(url, {
...options,
headers: {
...options.headers,
"Authorization": `Bearer ${auth.accessToken}`,
"X-Device-ID": deviceId,
"X-Machine-ID": deviceId
}
});
}
async validateDevice() {
try {
const auth = await this.getAuth();
if (!auth) {
return { valid: false, error: "Not authenticated" };
}
const deviceId = this.getDeviceFingerprint();
const deviceInfo = DeviceService.getDeviceInfo();
const response = await fetch(`${API_BASE}/api/device/validate`, {
method: "POST",
headers: {
"Authorization": `Bearer ${auth.accessToken}`,
"X-Device-ID": deviceId,
"Content-Type": "application/json"
},
body: JSON.stringify({ deviceInfo })
});
if (response.ok) {
const data = await response.json();
return { valid: data.valid };
} else {
const error = await response.json();
return { valid: false, error: error.error || "Device validation failed" };
}
} catch (error) {
return { valid: false, error: "Failed to validate device" };
}
}
async registerDevice() {
try {
const auth = await this.getAuth();
if (!auth) {
return { success: false, error: "Not authenticated" };
}
const deviceId = this.getDeviceFingerprint();
const deviceInfo = DeviceService.getDeviceInfo();
const response = await fetch(`${API_BASE}/api/device/register`, {
method: "POST",
headers: {
"Authorization": `Bearer ${auth.accessToken}`,
"X-Device-ID": deviceId,
"Content-Type": "application/json"
},
body: JSON.stringify({ deviceId, deviceInfo })
});
if (response.ok) {
const data = await response.json();
auth.deviceId = deviceId;
auth.deviceValidated = true;
await this.saveAuth(auth);
return { success: true };
} else {
const error = await response.json();
if (error.error === "Device limit exceeded") {
console.log(chalk.red("\n\u274C Device limit exceeded"));
console.log(chalk.yellow(` You have ${error.currentDevices}/${error.maxDevices} devices registered`));
console.log(chalk.blue(" Manage your devices at: https://moonui.dev/dashboard/devices"));
}
return { success: false, error: error.error };
}
} catch (error) {
return { success: false, error: "Failed to register device" };
}
}
};
export {
__require,
__toESM,
require_package,
DeviceService,
AuthService
};