diff --git a/.gitignore b/.gitignore index 5a404054f..43ac11e27 100644 --- a/.gitignore +++ b/.gitignore @@ -35,4 +35,5 @@ dist !dist/cli.js !dist/.gitkeep src-tauri/.cargo/config +src-tauri/.cargo/ .next diff --git a/bin/builders/LinuxBuilder.ts b/bin/builders/LinuxBuilder.ts index 369db2a0b..a98e05f16 100644 --- a/bin/builders/LinuxBuilder.ts +++ b/bin/builders/LinuxBuilder.ts @@ -46,15 +46,18 @@ export default class LinuxBuilder implements IBuilder { logger.debug('PakeAppOptions', options); const { name } = options; await mergeTauriConfig(url, options, tauriConf); - const isChina = isChinaDomain("www.npmjs.com") - + const isChina = await isChinaDomain("www.npmjs.com"); if (isChina) { - // crates.io也顺便换源 + logger.info("it's in China, use npm/rust cn mirror") const rust_project_dir = path.join(npmDirectory, 'src-tauri', ".cargo"); - const project_cn_conf = path.join(rust_project_dir, "cn_config.bak"); + const e1 = fs.access(rust_project_dir); + if (e1) { + await fs.mkdir(rust_project_dir, { recursive: true }); + } + const project_cn_conf = path.join(npmDirectory, "src-tauri", "cn_config.bak"); const project_conf = path.join(rust_project_dir, "config"); fs.copyFile(project_cn_conf, project_conf); - + const _ = await shellExec( `cd "${npmDirectory}" && npm install --registry=https://registry.npmmirror.com && npm run build` ); @@ -95,4 +98,4 @@ export default class LinuxBuilder implements IBuilder { packageName ); } -} \ No newline at end of file +} diff --git a/bin/builders/MacBuilder.ts b/bin/builders/MacBuilder.ts index 1c22f1ead..957207997 100644 --- a/bin/builders/MacBuilder.ts +++ b/bin/builders/MacBuilder.ts @@ -42,11 +42,15 @@ export default class MacBuilder implements IBuilder { await mergeTauriConfig(url, options, tauriConf); let dmgName: string; if (options.multiArch) { - const isChina = isChinaDomain("www.npmjs.com") + const isChina = await isChinaDomain("www.npmjs.com"); if (isChina) { - // crates.io也顺便换源 + logger.info("it's in China, use npm/rust cn mirror") const rust_project_dir = path.join(npmDirectory, 'src-tauri', ".cargo"); - const project_cn_conf = path.join(rust_project_dir, "cn_config.bak"); + const e1 = fs.access(rust_project_dir); + if (e1) { + await fs.mkdir(rust_project_dir, { recursive: true }); + } + const project_cn_conf = path.join(npmDirectory, "src-tauri", "cn_config.bak"); const project_conf = path.join(rust_project_dir, "config"); fs.copyFile(project_cn_conf, project_conf); diff --git a/bin/builders/WinBulider.ts b/bin/builders/WinBulider.ts index 15f65e559..c3a655ac2 100644 --- a/bin/builders/WinBulider.ts +++ b/bin/builders/WinBulider.ts @@ -45,14 +45,16 @@ export default class WinBuilder implements IBuilder { async build(url: string, options: PakeAppOptions) { logger.debug('PakeAppOptions', options); const { name } = options; - await mergeTauriConfig(url, options, tauriConf); - - const isChina = isChinaDomain("www.npmjs.com") + const isChina = await isChinaDomain("www.npmjs.com") if (isChina) { - // crates.io也顺便换源 + logger.info("it's in China, use npm/rust cn mirror") const rust_project_dir = path.join(npmDirectory, 'src-tauri', ".cargo"); - const project_cn_conf = path.join(rust_project_dir, "cn_config.bak"); + const e1 = fs.access(rust_project_dir); + if (e1) { + await fs.mkdir(rust_project_dir, { recursive: true }); + } + const project_cn_conf = path.join(npmDirectory, "src-tauri", "cn_config.bak"); const project_conf = path.join(rust_project_dir, "config"); fs.copyFile(project_cn_conf, project_conf); diff --git a/bin/helpers/rust.ts b/bin/helpers/rust.ts index 089397c7e..fec21dcbc 100644 --- a/bin/helpers/rust.ts +++ b/bin/helpers/rust.ts @@ -1,21 +1,23 @@ import { IS_WIN } from '@/utils/platform.js'; import ora from 'ora'; import shelljs from 'shelljs'; +import logger from '@/options/logger.js'; import { shellExec } from '../utils/shell.js'; import {isChinaDomain} from '@/utils/ip_addr.js' -const is_china = isChinaDomain("sh.rustup.rs"); -let RustInstallScriptFocMac = ""; -if (is_china) { - RustInstallScriptFocMac = - 'export RUSTUP_DIST_SERVER="https://rsproxy.cn" && export RUSTUP_UPDATE_ROOT="https://rsproxy.cn/rustup" && curl --proto "=https" --tlsv1.2 -sSf https://rsproxy.cn/rustup-init.sh | sh'; -} else { - RustInstallScriptFocMac = - "curl --proto '=https' --tlsv1.2 -sSf https://sh.rustup.rs | sh -s -- -y"; -} -const RustInstallScriptForWin = 'winget install --id Rustlang.Rustup'; export async function installRust() { + const is_china = await isChinaDomain("sh.rustup.rs"); + let RustInstallScriptFocMac = ""; + if (is_china) { + logger.info("it's in China, use rust cn mirror to install rust"); + RustInstallScriptFocMac = + 'export RUSTUP_DIST_SERVER="https://rsproxy.cn" && export RUSTUP_UPDATE_ROOT="https://rsproxy.cn/rustup" && curl --proto "=https" --tlsv1.2 -sSf https://rsproxy.cn/rustup-init.sh | sh'; + } else { + RustInstallScriptFocMac = + "curl --proto '=https' --tlsv1.2 -sSf https://sh.rustup.rs | sh -s -- -y"; + } + const RustInstallScriptForWin = 'winget install --id Rustlang.Rustup'; const spinner = ora('Downloading Rust').start(); try { await shellExec(IS_WIN ? RustInstallScriptForWin : RustInstallScriptFocMac); diff --git a/bin/utils/ip_addr.ts b/bin/utils/ip_addr.ts index 44b20fc64..a89f69766 100644 --- a/bin/utils/ip_addr.ts +++ b/bin/utils/ip_addr.ts @@ -39,20 +39,16 @@ async function isChinaDomain(domain: string): Promise { } async function isChinaIP(ip: string, domain: string): Promise { - return new Promise((resolve, reject) => { - // exec(`ping -c -w 1 ${ip}`, (error, stdout, stderr) => { - ping(ip) - .then((declay)=>{ - logger.info(`${domain} latency is ${declay} ms`); + try { + const delay = await ping(ip); + logger.info(`${domain} latency is ${delay} ms`); // 判断延迟是否超过500ms - resolve(declay > 500); - }) - .catch((error)=>{ + return delay > 500; + } catch (error) { // 命令执行出错,返回false - logger.info(`ping ${domain} failed!, is not in China!`); - resolve(false); - }) - }); + logger.info(`ping ${domain} failed!, is not in China!`); + return false; + } } -export { isChinaDomain, isChinaIP }; \ No newline at end of file +export { isChinaDomain, isChinaIP }; diff --git a/dist/cli.js b/dist/cli.js index 7d03087d6..ed506e011 100644 --- a/dist/cli.js +++ b/dist/cli.js @@ -45,2056 +45,2054 @@ function __awaiter(thisArg, _arguments, P, generator) { }); } -const DEFAULT_PAKE_OPTIONS = { - icon: '', - height: 780, - width: 1200, - fullscreen: false, - resizable: true, - transparent: false, - userAgent: '', - showMenu: false, - showSystemTray: false, - multiArch: false, - targets: 'deb', - iterCopyFile: false, - systemTrayIcon: '', - debug: false, +const DEFAULT_PAKE_OPTIONS = { + icon: '', + height: 780, + width: 1200, + fullscreen: false, + resizable: true, + transparent: false, + userAgent: '', + showMenu: false, + showSystemTray: false, + multiArch: false, + targets: 'deb', + iterCopyFile: false, + systemTrayIcon: '', + debug: false, }; -const tlds = [ - "aaa", - "aarp", - "abarth", - "abb", - "abbott", - "abbvie", - "abc", - "able", - "abogado", - "abudhabi", - "ac", - "academy", - "accenture", - "accountant", - "accountants", - "aco", - "actor", - "ad", - "adac", - "ads", - "adult", - "ae", - "aeg", - "aero", - "aetna", - "af", - "afl", - "africa", - "ag", - "agakhan", - "agency", - "ai", - "aig", - "airbus", - "airforce", - "airtel", - "akdn", - "al", - "alfaromeo", - "alibaba", - "alipay", - "allfinanz", - "allstate", - "ally", - "alsace", - "alstom", - "am", - "amazon", - "americanexpress", - "americanfamily", - "amex", - "amfam", - "amica", - "amsterdam", - "analytics", - "android", - "anquan", - "anz", - "ao", - "aol", - "apartments", - "app", - "apple", - "aq", - "aquarelle", - "ar", - "arab", - "aramco", - "archi", - "army", - "arpa", - "art", - "arte", - "as", - "asda", - "asia", - "associates", - "at", - "athleta", - "attorney", - "au", - "auction", - "audi", - "audible", - "audio", - "auspost", - "author", - "auto", - "autos", - "avianca", - "aw", - "aws", - "ax", - "axa", - "az", - "azure", - "ba", - "baby", - "baidu", - "banamex", - "bananarepublic", - "band", - "bank", - "bar", - "barcelona", - "barclaycard", - "barclays", - "barefoot", - "bargains", - "baseball", - "basketball", - "bauhaus", - "bayern", - "bb", - "bbc", - "bbt", - "bbva", - "bcg", - "bcn", - "bd", - "be", - "beats", - "beauty", - "beer", - "bentley", - "berlin", - "best", - "bestbuy", - "bet", - "bf", - "bg", - "bh", - "bharti", - "bi", - "bible", - "bid", - "bike", - "bing", - "bingo", - "bio", - "biz", - "bj", - "black", - "blackfriday", - "blockbuster", - "blog", - "bloomberg", - "blue", - "bm", - "bms", - "bmw", - "bn", - "bnpparibas", - "bo", - "boats", - "boehringer", - "bofa", - "bom", - "bond", - "boo", - "book", - "booking", - "bosch", - "bostik", - "boston", - "bot", - "boutique", - "box", - "br", - "bradesco", - "bridgestone", - "broadway", - "broker", - "brother", - "brussels", - "bs", - "bt", - "build", - "builders", - "business", - "buy", - "buzz", - "bv", - "bw", - "by", - "bz", - "bzh", - "ca", - "cab", - "cafe", - "cal", - "call", - "calvinklein", - "cam", - "camera", - "camp", - "canon", - "capetown", - "capital", - "capitalone", - "car", - "caravan", - "cards", - "care", - "career", - "careers", - "cars", - "casa", - "case", - "cash", - "casino", - "cat", - "catering", - "catholic", - "cba", - "cbn", - "cbre", - "cbs", - "cc", - "cd", - "center", - "ceo", - "cern", - "cf", - "cfa", - "cfd", - "cg", - "ch", - "chanel", - "channel", - "charity", - "chase", - "chat", - "cheap", - "chintai", - "christmas", - "chrome", - "church", - "ci", - "cipriani", - "circle", - "cisco", - "citadel", - "citi", - "citic", - "city", - "cityeats", - "ck", - "cl", - "claims", - "cleaning", - "click", - "clinic", - "clinique", - "clothing", - "cloud", - "club", - "clubmed", - "cm", - "cn", - "co", - "coach", - "codes", - "coffee", - "college", - "cologne", - "com", - "comcast", - "commbank", - "community", - "company", - "compare", - "computer", - "comsec", - "condos", - "construction", - "consulting", - "contact", - "contractors", - "cooking", - "cookingchannel", - "cool", - "coop", - "corsica", - "country", - "coupon", - "coupons", - "courses", - "cpa", - "cr", - "credit", - "creditcard", - "creditunion", - "cricket", - "crown", - "crs", - "cruise", - "cruises", - "cu", - "cuisinella", - "cv", - "cw", - "cx", - "cy", - "cymru", - "cyou", - "cz", - "dabur", - "dad", - "dance", - "data", - "date", - "dating", - "datsun", - "day", - "dclk", - "dds", - "de", - "deal", - "dealer", - "deals", - "degree", - "delivery", - "dell", - "deloitte", - "delta", - "democrat", - "dental", - "dentist", - "desi", - "design", - "dev", - "dhl", - "diamonds", - "diet", - "digital", - "direct", - "directory", - "discount", - "discover", - "dish", - "diy", - "dj", - "dk", - "dm", - "dnp", - "do", - "docs", - "doctor", - "dog", - "domains", - "dot", - "download", - "drive", - "dtv", - "dubai", - "dunlop", - "dupont", - "durban", - "dvag", - "dvr", - "dz", - "earth", - "eat", - "ec", - "eco", - "edeka", - "edu", - "education", - "ee", - "eg", - "email", - "emerck", - "energy", - "engineer", - "engineering", - "enterprises", - "epson", - "equipment", - "er", - "ericsson", - "erni", - "es", - "esq", - "estate", - "et", - "etisalat", - "eu", - "eurovision", - "eus", - "events", - "exchange", - "expert", - "exposed", - "express", - "extraspace", - "fage", - "fail", - "fairwinds", - "faith", - "family", - "fan", - "fans", - "farm", - "farmers", - "fashion", - "fast", - "fedex", - "feedback", - "ferrari", - "ferrero", - "fi", - "fiat", - "fidelity", - "fido", - "film", - "final", - "finance", - "financial", - "fire", - "firestone", - "firmdale", - "fish", - "fishing", - "fit", - "fitness", - "fj", - "fk", - "flickr", - "flights", - "flir", - "florist", - "flowers", - "fly", - "fm", - "fo", - "foo", - "food", - "foodnetwork", - "football", - "ford", - "forex", - "forsale", - "forum", - "foundation", - "fox", - "fr", - "free", - "fresenius", - "frl", - "frogans", - "frontdoor", - "frontier", - "ftr", - "fujitsu", - "fun", - "fund", - "furniture", - "futbol", - "fyi", - "ga", - "gal", - "gallery", - "gallo", - "gallup", - "game", - "games", - "gap", - "garden", - "gay", - "gb", - "gbiz", - "gd", - "gdn", - "ge", - "gea", - "gent", - "genting", - "george", - "gf", - "gg", - "ggee", - "gh", - "gi", - "gift", - "gifts", - "gives", - "giving", - "gl", - "glass", - "gle", - "global", - "globo", - "gm", - "gmail", - "gmbh", - "gmo", - "gmx", - "gn", - "godaddy", - "gold", - "goldpoint", - "golf", - "goo", - "goodyear", - "goog", - "google", - "gop", - "got", - "gov", - "gp", - "gq", - "gr", - "grainger", - "graphics", - "gratis", - "green", - "gripe", - "grocery", - "group", - "gs", - "gt", - "gu", - "guardian", - "gucci", - "guge", - "guide", - "guitars", - "guru", - "gw", - "gy", - "hair", - "hamburg", - "hangout", - "haus", - "hbo", - "hdfc", - "hdfcbank", - "health", - "healthcare", - "help", - "helsinki", - "here", - "hermes", - "hgtv", - "hiphop", - "hisamitsu", - "hitachi", - "hiv", - "hk", - "hkt", - "hm", - "hn", - "hockey", - "holdings", - "holiday", - "homedepot", - "homegoods", - "homes", - "homesense", - "honda", - "horse", - "hospital", - "host", - "hosting", - "hot", - "hoteles", - "hotels", - "hotmail", - "house", - "how", - "hr", - "hsbc", - "ht", - "hu", - "hughes", - "hyatt", - "hyundai", - "ibm", - "icbc", - "ice", - "icu", - "id", - "ie", - "ieee", - "ifm", - "ikano", - "il", - "im", - "imamat", - "imdb", - "immo", - "immobilien", - "in", - "inc", - "industries", - "infiniti", - "info", - "ing", - "ink", - "institute", - "insurance", - "insure", - "int", - "international", - "intuit", - "investments", - "io", - "ipiranga", - "iq", - "ir", - "irish", - "is", - "ismaili", - "ist", - "istanbul", - "it", - "itau", - "itv", - "jaguar", - "java", - "jcb", - "je", - "jeep", - "jetzt", - "jewelry", - "jio", - "jll", - "jm", - "jmp", - "jnj", - "jo", - "jobs", - "joburg", - "jot", - "joy", - "jp", - "jpmorgan", - "jprs", - "juegos", - "juniper", - "kaufen", - "kddi", - "ke", - "kerryhotels", - "kerrylogistics", - "kerryproperties", - "kfh", - "kg", - "kh", - "ki", - "kia", - "kids", - "kim", - "kinder", - "kindle", - "kitchen", - "kiwi", - "km", - "kn", - "koeln", - "komatsu", - "kosher", - "kp", - "kpmg", - "kpn", - "kr", - "krd", - "kred", - "kuokgroup", - "kw", - "ky", - "kyoto", - "kz", - "la", - "lacaixa", - "lamborghini", - "lamer", - "lancaster", - "lancia", - "land", - "landrover", - "lanxess", - "lasalle", - "lat", - "latino", - "latrobe", - "law", - "lawyer", - "lb", - "lc", - "lds", - "lease", - "leclerc", - "lefrak", - "legal", - "lego", - "lexus", - "lgbt", - "li", - "lidl", - "life", - "lifeinsurance", - "lifestyle", - "lighting", - "like", - "lilly", - "limited", - "limo", - "lincoln", - "linde", - "link", - "lipsy", - "live", - "living", - "lk", - "llc", - "llp", - "loan", - "loans", - "locker", - "locus", - "loft", - "lol", - "london", - "lotte", - "lotto", - "love", - "lpl", - "lplfinancial", - "lr", - "ls", - "lt", - "ltd", - "ltda", - "lu", - "lundbeck", - "luxe", - "luxury", - "lv", - "ly", - "ma", - "macys", - "madrid", - "maif", - "maison", - "makeup", - "man", - "management", - "mango", - "map", - "market", - "marketing", - "markets", - "marriott", - "marshalls", - "maserati", - "mattel", - "mba", - "mc", - "mckinsey", - "md", - "me", - "med", - "media", - "meet", - "melbourne", - "meme", - "memorial", - "men", - "menu", - "merckmsd", - "mg", - "mh", - "miami", - "microsoft", - "mil", - "mini", - "mint", - "mit", - "mitsubishi", - "mk", - "ml", - "mlb", - "mls", - "mm", - "mma", - "mn", - "mo", - "mobi", - "mobile", - "moda", - "moe", - "moi", - "mom", - "monash", - "money", - "monster", - "mormon", - "mortgage", - "moscow", - "moto", - "motorcycles", - "mov", - "movie", - "mp", - "mq", - "mr", - "ms", - "msd", - "mt", - "mtn", - "mtr", - "mu", - "museum", - "music", - "mutual", - "mv", - "mw", - "mx", - "my", - "mz", - "na", - "nab", - "nagoya", - "name", - "natura", - "navy", - "nba", - "nc", - "ne", - "nec", - "net", - "netbank", - "netflix", - "network", - "neustar", - "new", - "news", - "next", - "nextdirect", - "nexus", - "nf", - "nfl", - "ng", - "ngo", - "nhk", - "ni", - "nico", - "nike", - "nikon", - "ninja", - "nissan", - "nissay", - "nl", - "no", - "nokia", - "northwesternmutual", - "norton", - "now", - "nowruz", - "nowtv", - "np", - "nr", - "nra", - "nrw", - "ntt", - "nu", - "nyc", - "nz", - "obi", - "observer", - "office", - "okinawa", - "olayan", - "olayangroup", - "oldnavy", - "ollo", - "om", - "omega", - "one", - "ong", - "onl", - "online", - "ooo", - "open", - "oracle", - "orange", - "org", - "organic", - "origins", - "osaka", - "otsuka", - "ott", - "ovh", - "pa", - "page", - "panasonic", - "paris", - "pars", - "partners", - "parts", - "party", - "passagens", - "pay", - "pccw", - "pe", - "pet", - "pf", - "pfizer", - "pg", - "ph", - "pharmacy", - "phd", - "philips", - "phone", - "photo", - "photography", - "photos", - "physio", - "pics", - "pictet", - "pictures", - "pid", - "pin", - "ping", - "pink", - "pioneer", - "pizza", - "pk", - "pl", - "place", - "play", - "playstation", - "plumbing", - "plus", - "pm", - "pn", - "pnc", - "pohl", - "poker", - "politie", - "porn", - "post", - "pr", - "pramerica", - "praxi", - "press", - "prime", - "pro", - "prod", - "productions", - "prof", - "progressive", - "promo", - "properties", - "property", - "protection", - "pru", - "prudential", - "ps", - "pt", - "pub", - "pw", - "pwc", - "py", - "qa", - "qpon", - "quebec", - "quest", - "racing", - "radio", - "re", - "read", - "realestate", - "realtor", - "realty", - "recipes", - "red", - "redstone", - "redumbrella", - "rehab", - "reise", - "reisen", - "reit", - "reliance", - "ren", - "rent", - "rentals", - "repair", - "report", - "republican", - "rest", - "restaurant", - "review", - "reviews", - "rexroth", - "rich", - "richardli", - "ricoh", - "ril", - "rio", - "rip", - "ro", - "rocher", - "rocks", - "rodeo", - "rogers", - "room", - "rs", - "rsvp", - "ru", - "rugby", - "ruhr", - "run", - "rw", - "rwe", - "ryukyu", - "sa", - "saarland", - "safe", - "safety", - "sakura", - "sale", - "salon", - "samsclub", - "samsung", - "sandvik", - "sandvikcoromant", - "sanofi", - "sap", - "sarl", - "sas", - "save", - "saxo", - "sb", - "sbi", - "sbs", - "sc", - "sca", - "scb", - "schaeffler", - "schmidt", - "scholarships", - "school", - "schule", - "schwarz", - "science", - "scot", - "sd", - "se", - "search", - "seat", - "secure", - "security", - "seek", - "select", - "sener", - "services", - "ses", - "seven", - "sew", - "sex", - "sexy", - "sfr", - "sg", - "sh", - "shangrila", - "sharp", - "shaw", - "shell", - "shia", - "shiksha", - "shoes", - "shop", - "shopping", - "shouji", - "show", - "showtime", - "si", - "silk", - "sina", - "singles", - "site", - "sj", - "sk", - "ski", - "skin", - "sky", - "skype", - "sl", - "sling", - "sm", - "smart", - "smile", - "sn", - "sncf", - "so", - "soccer", - "social", - "softbank", - "software", - "sohu", - "solar", - "solutions", - "song", - "sony", - "soy", - "spa", - "space", - "sport", - "spot", - "sr", - "srl", - "ss", - "st", - "stada", - "staples", - "star", - "statebank", - "statefarm", - "stc", - "stcgroup", - "stockholm", - "storage", - "store", - "stream", - "studio", - "study", - "style", - "su", - "sucks", - "supplies", - "supply", - "support", - "surf", - "surgery", - "suzuki", - "sv", - "swatch", - "swiss", - "sx", - "sy", - "sydney", - "systems", - "sz", - "tab", - "taipei", - "talk", - "taobao", - "target", - "tatamotors", - "tatar", - "tattoo", - "tax", - "taxi", - "tc", - "tci", - "td", - "tdk", - "team", - "tech", - "technology", - "tel", - "temasek", - "tennis", - "teva", - "tf", - "tg", - "th", - "thd", - "theater", - "theatre", - "tiaa", - "tickets", - "tienda", - "tiffany", - "tips", - "tires", - "tirol", - "tj", - "tjmaxx", - "tjx", - "tk", - "tkmaxx", - "tl", - "tm", - "tmall", - "tn", - "to", - "today", - "tokyo", - "tools", - "top", - "toray", - "toshiba", - "total", - "tours", - "town", - "toyota", - "toys", - "tr", - "trade", - "trading", - "training", - "travel", - "travelchannel", - "travelers", - "travelersinsurance", - "trust", - "trv", - "tt", - "tube", - "tui", - "tunes", - "tushu", - "tv", - "tvs", - "tw", - "tz", - "ua", - "ubank", - "ubs", - "ug", - "uk", - "unicom", - "university", - "uno", - "uol", - "ups", - "us", - "uy", - "uz", - "va", - "vacations", - "vana", - "vanguard", - "vc", - "ve", - "vegas", - "ventures", - "verisign", - "vermögensberater", - "vermögensberatung", - "versicherung", - "vet", - "vg", - "vi", - "viajes", - "video", - "vig", - "viking", - "villas", - "vin", - "vip", - "virgin", - "visa", - "vision", - "viva", - "vivo", - "vlaanderen", - "vn", - "vodka", - "volkswagen", - "volvo", - "vote", - "voting", - "voto", - "voyage", - "vu", - "vuelos", - "wales", - "walmart", - "walter", - "wang", - "wanggou", - "watch", - "watches", - "weather", - "weatherchannel", - "webcam", - "weber", - "website", - "wed", - "wedding", - "weibo", - "weir", - "wf", - "whoswho", - "wien", - "wiki", - "williamhill", - "win", - "windows", - "wine", - "winners", - "wme", - "wolterskluwer", - "woodside", - "work", - "works", - "world", - "wow", - "ws", - "wtc", - "wtf", - "xbox", - "xerox", - "xfinity", - "xihuan", - "xin", - "xxx", - "xyz", - "yachts", - "yahoo", - "yamaxun", - "yandex", - "ye", - "yodobashi", - "yoga", - "yokohama", - "you", - "youtube", - "yt", - "yun", - "za", - "zappos", - "zara", - "zero", - "zip", - "zm", - "zone", - "zuerich", - "zw", - "ελ", - "ευ", - "бг", - "бел", - "дети", - "ею", - "католик", - "ком", - "мкд", - "мон", - "москва", - "онлайн", - "орг", - "рус", - "рф", - "сайт", - "срб", - "укр", - "қаз", - "հայ", - "ישראל", - "קום", - "ابوظبي", - "اتصالات", - "ارامكو", - "الاردن", - "البحرين", - "الجزائر", - "السعودية", - "العليان", - "المغرب", - "امارات", - "ایران", - "بارت", - "بازار", - "بيتك", - "بھارت", - "تونس", - "سودان", - "سورية", - "شبكة", - "عراق", - "عرب", - "عمان", - "فلسطين", - "قطر", - "كاثوليك", - "كوم", - "مصر", - "مليسيا", - "موريتانيا", - "موقع", - "همراه", - "پاکستان", - "ڀارت", - "कॉम", - "नेट", - "भारत", - "भारतम्", - "भारोत", - "संगठन", - "বাংলা", - "ভারত", - "ভাৰত", - "ਭਾਰਤ", - "ભારત", - "ଭାରତ", - "இந்தியா", - "இலங்கை", - "சிங்கப்பூர்", - "భారత్", - "ಭಾರತ", - "ഭാരതം", - "ලංකා", - "คอม", - "ไทย", - "ລາວ", - "გე", - "みんな", - "アマゾン", - "クラウド", - "グーグル", - "コム", - "ストア", - "セール", - "ファッション", - "ポイント", - "世界", - "中信", - "中国", - "中國", - "中文网", - "亚马逊", - "企业", - "佛山", - "信息", - "健康", - "八卦", - "公司", - "公益", - "台湾", - "台灣", - "商城", - "商店", - "商标", - "嘉里", - "嘉里大酒店", - "在线", - "大拿", - "天主教", - "娱乐", - "家電", - "广东", - "微博", - "慈善", - "我爱你", - "手机", - "招聘", - "政务", - "政府", - "新加坡", - "新闻", - "时尚", - "書籍", - "机构", - "淡马锡", - "游戏", - "澳門", - "点看", - "移动", - "组织机构", - "网址", - "网店", - "网站", - "网络", - "联通", - "诺基亚", - "谷歌", - "购物", - "通販", - "集团", - "電訊盈科", - "飞利浦", - "食品", - "餐厅", - "香格里拉", - "香港", - "닷넷", - "닷컴", - "삼성", - "한국", +const tlds = [ + "aaa", + "aarp", + "abarth", + "abb", + "abbott", + "abbvie", + "abc", + "able", + "abogado", + "abudhabi", + "ac", + "academy", + "accenture", + "accountant", + "accountants", + "aco", + "actor", + "ad", + "adac", + "ads", + "adult", + "ae", + "aeg", + "aero", + "aetna", + "af", + "afl", + "africa", + "ag", + "agakhan", + "agency", + "ai", + "aig", + "airbus", + "airforce", + "airtel", + "akdn", + "al", + "alfaromeo", + "alibaba", + "alipay", + "allfinanz", + "allstate", + "ally", + "alsace", + "alstom", + "am", + "amazon", + "americanexpress", + "americanfamily", + "amex", + "amfam", + "amica", + "amsterdam", + "analytics", + "android", + "anquan", + "anz", + "ao", + "aol", + "apartments", + "app", + "apple", + "aq", + "aquarelle", + "ar", + "arab", + "aramco", + "archi", + "army", + "arpa", + "art", + "arte", + "as", + "asda", + "asia", + "associates", + "at", + "athleta", + "attorney", + "au", + "auction", + "audi", + "audible", + "audio", + "auspost", + "author", + "auto", + "autos", + "avianca", + "aw", + "aws", + "ax", + "axa", + "az", + "azure", + "ba", + "baby", + "baidu", + "banamex", + "bananarepublic", + "band", + "bank", + "bar", + "barcelona", + "barclaycard", + "barclays", + "barefoot", + "bargains", + "baseball", + "basketball", + "bauhaus", + "bayern", + "bb", + "bbc", + "bbt", + "bbva", + "bcg", + "bcn", + "bd", + "be", + "beats", + "beauty", + "beer", + "bentley", + "berlin", + "best", + "bestbuy", + "bet", + "bf", + "bg", + "bh", + "bharti", + "bi", + "bible", + "bid", + "bike", + "bing", + "bingo", + "bio", + "biz", + "bj", + "black", + "blackfriday", + "blockbuster", + "blog", + "bloomberg", + "blue", + "bm", + "bms", + "bmw", + "bn", + "bnpparibas", + "bo", + "boats", + "boehringer", + "bofa", + "bom", + "bond", + "boo", + "book", + "booking", + "bosch", + "bostik", + "boston", + "bot", + "boutique", + "box", + "br", + "bradesco", + "bridgestone", + "broadway", + "broker", + "brother", + "brussels", + "bs", + "bt", + "build", + "builders", + "business", + "buy", + "buzz", + "bv", + "bw", + "by", + "bz", + "bzh", + "ca", + "cab", + "cafe", + "cal", + "call", + "calvinklein", + "cam", + "camera", + "camp", + "canon", + "capetown", + "capital", + "capitalone", + "car", + "caravan", + "cards", + "care", + "career", + "careers", + "cars", + "casa", + "case", + "cash", + "casino", + "cat", + "catering", + "catholic", + "cba", + "cbn", + "cbre", + "cbs", + "cc", + "cd", + "center", + "ceo", + "cern", + "cf", + "cfa", + "cfd", + "cg", + "ch", + "chanel", + "channel", + "charity", + "chase", + "chat", + "cheap", + "chintai", + "christmas", + "chrome", + "church", + "ci", + "cipriani", + "circle", + "cisco", + "citadel", + "citi", + "citic", + "city", + "cityeats", + "ck", + "cl", + "claims", + "cleaning", + "click", + "clinic", + "clinique", + "clothing", + "cloud", + "club", + "clubmed", + "cm", + "cn", + "co", + "coach", + "codes", + "coffee", + "college", + "cologne", + "com", + "comcast", + "commbank", + "community", + "company", + "compare", + "computer", + "comsec", + "condos", + "construction", + "consulting", + "contact", + "contractors", + "cooking", + "cookingchannel", + "cool", + "coop", + "corsica", + "country", + "coupon", + "coupons", + "courses", + "cpa", + "cr", + "credit", + "creditcard", + "creditunion", + "cricket", + "crown", + "crs", + "cruise", + "cruises", + "cu", + "cuisinella", + "cv", + "cw", + "cx", + "cy", + "cymru", + "cyou", + "cz", + "dabur", + "dad", + "dance", + "data", + "date", + "dating", + "datsun", + "day", + "dclk", + "dds", + "de", + "deal", + "dealer", + "deals", + "degree", + "delivery", + "dell", + "deloitte", + "delta", + "democrat", + "dental", + "dentist", + "desi", + "design", + "dev", + "dhl", + "diamonds", + "diet", + "digital", + "direct", + "directory", + "discount", + "discover", + "dish", + "diy", + "dj", + "dk", + "dm", + "dnp", + "do", + "docs", + "doctor", + "dog", + "domains", + "dot", + "download", + "drive", + "dtv", + "dubai", + "dunlop", + "dupont", + "durban", + "dvag", + "dvr", + "dz", + "earth", + "eat", + "ec", + "eco", + "edeka", + "edu", + "education", + "ee", + "eg", + "email", + "emerck", + "energy", + "engineer", + "engineering", + "enterprises", + "epson", + "equipment", + "er", + "ericsson", + "erni", + "es", + "esq", + "estate", + "et", + "etisalat", + "eu", + "eurovision", + "eus", + "events", + "exchange", + "expert", + "exposed", + "express", + "extraspace", + "fage", + "fail", + "fairwinds", + "faith", + "family", + "fan", + "fans", + "farm", + "farmers", + "fashion", + "fast", + "fedex", + "feedback", + "ferrari", + "ferrero", + "fi", + "fiat", + "fidelity", + "fido", + "film", + "final", + "finance", + "financial", + "fire", + "firestone", + "firmdale", + "fish", + "fishing", + "fit", + "fitness", + "fj", + "fk", + "flickr", + "flights", + "flir", + "florist", + "flowers", + "fly", + "fm", + "fo", + "foo", + "food", + "foodnetwork", + "football", + "ford", + "forex", + "forsale", + "forum", + "foundation", + "fox", + "fr", + "free", + "fresenius", + "frl", + "frogans", + "frontdoor", + "frontier", + "ftr", + "fujitsu", + "fun", + "fund", + "furniture", + "futbol", + "fyi", + "ga", + "gal", + "gallery", + "gallo", + "gallup", + "game", + "games", + "gap", + "garden", + "gay", + "gb", + "gbiz", + "gd", + "gdn", + "ge", + "gea", + "gent", + "genting", + "george", + "gf", + "gg", + "ggee", + "gh", + "gi", + "gift", + "gifts", + "gives", + "giving", + "gl", + "glass", + "gle", + "global", + "globo", + "gm", + "gmail", + "gmbh", + "gmo", + "gmx", + "gn", + "godaddy", + "gold", + "goldpoint", + "golf", + "goo", + "goodyear", + "goog", + "google", + "gop", + "got", + "gov", + "gp", + "gq", + "gr", + "grainger", + "graphics", + "gratis", + "green", + "gripe", + "grocery", + "group", + "gs", + "gt", + "gu", + "guardian", + "gucci", + "guge", + "guide", + "guitars", + "guru", + "gw", + "gy", + "hair", + "hamburg", + "hangout", + "haus", + "hbo", + "hdfc", + "hdfcbank", + "health", + "healthcare", + "help", + "helsinki", + "here", + "hermes", + "hgtv", + "hiphop", + "hisamitsu", + "hitachi", + "hiv", + "hk", + "hkt", + "hm", + "hn", + "hockey", + "holdings", + "holiday", + "homedepot", + "homegoods", + "homes", + "homesense", + "honda", + "horse", + "hospital", + "host", + "hosting", + "hot", + "hoteles", + "hotels", + "hotmail", + "house", + "how", + "hr", + "hsbc", + "ht", + "hu", + "hughes", + "hyatt", + "hyundai", + "ibm", + "icbc", + "ice", + "icu", + "id", + "ie", + "ieee", + "ifm", + "ikano", + "il", + "im", + "imamat", + "imdb", + "immo", + "immobilien", + "in", + "inc", + "industries", + "infiniti", + "info", + "ing", + "ink", + "institute", + "insurance", + "insure", + "int", + "international", + "intuit", + "investments", + "io", + "ipiranga", + "iq", + "ir", + "irish", + "is", + "ismaili", + "ist", + "istanbul", + "it", + "itau", + "itv", + "jaguar", + "java", + "jcb", + "je", + "jeep", + "jetzt", + "jewelry", + "jio", + "jll", + "jm", + "jmp", + "jnj", + "jo", + "jobs", + "joburg", + "jot", + "joy", + "jp", + "jpmorgan", + "jprs", + "juegos", + "juniper", + "kaufen", + "kddi", + "ke", + "kerryhotels", + "kerrylogistics", + "kerryproperties", + "kfh", + "kg", + "kh", + "ki", + "kia", + "kids", + "kim", + "kinder", + "kindle", + "kitchen", + "kiwi", + "km", + "kn", + "koeln", + "komatsu", + "kosher", + "kp", + "kpmg", + "kpn", + "kr", + "krd", + "kred", + "kuokgroup", + "kw", + "ky", + "kyoto", + "kz", + "la", + "lacaixa", + "lamborghini", + "lamer", + "lancaster", + "lancia", + "land", + "landrover", + "lanxess", + "lasalle", + "lat", + "latino", + "latrobe", + "law", + "lawyer", + "lb", + "lc", + "lds", + "lease", + "leclerc", + "lefrak", + "legal", + "lego", + "lexus", + "lgbt", + "li", + "lidl", + "life", + "lifeinsurance", + "lifestyle", + "lighting", + "like", + "lilly", + "limited", + "limo", + "lincoln", + "linde", + "link", + "lipsy", + "live", + "living", + "lk", + "llc", + "llp", + "loan", + "loans", + "locker", + "locus", + "loft", + "lol", + "london", + "lotte", + "lotto", + "love", + "lpl", + "lplfinancial", + "lr", + "ls", + "lt", + "ltd", + "ltda", + "lu", + "lundbeck", + "luxe", + "luxury", + "lv", + "ly", + "ma", + "macys", + "madrid", + "maif", + "maison", + "makeup", + "man", + "management", + "mango", + "map", + "market", + "marketing", + "markets", + "marriott", + "marshalls", + "maserati", + "mattel", + "mba", + "mc", + "mckinsey", + "md", + "me", + "med", + "media", + "meet", + "melbourne", + "meme", + "memorial", + "men", + "menu", + "merckmsd", + "mg", + "mh", + "miami", + "microsoft", + "mil", + "mini", + "mint", + "mit", + "mitsubishi", + "mk", + "ml", + "mlb", + "mls", + "mm", + "mma", + "mn", + "mo", + "mobi", + "mobile", + "moda", + "moe", + "moi", + "mom", + "monash", + "money", + "monster", + "mormon", + "mortgage", + "moscow", + "moto", + "motorcycles", + "mov", + "movie", + "mp", + "mq", + "mr", + "ms", + "msd", + "mt", + "mtn", + "mtr", + "mu", + "museum", + "music", + "mutual", + "mv", + "mw", + "mx", + "my", + "mz", + "na", + "nab", + "nagoya", + "name", + "natura", + "navy", + "nba", + "nc", + "ne", + "nec", + "net", + "netbank", + "netflix", + "network", + "neustar", + "new", + "news", + "next", + "nextdirect", + "nexus", + "nf", + "nfl", + "ng", + "ngo", + "nhk", + "ni", + "nico", + "nike", + "nikon", + "ninja", + "nissan", + "nissay", + "nl", + "no", + "nokia", + "northwesternmutual", + "norton", + "now", + "nowruz", + "nowtv", + "np", + "nr", + "nra", + "nrw", + "ntt", + "nu", + "nyc", + "nz", + "obi", + "observer", + "office", + "okinawa", + "olayan", + "olayangroup", + "oldnavy", + "ollo", + "om", + "omega", + "one", + "ong", + "onl", + "online", + "ooo", + "open", + "oracle", + "orange", + "org", + "organic", + "origins", + "osaka", + "otsuka", + "ott", + "ovh", + "pa", + "page", + "panasonic", + "paris", + "pars", + "partners", + "parts", + "party", + "passagens", + "pay", + "pccw", + "pe", + "pet", + "pf", + "pfizer", + "pg", + "ph", + "pharmacy", + "phd", + "philips", + "phone", + "photo", + "photography", + "photos", + "physio", + "pics", + "pictet", + "pictures", + "pid", + "pin", + "ping", + "pink", + "pioneer", + "pizza", + "pk", + "pl", + "place", + "play", + "playstation", + "plumbing", + "plus", + "pm", + "pn", + "pnc", + "pohl", + "poker", + "politie", + "porn", + "post", + "pr", + "pramerica", + "praxi", + "press", + "prime", + "pro", + "prod", + "productions", + "prof", + "progressive", + "promo", + "properties", + "property", + "protection", + "pru", + "prudential", + "ps", + "pt", + "pub", + "pw", + "pwc", + "py", + "qa", + "qpon", + "quebec", + "quest", + "racing", + "radio", + "re", + "read", + "realestate", + "realtor", + "realty", + "recipes", + "red", + "redstone", + "redumbrella", + "rehab", + "reise", + "reisen", + "reit", + "reliance", + "ren", + "rent", + "rentals", + "repair", + "report", + "republican", + "rest", + "restaurant", + "review", + "reviews", + "rexroth", + "rich", + "richardli", + "ricoh", + "ril", + "rio", + "rip", + "ro", + "rocher", + "rocks", + "rodeo", + "rogers", + "room", + "rs", + "rsvp", + "ru", + "rugby", + "ruhr", + "run", + "rw", + "rwe", + "ryukyu", + "sa", + "saarland", + "safe", + "safety", + "sakura", + "sale", + "salon", + "samsclub", + "samsung", + "sandvik", + "sandvikcoromant", + "sanofi", + "sap", + "sarl", + "sas", + "save", + "saxo", + "sb", + "sbi", + "sbs", + "sc", + "sca", + "scb", + "schaeffler", + "schmidt", + "scholarships", + "school", + "schule", + "schwarz", + "science", + "scot", + "sd", + "se", + "search", + "seat", + "secure", + "security", + "seek", + "select", + "sener", + "services", + "ses", + "seven", + "sew", + "sex", + "sexy", + "sfr", + "sg", + "sh", + "shangrila", + "sharp", + "shaw", + "shell", + "shia", + "shiksha", + "shoes", + "shop", + "shopping", + "shouji", + "show", + "showtime", + "si", + "silk", + "sina", + "singles", + "site", + "sj", + "sk", + "ski", + "skin", + "sky", + "skype", + "sl", + "sling", + "sm", + "smart", + "smile", + "sn", + "sncf", + "so", + "soccer", + "social", + "softbank", + "software", + "sohu", + "solar", + "solutions", + "song", + "sony", + "soy", + "spa", + "space", + "sport", + "spot", + "sr", + "srl", + "ss", + "st", + "stada", + "staples", + "star", + "statebank", + "statefarm", + "stc", + "stcgroup", + "stockholm", + "storage", + "store", + "stream", + "studio", + "study", + "style", + "su", + "sucks", + "supplies", + "supply", + "support", + "surf", + "surgery", + "suzuki", + "sv", + "swatch", + "swiss", + "sx", + "sy", + "sydney", + "systems", + "sz", + "tab", + "taipei", + "talk", + "taobao", + "target", + "tatamotors", + "tatar", + "tattoo", + "tax", + "taxi", + "tc", + "tci", + "td", + "tdk", + "team", + "tech", + "technology", + "tel", + "temasek", + "tennis", + "teva", + "tf", + "tg", + "th", + "thd", + "theater", + "theatre", + "tiaa", + "tickets", + "tienda", + "tiffany", + "tips", + "tires", + "tirol", + "tj", + "tjmaxx", + "tjx", + "tk", + "tkmaxx", + "tl", + "tm", + "tmall", + "tn", + "to", + "today", + "tokyo", + "tools", + "top", + "toray", + "toshiba", + "total", + "tours", + "town", + "toyota", + "toys", + "tr", + "trade", + "trading", + "training", + "travel", + "travelchannel", + "travelers", + "travelersinsurance", + "trust", + "trv", + "tt", + "tube", + "tui", + "tunes", + "tushu", + "tv", + "tvs", + "tw", + "tz", + "ua", + "ubank", + "ubs", + "ug", + "uk", + "unicom", + "university", + "uno", + "uol", + "ups", + "us", + "uy", + "uz", + "va", + "vacations", + "vana", + "vanguard", + "vc", + "ve", + "vegas", + "ventures", + "verisign", + "vermögensberater", + "vermögensberatung", + "versicherung", + "vet", + "vg", + "vi", + "viajes", + "video", + "vig", + "viking", + "villas", + "vin", + "vip", + "virgin", + "visa", + "vision", + "viva", + "vivo", + "vlaanderen", + "vn", + "vodka", + "volkswagen", + "volvo", + "vote", + "voting", + "voto", + "voyage", + "vu", + "vuelos", + "wales", + "walmart", + "walter", + "wang", + "wanggou", + "watch", + "watches", + "weather", + "weatherchannel", + "webcam", + "weber", + "website", + "wed", + "wedding", + "weibo", + "weir", + "wf", + "whoswho", + "wien", + "wiki", + "williamhill", + "win", + "windows", + "wine", + "winners", + "wme", + "wolterskluwer", + "woodside", + "work", + "works", + "world", + "wow", + "ws", + "wtc", + "wtf", + "xbox", + "xerox", + "xfinity", + "xihuan", + "xin", + "xxx", + "xyz", + "yachts", + "yahoo", + "yamaxun", + "yandex", + "ye", + "yodobashi", + "yoga", + "yokohama", + "you", + "youtube", + "yt", + "yun", + "za", + "zappos", + "zara", + "zero", + "zip", + "zm", + "zone", + "zuerich", + "zw", + "ελ", + "ευ", + "бг", + "бел", + "дети", + "ею", + "католик", + "ком", + "мкд", + "мон", + "москва", + "онлайн", + "орг", + "рус", + "рф", + "сайт", + "срб", + "укр", + "қаз", + "հայ", + "ישראל", + "קום", + "ابوظبي", + "اتصالات", + "ارامكو", + "الاردن", + "البحرين", + "الجزائر", + "السعودية", + "العليان", + "المغرب", + "امارات", + "ایران", + "بارت", + "بازار", + "بيتك", + "بھارت", + "تونس", + "سودان", + "سورية", + "شبكة", + "عراق", + "عرب", + "عمان", + "فلسطين", + "قطر", + "كاثوليك", + "كوم", + "مصر", + "مليسيا", + "موريتانيا", + "موقع", + "همراه", + "پاکستان", + "ڀارت", + "कॉम", + "नेट", + "भारत", + "भारतम्", + "भारोत", + "संगठन", + "বাংলা", + "ভারত", + "ভাৰত", + "ਭਾਰਤ", + "ભારત", + "ଭାରତ", + "இந்தியா", + "இலங்கை", + "சிங்கப்பூர்", + "భారత్", + "ಭಾರತ", + "ഭാരതം", + "ලංකා", + "คอม", + "ไทย", + "ລາວ", + "გე", + "みんな", + "アマゾン", + "クラウド", + "グーグル", + "コム", + "ストア", + "セール", + "ファッション", + "ポイント", + "世界", + "中信", + "中国", + "中國", + "中文网", + "亚马逊", + "企业", + "佛山", + "信息", + "健康", + "八卦", + "公司", + "公益", + "台湾", + "台灣", + "商城", + "商店", + "商标", + "嘉里", + "嘉里大酒店", + "在线", + "大拿", + "天主教", + "娱乐", + "家電", + "广东", + "微博", + "慈善", + "我爱你", + "手机", + "招聘", + "政务", + "政府", + "新加坡", + "新闻", + "时尚", + "書籍", + "机构", + "淡马锡", + "游戏", + "澳門", + "点看", + "移动", + "组织机构", + "网址", + "网店", + "网站", + "网络", + "联通", + "诺基亚", + "谷歌", + "购物", + "通販", + "集团", + "電訊盈科", + "飞利浦", + "食品", + "餐厅", + "香格里拉", + "香港", + "닷넷", + "닷컴", + "삼성", + "한국", ]; -function getDomain(inputUrl) { - const parsed = url.parse(inputUrl).host; - var parts = parsed.split('.'); - if (parts[0] === 'www' && parts[1] !== 'com') { - parts.shift(); - } - var ln = parts.length, i = ln, minLength = parts[parts.length - 1].length, part; - // iterate backwards - while ((part = parts[--i])) { - // stop when we find a non-TLD part - if (i === 0 || // 'asia.com' (last remaining must be the SLD) - i < ln - 2 || // TLDs only span 2 levels - part.length < minLength || // 'www.cn.com' (valid TLD as second-level domain) - tlds.indexOf(part) < 0 // officialy not a TLD - ) { - return part; - } - } -} -function appendProtocol(inputUrl) { - const parsed = url.parse(inputUrl); - if (!parsed.protocol) { - const urlWithProtocol = `https://${inputUrl}`; - return urlWithProtocol; - } - return inputUrl; -} -function normalizeUrl(urlToNormalize) { - const urlWithProtocol = appendProtocol(urlToNormalize); - if (isurl(urlWithProtocol)) { - return urlWithProtocol; - } - else { - throw new Error(`Your url "${urlWithProtocol}" is invalid`); - } +function getDomain(inputUrl) { + const parsed = url.parse(inputUrl).host; + var parts = parsed.split('.'); + if (parts[0] === 'www' && parts[1] !== 'com') { + parts.shift(); + } + var ln = parts.length, i = ln, minLength = parts[parts.length - 1].length, part; + // iterate backwards + while ((part = parts[--i])) { + // stop when we find a non-TLD part + if (i === 0 || // 'asia.com' (last remaining must be the SLD) + i < ln - 2 || // TLDs only span 2 levels + part.length < minLength || // 'www.cn.com' (valid TLD as second-level domain) + tlds.indexOf(part) < 0 // officialy not a TLD + ) { + return part; + } + } +} +function appendProtocol(inputUrl) { + const parsed = url.parse(inputUrl); + if (!parsed.protocol) { + const urlWithProtocol = `https://${inputUrl}`; + return urlWithProtocol; + } + return inputUrl; +} +function normalizeUrl(urlToNormalize) { + const urlWithProtocol = appendProtocol(urlToNormalize); + if (isurl(urlWithProtocol)) { + return urlWithProtocol; + } + else { + throw new Error(`Your url "${urlWithProtocol}" is invalid`); + } } -function validateNumberInput(value) { - const parsedValue = Number(value); - if (isNaN(parsedValue)) { - throw new Commander.InvalidArgumentError('Not a number.'); - } - return parsedValue; -} -function validateUrlInput(url) { - if (!fs.existsSync(url)) { - try { - return normalizeUrl(url); - } - catch (error) { - throw new Commander.InvalidArgumentError(error.message); - } - } - else { - return url; - } +function validateNumberInput(value) { + const parsedValue = Number(value); + if (isNaN(parsedValue)) { + throw new Commander.InvalidArgumentError('Not a number.'); + } + return parsedValue; +} +function validateUrlInput(url) { + if (!fs.existsSync(url)) { + try { + return normalizeUrl(url); + } + catch (error) { + throw new Commander.InvalidArgumentError(error.message); + } + } + else { + return url; + } } const npmDirectory = path.join(path.dirname(fileURLToPath(import.meta.url)), '..'); -const logger = { - info(...msg) { - log.info(...msg.map((m) => chalk.blue.bold(m))); - }, - debug(...msg) { - log.debug(...msg); - }, - error(...msg) { - log.error(...msg.map((m) => chalk.red.bold(m))); - }, - warn(...msg) { - log.info(...msg.map((m) => chalk.yellow.bold(m))); - }, - success(...msg) { - log.info(...msg.map((m) => chalk.green.bold(m))); - } +const logger = { + info(...msg) { + log.info(...msg.map((m) => chalk.blue.bold(m))); + }, + debug(...msg) { + log.debug(...msg); + }, + error(...msg) { + log.error(...msg.map((m) => chalk.red.bold(m))); + }, + warn(...msg) { + log.info(...msg.map((m) => chalk.yellow.bold(m))); + }, + success(...msg) { + log.info(...msg.map((m) => chalk.green.bold(m))); + } }; -function promptText(message, initial) { - return __awaiter(this, void 0, void 0, function* () { - const response = yield prompts({ - type: 'text', - name: 'content', - message, - initial, - }); - return response.content; - }); -} -function mergeTauriConfig(url, options, tauriConf) { - return __awaiter(this, void 0, void 0, function* () { - const { width, height, fullscreen, transparent, resizable, userAgent, showMenu, showSystemTray, systemTrayIcon, iterCopyFile, identifier, name, } = options; - const tauriConfWindowOptions = { - width, - height, - fullscreen, - transparent, - resizable, - }; - // Package name is valid ? - // for Linux, package name must be a-z, 0-9 or "-", not allow to A-Z and other - if (process.platform === "linux") { - const reg = new RegExp(/[0-9]*[a-z]+[0-9]*\-?[0-9]*[a-z]*[0-9]*\-?[0-9]*[a-z]*[0-9]*/); - if (!reg.test(name) || reg.exec(name)[0].length != name.length) { - logger.error("package name is illegal, it must be lowercase letters, numbers, dashes, and it must contain the lowercase letters."); - logger.error("E.g com-123-xxx, 123pan, pan123,weread, we-read"); - process.exit(); - } - } - if (process.platform === "win32" || process.platform === "darwin") { - const reg = new RegExp(/([0-9]*[a-zA-Z]+[0-9]*)+/); - if (!reg.test(name) || reg.exec(name)[0].length != name.length) { - logger.error("package name is illegal, it must be letters, numbers, and it must contain the letters"); - logger.error("E.g 123pan,123Pan Pan123,weread, WeRead, WERead"); - process.exit(); - } - } - // logger.warn(JSON.stringify(tauriConf.pake.windows, null, 4)); - Object.assign(tauriConf.pake.windows[0], Object.assign({ url }, tauriConfWindowOptions)); - tauriConf.package.productName = name; - tauriConf.tauri.bundle.identifier = identifier; - // 判断一下url类型,是文件还是网站 - // 如果是文件,并且开启了递归拷贝功能,则需要将该文件以及所在文件夹下的所有文件拷贝到src目录下,否则只拷贝单个文件。 - const url_exists = yield fs$1.stat(url) - .then(() => true) - .catch(() => false); - if (url_exists) { - logger.warn("you input may a local file"); - tauriConf.pake.windows[0].url_type = "local"; - const file_name = path.basename(url); - const dir_name = path.dirname(url); - if (!iterCopyFile) { - const url_path = path.join(npmDirectory, "dist/", file_name); - yield fs$1.copyFile(url, url_path); - } - else { - const old_dir = path.join(npmDirectory, "dist/"); - const new_dir = path.join(npmDirectory, "dist_bak/"); - fs2.moveSync(old_dir, new_dir, { "overwrite": true }); - fs2.copySync(dir_name, old_dir, { "overwrite": true }); - // logger.warn("dir name", dir_name); - // 将dist_bak里面的cli.js和about_pake.html拷贝回去 - const cli_path = path.join(new_dir, "cli.js"); - const cli_path_target = path.join(old_dir, "cli.js"); - const about_pake_path = path.join(new_dir, "about_pake.html"); - const about_patk_path_target = path.join(old_dir, "about_pake.html"); - fs$1.copyFile(cli_path, cli_path_target); - fs$1.copyFile(about_pake_path, about_patk_path_target); - } - tauriConf.pake.windows[0].url = file_name; - tauriConf.pake.windows[0].url_type = "local"; - } - else { - tauriConf.pake.windows[0].url_type = "web"; - } - // 处理user-agent - if (userAgent.length > 0) { - if (process.platform === "win32") { - tauriConf.pake.user_agent.windows = userAgent; - } - if (process.platform === "linux") { - tauriConf.pake.user_agent.linux = userAgent; - } - if (process.platform === "darwin") { - tauriConf.pake.user_agent.macos = userAgent; - } - } - // 处理菜单栏 - if (showMenu) { - if (process.platform === "win32") { - tauriConf.pake.menu.windows = true; - } - if (process.platform === "linux") { - tauriConf.pake.menu.linux = true; - } - if (process.platform === "darwin") { - tauriConf.pake.menu.macos = true; - } - } - else { - if (process.platform === "win32") { - tauriConf.pake.menu.windows = false; - } - if (process.platform === "linux") { - tauriConf.pake.menu.linux = false; - } - if (process.platform === "darwin") { - tauriConf.pake.menu.macos = false; - } - } - // 处理托盘 - if (showSystemTray) { - if (process.platform === "win32") { - tauriConf.pake.system_tray.windows = true; - } - if (process.platform === "linux") { - tauriConf.pake.system_tray.linux = true; - } - if (process.platform === "darwin") { - tauriConf.pake.system_tray.macos = true; - } - } - else { - if (process.platform === "win32") { - tauriConf.pake.system_tray.windows = false; - } - if (process.platform === "linux") { - tauriConf.pake.system_tray.linux = false; - } - if (process.platform === "darwin") { - tauriConf.pake.system_tray.macos = false; - } - } - // 处理targets 暂时只对linux开放 - if (process.platform === "linux") { - delete tauriConf.tauri.bundle.deb.files; - if (["all", "deb", "appimage"].includes(options.targets)) { - tauriConf.tauri.bundle.targets = [options.targets]; - } - else { - logger.warn("targets must be 'all', 'deb', 'appimage', we will use default 'all'"); - } - } - // 处理应用图标 - const exists = yield fs$1.stat(options.icon) - .then(() => true) - .catch(() => false); - if (exists) { - let updateIconPath = true; - let customIconExt = path.extname(options.icon).toLowerCase(); - if (process.platform === "win32") { - if (customIconExt === ".ico") { - const ico_path = path.join(npmDirectory, `src-tauri/png/${name.toLowerCase()}_32.ico`); - tauriConf.tauri.bundle.resources = [`png/${name.toLowerCase()}_32.ico`]; - yield fs$1.copyFile(options.icon, ico_path); - } - else { - updateIconPath = false; - logger.warn(`icon file in Windows must be 256 * 256 pix with .ico type, but you give ${customIconExt}`); - tauriConf.tauri.bundle.icon = ["png/icon_256.ico"]; - } - } - if (process.platform === "linux") { - if (customIconExt != ".png") { - updateIconPath = false; - logger.warn(`icon file in Linux must be 512 * 512 pix with .png type, but you give ${customIconExt}`); - tauriConf.tauri.bundle.icon = ["png/icon_512.png"]; - } - } - if (process.platform === "darwin" && customIconExt !== ".icns") { - updateIconPath = false; - logger.warn(`icon file in MacOS must be .icns type, but you give ${customIconExt}`); - tauriConf.tauri.bundle.icon = ["icons/icon.icns"]; - } - if (updateIconPath) { - tauriConf.tauri.bundle.icon = [options.icon]; - } - else { - logger.warn(`icon file will not change with default.`); - } - } - else { - logger.warn("the custom icon path may not exists. we will use default icon to replace it"); - if (process.platform === "win32") { - tauriConf.tauri.bundle.icon = ["png/icon_256.ico"]; - } - if (process.platform === "linux") { - tauriConf.tauri.bundle.icon = ["png/icon_512.png"]; - } - if (process.platform === "darwin") { - tauriConf.tauri.bundle.icon = ["icons/icon.icns"]; - } - } - // 处理托盘自定义图标 - let useDefaultIcon = true; // 是否使用默认托盘图标 - if (systemTrayIcon.length > 0) { - const icon_exists = yield fs$1.stat(systemTrayIcon) - .then(() => true) - .catch(() => false); - if (icon_exists) { - // 需要判断图标格式,默认只支持ico和png两种 - let iconExt = path.extname(systemTrayIcon).toLowerCase(); - if (iconExt == ".png" || iconExt == ".icon") { - useDefaultIcon = false; - const trayIcoPath = path.join(npmDirectory, `src-tauri/png/${name.toLowerCase()}${iconExt}`); - tauriConf.tauri.systemTray.iconPath = `png/${name.toLowerCase()}${iconExt}`; - yield fs$1.copyFile(systemTrayIcon, trayIcoPath); - } - else { - logger.warn(`file type for system tray icon mut be .ico or .png , but you give ${iconExt}`); - logger.warn(`system tray icon file will not change with default.`); - } - } - else { - logger.warn(`${systemTrayIcon} not exists!`); - logger.warn(`system tray icon file will not change with default.`); - } - } - // 处理托盘默认图标 - if (useDefaultIcon) { - if (process.platform === "linux" || process.platform === "win32") { - tauriConf.tauri.systemTray.iconPath = tauriConf.tauri.bundle.icon[0]; - } - else { - tauriConf.tauri.systemTray.iconPath = "png/icon_512.png"; - } - } - // 保存配置文件 - let configPath = ""; - switch (process.platform) { - case "win32": { - configPath = path.join(npmDirectory, 'src-tauri/tauri.windows.conf.json'); - break; - } - case "darwin": { - configPath = path.join(npmDirectory, 'src-tauri/tauri.macos.conf.json'); - break; - } - case "linux": { - configPath = path.join(npmDirectory, 'src-tauri/tauri.linux.conf.json'); - break; - } - } - let bundleConf = { tauri: { bundle: tauriConf.tauri.bundle } }; - yield fs$1.writeFile(configPath, Buffer.from(JSON.stringify(bundleConf, null, 4), 'utf-8')); - const pakeConfigPath = path.join(npmDirectory, 'src-tauri/pake.json'); - yield fs$1.writeFile(pakeConfigPath, Buffer.from(JSON.stringify(tauriConf.pake, null, 4), 'utf-8')); - // logger.info("tauri config", JSON.stringify(tauriConf.build)); - let tauriConf2 = JSON.parse(JSON.stringify(tauriConf)); - delete tauriConf2.pake; - delete tauriConf2.tauri.bundle; - const configJsonPath = path.join(npmDirectory, 'src-tauri/tauri.conf.json'); - yield fs$1.writeFile(configJsonPath, Buffer.from(JSON.stringify(tauriConf2, null, 4), 'utf-8')); - }); +function promptText(message, initial) { + return __awaiter(this, void 0, void 0, function* () { + const response = yield prompts({ + type: 'text', + name: 'content', + message, + initial, + }); + return response.content; + }); +} +function mergeTauriConfig(url, options, tauriConf) { + return __awaiter(this, void 0, void 0, function* () { + const { width, height, fullscreen, transparent, resizable, userAgent, showMenu, showSystemTray, systemTrayIcon, iterCopyFile, identifier, name, } = options; + const tauriConfWindowOptions = { + width, + height, + fullscreen, + transparent, + resizable, + }; + // Package name is valid ? + // for Linux, package name must be a-z, 0-9 or "-", not allow to A-Z and other + if (process.platform === "linux") { + const reg = new RegExp(/[0-9]*[a-z]+[0-9]*\-?[0-9]*[a-z]*[0-9]*\-?[0-9]*[a-z]*[0-9]*/); + if (!reg.test(name) || reg.exec(name)[0].length != name.length) { + logger.error("package name is illegal, it must be lowercase letters, numbers, dashes, and it must contain the lowercase letters."); + logger.error("E.g com-123-xxx, 123pan, pan123,weread, we-read"); + process.exit(); + } + } + if (process.platform === "win32" || process.platform === "darwin") { + const reg = new RegExp(/([0-9]*[a-zA-Z]+[0-9]*)+/); + if (!reg.test(name) || reg.exec(name)[0].length != name.length) { + logger.error("package name is illegal, it must be letters, numbers, and it must contain the letters"); + logger.error("E.g 123pan,123Pan Pan123,weread, WeRead, WERead"); + process.exit(); + } + } + // logger.warn(JSON.stringify(tauriConf.pake.windows, null, 4)); + Object.assign(tauriConf.pake.windows[0], Object.assign({ url }, tauriConfWindowOptions)); + tauriConf.package.productName = name; + tauriConf.tauri.bundle.identifier = identifier; + // 判断一下url类型,是文件还是网站 + // 如果是文件,并且开启了递归拷贝功能,则需要将该文件以及所在文件夹下的所有文件拷贝到src目录下,否则只拷贝单个文件。 + const url_exists = yield fs$1.stat(url) + .then(() => true) + .catch(() => false); + if (url_exists) { + logger.warn("you input may a local file"); + tauriConf.pake.windows[0].url_type = "local"; + const file_name = path.basename(url); + const dir_name = path.dirname(url); + if (!iterCopyFile) { + const url_path = path.join(npmDirectory, "dist/", file_name); + yield fs$1.copyFile(url, url_path); + } + else { + const old_dir = path.join(npmDirectory, "dist/"); + const new_dir = path.join(npmDirectory, "dist_bak/"); + fs2.moveSync(old_dir, new_dir, { "overwrite": true }); + fs2.copySync(dir_name, old_dir, { "overwrite": true }); + // logger.warn("dir name", dir_name); + // 将dist_bak里面的cli.js和about_pake.html拷贝回去 + const cli_path = path.join(new_dir, "cli.js"); + const cli_path_target = path.join(old_dir, "cli.js"); + const about_pake_path = path.join(new_dir, "about_pake.html"); + const about_patk_path_target = path.join(old_dir, "about_pake.html"); + fs$1.copyFile(cli_path, cli_path_target); + fs$1.copyFile(about_pake_path, about_patk_path_target); + } + tauriConf.pake.windows[0].url = file_name; + tauriConf.pake.windows[0].url_type = "local"; + } + else { + tauriConf.pake.windows[0].url_type = "web"; + } + // 处理user-agent + if (userAgent.length > 0) { + if (process.platform === "win32") { + tauriConf.pake.user_agent.windows = userAgent; + } + if (process.platform === "linux") { + tauriConf.pake.user_agent.linux = userAgent; + } + if (process.platform === "darwin") { + tauriConf.pake.user_agent.macos = userAgent; + } + } + // 处理菜单栏 + if (showMenu) { + if (process.platform === "win32") { + tauriConf.pake.menu.windows = true; + } + if (process.platform === "linux") { + tauriConf.pake.menu.linux = true; + } + if (process.platform === "darwin") { + tauriConf.pake.menu.macos = true; + } + } + else { + if (process.platform === "win32") { + tauriConf.pake.menu.windows = false; + } + if (process.platform === "linux") { + tauriConf.pake.menu.linux = false; + } + if (process.platform === "darwin") { + tauriConf.pake.menu.macos = false; + } + } + // 处理托盘 + if (showSystemTray) { + if (process.platform === "win32") { + tauriConf.pake.system_tray.windows = true; + } + if (process.platform === "linux") { + tauriConf.pake.system_tray.linux = true; + } + if (process.platform === "darwin") { + tauriConf.pake.system_tray.macos = true; + } + } + else { + if (process.platform === "win32") { + tauriConf.pake.system_tray.windows = false; + } + if (process.platform === "linux") { + tauriConf.pake.system_tray.linux = false; + } + if (process.platform === "darwin") { + tauriConf.pake.system_tray.macos = false; + } + } + // 处理targets 暂时只对linux开放 + if (process.platform === "linux") { + delete tauriConf.tauri.bundle.deb.files; + if (["all", "deb", "appimage"].includes(options.targets)) { + tauriConf.tauri.bundle.targets = [options.targets]; + } + else { + logger.warn("targets must be 'all', 'deb', 'appimage', we will use default 'all'"); + } + } + // 处理应用图标 + const exists = yield fs$1.stat(options.icon) + .then(() => true) + .catch(() => false); + if (exists) { + let updateIconPath = true; + let customIconExt = path.extname(options.icon).toLowerCase(); + if (process.platform === "win32") { + if (customIconExt === ".ico") { + const ico_path = path.join(npmDirectory, `src-tauri/png/${name.toLowerCase()}_32.ico`); + tauriConf.tauri.bundle.resources = [`png/${name.toLowerCase()}_32.ico`]; + yield fs$1.copyFile(options.icon, ico_path); + } + else { + updateIconPath = false; + logger.warn(`icon file in Windows must be 256 * 256 pix with .ico type, but you give ${customIconExt}`); + tauriConf.tauri.bundle.icon = ["png/icon_256.ico"]; + } + } + if (process.platform === "linux") { + if (customIconExt != ".png") { + updateIconPath = false; + logger.warn(`icon file in Linux must be 512 * 512 pix with .png type, but you give ${customIconExt}`); + tauriConf.tauri.bundle.icon = ["png/icon_512.png"]; + } + } + if (process.platform === "darwin" && customIconExt !== ".icns") { + updateIconPath = false; + logger.warn(`icon file in MacOS must be .icns type, but you give ${customIconExt}`); + tauriConf.tauri.bundle.icon = ["icons/icon.icns"]; + } + if (updateIconPath) { + tauriConf.tauri.bundle.icon = [options.icon]; + } + else { + logger.warn(`icon file will not change with default.`); + } + } + else { + logger.warn("the custom icon path may not exists. we will use default icon to replace it"); + if (process.platform === "win32") { + tauriConf.tauri.bundle.icon = ["png/icon_256.ico"]; + } + if (process.platform === "linux") { + tauriConf.tauri.bundle.icon = ["png/icon_512.png"]; + } + if (process.platform === "darwin") { + tauriConf.tauri.bundle.icon = ["icons/icon.icns"]; + } + } + // 处理托盘自定义图标 + let useDefaultIcon = true; // 是否使用默认托盘图标 + if (systemTrayIcon.length > 0) { + const icon_exists = yield fs$1.stat(systemTrayIcon) + .then(() => true) + .catch(() => false); + if (icon_exists) { + // 需要判断图标格式,默认只支持ico和png两种 + let iconExt = path.extname(systemTrayIcon).toLowerCase(); + if (iconExt == ".png" || iconExt == ".icon") { + useDefaultIcon = false; + const trayIcoPath = path.join(npmDirectory, `src-tauri/png/${name.toLowerCase()}${iconExt}`); + tauriConf.tauri.systemTray.iconPath = `png/${name.toLowerCase()}${iconExt}`; + yield fs$1.copyFile(systemTrayIcon, trayIcoPath); + } + else { + logger.warn(`file type for system tray icon mut be .ico or .png , but you give ${iconExt}`); + logger.warn(`system tray icon file will not change with default.`); + } + } + else { + logger.warn(`${systemTrayIcon} not exists!`); + logger.warn(`system tray icon file will not change with default.`); + } + } + // 处理托盘默认图标 + if (useDefaultIcon) { + if (process.platform === "linux" || process.platform === "win32") { + tauriConf.tauri.systemTray.iconPath = tauriConf.tauri.bundle.icon[0]; + } + else { + tauriConf.tauri.systemTray.iconPath = "png/icon_512.png"; + } + } + // 保存配置文件 + let configPath = ""; + switch (process.platform) { + case "win32": { + configPath = path.join(npmDirectory, 'src-tauri/tauri.windows.conf.json'); + break; + } + case "darwin": { + configPath = path.join(npmDirectory, 'src-tauri/tauri.macos.conf.json'); + break; + } + case "linux": { + configPath = path.join(npmDirectory, 'src-tauri/tauri.linux.conf.json'); + break; + } + } + let bundleConf = { tauri: { bundle: tauriConf.tauri.bundle } }; + yield fs$1.writeFile(configPath, Buffer.from(JSON.stringify(bundleConf, null, 4), 'utf-8')); + const pakeConfigPath = path.join(npmDirectory, 'src-tauri/pake.json'); + yield fs$1.writeFile(pakeConfigPath, Buffer.from(JSON.stringify(tauriConf.pake, null, 4), 'utf-8')); + // logger.info("tauri config", JSON.stringify(tauriConf.build)); + let tauriConf2 = JSON.parse(JSON.stringify(tauriConf)); + delete tauriConf2.pake; + delete tauriConf2.tauri.bundle; + const configJsonPath = path.join(npmDirectory, 'src-tauri/tauri.conf.json'); + yield fs$1.writeFile(configJsonPath, Buffer.from(JSON.stringify(tauriConf2, null, 4), 'utf-8')); + }); } -function getIdentifier(name, url) { - const hash = crypto.createHash('md5'); - hash.update(url); - const postFixHash = hash.digest('hex').substring(0, 6); - return `pake-${postFixHash}`; +function getIdentifier(name, url) { + const hash = crypto.createHash('md5'); + hash.update(url); + const postFixHash = hash.digest('hex').substring(0, 6); + return `pake-${postFixHash}`; } -const IS_MAC = process.platform === 'darwin'; -const IS_WIN = process.platform === 'win32'; +const IS_MAC = process.platform === 'darwin'; +const IS_WIN = process.platform === 'win32'; const IS_LINUX = process.platform === 'linux'; -function handleIcon(options, url) { - return __awaiter(this, void 0, void 0, function* () { - if (options.icon) { - if (options.icon.startsWith('http')) { - return downloadIcon(options.icon); - } - else { - return path.resolve(options.icon); - } - } - if (!options.icon) { - return getDefaultIcon(); - } - }); -} -function getDefaultIcon() { - return __awaiter(this, void 0, void 0, function* () { - logger.info('You have not provided an app icon, use the default icon.(use --icon option to assign an icon)'); - let iconPath = 'src-tauri/icons/icon.icns'; - if (IS_WIN) { - iconPath = 'src-tauri/png/icon_256.ico'; - } - else if (IS_LINUX) { - iconPath = 'src-tauri/png/icon_512.png'; - } - return path.join(npmDirectory, iconPath); - }); -} -// export async function getIconFromPageUrl(url: string) { -// const icon = await pageIcon(url); -// console.log(icon); -// if (icon.ext === '.ico') { -// const a = await ICO.parse(icon.data); -// icon.data = Buffer.from(a[0].buffer); -// } -// const iconDir = (await dir()).path; -// const iconPath = path.join(iconDir, `/icon.icns`); -// const out = png2icons.createICNS(icon.data, png2icons.BILINEAR, 0); -// await fs.writeFile(iconPath, out); -// return iconPath; -// } -// export async function getIconFromMacosIcons(name: string) { -// const data = { -// query: name, -// filters: 'approved:true', -// hitsPerPage: 10, -// page: 1, -// }; -// const res = await axios.post('https://p1txh7zfb3-2.algolianet.com/1/indexes/macOSicons/query?x-algolia-agent=Algolia%20for%20JavaScript%20(4.13.1)%3B%20Browser', data, { -// headers: { -// 'x-algolia-api-key': '0ba04276e457028f3e11e38696eab32c', -// 'x-algolia-application-id': 'P1TXH7ZFB3', -// }, -// }); -// if (!res.data.hits.length) { -// return ''; -// } else { -// return downloadIcon(res.data.hits[0].icnsUrl); -// } -// } -function downloadIcon(iconUrl) { - return __awaiter(this, void 0, void 0, function* () { - let iconResponse; - try { - iconResponse = yield axios.get(iconUrl, { - responseType: 'arraybuffer', - }); - } - catch (error) { - if (error.response && error.response.status === 404) { - return null; - } - throw error; - } - const iconData = yield iconResponse.data; - if (!iconData) { - return null; - } - const fileDetails = yield fileTypeFromBuffer(iconData); - if (!fileDetails) { - return null; - } - const { path } = yield dir(); - const iconPath = `${path}/icon.${fileDetails.ext}`; - yield fs$1.writeFile(iconPath, iconData); - return iconPath; - }); +function handleIcon(options, url) { + return __awaiter(this, void 0, void 0, function* () { + if (options.icon) { + if (options.icon.startsWith('http')) { + return downloadIcon(options.icon); + } + else { + return path.resolve(options.icon); + } + } + if (!options.icon) { + return getDefaultIcon(); + } + }); +} +function getDefaultIcon() { + return __awaiter(this, void 0, void 0, function* () { + logger.info('You have not provided an app icon, use the default icon.(use --icon option to assign an icon)'); + let iconPath = 'src-tauri/icons/icon.icns'; + if (IS_WIN) { + iconPath = 'src-tauri/png/icon_256.ico'; + } + else if (IS_LINUX) { + iconPath = 'src-tauri/png/icon_512.png'; + } + return path.join(npmDirectory, iconPath); + }); +} +// export async function getIconFromPageUrl(url: string) { +// const icon = await pageIcon(url); +// console.log(icon); +// if (icon.ext === '.ico') { +// const a = await ICO.parse(icon.data); +// icon.data = Buffer.from(a[0].buffer); +// } +// const iconDir = (await dir()).path; +// const iconPath = path.join(iconDir, `/icon.icns`); +// const out = png2icons.createICNS(icon.data, png2icons.BILINEAR, 0); +// await fs.writeFile(iconPath, out); +// return iconPath; +// } +// export async function getIconFromMacosIcons(name: string) { +// const data = { +// query: name, +// filters: 'approved:true', +// hitsPerPage: 10, +// page: 1, +// }; +// const res = await axios.post('https://p1txh7zfb3-2.algolianet.com/1/indexes/macOSicons/query?x-algolia-agent=Algolia%20for%20JavaScript%20(4.13.1)%3B%20Browser', data, { +// headers: { +// 'x-algolia-api-key': '0ba04276e457028f3e11e38696eab32c', +// 'x-algolia-application-id': 'P1TXH7ZFB3', +// }, +// }); +// if (!res.data.hits.length) { +// return ''; +// } else { +// return downloadIcon(res.data.hits[0].icnsUrl); +// } +// } +function downloadIcon(iconUrl) { + return __awaiter(this, void 0, void 0, function* () { + let iconResponse; + try { + iconResponse = yield axios.get(iconUrl, { + responseType: 'arraybuffer', + }); + } + catch (error) { + if (error.response && error.response.status === 404) { + return null; + } + throw error; + } + const iconData = yield iconResponse.data; + if (!iconData) { + return null; + } + const fileDetails = yield fileTypeFromBuffer(iconData); + if (!fileDetails) { + return null; + } + const { path } = yield dir(); + const iconPath = `${path}/icon.${fileDetails.ext}`; + yield fs$1.writeFile(iconPath, iconData); + return iconPath; + }); } -function handleOptions(options, url) { - return __awaiter(this, void 0, void 0, function* () { - const appOptions = Object.assign(Object.assign({}, options), { identifier: '' }); - const url_exists = yield fs$1.stat(url) - .then(() => true) - .catch(() => false); - if (!appOptions.name) { - if (!url_exists) { - appOptions.name = yield promptText('please input your application name', getDomain(url)); - } - else { - appOptions.name = yield promptText('please input your application name', ""); - } - } - appOptions.identifier = getIdentifier(appOptions.name, url); - appOptions.icon = yield handleIcon(appOptions); - return appOptions; - }); +function handleOptions(options, url) { + return __awaiter(this, void 0, void 0, function* () { + const appOptions = Object.assign(Object.assign({}, options), { identifier: '' }); + const url_exists = yield fs$1.stat(url) + .then(() => true) + .catch(() => false); + if (!appOptions.name) { + if (!url_exists) { + appOptions.name = yield promptText('please input your application name', getDomain(url)); + } + else { + appOptions.name = yield promptText('please input your application name', ""); + } + } + appOptions.identifier = getIdentifier(appOptions.name, url); + appOptions.icon = yield handleIcon(appOptions); + return appOptions; + }); } -function shellExec(command) { - return new Promise((resolve, reject) => { - shelljs.exec(command, { async: true, silent: false, cwd: npmDirectory }, (code) => { - if (code === 0) { - resolve(0); - } - else { - reject(new Error(`${code}`)); - } - }); - }); +function shellExec(command) { + return new Promise((resolve, reject) => { + shelljs.exec(command, { async: true, silent: false, cwd: npmDirectory }, (code) => { + if (code === 0) { + resolve(0); + } + else { + reject(new Error(`${code}`)); + } + }); + }); } -const ping = (host) => __awaiter(void 0, void 0, void 0, function* () { - const lookup = promisify(dns.lookup); - const ip = yield lookup(host); - const start = new Date(); - return new Promise((resolve, reject) => { - const req = http.get(`http://${ip.address}`, (res) => { - const delay = new Date().getTime() - start.getTime(); - res.resume(); - resolve(delay); - }); - req.on('error', (err) => { - reject(err); - }); - }); -}); -const resolve = promisify(dns.resolve); -function isChinaDomain(domain) { - return __awaiter(this, void 0, void 0, function* () { - try { - // 解析域名为IP地址 - const [ip] = yield resolve(domain); - return yield isChinaIP(ip, domain); - } - catch (error) { - // 域名无法解析,返回false - logger.info(`${domain} can't be parse, is not in China!`); - return false; - } - }); -} -function isChinaIP(ip, domain) { - return __awaiter(this, void 0, void 0, function* () { - return new Promise((resolve, reject) => { - // exec(`ping -c -w 1 ${ip}`, (error, stdout, stderr) => { - ping(ip) - .then((declay) => { - logger.info(`${domain} latency is ${declay} ms`); - // 判断延迟是否超过500ms - resolve(declay > 500); - }) - .catch((error) => { - // 命令执行出错,返回false - logger.info(`ping ${domain} failed!, is not in China!`); - resolve(false); - }); - }); - }); +const ping = (host) => __awaiter(void 0, void 0, void 0, function* () { + const lookup = promisify(dns.lookup); + const ip = yield lookup(host); + const start = new Date(); + return new Promise((resolve, reject) => { + const req = http.get(`http://${ip.address}`, (res) => { + const delay = new Date().getTime() - start.getTime(); + res.resume(); + resolve(delay); + }); + req.on('error', (err) => { + reject(err); + }); + }); +}); +const resolve = promisify(dns.resolve); +function isChinaDomain(domain) { + return __awaiter(this, void 0, void 0, function* () { + try { + // 解析域名为IP地址 + const [ip] = yield resolve(domain); + return yield isChinaIP(ip, domain); + } + catch (error) { + // 域名无法解析,返回false + logger.info(`${domain} can't be parse, is not in China!`); + return false; + } + }); +} +function isChinaIP(ip, domain) { + return __awaiter(this, void 0, void 0, function* () { + try { + const delay = yield ping(ip); + logger.info(`${domain} latency is ${delay} ms`); + // 判断延迟是否超过500ms + return delay > 500; + } + catch (error) { + // 命令执行出错,返回false + logger.info(`ping ${domain} failed!, is not in China!`); + return false; + } + }); } -const is_china = isChinaDomain("sh.rustup.rs"); -let RustInstallScriptFocMac = ""; -if (is_china) { - RustInstallScriptFocMac = - 'export RUSTUP_DIST_SERVER="https://rsproxy.cn" && export RUSTUP_UPDATE_ROOT="https://rsproxy.cn/rustup" && curl --proto "=https" --tlsv1.2 -sSf https://rsproxy.cn/rustup-init.sh | sh'; -} -else { - RustInstallScriptFocMac = - "curl --proto '=https' --tlsv1.2 -sSf https://sh.rustup.rs | sh -s -- -y"; -} -const RustInstallScriptForWin = 'winget install --id Rustlang.Rustup'; -function installRust() { - return __awaiter(this, void 0, void 0, function* () { - const spinner = ora('Downloading Rust').start(); - try { - yield shellExec(IS_WIN ? RustInstallScriptForWin : RustInstallScriptFocMac); - spinner.succeed(); - } - catch (error) { - console.error('install rust return code', error.message); - spinner.fail(); - process.exit(1); - } - }); -} -function checkRustInstalled() { - return shelljs.exec('rustc --version', { silent: true }).code === 0; +function installRust() { + return __awaiter(this, void 0, void 0, function* () { + const is_china = yield isChinaDomain("sh.rustup.rs"); + let RustInstallScriptFocMac = ""; + if (is_china) { + logger.info("it's in China, use rust cn mirror to install rust"); + RustInstallScriptFocMac = + 'export RUSTUP_DIST_SERVER="https://rsproxy.cn" && export RUSTUP_UPDATE_ROOT="https://rsproxy.cn/rustup" && curl --proto "=https" --tlsv1.2 -sSf https://rsproxy.cn/rustup-init.sh | sh'; + } + else { + RustInstallScriptFocMac = + "curl --proto '=https' --tlsv1.2 -sSf https://sh.rustup.rs | sh -s -- -y"; + } + const RustInstallScriptForWin = 'winget install --id Rustlang.Rustup'; + const spinner = ora('Downloading Rust').start(); + try { + yield shellExec(IS_WIN ? RustInstallScriptForWin : RustInstallScriptFocMac); + spinner.succeed(); + } + catch (error) { + console.error('install rust return code', error.message); + spinner.fail(); + process.exit(1); + } + }); +} +function checkRustInstalled() { + return shelljs.exec('rustc --version', { silent: true }).code === 0; } var tauri$3 = { @@ -2264,251 +2262,263 @@ var LinuxConf = { tauri: tauri }; -let tauriConf = { - package: CommonConf.package, - tauri: CommonConf.tauri, - build: CommonConf.build, - pake: pakeConf -}; -switch (process.platform) { - case "win32": { - tauriConf.tauri.bundle = WinConf.tauri.bundle; - break; - } - case "darwin": { - tauriConf.tauri.bundle = MacConf.tauri.bundle; - break; - } - case "linux": { - tauriConf.tauri.bundle = LinuxConf.tauri.bundle; - break; - } +let tauriConf = { + package: CommonConf.package, + tauri: CommonConf.tauri, + build: CommonConf.build, + pake: pakeConf +}; +switch (process.platform) { + case "win32": { + tauriConf.tauri.bundle = WinConf.tauri.bundle; + break; + } + case "darwin": { + tauriConf.tauri.bundle = MacConf.tauri.bundle; + break; + } + case "linux": { + tauriConf.tauri.bundle = LinuxConf.tauri.bundle; + break; + } } -class MacBuilder { - prepare() { - return __awaiter(this, void 0, void 0, function* () { - if (checkRustInstalled()) { - return; - } - const res = yield prompts({ - type: 'confirm', - message: 'We detected that you have not installed Rust. Install it now?', - name: 'value', - }); - if (res.value) { - // TODO 国内有可能会超时 - yield installRust(); - } - else { - log.error('Error: Pake need Rust to package your webapp!!!'); - process.exit(2); - } - }); - } - build(url, options) { - return __awaiter(this, void 0, void 0, function* () { - log.debug('PakeAppOptions', options); - const { name } = options; - yield mergeTauriConfig(url, options, tauriConf); - let dmgName; - if (options.multiArch) { - const isChina = isChinaDomain("www.npmjs.com"); - if (isChina) { - // crates.io也顺便换源 - const rust_project_dir = path.join(npmDirectory, 'src-tauri', ".cargo"); - const project_cn_conf = path.join(rust_project_dir, "cn_config.bak"); - const project_conf = path.join(rust_project_dir, "config"); - fs$1.copyFile(project_cn_conf, project_conf); - yield shellExec(`cd "${npmDirectory}" && npm install --registry=https://registry.npmmirror.com && npm run build:mac`); - } - else { - yield shellExec(`cd "${npmDirectory}" && npm install && npm run build:mac`); - } - dmgName = `${name}_${tauriConf.package.version}_universal.dmg`; - } - else { - const isChina = isChinaDomain("www.npmjs.com"); - if (isChina) { - yield shellExec(`cd ${npmDirectory} && npm install --registry=https://registry.npmmirror.com && npm run build`); - } - else { - yield shellExec(`cd ${npmDirectory} && npm install && npm run build`); - } - let arch = "x64"; - if (process.arch === "arm64") { - arch = "aarch64"; - } - else { - arch = process.arch; - } - dmgName = `${name}_${tauriConf.package.version}_${arch}.dmg`; - } - const appPath = this.getBuildAppPath(npmDirectory, dmgName, options.multiArch); - const distPath = path.resolve(`${name}.dmg`); - yield fs$1.copyFile(appPath, distPath); - yield fs$1.unlink(appPath); - logger.success('Build success!'); - logger.success('You can find the app installer in', distPath); - }); - } - getBuildAppPath(npmDirectory, dmgName, multiArch) { - let dmgPath; - if (multiArch) { - dmgPath = 'src-tauri/target/universal-apple-darwin/release/bundle/dmg'; - } - else { - dmgPath = 'src-tauri/target/release/bundle/dmg'; - } - return path.join(npmDirectory, dmgPath, dmgName); - } +class MacBuilder { + prepare() { + return __awaiter(this, void 0, void 0, function* () { + if (checkRustInstalled()) { + return; + } + const res = yield prompts({ + type: 'confirm', + message: 'We detected that you have not installed Rust. Install it now?', + name: 'value', + }); + if (res.value) { + // TODO 国内有可能会超时 + yield installRust(); + } + else { + log.error('Error: Pake need Rust to package your webapp!!!'); + process.exit(2); + } + }); + } + build(url, options) { + return __awaiter(this, void 0, void 0, function* () { + log.debug('PakeAppOptions', options); + const { name } = options; + yield mergeTauriConfig(url, options, tauriConf); + let dmgName; + if (options.multiArch) { + const isChina = yield isChinaDomain("www.npmjs.com"); + if (isChina) { + logger.info("it's in China, use npm/rust cn mirror"); + const rust_project_dir = path.join(npmDirectory, 'src-tauri', ".cargo"); + const e1 = fs$1.access(rust_project_dir); + if (e1) { + yield fs$1.mkdir(rust_project_dir, { recursive: true }); + } + const project_cn_conf = path.join(npmDirectory, "src-tauri", "cn_config.bak"); + const project_conf = path.join(rust_project_dir, "config"); + fs$1.copyFile(project_cn_conf, project_conf); + yield shellExec(`cd "${npmDirectory}" && npm install --registry=https://registry.npmmirror.com && npm run build:mac`); + } + else { + yield shellExec(`cd "${npmDirectory}" && npm install && npm run build:mac`); + } + dmgName = `${name}_${tauriConf.package.version}_universal.dmg`; + } + else { + const isChina = isChinaDomain("www.npmjs.com"); + if (isChina) { + yield shellExec(`cd ${npmDirectory} && npm install --registry=https://registry.npmmirror.com && npm run build`); + } + else { + yield shellExec(`cd ${npmDirectory} && npm install && npm run build`); + } + let arch = "x64"; + if (process.arch === "arm64") { + arch = "aarch64"; + } + else { + arch = process.arch; + } + dmgName = `${name}_${tauriConf.package.version}_${arch}.dmg`; + } + const appPath = this.getBuildAppPath(npmDirectory, dmgName, options.multiArch); + const distPath = path.resolve(`${name}.dmg`); + yield fs$1.copyFile(appPath, distPath); + yield fs$1.unlink(appPath); + logger.success('Build success!'); + logger.success('You can find the app installer in', distPath); + }); + } + getBuildAppPath(npmDirectory, dmgName, multiArch) { + let dmgPath; + if (multiArch) { + dmgPath = 'src-tauri/target/universal-apple-darwin/release/bundle/dmg'; + } + else { + dmgPath = 'src-tauri/target/release/bundle/dmg'; + } + return path.join(npmDirectory, dmgPath, dmgName); + } } -class WinBuilder { - prepare() { - return __awaiter(this, void 0, void 0, function* () { - logger.info('To build the Windows app, you need to install Rust and VS Build Tools.'); - logger.info('See more in https://tauri.app/v1/guides/getting-started/prerequisites#installing\n'); - if (checkRustInstalled()) { - return; - } - const res = yield prompts({ - type: 'confirm', - message: 'We detected that you have not installed Rust. Install it now?', - name: 'value', - }); - if (res.value) { - // TODO 国内有可能会超时 - yield installRust(); - } - else { - logger.error('Error: Pake needs Rust to package your webapp!!!'); - process.exit(2); - } - }); - } - build(url, options) { - return __awaiter(this, void 0, void 0, function* () { - logger.debug('PakeAppOptions', options); - const { name } = options; - yield mergeTauriConfig(url, options, tauriConf); - const isChina = isChinaDomain("www.npmjs.com"); - if (isChina) { - // crates.io也顺便换源 - const rust_project_dir = path.join(npmDirectory, 'src-tauri', ".cargo"); - const project_cn_conf = path.join(rust_project_dir, "cn_config.bak"); - const project_conf = path.join(rust_project_dir, "config"); - fs$1.copyFile(project_cn_conf, project_conf); - yield shellExec(`cd "${npmDirectory}" && npm install --registry=https://registry.npmmirror.com && npm run build`); - } - else { - yield shellExec(`cd "${npmDirectory}" && npm install && npm run build`); - } - const language = tauriConf.tauri.bundle.windows.wix.language[0]; - const arch = process.arch; - const msiName = `${name}_${tauriConf.package.version}_${arch}_${language}.msi`; - const appPath = this.getBuildedAppPath(npmDirectory, msiName); - const distPath = path.resolve(`${name}.msi`); - yield fs$1.copyFile(appPath, distPath); - yield fs$1.unlink(appPath); - logger.success('Build success!'); - logger.success('You can find the app installer in', distPath); - }); - } - getBuildedAppPath(npmDirectory, dmgName) { - return path.join(npmDirectory, 'src-tauri/target/release/bundle/msi', dmgName); - } +class WinBuilder { + prepare() { + return __awaiter(this, void 0, void 0, function* () { + logger.info('To build the Windows app, you need to install Rust and VS Build Tools.'); + logger.info('See more in https://tauri.app/v1/guides/getting-started/prerequisites#installing\n'); + if (checkRustInstalled()) { + return; + } + const res = yield prompts({ + type: 'confirm', + message: 'We detected that you have not installed Rust. Install it now?', + name: 'value', + }); + if (res.value) { + // TODO 国内有可能会超时 + yield installRust(); + } + else { + logger.error('Error: Pake needs Rust to package your webapp!!!'); + process.exit(2); + } + }); + } + build(url, options) { + return __awaiter(this, void 0, void 0, function* () { + logger.debug('PakeAppOptions', options); + const { name } = options; + yield mergeTauriConfig(url, options, tauriConf); + const isChina = yield isChinaDomain("www.npmjs.com"); + if (isChina) { + logger.info("it's in China, use npm/rust cn mirror"); + const rust_project_dir = path.join(npmDirectory, 'src-tauri', ".cargo"); + const e1 = fs$1.access(rust_project_dir); + if (e1) { + yield fs$1.mkdir(rust_project_dir, { recursive: true }); + } + const project_cn_conf = path.join(npmDirectory, "src-tauri", "cn_config.bak"); + const project_conf = path.join(rust_project_dir, "config"); + fs$1.copyFile(project_cn_conf, project_conf); + yield shellExec(`cd "${npmDirectory}" && npm install --registry=https://registry.npmmirror.com && npm run build`); + } + else { + yield shellExec(`cd "${npmDirectory}" && npm install && npm run build`); + } + const language = tauriConf.tauri.bundle.windows.wix.language[0]; + const arch = process.arch; + const msiName = `${name}_${tauriConf.package.version}_${arch}_${language}.msi`; + const appPath = this.getBuildedAppPath(npmDirectory, msiName); + const distPath = path.resolve(`${name}.msi`); + yield fs$1.copyFile(appPath, distPath); + yield fs$1.unlink(appPath); + logger.success('Build success!'); + logger.success('You can find the app installer in', distPath); + }); + } + getBuildedAppPath(npmDirectory, dmgName) { + return path.join(npmDirectory, 'src-tauri/target/release/bundle/msi', dmgName); + } } -class LinuxBuilder { - prepare() { - return __awaiter(this, void 0, void 0, function* () { - logger.info('To build the Linux app, you need to install Rust and Linux package'); - logger.info('See more in https://tauri.app/v1/guides/getting-started/prerequisites#installing\n'); - if (checkRustInstalled()) { - return; - } - const res = yield prompts({ - type: 'confirm', - message: 'We detected that you have not installed Rust. Install it now?', - name: 'value', - }); - if (res.value) { - // TODO 国内有可能会超时 - yield installRust(); - } - else { - logger.error('Error: Pake needs Rust to package your webapp!!!'); - process.exit(2); - } - }); - } - build(url, options) { - return __awaiter(this, void 0, void 0, function* () { - logger.debug('PakeAppOptions', options); - const { name } = options; - yield mergeTauriConfig(url, options, tauriConf); - const isChina = isChinaDomain("www.npmjs.com"); - if (isChina) { - // crates.io也顺便换源 - const rust_project_dir = path.join(npmDirectory, 'src-tauri', ".cargo"); - const project_cn_conf = path.join(rust_project_dir, "cn_config.bak"); - const project_conf = path.join(rust_project_dir, "config"); - fs$1.copyFile(project_cn_conf, project_conf); - yield shellExec(`cd "${npmDirectory}" && npm install --registry=https://registry.npmmirror.com && npm run build`); - } - else { - yield shellExec(`cd "${npmDirectory}" && npm install && npm run build`); - } - let arch; - if (process.arch === "x64") { - arch = "amd64"; - } - else { - arch = process.arch; - } - if (options.targets === "deb" || options.targets === "all") { - const debName = `${name}_${tauriConf.package.version}_${arch}.deb`; - const appPath = this.getBuildAppPath(npmDirectory, "deb", debName); - const distPath = path.resolve(`${name}.deb`); - yield fs$1.copyFile(appPath, distPath); - yield fs$1.unlink(appPath); - logger.success('Build Deb success!'); - logger.success('You can find the deb app installer in', distPath); - } - if (options.targets === "appimage" || options.targets === "all") { - const appImageName = `${name}_${tauriConf.package.version}_${arch}.AppImage`; - const appImagePath = this.getBuildAppPath(npmDirectory, "appimage", appImageName); - const distAppPath = path.resolve(`${name}.AppImage`); - yield fs$1.copyFile(appImagePath, distAppPath); - yield fs$1.unlink(appImagePath); - logger.success('Build AppImage success!'); - logger.success('You can find the AppImage app installer in', distAppPath); - } - }); - } - getBuildAppPath(npmDirectory, packageType, packageName) { - return path.join(npmDirectory, 'src-tauri/target/release/bundle/', packageType, packageName); - } +class LinuxBuilder { + prepare() { + return __awaiter(this, void 0, void 0, function* () { + logger.info('To build the Linux app, you need to install Rust and Linux package'); + logger.info('See more in https://tauri.app/v1/guides/getting-started/prerequisites#installing\n'); + if (checkRustInstalled()) { + return; + } + const res = yield prompts({ + type: 'confirm', + message: 'We detected that you have not installed Rust. Install it now?', + name: 'value', + }); + if (res.value) { + // TODO 国内有可能会超时 + yield installRust(); + } + else { + logger.error('Error: Pake needs Rust to package your webapp!!!'); + process.exit(2); + } + }); + } + build(url, options) { + return __awaiter(this, void 0, void 0, function* () { + logger.debug('PakeAppOptions', options); + const { name } = options; + yield mergeTauriConfig(url, options, tauriConf); + const isChina = yield isChinaDomain("www.npmjs.com"); + if (isChina) { + logger.info("it's in China, use npm/rust cn mirror"); + const rust_project_dir = path.join(npmDirectory, 'src-tauri', ".cargo"); + const e1 = fs$1.access(rust_project_dir); + if (e1) { + yield fs$1.mkdir(rust_project_dir, { recursive: true }); + } + const project_cn_conf = path.join(npmDirectory, "src-tauri", "cn_config.bak"); + const project_conf = path.join(rust_project_dir, "config"); + fs$1.copyFile(project_cn_conf, project_conf); + yield shellExec(`cd "${npmDirectory}" && npm install --registry=https://registry.npmmirror.com && npm run build`); + } + else { + yield shellExec(`cd "${npmDirectory}" && npm install && npm run build`); + } + let arch; + if (process.arch === "x64") { + arch = "amd64"; + } + else { + arch = process.arch; + } + if (options.targets === "deb" || options.targets === "all") { + const debName = `${name}_${tauriConf.package.version}_${arch}.deb`; + const appPath = this.getBuildAppPath(npmDirectory, "deb", debName); + const distPath = path.resolve(`${name}.deb`); + yield fs$1.copyFile(appPath, distPath); + yield fs$1.unlink(appPath); + logger.success('Build Deb success!'); + logger.success('You can find the deb app installer in', distPath); + } + if (options.targets === "appimage" || options.targets === "all") { + const appImageName = `${name}_${tauriConf.package.version}_${arch}.AppImage`; + const appImagePath = this.getBuildAppPath(npmDirectory, "appimage", appImageName); + const distAppPath = path.resolve(`${name}.AppImage`); + yield fs$1.copyFile(appImagePath, distAppPath); + yield fs$1.unlink(appImagePath); + logger.success('Build AppImage success!'); + logger.success('You can find the AppImage app installer in', distAppPath); + } + }); + } + getBuildAppPath(npmDirectory, packageType, packageName) { + return path.join(npmDirectory, 'src-tauri/target/release/bundle/', packageType, packageName); + } } -class BuilderFactory { - static create() { - if (IS_MAC) { - return new MacBuilder(); - } - if (IS_WIN) { - return new WinBuilder(); - } - if (IS_LINUX) { - return new LinuxBuilder(); - } - throw new Error('The current system does not support!!'); - } +class BuilderFactory { + static create() { + if (IS_MAC) { + return new MacBuilder(); + } + if (IS_WIN) { + return new WinBuilder(); + } + if (IS_LINUX) { + return new LinuxBuilder(); + } + throw new Error('The current system does not support!!'); + } } var name = "pake-cli"; -var version = "2.0.0-alpha7"; +var version = "2.0.0-alpha8"; var description = "🤱🏻 Turn any webpage into a desktop app with Rust. 🤱🏻 很简单的用 Rust 打包网页生成很小的桌面 App。"; var engines = { node: ">=16.0.0" @@ -2606,46 +2616,46 @@ var packageJson = { devDependencies: devDependencies }; -function checkUpdateTips() { - return __awaiter(this, void 0, void 0, function* () { - updateNotifier({ pkg: packageJson }).notify(); - }); +function checkUpdateTips() { + return __awaiter(this, void 0, void 0, function* () { + updateNotifier({ pkg: packageJson }).notify(); + }); } -program.version(packageJson.version).description('A cli application can package a web page to desktop application.'); -program - .showHelpAfterError() - .argument('[url]', 'the web url you want to package', validateUrlInput) - .option('--name ', 'application name') - .option('--icon ', 'application icon', DEFAULT_PAKE_OPTIONS.icon) - .option('--height ', 'window height', validateNumberInput, DEFAULT_PAKE_OPTIONS.height) - .option('--width ', 'window width', validateNumberInput, DEFAULT_PAKE_OPTIONS.width) - .option('--no-resizable', 'whether the window can be resizable', DEFAULT_PAKE_OPTIONS.resizable) - .option('--fullscreen', 'makes the packaged app start in full screen', DEFAULT_PAKE_OPTIONS.fullscreen) - .option('--transparent', 'transparent title bar', DEFAULT_PAKE_OPTIONS.transparent) - .option('--user-agent ', 'custom user agent', DEFAULT_PAKE_OPTIONS.userAgent) - .option('--show-menu', 'show menu in app', DEFAULT_PAKE_OPTIONS.showMenu) - .option('--show-system-tray', 'show system tray in app', DEFAULT_PAKE_OPTIONS.showSystemTray) - .option('--system-tray-icon ', 'custom system tray icon', DEFAULT_PAKE_OPTIONS.systemTrayIcon) - .option('--iter-copy-file', 'copy all static file to pake app when url is a local file', DEFAULT_PAKE_OPTIONS.iterCopyFile) - .option('-m, --multi-arch', "available for Mac only, and supports both Intel and M1", DEFAULT_PAKE_OPTIONS.multiArch) - .option('--targets ', 'only for linux, default is "deb", option "appaimge" or "all"(deb & appimage)', DEFAULT_PAKE_OPTIONS.targets) - .option('--debug', 'debug', DEFAULT_PAKE_OPTIONS.transparent) - .action((url, options) => __awaiter(void 0, void 0, void 0, function* () { - checkUpdateTips(); - if (!url) { - // 直接 pake 不需要出现url提示 - program.help(); - } - log.setDefaultLevel('info'); - if (options.debug) { - log.setLevel('debug'); - } - const builder = BuilderFactory.create(); - yield builder.prepare(); - // logger.warn("you input url is ", url); - const appOptions = yield handleOptions(options, url); - // logger.info(JSON.stringify(appOptions, null, 4)); - builder.build(url, appOptions); -})); +program.version(packageJson.version).description('A cli application can package a web page to desktop application.'); +program + .showHelpAfterError() + .argument('[url]', 'the web url you want to package', validateUrlInput) + .option('--name ', 'application name') + .option('--icon ', 'application icon', DEFAULT_PAKE_OPTIONS.icon) + .option('--height ', 'window height', validateNumberInput, DEFAULT_PAKE_OPTIONS.height) + .option('--width ', 'window width', validateNumberInput, DEFAULT_PAKE_OPTIONS.width) + .option('--no-resizable', 'whether the window can be resizable', DEFAULT_PAKE_OPTIONS.resizable) + .option('--fullscreen', 'makes the packaged app start in full screen', DEFAULT_PAKE_OPTIONS.fullscreen) + .option('--transparent', 'transparent title bar', DEFAULT_PAKE_OPTIONS.transparent) + .option('--user-agent ', 'custom user agent', DEFAULT_PAKE_OPTIONS.userAgent) + .option('--show-menu', 'show menu in app', DEFAULT_PAKE_OPTIONS.showMenu) + .option('--show-system-tray', 'show system tray in app', DEFAULT_PAKE_OPTIONS.showSystemTray) + .option('--system-tray-icon ', 'custom system tray icon', DEFAULT_PAKE_OPTIONS.systemTrayIcon) + .option('--iter-copy-file', 'copy all static file to pake app when url is a local file', DEFAULT_PAKE_OPTIONS.iterCopyFile) + .option('-m, --multi-arch', "available for Mac only, and supports both Intel and M1", DEFAULT_PAKE_OPTIONS.multiArch) + .option('--targets ', 'only for linux, default is "deb", option "appaimge" or "all"(deb & appimage)', DEFAULT_PAKE_OPTIONS.targets) + .option('--debug', 'debug', DEFAULT_PAKE_OPTIONS.transparent) + .action((url, options) => __awaiter(void 0, void 0, void 0, function* () { + checkUpdateTips(); + if (!url) { + // 直接 pake 不需要出现url提示 + program.help(); + } + log.setDefaultLevel('info'); + if (options.debug) { + log.setLevel('debug'); + } + const builder = BuilderFactory.create(); + yield builder.prepare(); + // logger.warn("you input url is ", url); + const appOptions = yield handleOptions(options, url); + // logger.info(JSON.stringify(appOptions, null, 4)); + builder.build(url, appOptions); +})); program.parse(); diff --git a/package.json b/package.json index 5194c300f..c11f7b5bd 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "pake-cli", - "version": "2.0.0-alpha8", + "version": "2.0.0-alpha9", "description": "🤱🏻 Turn any webpage into a desktop app with Rust. 🤱🏻 很简单的用 Rust 打包网页生成很小的桌面 App。", "engines": { "node": ">=16.0.0" diff --git a/src-tauri/.cargo/cn_config.bak b/src-tauri/cn_config.bak similarity index 100% rename from src-tauri/.cargo/cn_config.bak rename to src-tauri/cn_config.bak