diff --git a/ee/maintained-apps/inputs/homebrew/nagstamon.json b/ee/maintained-apps/inputs/homebrew/nagstamon.json new file mode 100644 index 00000000000..fb2468d5582 --- /dev/null +++ b/ee/maintained-apps/inputs/homebrew/nagstamon.json @@ -0,0 +1,10 @@ +{ + "name": "Nagstamon", + "unique_identifier": "de.nagstamon", + "token": "nagstamon", + "installer_format": "dmg", + "slug": "nagstamon/darwin", + "default_categories": [ + "Productivity" + ] +} \ No newline at end of file diff --git a/ee/maintained-apps/inputs/homebrew/name-mangler.json b/ee/maintained-apps/inputs/homebrew/name-mangler.json new file mode 100644 index 00000000000..19b4fbb363b --- /dev/null +++ b/ee/maintained-apps/inputs/homebrew/name-mangler.json @@ -0,0 +1,10 @@ +{ + "name": "Name Mangler", + "unique_identifier": "com.manytricks.NameMangler", + "token": "name-mangler", + "installer_format": "dmg", + "slug": "name-mangler/darwin", + "default_categories": [ + "Productivity" + ] +} \ No newline at end of file diff --git a/ee/maintained-apps/inputs/homebrew/naps2.json b/ee/maintained-apps/inputs/homebrew/naps2.json new file mode 100644 index 00000000000..545fec4a62f --- /dev/null +++ b/ee/maintained-apps/inputs/homebrew/naps2.json @@ -0,0 +1,10 @@ +{ + "name": "NAPS2", + "unique_identifier": "com.naps2.desktop", + "token": "naps2", + "installer_format": "pkg", + "slug": "naps2/darwin", + "default_categories": [ + "Productivity" + ] +} \ No newline at end of file diff --git a/ee/maintained-apps/inputs/homebrew/ndi-tools.json b/ee/maintained-apps/inputs/homebrew/ndi-tools.json new file mode 100644 index 00000000000..9e3488129de --- /dev/null +++ b/ee/maintained-apps/inputs/homebrew/ndi-tools.json @@ -0,0 +1,10 @@ +{ + "name": "NDI Tools", + "unique_identifier": "com.newtek.Application-Mac-NDI-ScanConverter", + "token": "ndi-tools", + "installer_format": "pkg", + "slug": "ndi-tools/darwin", + "default_categories": [ + "Productivity" + ] +} \ No newline at end of file diff --git a/ee/maintained-apps/inputs/homebrew/neofinder.json b/ee/maintained-apps/inputs/homebrew/neofinder.json new file mode 100644 index 00000000000..7e10e9c62e6 --- /dev/null +++ b/ee/maintained-apps/inputs/homebrew/neofinder.json @@ -0,0 +1,10 @@ +{ + "name": "NeoFinder", + "unique_identifier": "de.wfs-apps.neofinder", + "token": "neofinder", + "installer_format": "zip", + "slug": "neofinder/darwin", + "default_categories": [ + "Productivity" + ] +} \ No newline at end of file diff --git a/ee/maintained-apps/inputs/homebrew/netiquette.json b/ee/maintained-apps/inputs/homebrew/netiquette.json new file mode 100644 index 00000000000..5d4dc57f5f8 --- /dev/null +++ b/ee/maintained-apps/inputs/homebrew/netiquette.json @@ -0,0 +1,10 @@ +{ + "name": "Netiquette", + "unique_identifier": "com.objective-see.Netiquette", + "token": "netiquette", + "installer_format": "zip", + "slug": "netiquette/darwin", + "default_categories": [ + "Productivity" + ] +} \ No newline at end of file diff --git a/ee/maintained-apps/inputs/homebrew/netnewswire.json b/ee/maintained-apps/inputs/homebrew/netnewswire.json new file mode 100644 index 00000000000..849af809248 --- /dev/null +++ b/ee/maintained-apps/inputs/homebrew/netnewswire.json @@ -0,0 +1,10 @@ +{ + "name": "NetNewsWire", + "unique_identifier": "com.ranchero.NetNewsWire-Evergreen", + "token": "netnewswire", + "installer_format": "zip", + "slug": "netnewswire/darwin", + "default_categories": [ + "Productivity" + ] +} \ No newline at end of file diff --git a/ee/maintained-apps/inputs/homebrew/netron.json b/ee/maintained-apps/inputs/homebrew/netron.json new file mode 100644 index 00000000000..ce5c34a3829 --- /dev/null +++ b/ee/maintained-apps/inputs/homebrew/netron.json @@ -0,0 +1,10 @@ +{ + "name": "Netron", + "unique_identifier": "com.lutzroeder.netron", + "token": "netron", + "installer_format": "zip", + "slug": "netron/darwin", + "default_categories": [ + "Productivity" + ] +} \ No newline at end of file diff --git a/ee/maintained-apps/inputs/homebrew/netspot.json b/ee/maintained-apps/inputs/homebrew/netspot.json new file mode 100644 index 00000000000..0d62eaef75c --- /dev/null +++ b/ee/maintained-apps/inputs/homebrew/netspot.json @@ -0,0 +1,10 @@ +{ + "name": "NetSpot", + "unique_identifier": "com.etwok.netspotwifi", + "token": "netspot", + "installer_format": "dmg", + "slug": "netspot/darwin", + "default_categories": [ + "Productivity" + ] +} \ No newline at end of file diff --git a/ee/maintained-apps/inputs/homebrew/nextcloud-talk.json b/ee/maintained-apps/inputs/homebrew/nextcloud-talk.json new file mode 100644 index 00000000000..81d38ff7624 --- /dev/null +++ b/ee/maintained-apps/inputs/homebrew/nextcloud-talk.json @@ -0,0 +1,10 @@ +{ + "name": "Nextcloud Talk Desktop", + "unique_identifier": "com.nextcloud.talk.mac", + "token": "nextcloud-talk", + "installer_format": "dmg", + "slug": "nextcloud-talk/darwin", + "default_categories": [ + "Productivity" + ] +} \ No newline at end of file diff --git a/ee/maintained-apps/inputs/homebrew/nightfall.json b/ee/maintained-apps/inputs/homebrew/nightfall.json new file mode 100644 index 00000000000..6ed04ac2518 --- /dev/null +++ b/ee/maintained-apps/inputs/homebrew/nightfall.json @@ -0,0 +1,10 @@ +{ + "name": "Nightfall", + "unique_identifier": "net.ryanthomson.Nightfall", + "token": "nightfall", + "installer_format": "dmg", + "slug": "nightfall/darwin", + "default_categories": [ + "Utilities" + ] +} \ No newline at end of file diff --git a/ee/maintained-apps/inputs/homebrew/nitro-pdf-pro.json b/ee/maintained-apps/inputs/homebrew/nitro-pdf-pro.json new file mode 100644 index 00000000000..788e8681990 --- /dev/null +++ b/ee/maintained-apps/inputs/homebrew/nitro-pdf-pro.json @@ -0,0 +1,10 @@ +{ + "name": "Nitro PDF Pro", + "unique_identifier": "com.gonitro.NitroPDFPro", + "token": "nitro-pdf-pro", + "installer_format": "dmg", + "slug": "nitro-pdf-pro/darwin", + "default_categories": [ + "Productivity" + ] +} \ No newline at end of file diff --git a/ee/maintained-apps/inputs/homebrew/nocturnal.json b/ee/maintained-apps/inputs/homebrew/nocturnal.json new file mode 100644 index 00000000000..3922af8e442 --- /dev/null +++ b/ee/maintained-apps/inputs/homebrew/nocturnal.json @@ -0,0 +1,10 @@ +{ + "name": "Nocturnal", + "unique_identifier": "com.harshilshah.nocturnal", + "token": "nocturnal", + "installer_format": "zip", + "slug": "nocturnal/darwin", + "default_categories": [ + "Productivity" + ] +} \ No newline at end of file diff --git a/ee/maintained-apps/inputs/homebrew/nordlayer.json b/ee/maintained-apps/inputs/homebrew/nordlayer.json new file mode 100644 index 00000000000..e34234bf7cc --- /dev/null +++ b/ee/maintained-apps/inputs/homebrew/nordlayer.json @@ -0,0 +1,10 @@ +{ + "name": "NordLayer", + "unique_identifier": "com.nordvpn.macos.teams", + "token": "nordlayer", + "installer_format": "pkg", + "slug": "nordlayer/darwin", + "default_categories": [ + "Productivity" + ] +} \ No newline at end of file diff --git a/ee/maintained-apps/inputs/homebrew/nosql-workbench.json b/ee/maintained-apps/inputs/homebrew/nosql-workbench.json new file mode 100644 index 00000000000..64780426e39 --- /dev/null +++ b/ee/maintained-apps/inputs/homebrew/nosql-workbench.json @@ -0,0 +1,10 @@ +{ + "name": "NoSQL Workbench", + "unique_identifier": "com.dynamodb.workbench", + "token": "nosql-workbench", + "installer_format": "dmg", + "slug": "nosql-workbench/darwin", + "default_categories": [ + "Developer tools" + ] +} \ No newline at end of file diff --git a/ee/maintained-apps/inputs/homebrew/notchnook.json b/ee/maintained-apps/inputs/homebrew/notchnook.json new file mode 100644 index 00000000000..91fd77e7f83 --- /dev/null +++ b/ee/maintained-apps/inputs/homebrew/notchnook.json @@ -0,0 +1,10 @@ +{ + "name": "NotchNook", + "unique_identifier": "lo.cafe.NotchNook", + "token": "notchnook", + "installer_format": "zip", + "slug": "notchnook/darwin", + "default_categories": [ + "Utilities" + ] +} \ No newline at end of file diff --git a/ee/maintained-apps/inputs/homebrew/notepadexe.json b/ee/maintained-apps/inputs/homebrew/notepadexe.json new file mode 100644 index 00000000000..2c5b92cf3b7 --- /dev/null +++ b/ee/maintained-apps/inputs/homebrew/notepadexe.json @@ -0,0 +1,10 @@ +{ + "name": "Notepad.exe", + "unique_identifier": "best.swift.Notepad", + "token": "notepadexe", + "installer_format": "zip", + "slug": "notepadexe/darwin", + "default_categories": [ + "Developer tools" + ] +} \ No newline at end of file diff --git a/ee/maintained-apps/inputs/homebrew/notesnook.json b/ee/maintained-apps/inputs/homebrew/notesnook.json new file mode 100644 index 00000000000..50ee7944761 --- /dev/null +++ b/ee/maintained-apps/inputs/homebrew/notesnook.json @@ -0,0 +1,10 @@ +{ + "name": "Notesnook", + "unique_identifier": "com.streetwriters.notesnook", + "token": "notesnook", + "installer_format": "dmg", + "slug": "notesnook/darwin", + "default_categories": [ + "Productivity" + ] +} \ No newline at end of file diff --git a/ee/maintained-apps/inputs/homebrew/notesollama.json b/ee/maintained-apps/inputs/homebrew/notesollama.json new file mode 100644 index 00000000000..f7ba212532a --- /dev/null +++ b/ee/maintained-apps/inputs/homebrew/notesollama.json @@ -0,0 +1,10 @@ +{ + "name": "NotesOllama", + "unique_identifier": "app.smallest.NotesOllama", + "token": "notesollama", + "installer_format": "zip", + "slug": "notesollama/darwin", + "default_categories": [ + "Productivity" + ] +} \ No newline at end of file diff --git a/ee/maintained-apps/inputs/homebrew/noun-project.json b/ee/maintained-apps/inputs/homebrew/noun-project.json new file mode 100644 index 00000000000..9fe6e683b61 --- /dev/null +++ b/ee/maintained-apps/inputs/homebrew/noun-project.json @@ -0,0 +1,10 @@ +{ + "name": "Noun Project", + "unique_identifier": "com.thenounproject.Noun-Project", + "token": "noun-project", + "installer_format": "dmg", + "slug": "noun-project/darwin", + "default_categories": [ + "Productivity" + ] +} \ No newline at end of file diff --git a/ee/maintained-apps/inputs/homebrew/novabench.json b/ee/maintained-apps/inputs/homebrew/novabench.json new file mode 100644 index 00000000000..ce64e35516c --- /dev/null +++ b/ee/maintained-apps/inputs/homebrew/novabench.json @@ -0,0 +1,10 @@ +{ + "name": "Novabench", + "unique_identifier": "com.novabench.client", + "token": "novabench", + "installer_format": "dmg", + "slug": "novabench/darwin", + "default_categories": [ + "Productivity" + ] +} \ No newline at end of file diff --git a/ee/maintained-apps/inputs/homebrew/nucleo.json b/ee/maintained-apps/inputs/homebrew/nucleo.json new file mode 100644 index 00000000000..fc162ca5e81 --- /dev/null +++ b/ee/maintained-apps/inputs/homebrew/nucleo.json @@ -0,0 +1,10 @@ +{ + "name": "Nucleo", + "unique_identifier": "co.ambercreative.nucleo", + "token": "nucleo", + "installer_format": "zip", + "slug": "nucleo/darwin", + "default_categories": [ + "Productivity" + ] +} \ No newline at end of file diff --git a/ee/maintained-apps/inputs/homebrew/numi.json b/ee/maintained-apps/inputs/homebrew/numi.json new file mode 100644 index 00000000000..07d857d31e1 --- /dev/null +++ b/ee/maintained-apps/inputs/homebrew/numi.json @@ -0,0 +1,10 @@ +{ + "name": "Numi", + "unique_identifier": "com.dmitrynikolaev.numi", + "token": "numi", + "installer_format": "dmg", + "slug": "numi/darwin", + "default_categories": [ + "Productivity" + ] +} \ No newline at end of file diff --git a/ee/maintained-apps/inputs/homebrew/nvidia-geforce-now.json b/ee/maintained-apps/inputs/homebrew/nvidia-geforce-now.json new file mode 100644 index 00000000000..a1638aefe28 --- /dev/null +++ b/ee/maintained-apps/inputs/homebrew/nvidia-geforce-now.json @@ -0,0 +1,10 @@ +{ + "name": "NVIDIA GeForce NOW", + "unique_identifier": "com.nvidia.gfnpc.mall", + "token": "nvidia-geforce-now", + "installer_format": "dmg", + "slug": "nvidia-geforce-now/darwin", + "default_categories": [ + "Productivity" + ] +} \ No newline at end of file diff --git a/ee/maintained-apps/outputs/apps.json b/ee/maintained-apps/outputs/apps.json index 228902acd2c..592090a4a77 100644 --- a/ee/maintained-apps/outputs/apps.json +++ b/ee/maintained-apps/outputs/apps.json @@ -4348,6 +4348,41 @@ "unique_identifier": "MySQL Workbench", "description": "MySQL Workbench is a visual tool to design, develop and administer MySQL servers." }, + { + "name": "Nagstamon", + "slug": "nagstamon/darwin", + "platform": "darwin", + "unique_identifier": "de.nagstamon", + "description": "Nagstamon is a nagios status monitor." + }, + { + "name": "Name Mangler", + "slug": "name-mangler/darwin", + "platform": "darwin", + "unique_identifier": "com.manytricks.NameMangler", + "description": "Name Mangler is a multi-file renaming tool." + }, + { + "name": "NAPS2", + "slug": "naps2/darwin", + "platform": "darwin", + "unique_identifier": "com.naps2.desktop", + "description": "NAPS2 is a document scanning application." + }, + { + "name": "NDI Tools", + "slug": "ndi-tools/darwin", + "platform": "darwin", + "unique_identifier": "com.newtek.Application-Mac-NDI-ScanConverter", + "description": "NDI Tools is a set of tools and plugins for NDI." + }, + { + "name": "NeoFinder", + "slug": "neofinder/darwin", + "platform": "darwin", + "unique_identifier": "de.wfs-apps.neofinder", + "description": "NeoFinder is a digital media asset manager." + }, { "name": "Nessus Agent", "slug": "nessus-agent/windows", @@ -4355,6 +4390,41 @@ "unique_identifier": "Nessus Agent (x64)", "description": "Nessus Agent is a lightweight agent that performs local vulnerability and compliance scans and reports the results to Tenable Nessus Manager or Tenable Vulnerability Management." }, + { + "name": "Netiquette", + "slug": "netiquette/darwin", + "platform": "darwin", + "unique_identifier": "com.objective-see.Netiquette", + "description": "Netiquette is a network monitor." + }, + { + "name": "NetNewsWire", + "slug": "netnewswire/darwin", + "platform": "darwin", + "unique_identifier": "com.ranchero.NetNewsWire-Evergreen", + "description": "NetNewsWire is a free and open-source RSS reader." + }, + { + "name": "Netron", + "slug": "netron/darwin", + "platform": "darwin", + "unique_identifier": "com.lutzroeder.netron", + "description": "Netron is a visualiser for neural network, deep learning, and machine learning models." + }, + { + "name": "NetSpot", + "slug": "netspot/darwin", + "platform": "darwin", + "unique_identifier": "com.etwok.netspotwifi", + "description": "NetSpot is a WiFi site survey software and WiFi scanner." + }, + { + "name": "Nextcloud Talk Desktop", + "slug": "nextcloud-talk/darwin", + "platform": "darwin", + "unique_identifier": "com.nextcloud.talk.mac", + "description": "Nextcloud Talk Desktop is an official Nextcloud Talk Desktop client." + }, { "name": "Nextcloud", "slug": "nextcloud/darwin", @@ -4369,6 +4439,27 @@ "unique_identifier": "Nextcloud", "description": "Nextcloud is a self-hosted file sync and sharing platform that provides secure access to your data across devices with collaboration features." }, + { + "name": "Nightfall", + "slug": "nightfall/darwin", + "platform": "darwin", + "unique_identifier": "net.ryanthomson.Nightfall", + "description": "Nightfall is a menu bar utility for toggling dark mode." + }, + { + "name": "Nitro PDF Pro", + "slug": "nitro-pdf-pro/darwin", + "platform": "darwin", + "unique_identifier": "com.gonitro.NitroPDFPro", + "description": "Nitro PDF Pro is a PDF editing software." + }, + { + "name": "Nocturnal", + "slug": "nocturnal/darwin", + "platform": "darwin", + "unique_identifier": "com.harshilshah.nocturnal", + "description": "Nocturnal is a simple app to toggle dark mode with one click." + }, { "name": "Node.js", "slug": "nodejs/windows", @@ -4376,6 +4467,13 @@ "unique_identifier": "Node.js", "description": "Node.js is a cross-platform JavaScript runtime environment for running JavaScript outside the browser." }, + { + "name": "NordLayer", + "slug": "nordlayer/darwin", + "platform": "darwin", + "unique_identifier": "com.nordvpn.macos.teams", + "description": "NordLayer is a security software for business." + }, { "name": "NordPass", "slug": "nordpass/darwin", @@ -4404,6 +4502,20 @@ "unique_identifier": "NordVPN", "description": "NordVPN is a commercial VPN service." }, + { + "name": "NoSQL Workbench", + "slug": "nosql-workbench/darwin", + "platform": "darwin", + "unique_identifier": "com.dynamodb.workbench", + "description": "NoSQL Workbench is a client-side GUI application for modern database development and operations." + }, + { + "name": "NotchNook", + "slug": "notchnook/darwin", + "platform": "darwin", + "unique_identifier": "lo.cafe.NotchNook", + "description": "NotchNook is a handy utility to manage and customize the notch area." + }, { "name": "Notepad++", "slug": "notepad++/windows", @@ -4411,6 +4523,27 @@ "unique_identifier": "Notepad++", "description": "Notepad++ is a text editor for Windows." }, + { + "name": "Notepad.exe", + "slug": "notepadexe/darwin", + "platform": "darwin", + "unique_identifier": "best.swift.Notepad", + "description": "Notepad.exe is a lightweight code editor." + }, + { + "name": "Notesnook", + "slug": "notesnook/darwin", + "platform": "darwin", + "unique_identifier": "com.streetwriters.notesnook", + "description": "Notesnook is a privacy-focused note taking app." + }, + { + "name": "NotesOllama", + "slug": "notesollama/darwin", + "platform": "darwin", + "unique_identifier": "app.smallest.NotesOllama", + "description": "NotesOllama is a LLM support for Apple Notes through Ollama." + }, { "name": "Notion Calendar", "slug": "notion-calendar/darwin", @@ -4439,6 +4572,13 @@ "unique_identifier": "Notion 6.1.0", "description": "Notion is an all-in-one workspace for writing, planning, collaborating, and organizing." }, + { + "name": "Noun Project", + "slug": "noun-project/darwin", + "platform": "darwin", + "unique_identifier": "com.thenounproject.Noun-Project", + "description": "Noun Project is an icon manager." + }, { "name": "Nova", "slug": "nova/darwin", @@ -4446,6 +4586,20 @@ "unique_identifier": "com.panic.Nova", "description": "Nova is a native code editor by Panic." }, + { + "name": "Novabench", + "slug": "novabench/darwin", + "platform": "darwin", + "unique_identifier": "com.novabench.client", + "description": "Novabench is a benchmark tool to quickly test and compare the computer's performance." + }, + { + "name": "Nucleo", + "slug": "nucleo/darwin", + "platform": "darwin", + "unique_identifier": "co.ambercreative.nucleo", + "description": "Nucleo is an icon manager and library." + }, { "name": "Nudge", "slug": "nudge/darwin", @@ -4453,6 +4607,20 @@ "unique_identifier": "com.github.macadmins.Nudge", "description": "Nudge is an application for enforcing OS updates." }, + { + "name": "Numi", + "slug": "numi/darwin", + "platform": "darwin", + "unique_identifier": "com.dmitrynikolaev.numi", + "description": "Numi is a calculator and converter application." + }, + { + "name": "NVIDIA GeForce NOW", + "slug": "nvidia-geforce-now/darwin", + "platform": "darwin", + "unique_identifier": "com.nvidia.gfnpc.mall", + "description": "NVIDIA GeForce NOW is a cloud gaming platform." + }, { "name": "OBS", "slug": "obs/darwin", diff --git a/ee/maintained-apps/outputs/nagstamon/darwin.json b/ee/maintained-apps/outputs/nagstamon/darwin.json new file mode 100644 index 00000000000..9ba7ffffa1a --- /dev/null +++ b/ee/maintained-apps/outputs/nagstamon/darwin.json @@ -0,0 +1,22 @@ +{ + "versions": [ + { + "version": "3.18.2", + "queries": { + "exists": "SELECT 1 FROM apps WHERE bundle_identifier = 'de.nagstamon';", + "patched": "SELECT 1 WHERE NOT EXISTS (SELECT 1 FROM apps WHERE bundle_identifier = 'de.nagstamon' AND version_compare(bundle_short_version, '3.18.2') < 0);" + }, + "installer_url": "https://github.com/HenriWahl/Nagstamon/releases/download/v3.18.2/Nagstamon-3.18.2-ARM.dmg", + "install_script_ref": "aa257dc5", + "uninstall_script_ref": "f7cf5eb1", + "sha256": "c15cc9002635cc26e6ee496ab6b89ff3f453b9b9697f40a4b9bfa042a07772c7", + "default_categories": [ + "Productivity" + ] + } + ], + "refs": { + "aa257dc5": "#!/bin/bash\n\n# variables\nAPPDIR=\"/Applications/\"\nTMPDIR=$(dirname \"$(realpath \"$INSTALLER_PATH\")\")\n# functions\n\nquit_and_track_application() {\n local bundle_id=\"$1\"\n local var_name=\"APP_WAS_RUNNING_$(echo \"$bundle_id\" | tr '.-' '__')\"\n local timeout_duration=10\n\n # check if the application is running\n local app_running\n app_running=$(osascript -e \"application id \\\"$bundle_id\\\" is running\" 2>/dev/null)\n if [[ \"$app_running\" != \"true\" ]]; then\n eval \"export $var_name=0\"\n return\n fi\n\n local console_user\n console_user=$(stat -f \"%Su\" /dev/console)\n if [[ -z \"$console_user\" || \"$console_user\" == \"root\" || \"$console_user\" == \"loginwindow\" ]]; then\n echo \"Not logged into a non-root GUI; skipping quitting application ID '$bundle_id'.\"\n eval \"export $var_name=0\"\n return\n fi\n\n # App was running, mark it for relaunch\n eval \"export $var_name=1\"\n echo \"Application '$bundle_id' was running; will relaunch after installation.\"\n\n echo \"Quitting application '$bundle_id'...\"\n\n # try to quit the application within the timeout period\n local quit_success=false\n SECONDS=0\n while (( SECONDS < timeout_duration )); do\n if osascript -e \"tell application id \\\"$bundle_id\\\" to quit\" >/dev/null 2>&1; then\n if ! pgrep -f \"$bundle_id\" >/dev/null 2>&1; then\n echo \"Application '$bundle_id' quit successfully.\"\n quit_success=true\n break\n fi\n fi\n sleep 1\n done\n\n if [[ \"$quit_success\" = false ]]; then\n echo \"Application '$bundle_id' did not quit.\"\n fi\n}\n\n\nrelaunch_application() {\n local bundle_id=\"$1\"\n local var_name=\"APP_WAS_RUNNING_$(echo \"$bundle_id\" | tr '.-' '__')\"\n local was_running\n\n # Check if the app was running before installation\n eval \"was_running=\\$$var_name\"\n if [[ \"$was_running\" != \"1\" ]]; then\n return\n fi\n\n local console_user\n console_user=$(stat -f \"%Su\" /dev/console)\n if [[ -z \"$console_user\" || \"$console_user\" == \"root\" || \"$console_user\" == \"loginwindow\" ]]; then\n echo \"Not logged into a non-root GUI; skipping relaunching application ID '$bundle_id'.\"\n return\n fi\n\n echo \"Relaunching application '$bundle_id'...\"\n\n # Launch the app in the logged-in user's GUI session. Apps launched by root\n # won't register with the user's Dock/GUI, so run 'open' as the console user.\n # Use 'launchctl asuser' to bootstrap into the console user's Mach namespace\n # and GUI session — 'sudo -u' alone doesn't do this, which can cause\n # LSOpenURLsWithRole() failures even when 'open' exits 0.\n local open_status=0\n if [[ $EUID -eq 0 ]]; then\n local console_uid\n console_uid=$(id -u \"$console_user\")\n /bin/launchctl asuser \"$console_uid\" sudo -u \"$console_user\" open -b \"$bundle_id\" >/dev/null 2>&1 || open_status=$?\n else\n open -b \"$bundle_id\" >/dev/null 2>&1 || open_status=$?\n fi\n\n if [[ $open_status -eq 0 ]]; then\n echo \"Application '$bundle_id' relaunched successfully.\"\n else\n echo \"Failed to relaunch application '$bundle_id'.\"\n fi\n}\n\n\n# extract contents\nMOUNT_POINT=$(mktemp -d /tmp/dmg_mount_XXXXXX)\nyes | hdiutil attach -plist -nobrowse -readonly -mountpoint \"$MOUNT_POINT\" \"$INSTALLER_PATH\" || exit 1\nsudo cp -R \"$MOUNT_POINT\"/* \"$TMPDIR\"\nhdiutil detach \"$MOUNT_POINT\" || true\n# copy to the applications folder\nquit_and_track_application 'de.nagstamon'\nif [ -d \"$APPDIR/Nagstamon.app\" ]; then\n\tsudo mv \"$APPDIR/Nagstamon.app\" \"$TMPDIR/Nagstamon.app.bkp\"\nfi\nsudo cp -R \"$TMPDIR/Nagstamon.app\" \"$APPDIR\"\nrelaunch_application 'de.nagstamon'\n", + "f7cf5eb1": "#!/bin/bash\n\n# variables\nAPPDIR=\"/Applications/\"\nLOGGED_IN_USER=$(scutil <<< \"show State:/Users/ConsoleUser\" | awk '/Name :/ { print $3 }')\n# functions\n\ntrash() {\n local logged_in_user=\"$1\"\n local target_file=\"$2\"\n local timestamp=\"$(date +%Y-%m-%d-%s)\"\n local rand=\"$(jot -r 1 0 99999)\"\n\n # replace ~ with /Users/$logged_in_user\n if [[ \"$target_file\" == ~* ]]; then\n target_file=\"/Users/$logged_in_user${target_file:1}\"\n fi\n\n local trash=\"/Users/$logged_in_user/.Trash\"\n\n # If the target contains glob characters, expand it and move each match.\n if [[ \"$target_file\" == *[*?[]* ]]; then\n local file file_name\n local matched=false\n local i=0\n # compgen -G expands the (quoted) pattern itself, so paths containing\n # spaces glob correctly; reading line by line keeps each match intact.\n while IFS= read -r file; do\n [[ -n \"$file\" ]] || continue\n [[ -e \"$file\" || -L \"$file\" ]] || continue\n matched=true\n i=$((i + 1))\n file_name=\"$(basename \"$file\")\"\n echo \"removing $file.\"\n # The per-match counter keeps matches that share a basename from\n # overwriting each other in the trash.\n mv -f \"$file\" \"$trash/${file_name}_${timestamp}_${rand}_${i}\"\n done < <(compgen -G \"$target_file\" 2>/dev/null)\n if [[ \"$matched\" == false ]]; then\n echo \"$target_file doesn't exist.\"\n fi\n return\n fi\n\n local file_name=\"$(basename \"${target_file}\")\"\n\n if [[ -e \"$target_file\" ]]; then\n echo \"removing $target_file.\"\n mv -f \"$target_file\" \"$trash/${file_name}_${timestamp}_${rand}\"\n else\n echo \"$target_file doesn't exist.\"\n fi\n}\n\nsudo rm -rf \"$APPDIR/Nagstamon.app\"\ntrash $LOGGED_IN_USER '~/.nagstamon'\n" + } +} diff --git a/ee/maintained-apps/outputs/name-mangler/darwin.json b/ee/maintained-apps/outputs/name-mangler/darwin.json new file mode 100644 index 00000000000..5fe6bdfa032 --- /dev/null +++ b/ee/maintained-apps/outputs/name-mangler/darwin.json @@ -0,0 +1,22 @@ +{ + "versions": [ + { + "version": "3.9.3", + "queries": { + "exists": "SELECT 1 FROM apps WHERE bundle_identifier = 'com.manytricks.NameMangler';", + "patched": "SELECT 1 WHERE NOT EXISTS (SELECT 1 FROM apps WHERE bundle_identifier = 'com.manytricks.NameMangler' AND version_compare(bundle_short_version, '3.9.3') < 0);" + }, + "installer_url": "https://manytricks.com/download/_do_not_hotlink_/namemangler393.dmg", + "install_script_ref": "64d42878", + "uninstall_script_ref": "2e15983f", + "sha256": "97cb71af1145bb5b7bec59d7350f3542c554db2569508fb159785ee370578b5f", + "default_categories": [ + "Productivity" + ] + } + ], + "refs": { + "2e15983f": "#!/bin/bash\n\n# variables\nAPPDIR=\"/Applications/\"\nLOGGED_IN_USER=$(scutil <<< \"show State:/Users/ConsoleUser\" | awk '/Name :/ { print $3 }')\n# functions\n\ntrash() {\n local logged_in_user=\"$1\"\n local target_file=\"$2\"\n local timestamp=\"$(date +%Y-%m-%d-%s)\"\n local rand=\"$(jot -r 1 0 99999)\"\n\n # replace ~ with /Users/$logged_in_user\n if [[ \"$target_file\" == ~* ]]; then\n target_file=\"/Users/$logged_in_user${target_file:1}\"\n fi\n\n local trash=\"/Users/$logged_in_user/.Trash\"\n\n # If the target contains glob characters, expand it and move each match.\n if [[ \"$target_file\" == *[*?[]* ]]; then\n local file file_name\n local matched=false\n local i=0\n # compgen -G expands the (quoted) pattern itself, so paths containing\n # spaces glob correctly; reading line by line keeps each match intact.\n while IFS= read -r file; do\n [[ -n \"$file\" ]] || continue\n [[ -e \"$file\" || -L \"$file\" ]] || continue\n matched=true\n i=$((i + 1))\n file_name=\"$(basename \"$file\")\"\n echo \"removing $file.\"\n # The per-match counter keeps matches that share a basename from\n # overwriting each other in the trash.\n mv -f \"$file\" \"$trash/${file_name}_${timestamp}_${rand}_${i}\"\n done < <(compgen -G \"$target_file\" 2>/dev/null)\n if [[ \"$matched\" == false ]]; then\n echo \"$target_file doesn't exist.\"\n fi\n return\n fi\n\n local file_name=\"$(basename \"${target_file}\")\"\n\n if [[ -e \"$target_file\" ]]; then\n echo \"removing $target_file.\"\n mv -f \"$target_file\" \"$trash/${file_name}_${timestamp}_${rand}\"\n else\n echo \"$target_file doesn't exist.\"\n fi\n}\n\nsudo rm -rf \"$APPDIR/Name Mangler.app\"\ntrash $LOGGED_IN_USER '~/Library/Application Support/Name Mangler'\ntrash $LOGGED_IN_USER '~/Library/Preferences/com.manytricks.NameMangler.plist'\n", + "64d42878": "#!/bin/bash\n\n# variables\nAPPDIR=\"/Applications/\"\nTMPDIR=$(dirname \"$(realpath \"$INSTALLER_PATH\")\")\n# functions\n\nquit_and_track_application() {\n local bundle_id=\"$1\"\n local var_name=\"APP_WAS_RUNNING_$(echo \"$bundle_id\" | tr '.-' '__')\"\n local timeout_duration=10\n\n # check if the application is running\n local app_running\n app_running=$(osascript -e \"application id \\\"$bundle_id\\\" is running\" 2>/dev/null)\n if [[ \"$app_running\" != \"true\" ]]; then\n eval \"export $var_name=0\"\n return\n fi\n\n local console_user\n console_user=$(stat -f \"%Su\" /dev/console)\n if [[ -z \"$console_user\" || \"$console_user\" == \"root\" || \"$console_user\" == \"loginwindow\" ]]; then\n echo \"Not logged into a non-root GUI; skipping quitting application ID '$bundle_id'.\"\n eval \"export $var_name=0\"\n return\n fi\n\n # App was running, mark it for relaunch\n eval \"export $var_name=1\"\n echo \"Application '$bundle_id' was running; will relaunch after installation.\"\n\n echo \"Quitting application '$bundle_id'...\"\n\n # try to quit the application within the timeout period\n local quit_success=false\n SECONDS=0\n while (( SECONDS < timeout_duration )); do\n if osascript -e \"tell application id \\\"$bundle_id\\\" to quit\" >/dev/null 2>&1; then\n if ! pgrep -f \"$bundle_id\" >/dev/null 2>&1; then\n echo \"Application '$bundle_id' quit successfully.\"\n quit_success=true\n break\n fi\n fi\n sleep 1\n done\n\n if [[ \"$quit_success\" = false ]]; then\n echo \"Application '$bundle_id' did not quit.\"\n fi\n}\n\n\nrelaunch_application() {\n local bundle_id=\"$1\"\n local var_name=\"APP_WAS_RUNNING_$(echo \"$bundle_id\" | tr '.-' '__')\"\n local was_running\n\n # Check if the app was running before installation\n eval \"was_running=\\$$var_name\"\n if [[ \"$was_running\" != \"1\" ]]; then\n return\n fi\n\n local console_user\n console_user=$(stat -f \"%Su\" /dev/console)\n if [[ -z \"$console_user\" || \"$console_user\" == \"root\" || \"$console_user\" == \"loginwindow\" ]]; then\n echo \"Not logged into a non-root GUI; skipping relaunching application ID '$bundle_id'.\"\n return\n fi\n\n echo \"Relaunching application '$bundle_id'...\"\n\n # Launch the app in the logged-in user's GUI session. Apps launched by root\n # won't register with the user's Dock/GUI, so run 'open' as the console user.\n # Use 'launchctl asuser' to bootstrap into the console user's Mach namespace\n # and GUI session — 'sudo -u' alone doesn't do this, which can cause\n # LSOpenURLsWithRole() failures even when 'open' exits 0.\n local open_status=0\n if [[ $EUID -eq 0 ]]; then\n local console_uid\n console_uid=$(id -u \"$console_user\")\n /bin/launchctl asuser \"$console_uid\" sudo -u \"$console_user\" open -b \"$bundle_id\" >/dev/null 2>&1 || open_status=$?\n else\n open -b \"$bundle_id\" >/dev/null 2>&1 || open_status=$?\n fi\n\n if [[ $open_status -eq 0 ]]; then\n echo \"Application '$bundle_id' relaunched successfully.\"\n else\n echo \"Failed to relaunch application '$bundle_id'.\"\n fi\n}\n\n\n# extract contents\nMOUNT_POINT=$(mktemp -d /tmp/dmg_mount_XXXXXX)\nyes | hdiutil attach -plist -nobrowse -readonly -mountpoint \"$MOUNT_POINT\" \"$INSTALLER_PATH\" || exit 1\nsudo cp -R \"$MOUNT_POINT\"/* \"$TMPDIR\"\nhdiutil detach \"$MOUNT_POINT\" || true\n# copy to the applications folder\nquit_and_track_application 'com.manytricks.NameMangler'\nif [ -d \"$APPDIR/Name Mangler.app\" ]; then\n\tsudo mv \"$APPDIR/Name Mangler.app\" \"$TMPDIR/Name Mangler.app.bkp\"\nfi\nsudo cp -R \"$TMPDIR/Name Mangler.app\" \"$APPDIR\"\nrelaunch_application 'com.manytricks.NameMangler'\n" + } +} diff --git a/ee/maintained-apps/outputs/naps2/darwin.json b/ee/maintained-apps/outputs/naps2/darwin.json new file mode 100644 index 00000000000..1f44b8b4274 --- /dev/null +++ b/ee/maintained-apps/outputs/naps2/darwin.json @@ -0,0 +1,22 @@ +{ + "versions": [ + { + "version": "8.2.1", + "queries": { + "exists": "SELECT 1 FROM apps WHERE bundle_identifier = 'com.naps2.desktop';", + "patched": "SELECT 1 WHERE NOT EXISTS (SELECT 1 FROM apps WHERE bundle_identifier = 'com.naps2.desktop' AND version_compare(bundle_short_version, '8.2.1') < 0);" + }, + "installer_url": "https://github.com/cyanfish/naps2/releases/download/v8.2.1/naps2-8.2.1-mac-arm64.pkg", + "install_script_ref": "9af11ffc", + "uninstall_script_ref": "c24aa768", + "sha256": "4a40e0d1a717714bf12615325acbb938737962c076fc6d83007d973f3b241a4f", + "default_categories": [ + "Productivity" + ] + } + ], + "refs": { + "9af11ffc": "#!/bin/bash\n\n# variables\nAPPDIR=\"/Applications/\"\nTMPDIR=$(dirname \"$(realpath \"$INSTALLER_PATH\")\")\n# functions\n\nquit_and_track_application() {\n local bundle_id=\"$1\"\n local var_name=\"APP_WAS_RUNNING_$(echo \"$bundle_id\" | tr '.-' '__')\"\n local timeout_duration=10\n\n # check if the application is running\n local app_running\n app_running=$(osascript -e \"application id \\\"$bundle_id\\\" is running\" 2>/dev/null)\n if [[ \"$app_running\" != \"true\" ]]; then\n eval \"export $var_name=0\"\n return\n fi\n\n local console_user\n console_user=$(stat -f \"%Su\" /dev/console)\n if [[ -z \"$console_user\" || \"$console_user\" == \"root\" || \"$console_user\" == \"loginwindow\" ]]; then\n echo \"Not logged into a non-root GUI; skipping quitting application ID '$bundle_id'.\"\n eval \"export $var_name=0\"\n return\n fi\n\n # App was running, mark it for relaunch\n eval \"export $var_name=1\"\n echo \"Application '$bundle_id' was running; will relaunch after installation.\"\n\n echo \"Quitting application '$bundle_id'...\"\n\n # try to quit the application within the timeout period\n local quit_success=false\n SECONDS=0\n while (( SECONDS < timeout_duration )); do\n if osascript -e \"tell application id \\\"$bundle_id\\\" to quit\" >/dev/null 2>&1; then\n if ! pgrep -f \"$bundle_id\" >/dev/null 2>&1; then\n echo \"Application '$bundle_id' quit successfully.\"\n quit_success=true\n break\n fi\n fi\n sleep 1\n done\n\n if [[ \"$quit_success\" = false ]]; then\n echo \"Application '$bundle_id' did not quit.\"\n fi\n}\n\n\nrelaunch_application() {\n local bundle_id=\"$1\"\n local var_name=\"APP_WAS_RUNNING_$(echo \"$bundle_id\" | tr '.-' '__')\"\n local was_running\n\n # Check if the app was running before installation\n eval \"was_running=\\$$var_name\"\n if [[ \"$was_running\" != \"1\" ]]; then\n return\n fi\n\n local console_user\n console_user=$(stat -f \"%Su\" /dev/console)\n if [[ -z \"$console_user\" || \"$console_user\" == \"root\" || \"$console_user\" == \"loginwindow\" ]]; then\n echo \"Not logged into a non-root GUI; skipping relaunching application ID '$bundle_id'.\"\n return\n fi\n\n echo \"Relaunching application '$bundle_id'...\"\n\n # Launch the app in the logged-in user's GUI session. Apps launched by root\n # won't register with the user's Dock/GUI, so run 'open' as the console user.\n # Use 'launchctl asuser' to bootstrap into the console user's Mach namespace\n # and GUI session — 'sudo -u' alone doesn't do this, which can cause\n # LSOpenURLsWithRole() failures even when 'open' exits 0.\n local open_status=0\n if [[ $EUID -eq 0 ]]; then\n local console_uid\n console_uid=$(id -u \"$console_user\")\n /bin/launchctl asuser \"$console_uid\" sudo -u \"$console_user\" open -b \"$bundle_id\" >/dev/null 2>&1 || open_status=$?\n else\n open -b \"$bundle_id\" >/dev/null 2>&1 || open_status=$?\n fi\n\n if [[ $open_status -eq 0 ]]; then\n echo \"Application '$bundle_id' relaunched successfully.\"\n else\n echo \"Failed to relaunch application '$bundle_id'.\"\n fi\n}\n\n\n# install pkg files\nquit_and_track_application 'com.naps2.desktop'\nsudo installer -pkg \"$TMPDIR/naps2-8.2.1-mac-arm64.pkg\" -target /\nrelaunch_application 'com.naps2.desktop'\n", + "c24aa768": "#!/bin/bash\n\n# variables\nLOGGED_IN_USER=$(scutil <<< \"show State:/Users/ConsoleUser\" | awk '/Name :/ { print $3 }')\n# functions\n\nexpand_pkgid_and_map() {\n local PKGID=\"$1\"\n local FUNC=\"$2\"\n if [[ \"$PKGID\" == *\"*\" ]]; then\n local prefix=\"${PKGID%\\*}\"\n echo \"Expanding wildcard for PKGID: $PKGID\"\n for receipt in $(pkgutil --pkgs | grep \"^${prefix}\"); do\n echo \"Processing $receipt\"\n \"$FUNC\" \"$receipt\"\n done\n else\n \"$FUNC\" \"$PKGID\"\n fi\n}\n\nforget_pkg() {\n local PKGID=\"$1\"\n expand_pkgid_and_map \"$PKGID\" forget_receipt\n}\n\nforget_receipt() {\n local PKGID=\"$1\"\n sudo pkgutil --forget \"$PKGID\"\n}\n\nremove_pkg_files() {\n local PKGID=\"$1\"\n expand_pkgid_and_map \"$PKGID\" remove_receipt_files\n}\n\nremove_receipt_files() {\n local PKGID=\"$1\"\n local PKGINFO VOLUME INSTALL_LOCATION FULL_INSTALL_LOCATION\n\n echo \"pkgutil --pkg-info-plist \\\"$PKGID\\\"\"\n PKGINFO=$(pkgutil --pkg-info-plist \"$PKGID\")\n VOLUME=$(echo \"$PKGINFO\" | awk '/volume<\\/key>/ {getline; gsub(/.*|<\\/string>.*/, \"\"); print}')\n INSTALL_LOCATION=$(echo \"$PKGINFO\" | awk '/install-location<\\/key>/ {getline; gsub(/.*|<\\/string>.*/, \"\"); print}')\n\n if [ -z \"$INSTALL_LOCATION\" ] || [ \"$INSTALL_LOCATION\" = \"/\" ]; then\n FULL_INSTALL_LOCATION=\"$VOLUME\"\n else\n FULL_INSTALL_LOCATION=\"$VOLUME/$INSTALL_LOCATION\"\n FULL_INSTALL_LOCATION=$(echo \"$FULL_INSTALL_LOCATION\" | sed 's|//|/|g')\n fi\n\n echo \"sudo pkgutil --only-files --files \\\"$PKGID\\\" | sed \\\"s|^|${FULL_INSTALL_LOCATION}/|\\\" | tr '\\\\\\\\n' '\\\\\\\\0' | /usr/bin/sudo -u root -E -- /usr/bin/xargs -0 -- /bin/rm -rf\"\n sudo pkgutil --only-files --files \"$PKGID\" | sed \"s|^|/${INSTALL_LOCATION}/|\" | tr '\\n' '\\0' | /usr/bin/sudo -u root -E -- /usr/bin/xargs -0 -- /bin/rm -rf\n\n echo \"sudo pkgutil --only-dirs --files \\\"$PKGID\\\" | sed \\\"s|^|${FULL_INSTALL_LOCATION}/|\\\" | grep '\\\\.app$' | tr '\\\\\\\\n' '\\\\\\\\0' | /usr/bin/sudo -u root -E -- /usr/bin/xargs -0 -- /bin/rm -rf\"\n sudo pkgutil --only-dirs --files \"$PKGID\" | sed \"s|^|${FULL_INSTALL_LOCATION}/|\" | grep '\\.app$' | tr '\\n' '\\0' | /usr/bin/sudo -u root -E -- /usr/bin/xargs -0 -- /bin/rm -rf\n\n root_app_dir=$(\n sudo pkgutil --only-dirs --files \"$PKGID\" \\\n | sed \"s|^|${FULL_INSTALL_LOCATION}/|\" \\\n | grep 'Applications' \\\n | awk '{ print length, $0 }' \\\n | sort -n \\\n | head -n1 \\\n | cut -d' ' -f2-\n )\n if [ -n \"$root_app_dir\" ]; then\n echo \"sudo rmdir -p \\\"$root_app_dir\\\" 2>/dev/null || :\"\n sudo rmdir -p \"$root_app_dir\" 2>/dev/null || :\n fi\n}\n\ntrash() {\n local logged_in_user=\"$1\"\n local target_file=\"$2\"\n local timestamp=\"$(date +%Y-%m-%d-%s)\"\n local rand=\"$(jot -r 1 0 99999)\"\n\n # replace ~ with /Users/$logged_in_user\n if [[ \"$target_file\" == ~* ]]; then\n target_file=\"/Users/$logged_in_user${target_file:1}\"\n fi\n\n local trash=\"/Users/$logged_in_user/.Trash\"\n\n # If the target contains glob characters, expand it and move each match.\n if [[ \"$target_file\" == *[*?[]* ]]; then\n local file file_name\n local matched=false\n local i=0\n # compgen -G expands the (quoted) pattern itself, so paths containing\n # spaces glob correctly; reading line by line keeps each match intact.\n while IFS= read -r file; do\n [[ -n \"$file\" ]] || continue\n [[ -e \"$file\" || -L \"$file\" ]] || continue\n matched=true\n i=$((i + 1))\n file_name=\"$(basename \"$file\")\"\n echo \"removing $file.\"\n # The per-match counter keeps matches that share a basename from\n # overwriting each other in the trash.\n mv -f \"$file\" \"$trash/${file_name}_${timestamp}_${rand}_${i}\"\n done < <(compgen -G \"$target_file\" 2>/dev/null)\n if [[ \"$matched\" == false ]]; then\n echo \"$target_file doesn't exist.\"\n fi\n return\n fi\n\n local file_name=\"$(basename \"${target_file}\")\"\n\n if [[ -e \"$target_file\" ]]; then\n echo \"removing $target_file.\"\n mv -f \"$target_file\" \"$trash/${file_name}_${timestamp}_${rand}\"\n else\n echo \"$target_file doesn't exist.\"\n fi\n}\n\nremove_pkg_files 'com.naps2.desktop'\nforget_pkg 'com.naps2.desktop'\ntrash $LOGGED_IN_USER '~/.config/NAPS2'\ntrash $LOGGED_IN_USER '~/Library/Preferences/com.naps2.desktop.plist'\ntrash $LOGGED_IN_USER '~/Library/Saved Application State/com.naps2.desktop.savedState'\n" + } +} diff --git a/ee/maintained-apps/outputs/ndi-tools/darwin.json b/ee/maintained-apps/outputs/ndi-tools/darwin.json new file mode 100644 index 00000000000..cf72d5b7b34 --- /dev/null +++ b/ee/maintained-apps/outputs/ndi-tools/darwin.json @@ -0,0 +1,22 @@ +{ + "versions": [ + { + "version": "6.3.2.0", + "queries": { + "exists": "SELECT 1 FROM apps WHERE bundle_identifier = 'com.newtek.Application-Mac-NDI-ScanConverter';", + "patched": "SELECT 1 WHERE NOT EXISTS (SELECT 1 FROM apps WHERE bundle_identifier = 'com.newtek.Application-Mac-NDI-ScanConverter' AND version_compare(bundle_short_version, '6.3.2.0') < 0);" + }, + "installer_url": "https://downloads.ndi.tv/Tools/NDIToolsInstaller.pkg", + "install_script_ref": "fe7a9384", + "uninstall_script_ref": "55c6908f", + "sha256": "no_check", + "default_categories": [ + "Productivity" + ] + } + ], + "refs": { + "55c6908f": "#!/bin/bash\n\n# variables\nLOGGED_IN_USER=$(scutil <<< \"show State:/Users/ConsoleUser\" | awk '/Name :/ { print $3 }')\n# functions\n\nexpand_pkgid_and_map() {\n local PKGID=\"$1\"\n local FUNC=\"$2\"\n if [[ \"$PKGID\" == *\"*\" ]]; then\n local prefix=\"${PKGID%\\*}\"\n echo \"Expanding wildcard for PKGID: $PKGID\"\n for receipt in $(pkgutil --pkgs | grep \"^${prefix}\"); do\n echo \"Processing $receipt\"\n \"$FUNC\" \"$receipt\"\n done\n else\n \"$FUNC\" \"$PKGID\"\n fi\n}\n\nforget_pkg() {\n local PKGID=\"$1\"\n expand_pkgid_and_map \"$PKGID\" forget_receipt\n}\n\nforget_receipt() {\n local PKGID=\"$1\"\n sudo pkgutil --forget \"$PKGID\"\n}\n\nremove_launchctl_service() {\n local service=\"$1\"\n local booleans=(\"true\" \"false\")\n local plist_status\n local paths\n local should_sudo\n\n echo \"Removing launchctl service ${service}\"\n\n for should_sudo in \"${booleans[@]}\"; do\n plist_status=$(launchctl list \"${service}\" 2>/dev/null)\n\n if [[ $plist_status == \\{* ]]; then\n if [[ $should_sudo == \"true\" ]]; then\n sudo launchctl remove \"${service}\"\n else\n launchctl remove \"${service}\"\n fi\n sleep 1\n fi\n\n paths=(\n \"/Library/LaunchAgents/${service}.plist\"\n \"/Library/LaunchDaemons/${service}.plist\"\n )\n\n # if not using sudo, prepend the home directory to the paths\n if [[ $should_sudo == \"false\" ]]; then\n for i in \"${!paths[@]}\"; do\n paths[i]=\"${HOME}${paths[i]}\"\n done\n fi\n\n for path in \"${paths[@]}\"; do\n if [[ -e \"$path\" ]]; then\n if [[ $should_sudo == \"true\" ]]; then\n sudo rm -f -- \"$path\"\n else\n rm -f -- \"$path\"\n fi\n fi\n done\n done\n}\n\nremove_pkg_files() {\n local PKGID=\"$1\"\n expand_pkgid_and_map \"$PKGID\" remove_receipt_files\n}\n\nremove_receipt_files() {\n local PKGID=\"$1\"\n local PKGINFO VOLUME INSTALL_LOCATION FULL_INSTALL_LOCATION\n\n echo \"pkgutil --pkg-info-plist \\\"$PKGID\\\"\"\n PKGINFO=$(pkgutil --pkg-info-plist \"$PKGID\")\n VOLUME=$(echo \"$PKGINFO\" | awk '/volume<\\/key>/ {getline; gsub(/.*|<\\/string>.*/, \"\"); print}')\n INSTALL_LOCATION=$(echo \"$PKGINFO\" | awk '/install-location<\\/key>/ {getline; gsub(/.*|<\\/string>.*/, \"\"); print}')\n\n if [ -z \"$INSTALL_LOCATION\" ] || [ \"$INSTALL_LOCATION\" = \"/\" ]; then\n FULL_INSTALL_LOCATION=\"$VOLUME\"\n else\n FULL_INSTALL_LOCATION=\"$VOLUME/$INSTALL_LOCATION\"\n FULL_INSTALL_LOCATION=$(echo \"$FULL_INSTALL_LOCATION\" | sed 's|//|/|g')\n fi\n\n echo \"sudo pkgutil --only-files --files \\\"$PKGID\\\" | sed \\\"s|^|${FULL_INSTALL_LOCATION}/|\\\" | tr '\\\\\\\\n' '\\\\\\\\0' | /usr/bin/sudo -u root -E -- /usr/bin/xargs -0 -- /bin/rm -rf\"\n sudo pkgutil --only-files --files \"$PKGID\" | sed \"s|^|/${INSTALL_LOCATION}/|\" | tr '\\n' '\\0' | /usr/bin/sudo -u root -E -- /usr/bin/xargs -0 -- /bin/rm -rf\n\n echo \"sudo pkgutil --only-dirs --files \\\"$PKGID\\\" | sed \\\"s|^|${FULL_INSTALL_LOCATION}/|\\\" | grep '\\\\.app$' | tr '\\\\\\\\n' '\\\\\\\\0' | /usr/bin/sudo -u root -E -- /usr/bin/xargs -0 -- /bin/rm -rf\"\n sudo pkgutil --only-dirs --files \"$PKGID\" | sed \"s|^|${FULL_INSTALL_LOCATION}/|\" | grep '\\.app$' | tr '\\n' '\\0' | /usr/bin/sudo -u root -E -- /usr/bin/xargs -0 -- /bin/rm -rf\n\n root_app_dir=$(\n sudo pkgutil --only-dirs --files \"$PKGID\" \\\n | sed \"s|^|${FULL_INSTALL_LOCATION}/|\" \\\n | grep 'Applications' \\\n | awk '{ print length, $0 }' \\\n | sort -n \\\n | head -n1 \\\n | cut -d' ' -f2-\n )\n if [ -n \"$root_app_dir\" ]; then\n echo \"sudo rmdir -p \\\"$root_app_dir\\\" 2>/dev/null || :\"\n sudo rmdir -p \"$root_app_dir\" 2>/dev/null || :\n fi\n}\n\ntrash() {\n local logged_in_user=\"$1\"\n local target_file=\"$2\"\n local timestamp=\"$(date +%Y-%m-%d-%s)\"\n local rand=\"$(jot -r 1 0 99999)\"\n\n # replace ~ with /Users/$logged_in_user\n if [[ \"$target_file\" == ~* ]]; then\n target_file=\"/Users/$logged_in_user${target_file:1}\"\n fi\n\n local trash=\"/Users/$logged_in_user/.Trash\"\n\n # If the target contains glob characters, expand it and move each match.\n if [[ \"$target_file\" == *[*?[]* ]]; then\n local file file_name\n local matched=false\n local i=0\n # compgen -G expands the (quoted) pattern itself, so paths containing\n # spaces glob correctly; reading line by line keeps each match intact.\n while IFS= read -r file; do\n [[ -n \"$file\" ]] || continue\n [[ -e \"$file\" || -L \"$file\" ]] || continue\n matched=true\n i=$((i + 1))\n file_name=\"$(basename \"$file\")\"\n echo \"removing $file.\"\n # The per-match counter keeps matches that share a basename from\n # overwriting each other in the trash.\n mv -f \"$file\" \"$trash/${file_name}_${timestamp}_${rand}_${i}\"\n done < <(compgen -G \"$target_file\" 2>/dev/null)\n if [[ \"$matched\" == false ]]; then\n echo \"$target_file doesn't exist.\"\n fi\n return\n fi\n\n local file_name=\"$(basename \"${target_file}\")\"\n\n if [[ -e \"$target_file\" ]]; then\n echo \"removing $target_file.\"\n mv -f \"$target_file\" \"$trash/${file_name}_${timestamp}_${rand}\"\n else\n echo \"$target_file doesn't exist.\"\n fi\n}\n\nremove_launchctl_service 'com.newtek.cmio.DPA.NDI'\nremove_pkg_files 'com.newtek.Application-Mac-NDI-AccessManager'\nforget_pkg 'com.newtek.Application-Mac-NDI-AccessManager'\nremove_pkg_files 'com.newtek.Application-Mac-NDI-ScanConverter'\nforget_pkg 'com.newtek.Application-Mac-NDI-ScanConverter'\nremove_pkg_files 'com.newtek.Application-Mac-NDI-StudioMonitor'\nforget_pkg 'com.newtek.Application-Mac-NDI-StudioMonitor'\nremove_pkg_files 'com.newtek.Application-Mac-NDI-VirtualInput'\nforget_pkg 'com.newtek.Application-Mac-NDI-VirtualInput'\nremove_pkg_files 'com.newtek.DAL.NDIplugin'\nforget_pkg 'com.newtek.DAL.NDIplugin'\nremove_pkg_files 'com.newtek.DAL.NDIpluginlaunchdaemon'\nforget_pkg 'com.newtek.DAL.NDIpluginlaunchdaemon'\nremove_pkg_files 'com.newtek.driver.NDIAudio'\nforget_pkg 'com.newtek.driver.NDIAudio'\nremove_pkg_files 'com.newtek.HAL.NDIaudioplugin'\nforget_pkg 'com.newtek.HAL.NDIaudioplugin'\nremove_pkg_files 'com.newtek.NDI-HX-Driver'\nforget_pkg 'com.newtek.NDI-HX-Driver'\nremove_pkg_files 'com.newtek.NDI-Tools'\nforget_pkg 'com.newtek.NDI-Tools'\nremove_pkg_files 'com.newtek.NDI-Transmit-AdobeCC'\nforget_pkg 'com.newtek.NDI-Transmit-AdobeCC'\nremove_pkg_files 'com.newtek.NDI.prefpane'\nforget_pkg 'com.newtek.NDI.prefpane'\nremove_pkg_files 'com.newtek.ndi.recording'\nforget_pkg 'com.newtek.ndi.recording'\nremove_pkg_files 'com.newtek.ndidiscovery'\nforget_pkg 'com.newtek.ndidiscovery'\nremove_pkg_files 'com.newtek.NDIRouter'\nforget_pkg 'com.newtek.NDIRouter'\nremove_pkg_files 'com.newtek.NDIVirtualCamera'\nforget_pkg 'com.newtek.NDIVirtualCamera'\nremove_pkg_files 'com.newtek.NewTek-Import-SpeedHQ'\nforget_pkg 'com.newtek.NewTek-Import-SpeedHQ'\nremove_pkg_files 'com.newtek.Test-Patterns-Mac-'\nforget_pkg 'com.newtek.Test-Patterns-Mac-'\ntrash $LOGGED_IN_USER '/Library/Application Support/NewTek'\ntrash $LOGGED_IN_USER '/Library/LaunchDaemons/com.newtek.cmio.DPA.NDI.plist'\ntrash $LOGGED_IN_USER '~/Library/Caches/com.newtek.NDI-Tools'\ntrash $LOGGED_IN_USER '~/Library/Preferences/com.newtek.Application-Mac-NDI-ScanConverter.plist'\ntrash $LOGGED_IN_USER '~/Library/Preferences/com.newtek.Application-Mac-NDI-StudioMonitor.plist'\ntrash $LOGGED_IN_USER '~/Library/Preferences/com.newtek.NDI-Tools.plist'\ntrash $LOGGED_IN_USER '~/Library/Preferences/com.newtek.Test-Patterns-Mac-.plist'\ntrash $LOGGED_IN_USER '~/Library/WebKit/com.newtek.NDI-Tools'\n", + "fe7a9384": "#!/bin/bash\n\n# variables\nAPPDIR=\"/Applications/\"\nTMPDIR=$(dirname \"$(realpath \"$INSTALLER_PATH\")\")\n# functions\n\nquit_and_track_application() {\n local bundle_id=\"$1\"\n local var_name=\"APP_WAS_RUNNING_$(echo \"$bundle_id\" | tr '.-' '__')\"\n local timeout_duration=10\n\n # check if the application is running\n local app_running\n app_running=$(osascript -e \"application id \\\"$bundle_id\\\" is running\" 2>/dev/null)\n if [[ \"$app_running\" != \"true\" ]]; then\n eval \"export $var_name=0\"\n return\n fi\n\n local console_user\n console_user=$(stat -f \"%Su\" /dev/console)\n if [[ -z \"$console_user\" || \"$console_user\" == \"root\" || \"$console_user\" == \"loginwindow\" ]]; then\n echo \"Not logged into a non-root GUI; skipping quitting application ID '$bundle_id'.\"\n eval \"export $var_name=0\"\n return\n fi\n\n # App was running, mark it for relaunch\n eval \"export $var_name=1\"\n echo \"Application '$bundle_id' was running; will relaunch after installation.\"\n\n echo \"Quitting application '$bundle_id'...\"\n\n # try to quit the application within the timeout period\n local quit_success=false\n SECONDS=0\n while (( SECONDS < timeout_duration )); do\n if osascript -e \"tell application id \\\"$bundle_id\\\" to quit\" >/dev/null 2>&1; then\n if ! pgrep -f \"$bundle_id\" >/dev/null 2>&1; then\n echo \"Application '$bundle_id' quit successfully.\"\n quit_success=true\n break\n fi\n fi\n sleep 1\n done\n\n if [[ \"$quit_success\" = false ]]; then\n echo \"Application '$bundle_id' did not quit.\"\n fi\n}\n\n\nrelaunch_application() {\n local bundle_id=\"$1\"\n local var_name=\"APP_WAS_RUNNING_$(echo \"$bundle_id\" | tr '.-' '__')\"\n local was_running\n\n # Check if the app was running before installation\n eval \"was_running=\\$$var_name\"\n if [[ \"$was_running\" != \"1\" ]]; then\n return\n fi\n\n local console_user\n console_user=$(stat -f \"%Su\" /dev/console)\n if [[ -z \"$console_user\" || \"$console_user\" == \"root\" || \"$console_user\" == \"loginwindow\" ]]; then\n echo \"Not logged into a non-root GUI; skipping relaunching application ID '$bundle_id'.\"\n return\n fi\n\n echo \"Relaunching application '$bundle_id'...\"\n\n # Launch the app in the logged-in user's GUI session. Apps launched by root\n # won't register with the user's Dock/GUI, so run 'open' as the console user.\n # Use 'launchctl asuser' to bootstrap into the console user's Mach namespace\n # and GUI session — 'sudo -u' alone doesn't do this, which can cause\n # LSOpenURLsWithRole() failures even when 'open' exits 0.\n local open_status=0\n if [[ $EUID -eq 0 ]]; then\n local console_uid\n console_uid=$(id -u \"$console_user\")\n /bin/launchctl asuser \"$console_uid\" sudo -u \"$console_user\" open -b \"$bundle_id\" >/dev/null 2>&1 || open_status=$?\n else\n open -b \"$bundle_id\" >/dev/null 2>&1 || open_status=$?\n fi\n\n if [[ $open_status -eq 0 ]]; then\n echo \"Application '$bundle_id' relaunched successfully.\"\n else\n echo \"Failed to relaunch application '$bundle_id'.\"\n fi\n}\n\n\n# install pkg files\nquit_and_track_application 'com.newtek.Application-Mac-NDI-ScanConverter'\nsudo installer -pkg \"$TMPDIR/NDIToolsInstaller.pkg\" -target /\nrelaunch_application 'com.newtek.Application-Mac-NDI-ScanConverter'\n" + } +} diff --git a/ee/maintained-apps/outputs/neofinder/darwin.json b/ee/maintained-apps/outputs/neofinder/darwin.json new file mode 100644 index 00000000000..52d7ae8b8c5 --- /dev/null +++ b/ee/maintained-apps/outputs/neofinder/darwin.json @@ -0,0 +1,22 @@ +{ + "versions": [ + { + "version": "9.2.1", + "queries": { + "exists": "SELECT 1 FROM apps WHERE bundle_identifier = 'de.wfs-apps.neofinder';", + "patched": "SELECT 1 WHERE NOT EXISTS (SELECT 1 FROM apps WHERE bundle_identifier = 'de.wfs-apps.neofinder' AND version_compare(bundle_short_version, '9.2.1') < 0);" + }, + "installer_url": "https://www.wfs-apps.de/updates/neofinder-mac.9.2.1.zip", + "install_script_ref": "586a3071", + "uninstall_script_ref": "eaee82d4", + "sha256": "a59758e0189ffc6488af92d4ed50a30077cbc4cf804520eddf8b24a6eca4a4d7", + "default_categories": [ + "Productivity" + ] + } + ], + "refs": { + "586a3071": "#!/bin/bash\n\n# variables\nAPPDIR=\"/Applications/\"\nTMPDIR=$(dirname \"$(realpath \"$INSTALLER_PATH\")\")\n# functions\n\nquit_and_track_application() {\n local bundle_id=\"$1\"\n local var_name=\"APP_WAS_RUNNING_$(echo \"$bundle_id\" | tr '.-' '__')\"\n local timeout_duration=10\n\n # check if the application is running\n local app_running\n app_running=$(osascript -e \"application id \\\"$bundle_id\\\" is running\" 2>/dev/null)\n if [[ \"$app_running\" != \"true\" ]]; then\n eval \"export $var_name=0\"\n return\n fi\n\n local console_user\n console_user=$(stat -f \"%Su\" /dev/console)\n if [[ -z \"$console_user\" || \"$console_user\" == \"root\" || \"$console_user\" == \"loginwindow\" ]]; then\n echo \"Not logged into a non-root GUI; skipping quitting application ID '$bundle_id'.\"\n eval \"export $var_name=0\"\n return\n fi\n\n # App was running, mark it for relaunch\n eval \"export $var_name=1\"\n echo \"Application '$bundle_id' was running; will relaunch after installation.\"\n\n echo \"Quitting application '$bundle_id'...\"\n\n # try to quit the application within the timeout period\n local quit_success=false\n SECONDS=0\n while (( SECONDS < timeout_duration )); do\n if osascript -e \"tell application id \\\"$bundle_id\\\" to quit\" >/dev/null 2>&1; then\n if ! pgrep -f \"$bundle_id\" >/dev/null 2>&1; then\n echo \"Application '$bundle_id' quit successfully.\"\n quit_success=true\n break\n fi\n fi\n sleep 1\n done\n\n if [[ \"$quit_success\" = false ]]; then\n echo \"Application '$bundle_id' did not quit.\"\n fi\n}\n\n\nrelaunch_application() {\n local bundle_id=\"$1\"\n local var_name=\"APP_WAS_RUNNING_$(echo \"$bundle_id\" | tr '.-' '__')\"\n local was_running\n\n # Check if the app was running before installation\n eval \"was_running=\\$$var_name\"\n if [[ \"$was_running\" != \"1\" ]]; then\n return\n fi\n\n local console_user\n console_user=$(stat -f \"%Su\" /dev/console)\n if [[ -z \"$console_user\" || \"$console_user\" == \"root\" || \"$console_user\" == \"loginwindow\" ]]; then\n echo \"Not logged into a non-root GUI; skipping relaunching application ID '$bundle_id'.\"\n return\n fi\n\n echo \"Relaunching application '$bundle_id'...\"\n\n # Launch the app in the logged-in user's GUI session. Apps launched by root\n # won't register with the user's Dock/GUI, so run 'open' as the console user.\n # Use 'launchctl asuser' to bootstrap into the console user's Mach namespace\n # and GUI session — 'sudo -u' alone doesn't do this, which can cause\n # LSOpenURLsWithRole() failures even when 'open' exits 0.\n local open_status=0\n if [[ $EUID -eq 0 ]]; then\n local console_uid\n console_uid=$(id -u \"$console_user\")\n /bin/launchctl asuser \"$console_uid\" sudo -u \"$console_user\" open -b \"$bundle_id\" >/dev/null 2>&1 || open_status=$?\n else\n open -b \"$bundle_id\" >/dev/null 2>&1 || open_status=$?\n fi\n\n if [[ $open_status -eq 0 ]]; then\n echo \"Application '$bundle_id' relaunched successfully.\"\n else\n echo \"Failed to relaunch application '$bundle_id'.\"\n fi\n}\n\n\n# extract contents\nunzip \"$INSTALLER_PATH\" -d \"$TMPDIR\"\n# copy to the applications folder\nquit_and_track_application 'de.wfs-apps.neofinder'\nif [ -d \"$APPDIR/NeoFinder.app\" ]; then\n\tsudo mv \"$APPDIR/NeoFinder.app\" \"$TMPDIR/NeoFinder.app.bkp\"\nfi\nsudo cp -R \"$TMPDIR/NeoFinder.app\" \"$APPDIR\"\nrelaunch_application 'de.wfs-apps.neofinder'\n", + "eaee82d4": "#!/bin/bash\n\n# variables\nAPPDIR=\"/Applications/\"\nLOGGED_IN_USER=$(scutil <<< \"show State:/Users/ConsoleUser\" | awk '/Name :/ { print $3 }')\n# functions\n\ntrash() {\n local logged_in_user=\"$1\"\n local target_file=\"$2\"\n local timestamp=\"$(date +%Y-%m-%d-%s)\"\n local rand=\"$(jot -r 1 0 99999)\"\n\n # replace ~ with /Users/$logged_in_user\n if [[ \"$target_file\" == ~* ]]; then\n target_file=\"/Users/$logged_in_user${target_file:1}\"\n fi\n\n local trash=\"/Users/$logged_in_user/.Trash\"\n\n # If the target contains glob characters, expand it and move each match.\n if [[ \"$target_file\" == *[*?[]* ]]; then\n local file file_name\n local matched=false\n local i=0\n # compgen -G expands the (quoted) pattern itself, so paths containing\n # spaces glob correctly; reading line by line keeps each match intact.\n while IFS= read -r file; do\n [[ -n \"$file\" ]] || continue\n [[ -e \"$file\" || -L \"$file\" ]] || continue\n matched=true\n i=$((i + 1))\n file_name=\"$(basename \"$file\")\"\n echo \"removing $file.\"\n # The per-match counter keeps matches that share a basename from\n # overwriting each other in the trash.\n mv -f \"$file\" \"$trash/${file_name}_${timestamp}_${rand}_${i}\"\n done < <(compgen -G \"$target_file\" 2>/dev/null)\n if [[ \"$matched\" == false ]]; then\n echo \"$target_file doesn't exist.\"\n fi\n return\n fi\n\n local file_name=\"$(basename \"${target_file}\")\"\n\n if [[ -e \"$target_file\" ]]; then\n echo \"removing $target_file.\"\n mv -f \"$target_file\" \"$trash/${file_name}_${timestamp}_${rand}\"\n else\n echo \"$target_file doesn't exist.\"\n fi\n}\n\nsudo rm -rf \"$APPDIR/NeoFinder.app\"\ntrash $LOGGED_IN_USER '~/Library/Application Support/CrashReporter/NeoFinder_*'\ntrash $LOGGED_IN_USER '~/Library/Application Support/NeoFinder'\ntrash $LOGGED_IN_USER '~/Library/Caches/de.wfs-apps.neofinder'\ntrash $LOGGED_IN_USER '~/Library/Caches/de.wfs-apps.neofinder.quicklaunch.cache'\ntrash $LOGGED_IN_USER '~/Library/Preferences/de.wfs-apps.neofinder.plist'\ntrash $LOGGED_IN_USER '~/Library/Preferences/de.wfs-apps.neofinder.statusBar.plist'\n" + } +} diff --git a/ee/maintained-apps/outputs/netiquette/darwin.json b/ee/maintained-apps/outputs/netiquette/darwin.json new file mode 100644 index 00000000000..2de06427190 --- /dev/null +++ b/ee/maintained-apps/outputs/netiquette/darwin.json @@ -0,0 +1,22 @@ +{ + "versions": [ + { + "version": "2.3.0", + "queries": { + "exists": "SELECT 1 FROM apps WHERE bundle_identifier = 'com.objective-see.Netiquette';", + "patched": "SELECT 1 WHERE NOT EXISTS (SELECT 1 FROM apps WHERE bundle_identifier = 'com.objective-see.Netiquette' AND version_compare(bundle_short_version, '2.3.0') < 0);" + }, + "installer_url": "https://github.com/objective-see/Netiquette/releases/download/v2.3.0/Netiquette_2.3.0.zip", + "install_script_ref": "ca3eff9a", + "uninstall_script_ref": "bc67cd1b", + "sha256": "e204ac0c268942b9005f4f17be78b97a7b2d3b19803330d432c196021a0e8d4a", + "default_categories": [ + "Productivity" + ] + } + ], + "refs": { + "bc67cd1b": "#!/bin/bash\n\n# variables\nAPPDIR=\"/Applications/\"\nLOGGED_IN_USER=$(scutil <<< \"show State:/Users/ConsoleUser\" | awk '/Name :/ { print $3 }')\n# functions\n\ntrash() {\n local logged_in_user=\"$1\"\n local target_file=\"$2\"\n local timestamp=\"$(date +%Y-%m-%d-%s)\"\n local rand=\"$(jot -r 1 0 99999)\"\n\n # replace ~ with /Users/$logged_in_user\n if [[ \"$target_file\" == ~* ]]; then\n target_file=\"/Users/$logged_in_user${target_file:1}\"\n fi\n\n local trash=\"/Users/$logged_in_user/.Trash\"\n\n # If the target contains glob characters, expand it and move each match.\n if [[ \"$target_file\" == *[*?[]* ]]; then\n local file file_name\n local matched=false\n local i=0\n # compgen -G expands the (quoted) pattern itself, so paths containing\n # spaces glob correctly; reading line by line keeps each match intact.\n while IFS= read -r file; do\n [[ -n \"$file\" ]] || continue\n [[ -e \"$file\" || -L \"$file\" ]] || continue\n matched=true\n i=$((i + 1))\n file_name=\"$(basename \"$file\")\"\n echo \"removing $file.\"\n # The per-match counter keeps matches that share a basename from\n # overwriting each other in the trash.\n mv -f \"$file\" \"$trash/${file_name}_${timestamp}_${rand}_${i}\"\n done < <(compgen -G \"$target_file\" 2>/dev/null)\n if [[ \"$matched\" == false ]]; then\n echo \"$target_file doesn't exist.\"\n fi\n return\n fi\n\n local file_name=\"$(basename \"${target_file}\")\"\n\n if [[ -e \"$target_file\" ]]; then\n echo \"removing $target_file.\"\n mv -f \"$target_file\" \"$trash/${file_name}_${timestamp}_${rand}\"\n else\n echo \"$target_file doesn't exist.\"\n fi\n}\n\nsudo rm -rf \"$APPDIR/Netiquette.app\"\ntrash $LOGGED_IN_USER '~/Library/Caches/com.objective-see.Netiquette'\ntrash $LOGGED_IN_USER '~/Library/Preferences/com.objective-see.Netiquette.plist'\n", + "ca3eff9a": "#!/bin/bash\n\n# variables\nAPPDIR=\"/Applications/\"\nTMPDIR=$(dirname \"$(realpath \"$INSTALLER_PATH\")\")\n# functions\n\nquit_and_track_application() {\n local bundle_id=\"$1\"\n local var_name=\"APP_WAS_RUNNING_$(echo \"$bundle_id\" | tr '.-' '__')\"\n local timeout_duration=10\n\n # check if the application is running\n local app_running\n app_running=$(osascript -e \"application id \\\"$bundle_id\\\" is running\" 2>/dev/null)\n if [[ \"$app_running\" != \"true\" ]]; then\n eval \"export $var_name=0\"\n return\n fi\n\n local console_user\n console_user=$(stat -f \"%Su\" /dev/console)\n if [[ -z \"$console_user\" || \"$console_user\" == \"root\" || \"$console_user\" == \"loginwindow\" ]]; then\n echo \"Not logged into a non-root GUI; skipping quitting application ID '$bundle_id'.\"\n eval \"export $var_name=0\"\n return\n fi\n\n # App was running, mark it for relaunch\n eval \"export $var_name=1\"\n echo \"Application '$bundle_id' was running; will relaunch after installation.\"\n\n echo \"Quitting application '$bundle_id'...\"\n\n # try to quit the application within the timeout period\n local quit_success=false\n SECONDS=0\n while (( SECONDS < timeout_duration )); do\n if osascript -e \"tell application id \\\"$bundle_id\\\" to quit\" >/dev/null 2>&1; then\n if ! pgrep -f \"$bundle_id\" >/dev/null 2>&1; then\n echo \"Application '$bundle_id' quit successfully.\"\n quit_success=true\n break\n fi\n fi\n sleep 1\n done\n\n if [[ \"$quit_success\" = false ]]; then\n echo \"Application '$bundle_id' did not quit.\"\n fi\n}\n\n\nrelaunch_application() {\n local bundle_id=\"$1\"\n local var_name=\"APP_WAS_RUNNING_$(echo \"$bundle_id\" | tr '.-' '__')\"\n local was_running\n\n # Check if the app was running before installation\n eval \"was_running=\\$$var_name\"\n if [[ \"$was_running\" != \"1\" ]]; then\n return\n fi\n\n local console_user\n console_user=$(stat -f \"%Su\" /dev/console)\n if [[ -z \"$console_user\" || \"$console_user\" == \"root\" || \"$console_user\" == \"loginwindow\" ]]; then\n echo \"Not logged into a non-root GUI; skipping relaunching application ID '$bundle_id'.\"\n return\n fi\n\n echo \"Relaunching application '$bundle_id'...\"\n\n # Launch the app in the logged-in user's GUI session. Apps launched by root\n # won't register with the user's Dock/GUI, so run 'open' as the console user.\n # Use 'launchctl asuser' to bootstrap into the console user's Mach namespace\n # and GUI session — 'sudo -u' alone doesn't do this, which can cause\n # LSOpenURLsWithRole() failures even when 'open' exits 0.\n local open_status=0\n if [[ $EUID -eq 0 ]]; then\n local console_uid\n console_uid=$(id -u \"$console_user\")\n /bin/launchctl asuser \"$console_uid\" sudo -u \"$console_user\" open -b \"$bundle_id\" >/dev/null 2>&1 || open_status=$?\n else\n open -b \"$bundle_id\" >/dev/null 2>&1 || open_status=$?\n fi\n\n if [[ $open_status -eq 0 ]]; then\n echo \"Application '$bundle_id' relaunched successfully.\"\n else\n echo \"Failed to relaunch application '$bundle_id'.\"\n fi\n}\n\n\n# extract contents\nunzip \"$INSTALLER_PATH\" -d \"$TMPDIR\"\n# copy to the applications folder\nquit_and_track_application 'com.objective-see.Netiquette'\nif [ -d \"$APPDIR/Netiquette.app\" ]; then\n\tsudo mv \"$APPDIR/Netiquette.app\" \"$TMPDIR/Netiquette.app.bkp\"\nfi\nsudo cp -R \"$TMPDIR/Netiquette.app\" \"$APPDIR\"\nrelaunch_application 'com.objective-see.Netiquette'\n" + } +} diff --git a/ee/maintained-apps/outputs/netnewswire/darwin.json b/ee/maintained-apps/outputs/netnewswire/darwin.json new file mode 100644 index 00000000000..db5aee65673 --- /dev/null +++ b/ee/maintained-apps/outputs/netnewswire/darwin.json @@ -0,0 +1,22 @@ +{ + "versions": [ + { + "version": "7.0.6", + "queries": { + "exists": "SELECT 1 FROM apps WHERE bundle_identifier = 'com.ranchero.NetNewsWire-Evergreen';", + "patched": "SELECT 1 WHERE NOT EXISTS (SELECT 1 FROM apps WHERE bundle_identifier = 'com.ranchero.NetNewsWire-Evergreen' AND version_compare(bundle_short_version, '7.0.6') < 0);" + }, + "installer_url": "https://github.com/Ranchero-Software/NetNewsWire/releases/download/mac-7.0.6/NetNewsWire7.0.6.zip", + "install_script_ref": "9c96cda2", + "uninstall_script_ref": "01498874", + "sha256": "dc43092c01be77a91b745aee1a3483ad701d346b3bde8fc26facc8a0ccdd8ed0", + "default_categories": [ + "Productivity" + ] + } + ], + "refs": { + "01498874": "#!/bin/bash\n\n# variables\nAPPDIR=\"/Applications/\"\nLOGGED_IN_USER=$(scutil <<< \"show State:/Users/ConsoleUser\" | awk '/Name :/ { print $3 }')\n# functions\n\ntrash() {\n local logged_in_user=\"$1\"\n local target_file=\"$2\"\n local timestamp=\"$(date +%Y-%m-%d-%s)\"\n local rand=\"$(jot -r 1 0 99999)\"\n\n # replace ~ with /Users/$logged_in_user\n if [[ \"$target_file\" == ~* ]]; then\n target_file=\"/Users/$logged_in_user${target_file:1}\"\n fi\n\n local trash=\"/Users/$logged_in_user/.Trash\"\n\n # If the target contains glob characters, expand it and move each match.\n if [[ \"$target_file\" == *[*?[]* ]]; then\n local file file_name\n local matched=false\n local i=0\n # compgen -G expands the (quoted) pattern itself, so paths containing\n # spaces glob correctly; reading line by line keeps each match intact.\n while IFS= read -r file; do\n [[ -n \"$file\" ]] || continue\n [[ -e \"$file\" || -L \"$file\" ]] || continue\n matched=true\n i=$((i + 1))\n file_name=\"$(basename \"$file\")\"\n echo \"removing $file.\"\n # The per-match counter keeps matches that share a basename from\n # overwriting each other in the trash.\n mv -f \"$file\" \"$trash/${file_name}_${timestamp}_${rand}_${i}\"\n done < <(compgen -G \"$target_file\" 2>/dev/null)\n if [[ \"$matched\" == false ]]; then\n echo \"$target_file doesn't exist.\"\n fi\n return\n fi\n\n local file_name=\"$(basename \"${target_file}\")\"\n\n if [[ -e \"$target_file\" ]]; then\n echo \"removing $target_file.\"\n mv -f \"$target_file\" \"$trash/${file_name}_${timestamp}_${rand}\"\n else\n echo \"$target_file doesn't exist.\"\n fi\n}\n\nsudo rm -rf \"$APPDIR/NetNewsWire.app\"\ntrash $LOGGED_IN_USER '~/Library/Application Scripts/com.ranchero.NetNewsWire-Evergreen*'\ntrash $LOGGED_IN_USER '~/Library/Application Scripts/group.com.ranchero.NetNewsWire-Evergreen'\ntrash $LOGGED_IN_USER '~/Library/Application Support/NetNewsWire'\ntrash $LOGGED_IN_USER '~/Library/Caches/com.ranchero.NetNewsWire-Evergreen'\ntrash $LOGGED_IN_USER '~/Library/Containers/com.ranchero.NetNewsWire-Evergreen*'\ntrash $LOGGED_IN_USER '~/Library/Group Containers/group.com.ranchero.NetNewsWire-Evergreen'\ntrash $LOGGED_IN_USER '~/Library/Preferences/com.ranchero.NetNewsWire-Evergreen.plist'\ntrash $LOGGED_IN_USER '~/Library/Saved Application State/com.ranchero.NetNewsWire-Evergreen.savedState'\ntrash $LOGGED_IN_USER '~/Library/WebKit/com.ranchero.NetNewsWire-Evergreen'\n", + "9c96cda2": "#!/bin/bash\n\n# variables\nAPPDIR=\"/Applications/\"\nTMPDIR=$(dirname \"$(realpath \"$INSTALLER_PATH\")\")\n# functions\n\nquit_and_track_application() {\n local bundle_id=\"$1\"\n local var_name=\"APP_WAS_RUNNING_$(echo \"$bundle_id\" | tr '.-' '__')\"\n local timeout_duration=10\n\n # check if the application is running\n local app_running\n app_running=$(osascript -e \"application id \\\"$bundle_id\\\" is running\" 2>/dev/null)\n if [[ \"$app_running\" != \"true\" ]]; then\n eval \"export $var_name=0\"\n return\n fi\n\n local console_user\n console_user=$(stat -f \"%Su\" /dev/console)\n if [[ -z \"$console_user\" || \"$console_user\" == \"root\" || \"$console_user\" == \"loginwindow\" ]]; then\n echo \"Not logged into a non-root GUI; skipping quitting application ID '$bundle_id'.\"\n eval \"export $var_name=0\"\n return\n fi\n\n # App was running, mark it for relaunch\n eval \"export $var_name=1\"\n echo \"Application '$bundle_id' was running; will relaunch after installation.\"\n\n echo \"Quitting application '$bundle_id'...\"\n\n # try to quit the application within the timeout period\n local quit_success=false\n SECONDS=0\n while (( SECONDS < timeout_duration )); do\n if osascript -e \"tell application id \\\"$bundle_id\\\" to quit\" >/dev/null 2>&1; then\n if ! pgrep -f \"$bundle_id\" >/dev/null 2>&1; then\n echo \"Application '$bundle_id' quit successfully.\"\n quit_success=true\n break\n fi\n fi\n sleep 1\n done\n\n if [[ \"$quit_success\" = false ]]; then\n echo \"Application '$bundle_id' did not quit.\"\n fi\n}\n\n\nrelaunch_application() {\n local bundle_id=\"$1\"\n local var_name=\"APP_WAS_RUNNING_$(echo \"$bundle_id\" | tr '.-' '__')\"\n local was_running\n\n # Check if the app was running before installation\n eval \"was_running=\\$$var_name\"\n if [[ \"$was_running\" != \"1\" ]]; then\n return\n fi\n\n local console_user\n console_user=$(stat -f \"%Su\" /dev/console)\n if [[ -z \"$console_user\" || \"$console_user\" == \"root\" || \"$console_user\" == \"loginwindow\" ]]; then\n echo \"Not logged into a non-root GUI; skipping relaunching application ID '$bundle_id'.\"\n return\n fi\n\n echo \"Relaunching application '$bundle_id'...\"\n\n # Launch the app in the logged-in user's GUI session. Apps launched by root\n # won't register with the user's Dock/GUI, so run 'open' as the console user.\n # Use 'launchctl asuser' to bootstrap into the console user's Mach namespace\n # and GUI session — 'sudo -u' alone doesn't do this, which can cause\n # LSOpenURLsWithRole() failures even when 'open' exits 0.\n local open_status=0\n if [[ $EUID -eq 0 ]]; then\n local console_uid\n console_uid=$(id -u \"$console_user\")\n /bin/launchctl asuser \"$console_uid\" sudo -u \"$console_user\" open -b \"$bundle_id\" >/dev/null 2>&1 || open_status=$?\n else\n open -b \"$bundle_id\" >/dev/null 2>&1 || open_status=$?\n fi\n\n if [[ $open_status -eq 0 ]]; then\n echo \"Application '$bundle_id' relaunched successfully.\"\n else\n echo \"Failed to relaunch application '$bundle_id'.\"\n fi\n}\n\n\n# extract contents\nunzip \"$INSTALLER_PATH\" -d \"$TMPDIR\"\n# copy to the applications folder\nquit_and_track_application 'com.ranchero.NetNewsWire-Evergreen'\nif [ -d \"$APPDIR/NetNewsWire.app\" ]; then\n\tsudo mv \"$APPDIR/NetNewsWire.app\" \"$TMPDIR/NetNewsWire.app.bkp\"\nfi\nsudo cp -R \"$TMPDIR/NetNewsWire.app\" \"$APPDIR\"\nrelaunch_application 'com.ranchero.NetNewsWire-Evergreen'\n" + } +} diff --git a/ee/maintained-apps/outputs/netron/darwin.json b/ee/maintained-apps/outputs/netron/darwin.json new file mode 100644 index 00000000000..add8efe11d8 --- /dev/null +++ b/ee/maintained-apps/outputs/netron/darwin.json @@ -0,0 +1,22 @@ +{ + "versions": [ + { + "version": "9.1.1", + "queries": { + "exists": "SELECT 1 FROM apps WHERE bundle_identifier = 'com.lutzroeder.netron';", + "patched": "SELECT 1 WHERE NOT EXISTS (SELECT 1 FROM apps WHERE bundle_identifier = 'com.lutzroeder.netron' AND version_compare(bundle_short_version, '9.1.1') < 0);" + }, + "installer_url": "https://github.com/lutzroeder/netron/releases/download/v9.1.1/Netron-9.1.1-mac.zip", + "install_script_ref": "4929401f", + "uninstall_script_ref": "acbbb0d7", + "sha256": "8f2ccd7b4a081b16477a032c512638727a9d37db2b5c19b01adc142063f03e89", + "default_categories": [ + "Productivity" + ] + } + ], + "refs": { + "4929401f": "#!/bin/bash\n\n# variables\nAPPDIR=\"/Applications/\"\nTMPDIR=$(dirname \"$(realpath \"$INSTALLER_PATH\")\")\n# functions\n\nquit_and_track_application() {\n local bundle_id=\"$1\"\n local var_name=\"APP_WAS_RUNNING_$(echo \"$bundle_id\" | tr '.-' '__')\"\n local timeout_duration=10\n\n # check if the application is running\n local app_running\n app_running=$(osascript -e \"application id \\\"$bundle_id\\\" is running\" 2>/dev/null)\n if [[ \"$app_running\" != \"true\" ]]; then\n eval \"export $var_name=0\"\n return\n fi\n\n local console_user\n console_user=$(stat -f \"%Su\" /dev/console)\n if [[ -z \"$console_user\" || \"$console_user\" == \"root\" || \"$console_user\" == \"loginwindow\" ]]; then\n echo \"Not logged into a non-root GUI; skipping quitting application ID '$bundle_id'.\"\n eval \"export $var_name=0\"\n return\n fi\n\n # App was running, mark it for relaunch\n eval \"export $var_name=1\"\n echo \"Application '$bundle_id' was running; will relaunch after installation.\"\n\n echo \"Quitting application '$bundle_id'...\"\n\n # try to quit the application within the timeout period\n local quit_success=false\n SECONDS=0\n while (( SECONDS < timeout_duration )); do\n if osascript -e \"tell application id \\\"$bundle_id\\\" to quit\" >/dev/null 2>&1; then\n if ! pgrep -f \"$bundle_id\" >/dev/null 2>&1; then\n echo \"Application '$bundle_id' quit successfully.\"\n quit_success=true\n break\n fi\n fi\n sleep 1\n done\n\n if [[ \"$quit_success\" = false ]]; then\n echo \"Application '$bundle_id' did not quit.\"\n fi\n}\n\n\nrelaunch_application() {\n local bundle_id=\"$1\"\n local var_name=\"APP_WAS_RUNNING_$(echo \"$bundle_id\" | tr '.-' '__')\"\n local was_running\n\n # Check if the app was running before installation\n eval \"was_running=\\$$var_name\"\n if [[ \"$was_running\" != \"1\" ]]; then\n return\n fi\n\n local console_user\n console_user=$(stat -f \"%Su\" /dev/console)\n if [[ -z \"$console_user\" || \"$console_user\" == \"root\" || \"$console_user\" == \"loginwindow\" ]]; then\n echo \"Not logged into a non-root GUI; skipping relaunching application ID '$bundle_id'.\"\n return\n fi\n\n echo \"Relaunching application '$bundle_id'...\"\n\n # Launch the app in the logged-in user's GUI session. Apps launched by root\n # won't register with the user's Dock/GUI, so run 'open' as the console user.\n # Use 'launchctl asuser' to bootstrap into the console user's Mach namespace\n # and GUI session — 'sudo -u' alone doesn't do this, which can cause\n # LSOpenURLsWithRole() failures even when 'open' exits 0.\n local open_status=0\n if [[ $EUID -eq 0 ]]; then\n local console_uid\n console_uid=$(id -u \"$console_user\")\n /bin/launchctl asuser \"$console_uid\" sudo -u \"$console_user\" open -b \"$bundle_id\" >/dev/null 2>&1 || open_status=$?\n else\n open -b \"$bundle_id\" >/dev/null 2>&1 || open_status=$?\n fi\n\n if [[ $open_status -eq 0 ]]; then\n echo \"Application '$bundle_id' relaunched successfully.\"\n else\n echo \"Failed to relaunch application '$bundle_id'.\"\n fi\n}\n\n\n# extract contents\nunzip \"$INSTALLER_PATH\" -d \"$TMPDIR\"\n# copy to the applications folder\nquit_and_track_application 'com.lutzroeder.netron'\nif [ -d \"$APPDIR/Netron.app\" ]; then\n\tsudo mv \"$APPDIR/Netron.app\" \"$TMPDIR/Netron.app.bkp\"\nfi\nsudo cp -R \"$TMPDIR/Netron.app\" \"$APPDIR\"\nrelaunch_application 'com.lutzroeder.netron'\n", + "acbbb0d7": "#!/bin/bash\n\n# variables\nAPPDIR=\"/Applications/\"\nLOGGED_IN_USER=$(scutil <<< \"show State:/Users/ConsoleUser\" | awk '/Name :/ { print $3 }')\n# functions\n\ntrash() {\n local logged_in_user=\"$1\"\n local target_file=\"$2\"\n local timestamp=\"$(date +%Y-%m-%d-%s)\"\n local rand=\"$(jot -r 1 0 99999)\"\n\n # replace ~ with /Users/$logged_in_user\n if [[ \"$target_file\" == ~* ]]; then\n target_file=\"/Users/$logged_in_user${target_file:1}\"\n fi\n\n local trash=\"/Users/$logged_in_user/.Trash\"\n\n # If the target contains glob characters, expand it and move each match.\n if [[ \"$target_file\" == *[*?[]* ]]; then\n local file file_name\n local matched=false\n local i=0\n # compgen -G expands the (quoted) pattern itself, so paths containing\n # spaces glob correctly; reading line by line keeps each match intact.\n while IFS= read -r file; do\n [[ -n \"$file\" ]] || continue\n [[ -e \"$file\" || -L \"$file\" ]] || continue\n matched=true\n i=$((i + 1))\n file_name=\"$(basename \"$file\")\"\n echo \"removing $file.\"\n # The per-match counter keeps matches that share a basename from\n # overwriting each other in the trash.\n mv -f \"$file\" \"$trash/${file_name}_${timestamp}_${rand}_${i}\"\n done < <(compgen -G \"$target_file\" 2>/dev/null)\n if [[ \"$matched\" == false ]]; then\n echo \"$target_file doesn't exist.\"\n fi\n return\n fi\n\n local file_name=\"$(basename \"${target_file}\")\"\n\n if [[ -e \"$target_file\" ]]; then\n echo \"removing $target_file.\"\n mv -f \"$target_file\" \"$trash/${file_name}_${timestamp}_${rand}\"\n else\n echo \"$target_file doesn't exist.\"\n fi\n}\n\nsudo rm -rf \"$APPDIR/Netron.app\"\ntrash $LOGGED_IN_USER '~/Library/Application Support/Netron'\ntrash $LOGGED_IN_USER '~/Library/Preferences/com.lutzroeder.netron.plist'\ntrash $LOGGED_IN_USER '~/Library/Saved Application State/com.lutzroeder.netron.savedState'\n" + } +} diff --git a/ee/maintained-apps/outputs/netspot/darwin.json b/ee/maintained-apps/outputs/netspot/darwin.json new file mode 100644 index 00000000000..38a70eae17f --- /dev/null +++ b/ee/maintained-apps/outputs/netspot/darwin.json @@ -0,0 +1,22 @@ +{ + "versions": [ + { + "version": "5.1.4971", + "queries": { + "exists": "SELECT 1 FROM apps WHERE bundle_identifier = 'com.etwok.netspotwifi';", + "patched": "SELECT 1 WHERE NOT EXISTS (SELECT 1 FROM apps WHERE bundle_identifier = 'com.etwok.netspotwifi' AND version_compare(bundle_short_version, '5.1.4971') < 0);" + }, + "installer_url": "https://cdn.netspotapp.com/download/NetSpot.dmg", + "install_script_ref": "bf337d03", + "uninstall_script_ref": "65891ee6", + "sha256": "no_check", + "default_categories": [ + "Productivity" + ] + } + ], + "refs": { + "65891ee6": "#!/bin/bash\n\n# variables\nAPPDIR=\"/Applications/\"\nLOGGED_IN_USER=$(scutil <<< \"show State:/Users/ConsoleUser\" | awk '/Name :/ { print $3 }')\n# functions\n\ntrash() {\n local logged_in_user=\"$1\"\n local target_file=\"$2\"\n local timestamp=\"$(date +%Y-%m-%d-%s)\"\n local rand=\"$(jot -r 1 0 99999)\"\n\n # replace ~ with /Users/$logged_in_user\n if [[ \"$target_file\" == ~* ]]; then\n target_file=\"/Users/$logged_in_user${target_file:1}\"\n fi\n\n local trash=\"/Users/$logged_in_user/.Trash\"\n\n # If the target contains glob characters, expand it and move each match.\n if [[ \"$target_file\" == *[*?[]* ]]; then\n local file file_name\n local matched=false\n local i=0\n # compgen -G expands the (quoted) pattern itself, so paths containing\n # spaces glob correctly; reading line by line keeps each match intact.\n while IFS= read -r file; do\n [[ -n \"$file\" ]] || continue\n [[ -e \"$file\" || -L \"$file\" ]] || continue\n matched=true\n i=$((i + 1))\n file_name=\"$(basename \"$file\")\"\n echo \"removing $file.\"\n # The per-match counter keeps matches that share a basename from\n # overwriting each other in the trash.\n mv -f \"$file\" \"$trash/${file_name}_${timestamp}_${rand}_${i}\"\n done < <(compgen -G \"$target_file\" 2>/dev/null)\n if [[ \"$matched\" == false ]]; then\n echo \"$target_file doesn't exist.\"\n fi\n return\n fi\n\n local file_name=\"$(basename \"${target_file}\")\"\n\n if [[ -e \"$target_file\" ]]; then\n echo \"removing $target_file.\"\n mv -f \"$target_file\" \"$trash/${file_name}_${timestamp}_${rand}\"\n else\n echo \"$target_file doesn't exist.\"\n fi\n}\n\nsudo rm -rf \"$APPDIR/NetSpot.app\"\ntrash $LOGGED_IN_USER '~/Library/Application Support/NetSpot'\ntrash $LOGGED_IN_USER '~/Library/Caches/com.etwok.netspotwifi'\ntrash $LOGGED_IN_USER '~/Library/Preferences/com.etwok.netspotwifi.plist'\n", + "bf337d03": "#!/bin/bash\n\n# variables\nAPPDIR=\"/Applications/\"\nTMPDIR=$(dirname \"$(realpath \"$INSTALLER_PATH\")\")\n# functions\n\nquit_and_track_application() {\n local bundle_id=\"$1\"\n local var_name=\"APP_WAS_RUNNING_$(echo \"$bundle_id\" | tr '.-' '__')\"\n local timeout_duration=10\n\n # check if the application is running\n local app_running\n app_running=$(osascript -e \"application id \\\"$bundle_id\\\" is running\" 2>/dev/null)\n if [[ \"$app_running\" != \"true\" ]]; then\n eval \"export $var_name=0\"\n return\n fi\n\n local console_user\n console_user=$(stat -f \"%Su\" /dev/console)\n if [[ -z \"$console_user\" || \"$console_user\" == \"root\" || \"$console_user\" == \"loginwindow\" ]]; then\n echo \"Not logged into a non-root GUI; skipping quitting application ID '$bundle_id'.\"\n eval \"export $var_name=0\"\n return\n fi\n\n # App was running, mark it for relaunch\n eval \"export $var_name=1\"\n echo \"Application '$bundle_id' was running; will relaunch after installation.\"\n\n echo \"Quitting application '$bundle_id'...\"\n\n # try to quit the application within the timeout period\n local quit_success=false\n SECONDS=0\n while (( SECONDS < timeout_duration )); do\n if osascript -e \"tell application id \\\"$bundle_id\\\" to quit\" >/dev/null 2>&1; then\n if ! pgrep -f \"$bundle_id\" >/dev/null 2>&1; then\n echo \"Application '$bundle_id' quit successfully.\"\n quit_success=true\n break\n fi\n fi\n sleep 1\n done\n\n if [[ \"$quit_success\" = false ]]; then\n echo \"Application '$bundle_id' did not quit.\"\n fi\n}\n\n\nrelaunch_application() {\n local bundle_id=\"$1\"\n local var_name=\"APP_WAS_RUNNING_$(echo \"$bundle_id\" | tr '.-' '__')\"\n local was_running\n\n # Check if the app was running before installation\n eval \"was_running=\\$$var_name\"\n if [[ \"$was_running\" != \"1\" ]]; then\n return\n fi\n\n local console_user\n console_user=$(stat -f \"%Su\" /dev/console)\n if [[ -z \"$console_user\" || \"$console_user\" == \"root\" || \"$console_user\" == \"loginwindow\" ]]; then\n echo \"Not logged into a non-root GUI; skipping relaunching application ID '$bundle_id'.\"\n return\n fi\n\n echo \"Relaunching application '$bundle_id'...\"\n\n # Launch the app in the logged-in user's GUI session. Apps launched by root\n # won't register with the user's Dock/GUI, so run 'open' as the console user.\n # Use 'launchctl asuser' to bootstrap into the console user's Mach namespace\n # and GUI session — 'sudo -u' alone doesn't do this, which can cause\n # LSOpenURLsWithRole() failures even when 'open' exits 0.\n local open_status=0\n if [[ $EUID -eq 0 ]]; then\n local console_uid\n console_uid=$(id -u \"$console_user\")\n /bin/launchctl asuser \"$console_uid\" sudo -u \"$console_user\" open -b \"$bundle_id\" >/dev/null 2>&1 || open_status=$?\n else\n open -b \"$bundle_id\" >/dev/null 2>&1 || open_status=$?\n fi\n\n if [[ $open_status -eq 0 ]]; then\n echo \"Application '$bundle_id' relaunched successfully.\"\n else\n echo \"Failed to relaunch application '$bundle_id'.\"\n fi\n}\n\n\n# extract contents\nMOUNT_POINT=$(mktemp -d /tmp/dmg_mount_XXXXXX)\nyes | hdiutil attach -plist -nobrowse -readonly -mountpoint \"$MOUNT_POINT\" \"$INSTALLER_PATH\" || exit 1\nsudo cp -R \"$MOUNT_POINT\"/* \"$TMPDIR\"\nhdiutil detach \"$MOUNT_POINT\" || true\n# copy to the applications folder\nquit_and_track_application 'com.etwok.netspotwifi'\nif [ -d \"$APPDIR/NetSpot.app\" ]; then\n\tsudo mv \"$APPDIR/NetSpot.app\" \"$TMPDIR/NetSpot.app.bkp\"\nfi\nsudo cp -R \"$TMPDIR/NetSpot.app\" \"$APPDIR\"\nrelaunch_application 'com.etwok.netspotwifi'\n" + } +} diff --git a/ee/maintained-apps/outputs/nextcloud-talk/darwin.json b/ee/maintained-apps/outputs/nextcloud-talk/darwin.json new file mode 100644 index 00000000000..19ecf309311 --- /dev/null +++ b/ee/maintained-apps/outputs/nextcloud-talk/darwin.json @@ -0,0 +1,22 @@ +{ + "versions": [ + { + "version": "2.1.2", + "queries": { + "exists": "SELECT 1 FROM apps WHERE bundle_identifier = 'com.nextcloud.talk.mac';", + "patched": "SELECT 1 WHERE NOT EXISTS (SELECT 1 FROM apps WHERE bundle_identifier = 'com.nextcloud.talk.mac' AND version_compare(bundle_short_version, '2.1.2') < 0);" + }, + "installer_url": "https://github.com/nextcloud-releases/talk-desktop/releases/download/v2.1.2/Nextcloud.Talk-macos-universal.dmg", + "install_script_ref": "597512da", + "uninstall_script_ref": "baa87dcf", + "sha256": "9a3362ef9757e01fe8bfecc49a22434d5fb6a369d59f5cef39c0f992e709767a", + "default_categories": [ + "Productivity" + ] + } + ], + "refs": { + "597512da": "#!/bin/bash\n\n# variables\nAPPDIR=\"/Applications/\"\nTMPDIR=$(dirname \"$(realpath \"$INSTALLER_PATH\")\")\n# functions\n\nquit_and_track_application() {\n local bundle_id=\"$1\"\n local var_name=\"APP_WAS_RUNNING_$(echo \"$bundle_id\" | tr '.-' '__')\"\n local timeout_duration=10\n\n # check if the application is running\n local app_running\n app_running=$(osascript -e \"application id \\\"$bundle_id\\\" is running\" 2>/dev/null)\n if [[ \"$app_running\" != \"true\" ]]; then\n eval \"export $var_name=0\"\n return\n fi\n\n local console_user\n console_user=$(stat -f \"%Su\" /dev/console)\n if [[ -z \"$console_user\" || \"$console_user\" == \"root\" || \"$console_user\" == \"loginwindow\" ]]; then\n echo \"Not logged into a non-root GUI; skipping quitting application ID '$bundle_id'.\"\n eval \"export $var_name=0\"\n return\n fi\n\n # App was running, mark it for relaunch\n eval \"export $var_name=1\"\n echo \"Application '$bundle_id' was running; will relaunch after installation.\"\n\n echo \"Quitting application '$bundle_id'...\"\n\n # try to quit the application within the timeout period\n local quit_success=false\n SECONDS=0\n while (( SECONDS < timeout_duration )); do\n if osascript -e \"tell application id \\\"$bundle_id\\\" to quit\" >/dev/null 2>&1; then\n if ! pgrep -f \"$bundle_id\" >/dev/null 2>&1; then\n echo \"Application '$bundle_id' quit successfully.\"\n quit_success=true\n break\n fi\n fi\n sleep 1\n done\n\n if [[ \"$quit_success\" = false ]]; then\n echo \"Application '$bundle_id' did not quit.\"\n fi\n}\n\n\nrelaunch_application() {\n local bundle_id=\"$1\"\n local var_name=\"APP_WAS_RUNNING_$(echo \"$bundle_id\" | tr '.-' '__')\"\n local was_running\n\n # Check if the app was running before installation\n eval \"was_running=\\$$var_name\"\n if [[ \"$was_running\" != \"1\" ]]; then\n return\n fi\n\n local console_user\n console_user=$(stat -f \"%Su\" /dev/console)\n if [[ -z \"$console_user\" || \"$console_user\" == \"root\" || \"$console_user\" == \"loginwindow\" ]]; then\n echo \"Not logged into a non-root GUI; skipping relaunching application ID '$bundle_id'.\"\n return\n fi\n\n echo \"Relaunching application '$bundle_id'...\"\n\n # Launch the app in the logged-in user's GUI session. Apps launched by root\n # won't register with the user's Dock/GUI, so run 'open' as the console user.\n # Use 'launchctl asuser' to bootstrap into the console user's Mach namespace\n # and GUI session — 'sudo -u' alone doesn't do this, which can cause\n # LSOpenURLsWithRole() failures even when 'open' exits 0.\n local open_status=0\n if [[ $EUID -eq 0 ]]; then\n local console_uid\n console_uid=$(id -u \"$console_user\")\n /bin/launchctl asuser \"$console_uid\" sudo -u \"$console_user\" open -b \"$bundle_id\" >/dev/null 2>&1 || open_status=$?\n else\n open -b \"$bundle_id\" >/dev/null 2>&1 || open_status=$?\n fi\n\n if [[ $open_status -eq 0 ]]; then\n echo \"Application '$bundle_id' relaunched successfully.\"\n else\n echo \"Failed to relaunch application '$bundle_id'.\"\n fi\n}\n\n\n# extract contents\nMOUNT_POINT=$(mktemp -d /tmp/dmg_mount_XXXXXX)\nyes | hdiutil attach -plist -nobrowse -readonly -mountpoint \"$MOUNT_POINT\" \"$INSTALLER_PATH\" || exit 1\nsudo cp -R \"$MOUNT_POINT\"/* \"$TMPDIR\"\nhdiutil detach \"$MOUNT_POINT\" || true\n# copy to the applications folder\nquit_and_track_application 'com.nextcloud.talk.mac'\nif [ -d \"$APPDIR/Nextcloud Talk.app\" ]; then\n\tsudo mv \"$APPDIR/Nextcloud Talk.app\" \"$TMPDIR/Nextcloud Talk.app.bkp\"\nfi\nsudo cp -R \"$TMPDIR/Nextcloud Talk.app\" \"$APPDIR\"\nrelaunch_application 'com.nextcloud.talk.mac'\n", + "baa87dcf": "#!/bin/bash\n\n# variables\nAPPDIR=\"/Applications/\"\nLOGGED_IN_USER=$(scutil <<< \"show State:/Users/ConsoleUser\" | awk '/Name :/ { print $3 }')\n# functions\n\ntrash() {\n local logged_in_user=\"$1\"\n local target_file=\"$2\"\n local timestamp=\"$(date +%Y-%m-%d-%s)\"\n local rand=\"$(jot -r 1 0 99999)\"\n\n # replace ~ with /Users/$logged_in_user\n if [[ \"$target_file\" == ~* ]]; then\n target_file=\"/Users/$logged_in_user${target_file:1}\"\n fi\n\n local trash=\"/Users/$logged_in_user/.Trash\"\n\n # If the target contains glob characters, expand it and move each match.\n if [[ \"$target_file\" == *[*?[]* ]]; then\n local file file_name\n local matched=false\n local i=0\n # compgen -G expands the (quoted) pattern itself, so paths containing\n # spaces glob correctly; reading line by line keeps each match intact.\n while IFS= read -r file; do\n [[ -n \"$file\" ]] || continue\n [[ -e \"$file\" || -L \"$file\" ]] || continue\n matched=true\n i=$((i + 1))\n file_name=\"$(basename \"$file\")\"\n echo \"removing $file.\"\n # The per-match counter keeps matches that share a basename from\n # overwriting each other in the trash.\n mv -f \"$file\" \"$trash/${file_name}_${timestamp}_${rand}_${i}\"\n done < <(compgen -G \"$target_file\" 2>/dev/null)\n if [[ \"$matched\" == false ]]; then\n echo \"$target_file doesn't exist.\"\n fi\n return\n fi\n\n local file_name=\"$(basename \"${target_file}\")\"\n\n if [[ -e \"$target_file\" ]]; then\n echo \"removing $target_file.\"\n mv -f \"$target_file\" \"$trash/${file_name}_${timestamp}_${rand}\"\n else\n echo \"$target_file doesn't exist.\"\n fi\n}\n\nsudo rm -rf \"$APPDIR/Nextcloud Talk.app\"\ntrash $LOGGED_IN_USER '~/Library/Application Support/Nextcloud Talk'\ntrash $LOGGED_IN_USER '~/Library/Preferences/com.nextcloud.talk.mac.plist'\n" + } +} diff --git a/ee/maintained-apps/outputs/nightfall/darwin.json b/ee/maintained-apps/outputs/nightfall/darwin.json new file mode 100644 index 00000000000..221d999a2b4 --- /dev/null +++ b/ee/maintained-apps/outputs/nightfall/darwin.json @@ -0,0 +1,22 @@ +{ + "versions": [ + { + "version": "3.1.0", + "queries": { + "exists": "SELECT 1 FROM apps WHERE bundle_identifier = 'net.ryanthomson.Nightfall';", + "patched": "SELECT 1 WHERE NOT EXISTS (SELECT 1 FROM apps WHERE bundle_identifier = 'net.ryanthomson.Nightfall' AND version_compare(bundle_short_version, '3.1.0') < 0);" + }, + "installer_url": "https://github.com/r-thomson/Nightfall/releases/download/v3.1.0/Nightfall.dmg", + "install_script_ref": "d4198e2f", + "uninstall_script_ref": "33e0fdca", + "sha256": "b98e86466bb89b04b9f5d3f98e4b74c03950052e8821b515ec1ea0c7f71bef6a", + "default_categories": [ + "Utilities" + ] + } + ], + "refs": { + "33e0fdca": "#!/bin/bash\n\n# variables\nAPPDIR=\"/Applications/\"\nLOGGED_IN_USER=$(scutil <<< \"show State:/Users/ConsoleUser\" | awk '/Name :/ { print $3 }')\n# functions\n\ntrash() {\n local logged_in_user=\"$1\"\n local target_file=\"$2\"\n local timestamp=\"$(date +%Y-%m-%d-%s)\"\n local rand=\"$(jot -r 1 0 99999)\"\n\n # replace ~ with /Users/$logged_in_user\n if [[ \"$target_file\" == ~* ]]; then\n target_file=\"/Users/$logged_in_user${target_file:1}\"\n fi\n\n local trash=\"/Users/$logged_in_user/.Trash\"\n\n # If the target contains glob characters, expand it and move each match.\n if [[ \"$target_file\" == *[*?[]* ]]; then\n local file file_name\n local matched=false\n local i=0\n # compgen -G expands the (quoted) pattern itself, so paths containing\n # spaces glob correctly; reading line by line keeps each match intact.\n while IFS= read -r file; do\n [[ -n \"$file\" ]] || continue\n [[ -e \"$file\" || -L \"$file\" ]] || continue\n matched=true\n i=$((i + 1))\n file_name=\"$(basename \"$file\")\"\n echo \"removing $file.\"\n # The per-match counter keeps matches that share a basename from\n # overwriting each other in the trash.\n mv -f \"$file\" \"$trash/${file_name}_${timestamp}_${rand}_${i}\"\n done < <(compgen -G \"$target_file\" 2>/dev/null)\n if [[ \"$matched\" == false ]]; then\n echo \"$target_file doesn't exist.\"\n fi\n return\n fi\n\n local file_name=\"$(basename \"${target_file}\")\"\n\n if [[ -e \"$target_file\" ]]; then\n echo \"removing $target_file.\"\n mv -f \"$target_file\" \"$trash/${file_name}_${timestamp}_${rand}\"\n else\n echo \"$target_file doesn't exist.\"\n fi\n}\n\nsudo rm -rf \"$APPDIR/Nightfall.app\"\ntrash $LOGGED_IN_USER '~/Library/Application Scripts/com.ryanthomson.Nightfall'\ntrash $LOGGED_IN_USER '~/Library/Containers/com.ryanthomson.Nightfall'\n", + "d4198e2f": "#!/bin/bash\n\n# variables\nAPPDIR=\"/Applications/\"\nTMPDIR=$(dirname \"$(realpath \"$INSTALLER_PATH\")\")\n# functions\n\nquit_and_track_application() {\n local bundle_id=\"$1\"\n local var_name=\"APP_WAS_RUNNING_$(echo \"$bundle_id\" | tr '.-' '__')\"\n local timeout_duration=10\n\n # check if the application is running\n local app_running\n app_running=$(osascript -e \"application id \\\"$bundle_id\\\" is running\" 2>/dev/null)\n if [[ \"$app_running\" != \"true\" ]]; then\n eval \"export $var_name=0\"\n return\n fi\n\n local console_user\n console_user=$(stat -f \"%Su\" /dev/console)\n if [[ -z \"$console_user\" || \"$console_user\" == \"root\" || \"$console_user\" == \"loginwindow\" ]]; then\n echo \"Not logged into a non-root GUI; skipping quitting application ID '$bundle_id'.\"\n eval \"export $var_name=0\"\n return\n fi\n\n # App was running, mark it for relaunch\n eval \"export $var_name=1\"\n echo \"Application '$bundle_id' was running; will relaunch after installation.\"\n\n echo \"Quitting application '$bundle_id'...\"\n\n # try to quit the application within the timeout period\n local quit_success=false\n SECONDS=0\n while (( SECONDS < timeout_duration )); do\n if osascript -e \"tell application id \\\"$bundle_id\\\" to quit\" >/dev/null 2>&1; then\n if ! pgrep -f \"$bundle_id\" >/dev/null 2>&1; then\n echo \"Application '$bundle_id' quit successfully.\"\n quit_success=true\n break\n fi\n fi\n sleep 1\n done\n\n if [[ \"$quit_success\" = false ]]; then\n echo \"Application '$bundle_id' did not quit.\"\n fi\n}\n\n\nrelaunch_application() {\n local bundle_id=\"$1\"\n local var_name=\"APP_WAS_RUNNING_$(echo \"$bundle_id\" | tr '.-' '__')\"\n local was_running\n\n # Check if the app was running before installation\n eval \"was_running=\\$$var_name\"\n if [[ \"$was_running\" != \"1\" ]]; then\n return\n fi\n\n local console_user\n console_user=$(stat -f \"%Su\" /dev/console)\n if [[ -z \"$console_user\" || \"$console_user\" == \"root\" || \"$console_user\" == \"loginwindow\" ]]; then\n echo \"Not logged into a non-root GUI; skipping relaunching application ID '$bundle_id'.\"\n return\n fi\n\n echo \"Relaunching application '$bundle_id'...\"\n\n # Launch the app in the logged-in user's GUI session. Apps launched by root\n # won't register with the user's Dock/GUI, so run 'open' as the console user.\n # Use 'launchctl asuser' to bootstrap into the console user's Mach namespace\n # and GUI session — 'sudo -u' alone doesn't do this, which can cause\n # LSOpenURLsWithRole() failures even when 'open' exits 0.\n local open_status=0\n if [[ $EUID -eq 0 ]]; then\n local console_uid\n console_uid=$(id -u \"$console_user\")\n /bin/launchctl asuser \"$console_uid\" sudo -u \"$console_user\" open -b \"$bundle_id\" >/dev/null 2>&1 || open_status=$?\n else\n open -b \"$bundle_id\" >/dev/null 2>&1 || open_status=$?\n fi\n\n if [[ $open_status -eq 0 ]]; then\n echo \"Application '$bundle_id' relaunched successfully.\"\n else\n echo \"Failed to relaunch application '$bundle_id'.\"\n fi\n}\n\n\n# extract contents\nMOUNT_POINT=$(mktemp -d /tmp/dmg_mount_XXXXXX)\nyes | hdiutil attach -plist -nobrowse -readonly -mountpoint \"$MOUNT_POINT\" \"$INSTALLER_PATH\" || exit 1\nsudo cp -R \"$MOUNT_POINT\"/* \"$TMPDIR\"\nhdiutil detach \"$MOUNT_POINT\" || true\n# copy to the applications folder\nquit_and_track_application 'net.ryanthomson.Nightfall'\nif [ -d \"$APPDIR/Nightfall.app\" ]; then\n\tsudo mv \"$APPDIR/Nightfall.app\" \"$TMPDIR/Nightfall.app.bkp\"\nfi\nsudo cp -R \"$TMPDIR/Nightfall.app\" \"$APPDIR\"\nrelaunch_application 'net.ryanthomson.Nightfall'\n" + } +} diff --git a/ee/maintained-apps/outputs/nitro-pdf-pro/darwin.json b/ee/maintained-apps/outputs/nitro-pdf-pro/darwin.json new file mode 100644 index 00000000000..479d51c0b35 --- /dev/null +++ b/ee/maintained-apps/outputs/nitro-pdf-pro/darwin.json @@ -0,0 +1,22 @@ +{ + "versions": [ + { + "version": "26.0", + "queries": { + "exists": "SELECT 1 FROM apps WHERE bundle_identifier = 'com.gonitro.NitroPDFPro';", + "patched": "SELECT 1 WHERE NOT EXISTS (SELECT 1 FROM apps WHERE bundle_identifier = 'com.gonitro.NitroPDFPro' AND version_compare(bundle_short_version, '26.0') < 0);" + }, + "installer_url": "https://downloads.gonitro.com/macos/Nitro%20PDF%20Pro_26.0.dmg", + "install_script_ref": "054b6793", + "uninstall_script_ref": "fda95c8b", + "sha256": "5f1e9f846bca80a95b0faa43b11f6daf04d40be5301a3a9b8255541a5cf0f0f2", + "default_categories": [ + "Productivity" + ] + } + ], + "refs": { + "054b6793": "#!/bin/bash\n\n# variables\nAPPDIR=\"/Applications/\"\nTMPDIR=$(dirname \"$(realpath \"$INSTALLER_PATH\")\")\n# functions\n\nquit_and_track_application() {\n local bundle_id=\"$1\"\n local var_name=\"APP_WAS_RUNNING_$(echo \"$bundle_id\" | tr '.-' '__')\"\n local timeout_duration=10\n\n # check if the application is running\n local app_running\n app_running=$(osascript -e \"application id \\\"$bundle_id\\\" is running\" 2>/dev/null)\n if [[ \"$app_running\" != \"true\" ]]; then\n eval \"export $var_name=0\"\n return\n fi\n\n local console_user\n console_user=$(stat -f \"%Su\" /dev/console)\n if [[ -z \"$console_user\" || \"$console_user\" == \"root\" || \"$console_user\" == \"loginwindow\" ]]; then\n echo \"Not logged into a non-root GUI; skipping quitting application ID '$bundle_id'.\"\n eval \"export $var_name=0\"\n return\n fi\n\n # App was running, mark it for relaunch\n eval \"export $var_name=1\"\n echo \"Application '$bundle_id' was running; will relaunch after installation.\"\n\n echo \"Quitting application '$bundle_id'...\"\n\n # try to quit the application within the timeout period\n local quit_success=false\n SECONDS=0\n while (( SECONDS < timeout_duration )); do\n if osascript -e \"tell application id \\\"$bundle_id\\\" to quit\" >/dev/null 2>&1; then\n if ! pgrep -f \"$bundle_id\" >/dev/null 2>&1; then\n echo \"Application '$bundle_id' quit successfully.\"\n quit_success=true\n break\n fi\n fi\n sleep 1\n done\n\n if [[ \"$quit_success\" = false ]]; then\n echo \"Application '$bundle_id' did not quit.\"\n fi\n}\n\n\nrelaunch_application() {\n local bundle_id=\"$1\"\n local var_name=\"APP_WAS_RUNNING_$(echo \"$bundle_id\" | tr '.-' '__')\"\n local was_running\n\n # Check if the app was running before installation\n eval \"was_running=\\$$var_name\"\n if [[ \"$was_running\" != \"1\" ]]; then\n return\n fi\n\n local console_user\n console_user=$(stat -f \"%Su\" /dev/console)\n if [[ -z \"$console_user\" || \"$console_user\" == \"root\" || \"$console_user\" == \"loginwindow\" ]]; then\n echo \"Not logged into a non-root GUI; skipping relaunching application ID '$bundle_id'.\"\n return\n fi\n\n echo \"Relaunching application '$bundle_id'...\"\n\n # Launch the app in the logged-in user's GUI session. Apps launched by root\n # won't register with the user's Dock/GUI, so run 'open' as the console user.\n # Use 'launchctl asuser' to bootstrap into the console user's Mach namespace\n # and GUI session — 'sudo -u' alone doesn't do this, which can cause\n # LSOpenURLsWithRole() failures even when 'open' exits 0.\n local open_status=0\n if [[ $EUID -eq 0 ]]; then\n local console_uid\n console_uid=$(id -u \"$console_user\")\n /bin/launchctl asuser \"$console_uid\" sudo -u \"$console_user\" open -b \"$bundle_id\" >/dev/null 2>&1 || open_status=$?\n else\n open -b \"$bundle_id\" >/dev/null 2>&1 || open_status=$?\n fi\n\n if [[ $open_status -eq 0 ]]; then\n echo \"Application '$bundle_id' relaunched successfully.\"\n else\n echo \"Failed to relaunch application '$bundle_id'.\"\n fi\n}\n\n\n# extract contents\nMOUNT_POINT=$(mktemp -d /tmp/dmg_mount_XXXXXX)\nyes | hdiutil attach -plist -nobrowse -readonly -mountpoint \"$MOUNT_POINT\" \"$INSTALLER_PATH\" || exit 1\nsudo cp -R \"$MOUNT_POINT\"/* \"$TMPDIR\"\nhdiutil detach \"$MOUNT_POINT\" || true\n# copy to the applications folder\nquit_and_track_application 'com.gonitro.NitroPDFPro'\nif [ -d \"$APPDIR/Nitro PDF Pro.app\" ]; then\n\tsudo mv \"$APPDIR/Nitro PDF Pro.app\" \"$TMPDIR/Nitro PDF Pro.app.bkp\"\nfi\nsudo cp -R \"$TMPDIR/Nitro PDF Pro.app\" \"$APPDIR\"\nrelaunch_application 'com.gonitro.NitroPDFPro'\n", + "fda95c8b": "#!/bin/bash\n\n# variables\nAPPDIR=\"/Applications/\"\nLOGGED_IN_USER=$(scutil <<< \"show State:/Users/ConsoleUser\" | awk '/Name :/ { print $3 }')\n# functions\n\ntrash() {\n local logged_in_user=\"$1\"\n local target_file=\"$2\"\n local timestamp=\"$(date +%Y-%m-%d-%s)\"\n local rand=\"$(jot -r 1 0 99999)\"\n\n # replace ~ with /Users/$logged_in_user\n if [[ \"$target_file\" == ~* ]]; then\n target_file=\"/Users/$logged_in_user${target_file:1}\"\n fi\n\n local trash=\"/Users/$logged_in_user/.Trash\"\n\n # If the target contains glob characters, expand it and move each match.\n if [[ \"$target_file\" == *[*?[]* ]]; then\n local file file_name\n local matched=false\n local i=0\n # compgen -G expands the (quoted) pattern itself, so paths containing\n # spaces glob correctly; reading line by line keeps each match intact.\n while IFS= read -r file; do\n [[ -n \"$file\" ]] || continue\n [[ -e \"$file\" || -L \"$file\" ]] || continue\n matched=true\n i=$((i + 1))\n file_name=\"$(basename \"$file\")\"\n echo \"removing $file.\"\n # The per-match counter keeps matches that share a basename from\n # overwriting each other in the trash.\n mv -f \"$file\" \"$trash/${file_name}_${timestamp}_${rand}_${i}\"\n done < <(compgen -G \"$target_file\" 2>/dev/null)\n if [[ \"$matched\" == false ]]; then\n echo \"$target_file doesn't exist.\"\n fi\n return\n fi\n\n local file_name=\"$(basename \"${target_file}\")\"\n\n if [[ -e \"$target_file\" ]]; then\n echo \"removing $target_file.\"\n mv -f \"$target_file\" \"$trash/${file_name}_${timestamp}_${rand}\"\n else\n echo \"$target_file doesn't exist.\"\n fi\n}\n\nsudo rm -rf \"$APPDIR/Nitro PDF Pro.app\"\ntrash $LOGGED_IN_USER '~/Library/Application Scripts/com.gonitro.NitroPDFPro'\ntrash $LOGGED_IN_USER '~/Library/Application Support/com.apple.sharedfilelist/com.apple.LSSharedFileList.ApplicationRecentDocuments/com.gonitro.nitropdfpro.sfl*'\ntrash $LOGGED_IN_USER '~/Library/Containers/com.gonitro.NitroPDFPro'\n" + } +} diff --git a/ee/maintained-apps/outputs/nocturnal/darwin.json b/ee/maintained-apps/outputs/nocturnal/darwin.json new file mode 100644 index 00000000000..73d8a17c699 --- /dev/null +++ b/ee/maintained-apps/outputs/nocturnal/darwin.json @@ -0,0 +1,22 @@ +{ + "versions": [ + { + "version": "0.3", + "queries": { + "exists": "SELECT 1 FROM apps WHERE bundle_identifier = 'com.harshilshah.nocturnal';", + "patched": "SELECT 1 WHERE NOT EXISTS (SELECT 1 FROM apps WHERE bundle_identifier = 'com.harshilshah.nocturnal' AND version_compare(bundle_short_version, '0.3') < 0);" + }, + "installer_url": "https://github.com/HarshilShah/Nocturnal/releases/download/0.3/Nocturnal.zip", + "install_script_ref": "2ce8074e", + "uninstall_script_ref": "55eed5ec", + "sha256": "a66c59daa1d1c59e5403aee4eb868a3967f1bdb4d90033fa3ee692bffd7db0b9", + "default_categories": [ + "Productivity" + ] + } + ], + "refs": { + "2ce8074e": "#!/bin/bash\n\n# variables\nAPPDIR=\"/Applications/\"\nTMPDIR=$(dirname \"$(realpath \"$INSTALLER_PATH\")\")\n# functions\n\nquit_and_track_application() {\n local bundle_id=\"$1\"\n local var_name=\"APP_WAS_RUNNING_$(echo \"$bundle_id\" | tr '.-' '__')\"\n local timeout_duration=10\n\n # check if the application is running\n local app_running\n app_running=$(osascript -e \"application id \\\"$bundle_id\\\" is running\" 2>/dev/null)\n if [[ \"$app_running\" != \"true\" ]]; then\n eval \"export $var_name=0\"\n return\n fi\n\n local console_user\n console_user=$(stat -f \"%Su\" /dev/console)\n if [[ -z \"$console_user\" || \"$console_user\" == \"root\" || \"$console_user\" == \"loginwindow\" ]]; then\n echo \"Not logged into a non-root GUI; skipping quitting application ID '$bundle_id'.\"\n eval \"export $var_name=0\"\n return\n fi\n\n # App was running, mark it for relaunch\n eval \"export $var_name=1\"\n echo \"Application '$bundle_id' was running; will relaunch after installation.\"\n\n echo \"Quitting application '$bundle_id'...\"\n\n # try to quit the application within the timeout period\n local quit_success=false\n SECONDS=0\n while (( SECONDS < timeout_duration )); do\n if osascript -e \"tell application id \\\"$bundle_id\\\" to quit\" >/dev/null 2>&1; then\n if ! pgrep -f \"$bundle_id\" >/dev/null 2>&1; then\n echo \"Application '$bundle_id' quit successfully.\"\n quit_success=true\n break\n fi\n fi\n sleep 1\n done\n\n if [[ \"$quit_success\" = false ]]; then\n echo \"Application '$bundle_id' did not quit.\"\n fi\n}\n\n\nrelaunch_application() {\n local bundle_id=\"$1\"\n local var_name=\"APP_WAS_RUNNING_$(echo \"$bundle_id\" | tr '.-' '__')\"\n local was_running\n\n # Check if the app was running before installation\n eval \"was_running=\\$$var_name\"\n if [[ \"$was_running\" != \"1\" ]]; then\n return\n fi\n\n local console_user\n console_user=$(stat -f \"%Su\" /dev/console)\n if [[ -z \"$console_user\" || \"$console_user\" == \"root\" || \"$console_user\" == \"loginwindow\" ]]; then\n echo \"Not logged into a non-root GUI; skipping relaunching application ID '$bundle_id'.\"\n return\n fi\n\n echo \"Relaunching application '$bundle_id'...\"\n\n # Launch the app in the logged-in user's GUI session. Apps launched by root\n # won't register with the user's Dock/GUI, so run 'open' as the console user.\n # Use 'launchctl asuser' to bootstrap into the console user's Mach namespace\n # and GUI session — 'sudo -u' alone doesn't do this, which can cause\n # LSOpenURLsWithRole() failures even when 'open' exits 0.\n local open_status=0\n if [[ $EUID -eq 0 ]]; then\n local console_uid\n console_uid=$(id -u \"$console_user\")\n /bin/launchctl asuser \"$console_uid\" sudo -u \"$console_user\" open -b \"$bundle_id\" >/dev/null 2>&1 || open_status=$?\n else\n open -b \"$bundle_id\" >/dev/null 2>&1 || open_status=$?\n fi\n\n if [[ $open_status -eq 0 ]]; then\n echo \"Application '$bundle_id' relaunched successfully.\"\n else\n echo \"Failed to relaunch application '$bundle_id'.\"\n fi\n}\n\n\n# extract contents\nunzip \"$INSTALLER_PATH\" -d \"$TMPDIR\"\n# copy to the applications folder\nquit_and_track_application 'com.harshilshah.nocturnal'\nif [ -d \"$APPDIR/Nocturnal.app\" ]; then\n\tsudo mv \"$APPDIR/Nocturnal.app\" \"$TMPDIR/Nocturnal.app.bkp\"\nfi\nsudo cp -R \"$TMPDIR/Nocturnal.app\" \"$APPDIR\"\nrelaunch_application 'com.harshilshah.nocturnal'\n", + "55eed5ec": "#!/bin/bash\n\n# variables\nAPPDIR=\"/Applications/\"\n\nsudo rm -rf \"$APPDIR/Nocturnal.app\"\n" + } +} diff --git a/ee/maintained-apps/outputs/nordlayer/darwin.json b/ee/maintained-apps/outputs/nordlayer/darwin.json new file mode 100644 index 00000000000..b128f81f0f2 --- /dev/null +++ b/ee/maintained-apps/outputs/nordlayer/darwin.json @@ -0,0 +1,22 @@ +{ + "versions": [ + { + "version": "3.10.0", + "queries": { + "exists": "SELECT 1 FROM apps WHERE bundle_identifier = 'com.nordvpn.macos.teams';", + "patched": "SELECT 1 WHERE NOT EXISTS (SELECT 1 FROM apps WHERE bundle_identifier = 'com.nordvpn.macos.teams' AND version_compare(bundle_short_version, '3.10.0') < 0);" + }, + "installer_url": "https://downloads.nordlayer.com/mac/latest/NordLayer_v3.10.0.pkg", + "install_script_ref": "f9f57c4d", + "uninstall_script_ref": "af9ea63b", + "sha256": "140e1cf5748a7a17176e44ac0334b081531b38ae57911418226e2ae41a955b29", + "default_categories": [ + "Productivity" + ] + } + ], + "refs": { + "af9ea63b": "#!/bin/bash\n\n# variables\nLOGGED_IN_USER=$(scutil <<< \"show State:/Users/ConsoleUser\" | awk '/Name :/ { print $3 }')\n# functions\n\nexpand_pkgid_and_map() {\n local PKGID=\"$1\"\n local FUNC=\"$2\"\n if [[ \"$PKGID\" == *\"*\" ]]; then\n local prefix=\"${PKGID%\\*}\"\n echo \"Expanding wildcard for PKGID: $PKGID\"\n for receipt in $(pkgutil --pkgs | grep \"^${prefix}\"); do\n echo \"Processing $receipt\"\n \"$FUNC\" \"$receipt\"\n done\n else\n \"$FUNC\" \"$PKGID\"\n fi\n}\n\nforget_pkg() {\n local PKGID=\"$1\"\n expand_pkgid_and_map \"$PKGID\" forget_receipt\n}\n\nforget_receipt() {\n local PKGID=\"$1\"\n sudo pkgutil --forget \"$PKGID\"\n}\n\nquit_application() {\n local bundle_id=\"$1\"\n local timeout_duration=10\n\n # check if the application is running\n local app_running\n app_running=$(osascript -e \"application id \\\"$bundle_id\\\" is running\" 2>/dev/null)\n if [[ \"$app_running\" != \"true\" ]]; then\n return\n fi\n\n local console_user\n console_user=$(stat -f \"%Su\" /dev/console)\n if [[ -z \"$console_user\" || \"$console_user\" == \"root\" || \"$console_user\" == \"loginwindow\" ]]; then\n echo \"Not logged into a non-root GUI; skipping quitting application ID '$bundle_id'.\"\n return\n fi\n\n echo \"Quitting application '$bundle_id'...\"\n\n # try to quit the application within the timeout period\n local quit_success=false\n SECONDS=0\n while (( SECONDS < timeout_duration )); do\n if osascript -e \"tell application id \\\"$bundle_id\\\" to quit\" >/dev/null 2>&1; then\n if ! pgrep -f \"$bundle_id\" >/dev/null 2>&1; then\n echo \"Application '$bundle_id' quit successfully.\"\n quit_success=true\n break\n fi\n fi\n sleep 1\n done\n\n if [[ \"$quit_success\" = false ]]; then\n echo \"Application '$bundle_id' did not quit.\"\n fi\n}\n\n\nremove_launchctl_service() {\n local service=\"$1\"\n local booleans=(\"true\" \"false\")\n local plist_status\n local paths\n local should_sudo\n\n echo \"Removing launchctl service ${service}\"\n\n for should_sudo in \"${booleans[@]}\"; do\n plist_status=$(launchctl list \"${service}\" 2>/dev/null)\n\n if [[ $plist_status == \\{* ]]; then\n if [[ $should_sudo == \"true\" ]]; then\n sudo launchctl remove \"${service}\"\n else\n launchctl remove \"${service}\"\n fi\n sleep 1\n fi\n\n paths=(\n \"/Library/LaunchAgents/${service}.plist\"\n \"/Library/LaunchDaemons/${service}.plist\"\n )\n\n # if not using sudo, prepend the home directory to the paths\n if [[ $should_sudo == \"false\" ]]; then\n for i in \"${!paths[@]}\"; do\n paths[i]=\"${HOME}${paths[i]}\"\n done\n fi\n\n for path in \"${paths[@]}\"; do\n if [[ -e \"$path\" ]]; then\n if [[ $should_sudo == \"true\" ]]; then\n sudo rm -f -- \"$path\"\n else\n rm -f -- \"$path\"\n fi\n fi\n done\n done\n}\n\nremove_pkg_files() {\n local PKGID=\"$1\"\n expand_pkgid_and_map \"$PKGID\" remove_receipt_files\n}\n\nremove_receipt_files() {\n local PKGID=\"$1\"\n local PKGINFO VOLUME INSTALL_LOCATION FULL_INSTALL_LOCATION\n\n echo \"pkgutil --pkg-info-plist \\\"$PKGID\\\"\"\n PKGINFO=$(pkgutil --pkg-info-plist \"$PKGID\")\n VOLUME=$(echo \"$PKGINFO\" | awk '/volume<\\/key>/ {getline; gsub(/.*|<\\/string>.*/, \"\"); print}')\n INSTALL_LOCATION=$(echo \"$PKGINFO\" | awk '/install-location<\\/key>/ {getline; gsub(/.*|<\\/string>.*/, \"\"); print}')\n\n if [ -z \"$INSTALL_LOCATION\" ] || [ \"$INSTALL_LOCATION\" = \"/\" ]; then\n FULL_INSTALL_LOCATION=\"$VOLUME\"\n else\n FULL_INSTALL_LOCATION=\"$VOLUME/$INSTALL_LOCATION\"\n FULL_INSTALL_LOCATION=$(echo \"$FULL_INSTALL_LOCATION\" | sed 's|//|/|g')\n fi\n\n echo \"sudo pkgutil --only-files --files \\\"$PKGID\\\" | sed \\\"s|^|${FULL_INSTALL_LOCATION}/|\\\" | tr '\\\\\\\\n' '\\\\\\\\0' | /usr/bin/sudo -u root -E -- /usr/bin/xargs -0 -- /bin/rm -rf\"\n sudo pkgutil --only-files --files \"$PKGID\" | sed \"s|^|/${INSTALL_LOCATION}/|\" | tr '\\n' '\\0' | /usr/bin/sudo -u root -E -- /usr/bin/xargs -0 -- /bin/rm -rf\n\n echo \"sudo pkgutil --only-dirs --files \\\"$PKGID\\\" | sed \\\"s|^|${FULL_INSTALL_LOCATION}/|\\\" | grep '\\\\.app$' | tr '\\\\\\\\n' '\\\\\\\\0' | /usr/bin/sudo -u root -E -- /usr/bin/xargs -0 -- /bin/rm -rf\"\n sudo pkgutil --only-dirs --files \"$PKGID\" | sed \"s|^|${FULL_INSTALL_LOCATION}/|\" | grep '\\.app$' | tr '\\n' '\\0' | /usr/bin/sudo -u root -E -- /usr/bin/xargs -0 -- /bin/rm -rf\n\n root_app_dir=$(\n sudo pkgutil --only-dirs --files \"$PKGID\" \\\n | sed \"s|^|${FULL_INSTALL_LOCATION}/|\" \\\n | grep 'Applications' \\\n | awk '{ print length, $0 }' \\\n | sort -n \\\n | head -n1 \\\n | cut -d' ' -f2-\n )\n if [ -n \"$root_app_dir\" ]; then\n echo \"sudo rmdir -p \\\"$root_app_dir\\\" 2>/dev/null || :\"\n sudo rmdir -p \"$root_app_dir\" 2>/dev/null || :\n fi\n}\n\ntrash() {\n local logged_in_user=\"$1\"\n local target_file=\"$2\"\n local timestamp=\"$(date +%Y-%m-%d-%s)\"\n local rand=\"$(jot -r 1 0 99999)\"\n\n # replace ~ with /Users/$logged_in_user\n if [[ \"$target_file\" == ~* ]]; then\n target_file=\"/Users/$logged_in_user${target_file:1}\"\n fi\n\n local trash=\"/Users/$logged_in_user/.Trash\"\n\n # If the target contains glob characters, expand it and move each match.\n if [[ \"$target_file\" == *[*?[]* ]]; then\n local file file_name\n local matched=false\n local i=0\n # compgen -G expands the (quoted) pattern itself, so paths containing\n # spaces glob correctly; reading line by line keeps each match intact.\n while IFS= read -r file; do\n [[ -n \"$file\" ]] || continue\n [[ -e \"$file\" || -L \"$file\" ]] || continue\n matched=true\n i=$((i + 1))\n file_name=\"$(basename \"$file\")\"\n echo \"removing $file.\"\n # The per-match counter keeps matches that share a basename from\n # overwriting each other in the trash.\n mv -f \"$file\" \"$trash/${file_name}_${timestamp}_${rand}_${i}\"\n done < <(compgen -G \"$target_file\" 2>/dev/null)\n if [[ \"$matched\" == false ]]; then\n echo \"$target_file doesn't exist.\"\n fi\n return\n fi\n\n local file_name=\"$(basename \"${target_file}\")\"\n\n if [[ -e \"$target_file\" ]]; then\n echo \"removing $target_file.\"\n mv -f \"$target_file\" \"$trash/${file_name}_${timestamp}_${rand}\"\n else\n echo \"$target_file doesn't exist.\"\n fi\n}\n\nremove_launchctl_service 'com.nordvpn.macos.teams'\nremove_launchctl_service 'com.nordvpn.macos.teams.assistant'\nremove_launchctl_service 'com.nordvpn.macos.teams.helper'\nquit_application 'com.nordvpn.macos.teams'\nremove_pkg_files 'com.nordvpn.macos.teams'\nforget_pkg 'com.nordvpn.macos.teams'\ntrash $LOGGED_IN_USER '~/Library/Application Scripts/com.nordvpn.macos.teams'\ntrash $LOGGED_IN_USER '~/Library/Application Support/com.apple.sharedfilelist/com.apple.LSSharedFileList.ApplicationRecentDocuments/com.nordvpn.macos.teams.sfl*'\ntrash $LOGGED_IN_USER '~/Library/Application Support/com.nordvpn.macos.teams'\ntrash $LOGGED_IN_USER '~/Library/Caches/com.nordvpn.macos.teams'\ntrash $LOGGED_IN_USER '~/Library/Containers/com.nordvpn.macos.teams'\ntrash $LOGGED_IN_USER '~/Library/HTTPStorages/com.nordvpn.macos.teams'\ntrash $LOGGED_IN_USER '~/Library/Preferences/com.nordvpn.macos.teams.plist'\n", + "f9f57c4d": "#!/bin/bash\n\n# variables\nAPPDIR=\"/Applications/\"\nTMPDIR=$(dirname \"$(realpath \"$INSTALLER_PATH\")\")\n# functions\n\nquit_and_track_application() {\n local bundle_id=\"$1\"\n local var_name=\"APP_WAS_RUNNING_$(echo \"$bundle_id\" | tr '.-' '__')\"\n local timeout_duration=10\n\n # check if the application is running\n local app_running\n app_running=$(osascript -e \"application id \\\"$bundle_id\\\" is running\" 2>/dev/null)\n if [[ \"$app_running\" != \"true\" ]]; then\n eval \"export $var_name=0\"\n return\n fi\n\n local console_user\n console_user=$(stat -f \"%Su\" /dev/console)\n if [[ -z \"$console_user\" || \"$console_user\" == \"root\" || \"$console_user\" == \"loginwindow\" ]]; then\n echo \"Not logged into a non-root GUI; skipping quitting application ID '$bundle_id'.\"\n eval \"export $var_name=0\"\n return\n fi\n\n # App was running, mark it for relaunch\n eval \"export $var_name=1\"\n echo \"Application '$bundle_id' was running; will relaunch after installation.\"\n\n echo \"Quitting application '$bundle_id'...\"\n\n # try to quit the application within the timeout period\n local quit_success=false\n SECONDS=0\n while (( SECONDS < timeout_duration )); do\n if osascript -e \"tell application id \\\"$bundle_id\\\" to quit\" >/dev/null 2>&1; then\n if ! pgrep -f \"$bundle_id\" >/dev/null 2>&1; then\n echo \"Application '$bundle_id' quit successfully.\"\n quit_success=true\n break\n fi\n fi\n sleep 1\n done\n\n if [[ \"$quit_success\" = false ]]; then\n echo \"Application '$bundle_id' did not quit.\"\n fi\n}\n\n\nrelaunch_application() {\n local bundle_id=\"$1\"\n local var_name=\"APP_WAS_RUNNING_$(echo \"$bundle_id\" | tr '.-' '__')\"\n local was_running\n\n # Check if the app was running before installation\n eval \"was_running=\\$$var_name\"\n if [[ \"$was_running\" != \"1\" ]]; then\n return\n fi\n\n local console_user\n console_user=$(stat -f \"%Su\" /dev/console)\n if [[ -z \"$console_user\" || \"$console_user\" == \"root\" || \"$console_user\" == \"loginwindow\" ]]; then\n echo \"Not logged into a non-root GUI; skipping relaunching application ID '$bundle_id'.\"\n return\n fi\n\n echo \"Relaunching application '$bundle_id'...\"\n\n # Launch the app in the logged-in user's GUI session. Apps launched by root\n # won't register with the user's Dock/GUI, so run 'open' as the console user.\n # Use 'launchctl asuser' to bootstrap into the console user's Mach namespace\n # and GUI session — 'sudo -u' alone doesn't do this, which can cause\n # LSOpenURLsWithRole() failures even when 'open' exits 0.\n local open_status=0\n if [[ $EUID -eq 0 ]]; then\n local console_uid\n console_uid=$(id -u \"$console_user\")\n /bin/launchctl asuser \"$console_uid\" sudo -u \"$console_user\" open -b \"$bundle_id\" >/dev/null 2>&1 || open_status=$?\n else\n open -b \"$bundle_id\" >/dev/null 2>&1 || open_status=$?\n fi\n\n if [[ $open_status -eq 0 ]]; then\n echo \"Application '$bundle_id' relaunched successfully.\"\n else\n echo \"Failed to relaunch application '$bundle_id'.\"\n fi\n}\n\n\n# install pkg files\nquit_and_track_application 'com.nordvpn.macos.teams'\nsudo installer -pkg \"$TMPDIR/NordLayer_v3.10.0.pkg\" -target /\nrelaunch_application 'com.nordvpn.macos.teams'\n" + } +} diff --git a/ee/maintained-apps/outputs/nosql-workbench/darwin.json b/ee/maintained-apps/outputs/nosql-workbench/darwin.json new file mode 100644 index 00000000000..244ea78b4bc --- /dev/null +++ b/ee/maintained-apps/outputs/nosql-workbench/darwin.json @@ -0,0 +1,22 @@ +{ + "versions": [ + { + "version": "3.20.2", + "queries": { + "exists": "SELECT 1 FROM apps WHERE bundle_identifier = 'com.dynamodb.workbench';", + "patched": "SELECT 1 WHERE NOT EXISTS (SELECT 1 FROM apps WHERE bundle_identifier = 'com.dynamodb.workbench' AND version_compare(bundle_short_version, '3.20.2') < 0);" + }, + "installer_url": "https://nosql-workbench.s3.amazonaws.com/NoSQL%20Workbench-mac-arm64-3.20.2.dmg", + "install_script_ref": "2726eecb", + "uninstall_script_ref": "8ba01429", + "sha256": "53a19e6bcf7f71763d15de89016ad4b5fed0e157c45c33f36e30907073118e21", + "default_categories": [ + "Developer tools" + ] + } + ], + "refs": { + "2726eecb": "#!/bin/bash\n\n# variables\nAPPDIR=\"/Applications/\"\nTMPDIR=$(dirname \"$(realpath \"$INSTALLER_PATH\")\")\n# functions\n\nquit_and_track_application() {\n local bundle_id=\"$1\"\n local var_name=\"APP_WAS_RUNNING_$(echo \"$bundle_id\" | tr '.-' '__')\"\n local timeout_duration=10\n\n # check if the application is running\n local app_running\n app_running=$(osascript -e \"application id \\\"$bundle_id\\\" is running\" 2>/dev/null)\n if [[ \"$app_running\" != \"true\" ]]; then\n eval \"export $var_name=0\"\n return\n fi\n\n local console_user\n console_user=$(stat -f \"%Su\" /dev/console)\n if [[ -z \"$console_user\" || \"$console_user\" == \"root\" || \"$console_user\" == \"loginwindow\" ]]; then\n echo \"Not logged into a non-root GUI; skipping quitting application ID '$bundle_id'.\"\n eval \"export $var_name=0\"\n return\n fi\n\n # App was running, mark it for relaunch\n eval \"export $var_name=1\"\n echo \"Application '$bundle_id' was running; will relaunch after installation.\"\n\n echo \"Quitting application '$bundle_id'...\"\n\n # try to quit the application within the timeout period\n local quit_success=false\n SECONDS=0\n while (( SECONDS < timeout_duration )); do\n if osascript -e \"tell application id \\\"$bundle_id\\\" to quit\" >/dev/null 2>&1; then\n if ! pgrep -f \"$bundle_id\" >/dev/null 2>&1; then\n echo \"Application '$bundle_id' quit successfully.\"\n quit_success=true\n break\n fi\n fi\n sleep 1\n done\n\n if [[ \"$quit_success\" = false ]]; then\n echo \"Application '$bundle_id' did not quit.\"\n fi\n}\n\n\nrelaunch_application() {\n local bundle_id=\"$1\"\n local var_name=\"APP_WAS_RUNNING_$(echo \"$bundle_id\" | tr '.-' '__')\"\n local was_running\n\n # Check if the app was running before installation\n eval \"was_running=\\$$var_name\"\n if [[ \"$was_running\" != \"1\" ]]; then\n return\n fi\n\n local console_user\n console_user=$(stat -f \"%Su\" /dev/console)\n if [[ -z \"$console_user\" || \"$console_user\" == \"root\" || \"$console_user\" == \"loginwindow\" ]]; then\n echo \"Not logged into a non-root GUI; skipping relaunching application ID '$bundle_id'.\"\n return\n fi\n\n echo \"Relaunching application '$bundle_id'...\"\n\n # Launch the app in the logged-in user's GUI session. Apps launched by root\n # won't register with the user's Dock/GUI, so run 'open' as the console user.\n # Use 'launchctl asuser' to bootstrap into the console user's Mach namespace\n # and GUI session — 'sudo -u' alone doesn't do this, which can cause\n # LSOpenURLsWithRole() failures even when 'open' exits 0.\n local open_status=0\n if [[ $EUID -eq 0 ]]; then\n local console_uid\n console_uid=$(id -u \"$console_user\")\n /bin/launchctl asuser \"$console_uid\" sudo -u \"$console_user\" open -b \"$bundle_id\" >/dev/null 2>&1 || open_status=$?\n else\n open -b \"$bundle_id\" >/dev/null 2>&1 || open_status=$?\n fi\n\n if [[ $open_status -eq 0 ]]; then\n echo \"Application '$bundle_id' relaunched successfully.\"\n else\n echo \"Failed to relaunch application '$bundle_id'.\"\n fi\n}\n\n\n# extract contents\nMOUNT_POINT=$(mktemp -d /tmp/dmg_mount_XXXXXX)\nyes | hdiutil attach -plist -nobrowse -readonly -mountpoint \"$MOUNT_POINT\" \"$INSTALLER_PATH\" || exit 1\nsudo cp -R \"$MOUNT_POINT\"/* \"$TMPDIR\"\nhdiutil detach \"$MOUNT_POINT\" || true\n# copy to the applications folder\nquit_and_track_application 'com.dynamodb.workbench'\nif [ -d \"$APPDIR/NoSQL Workbench.app\" ]; then\n\tsudo mv \"$APPDIR/NoSQL Workbench.app\" \"$TMPDIR/NoSQL Workbench.app.bkp\"\nfi\nsudo cp -R \"$TMPDIR/NoSQL Workbench.app\" \"$APPDIR\"\nrelaunch_application 'com.dynamodb.workbench'\n", + "8ba01429": "#!/bin/bash\n\n# variables\nAPPDIR=\"/Applications/\"\nLOGGED_IN_USER=$(scutil <<< \"show State:/Users/ConsoleUser\" | awk '/Name :/ { print $3 }')\n# functions\n\ntrash() {\n local logged_in_user=\"$1\"\n local target_file=\"$2\"\n local timestamp=\"$(date +%Y-%m-%d-%s)\"\n local rand=\"$(jot -r 1 0 99999)\"\n\n # replace ~ with /Users/$logged_in_user\n if [[ \"$target_file\" == ~* ]]; then\n target_file=\"/Users/$logged_in_user${target_file:1}\"\n fi\n\n local trash=\"/Users/$logged_in_user/.Trash\"\n\n # If the target contains glob characters, expand it and move each match.\n if [[ \"$target_file\" == *[*?[]* ]]; then\n local file file_name\n local matched=false\n local i=0\n # compgen -G expands the (quoted) pattern itself, so paths containing\n # spaces glob correctly; reading line by line keeps each match intact.\n while IFS= read -r file; do\n [[ -n \"$file\" ]] || continue\n [[ -e \"$file\" || -L \"$file\" ]] || continue\n matched=true\n i=$((i + 1))\n file_name=\"$(basename \"$file\")\"\n echo \"removing $file.\"\n # The per-match counter keeps matches that share a basename from\n # overwriting each other in the trash.\n mv -f \"$file\" \"$trash/${file_name}_${timestamp}_${rand}_${i}\"\n done < <(compgen -G \"$target_file\" 2>/dev/null)\n if [[ \"$matched\" == false ]]; then\n echo \"$target_file doesn't exist.\"\n fi\n return\n fi\n\n local file_name=\"$(basename \"${target_file}\")\"\n\n if [[ -e \"$target_file\" ]]; then\n echo \"removing $target_file.\"\n mv -f \"$target_file\" \"$trash/${file_name}_${timestamp}_${rand}\"\n else\n echo \"$target_file doesn't exist.\"\n fi\n}\n\nsudo rm -rf \"$APPDIR/NoSQL Workbench.app\"\ntrash $LOGGED_IN_USER '~/Library/Application Support/Caches/nosql-workbench-updater'\ntrash $LOGGED_IN_USER '~/Library/Application Support/NoSQL Workbench'\ntrash $LOGGED_IN_USER '~/Library/Caches/com.dynamodb.workbench'\ntrash $LOGGED_IN_USER '~/Library/Caches/com.dynamodb.workbench.ShipIt'\ntrash $LOGGED_IN_USER '~/Library/Preferences/com.dynamodb.workbench.plist'\ntrash $LOGGED_IN_USER '~/Library/Saved Application State/com.dynamodb.workbench.savedState'\n" + } +} diff --git a/ee/maintained-apps/outputs/notchnook/darwin.json b/ee/maintained-apps/outputs/notchnook/darwin.json new file mode 100644 index 00000000000..f67ffe00681 --- /dev/null +++ b/ee/maintained-apps/outputs/notchnook/darwin.json @@ -0,0 +1,22 @@ +{ + "versions": [ + { + "version": "1.5.5", + "queries": { + "exists": "SELECT 1 FROM apps WHERE bundle_identifier = 'lo.cafe.NotchNook';", + "patched": "SELECT 1 WHERE NOT EXISTS (SELECT 1 FROM apps WHERE bundle_identifier = 'lo.cafe.NotchNook' AND version_compare(bundle_short_version, '1.5.5') < 0);" + }, + "installer_url": "https://lo.cafe/notchnook-files/NotchNook-1.5.5.zip", + "install_script_ref": "f99dc21b", + "uninstall_script_ref": "2b68da1f", + "sha256": "11d03f16e8de481a1ee7bc910736ef67df2922ab8a1cb823d0e4f502b29fe527", + "default_categories": [ + "Utilities" + ] + } + ], + "refs": { + "2b68da1f": "#!/bin/bash\n\n# variables\nAPPDIR=\"/Applications/\"\nLOGGED_IN_USER=$(scutil <<< \"show State:/Users/ConsoleUser\" | awk '/Name :/ { print $3 }')\n# functions\n\ntrash() {\n local logged_in_user=\"$1\"\n local target_file=\"$2\"\n local timestamp=\"$(date +%Y-%m-%d-%s)\"\n local rand=\"$(jot -r 1 0 99999)\"\n\n # replace ~ with /Users/$logged_in_user\n if [[ \"$target_file\" == ~* ]]; then\n target_file=\"/Users/$logged_in_user${target_file:1}\"\n fi\n\n local trash=\"/Users/$logged_in_user/.Trash\"\n\n # If the target contains glob characters, expand it and move each match.\n if [[ \"$target_file\" == *[*?[]* ]]; then\n local file file_name\n local matched=false\n local i=0\n # compgen -G expands the (quoted) pattern itself, so paths containing\n # spaces glob correctly; reading line by line keeps each match intact.\n while IFS= read -r file; do\n [[ -n \"$file\" ]] || continue\n [[ -e \"$file\" || -L \"$file\" ]] || continue\n matched=true\n i=$((i + 1))\n file_name=\"$(basename \"$file\")\"\n echo \"removing $file.\"\n # The per-match counter keeps matches that share a basename from\n # overwriting each other in the trash.\n mv -f \"$file\" \"$trash/${file_name}_${timestamp}_${rand}_${i}\"\n done < <(compgen -G \"$target_file\" 2>/dev/null)\n if [[ \"$matched\" == false ]]; then\n echo \"$target_file doesn't exist.\"\n fi\n return\n fi\n\n local file_name=\"$(basename \"${target_file}\")\"\n\n if [[ -e \"$target_file\" ]]; then\n echo \"removing $target_file.\"\n mv -f \"$target_file\" \"$trash/${file_name}_${timestamp}_${rand}\"\n else\n echo \"$target_file doesn't exist.\"\n fi\n}\n\nsudo rm -rf \"$APPDIR/NotchNook.app\"\ntrash $LOGGED_IN_USER '~/Library/Application Support/NotchNook'\ntrash $LOGGED_IN_USER '~/Library/Caches/lo.cafe.NotchNook'\ntrash $LOGGED_IN_USER '~/Library/HTTPStorages/lo.cafe.NotchNook'\ntrash $LOGGED_IN_USER '~/Library/Preferences/lo.cafe.NotchNook.plist'\n", + "f99dc21b": "#!/bin/bash\n\n# variables\nAPPDIR=\"/Applications/\"\nTMPDIR=$(dirname \"$(realpath \"$INSTALLER_PATH\")\")\n# functions\n\nquit_and_track_application() {\n local bundle_id=\"$1\"\n local var_name=\"APP_WAS_RUNNING_$(echo \"$bundle_id\" | tr '.-' '__')\"\n local timeout_duration=10\n\n # check if the application is running\n local app_running\n app_running=$(osascript -e \"application id \\\"$bundle_id\\\" is running\" 2>/dev/null)\n if [[ \"$app_running\" != \"true\" ]]; then\n eval \"export $var_name=0\"\n return\n fi\n\n local console_user\n console_user=$(stat -f \"%Su\" /dev/console)\n if [[ -z \"$console_user\" || \"$console_user\" == \"root\" || \"$console_user\" == \"loginwindow\" ]]; then\n echo \"Not logged into a non-root GUI; skipping quitting application ID '$bundle_id'.\"\n eval \"export $var_name=0\"\n return\n fi\n\n # App was running, mark it for relaunch\n eval \"export $var_name=1\"\n echo \"Application '$bundle_id' was running; will relaunch after installation.\"\n\n echo \"Quitting application '$bundle_id'...\"\n\n # try to quit the application within the timeout period\n local quit_success=false\n SECONDS=0\n while (( SECONDS < timeout_duration )); do\n if osascript -e \"tell application id \\\"$bundle_id\\\" to quit\" >/dev/null 2>&1; then\n if ! pgrep -f \"$bundle_id\" >/dev/null 2>&1; then\n echo \"Application '$bundle_id' quit successfully.\"\n quit_success=true\n break\n fi\n fi\n sleep 1\n done\n\n if [[ \"$quit_success\" = false ]]; then\n echo \"Application '$bundle_id' did not quit.\"\n fi\n}\n\n\nrelaunch_application() {\n local bundle_id=\"$1\"\n local var_name=\"APP_WAS_RUNNING_$(echo \"$bundle_id\" | tr '.-' '__')\"\n local was_running\n\n # Check if the app was running before installation\n eval \"was_running=\\$$var_name\"\n if [[ \"$was_running\" != \"1\" ]]; then\n return\n fi\n\n local console_user\n console_user=$(stat -f \"%Su\" /dev/console)\n if [[ -z \"$console_user\" || \"$console_user\" == \"root\" || \"$console_user\" == \"loginwindow\" ]]; then\n echo \"Not logged into a non-root GUI; skipping relaunching application ID '$bundle_id'.\"\n return\n fi\n\n echo \"Relaunching application '$bundle_id'...\"\n\n # Launch the app in the logged-in user's GUI session. Apps launched by root\n # won't register with the user's Dock/GUI, so run 'open' as the console user.\n # Use 'launchctl asuser' to bootstrap into the console user's Mach namespace\n # and GUI session — 'sudo -u' alone doesn't do this, which can cause\n # LSOpenURLsWithRole() failures even when 'open' exits 0.\n local open_status=0\n if [[ $EUID -eq 0 ]]; then\n local console_uid\n console_uid=$(id -u \"$console_user\")\n /bin/launchctl asuser \"$console_uid\" sudo -u \"$console_user\" open -b \"$bundle_id\" >/dev/null 2>&1 || open_status=$?\n else\n open -b \"$bundle_id\" >/dev/null 2>&1 || open_status=$?\n fi\n\n if [[ $open_status -eq 0 ]]; then\n echo \"Application '$bundle_id' relaunched successfully.\"\n else\n echo \"Failed to relaunch application '$bundle_id'.\"\n fi\n}\n\n\n# extract contents\nunzip \"$INSTALLER_PATH\" -d \"$TMPDIR\"\n# copy to the applications folder\nquit_and_track_application 'lo.cafe.NotchNook'\nif [ -d \"$APPDIR/NotchNook.app\" ]; then\n\tsudo mv \"$APPDIR/NotchNook.app\" \"$TMPDIR/NotchNook.app.bkp\"\nfi\nsudo cp -R \"$TMPDIR/NotchNook.app\" \"$APPDIR\"\nrelaunch_application 'lo.cafe.NotchNook'\n" + } +} diff --git a/ee/maintained-apps/outputs/notepadexe/darwin.json b/ee/maintained-apps/outputs/notepadexe/darwin.json new file mode 100644 index 00000000000..94e2ff435d8 --- /dev/null +++ b/ee/maintained-apps/outputs/notepadexe/darwin.json @@ -0,0 +1,22 @@ +{ + "versions": [ + { + "version": "1.4.1803", + "queries": { + "exists": "SELECT 1 FROM apps WHERE bundle_identifier = 'best.swift.Notepad';", + "patched": "SELECT 1 WHERE NOT EXISTS (SELECT 1 FROM apps WHERE bundle_identifier = 'best.swift.Notepad' AND version_compare(bundle_short_version, '1.4.1803') < 0);" + }, + "installer_url": "https://github.com/notepadhq/notepadexe-public/releases/download/1.4.1803/Notepad.zip", + "install_script_ref": "17716d6a", + "uninstall_script_ref": "7d5a03ab", + "sha256": "769160491fe526458b303fef73b539e9ad05509593055af444ed96d4838f365f", + "default_categories": [ + "Developer tools" + ] + } + ], + "refs": { + "17716d6a": "#!/bin/bash\n\n# variables\nAPPDIR=\"/Applications/\"\nTMPDIR=$(dirname \"$(realpath \"$INSTALLER_PATH\")\")\n# functions\n\nquit_and_track_application() {\n local bundle_id=\"$1\"\n local var_name=\"APP_WAS_RUNNING_$(echo \"$bundle_id\" | tr '.-' '__')\"\n local timeout_duration=10\n\n # check if the application is running\n local app_running\n app_running=$(osascript -e \"application id \\\"$bundle_id\\\" is running\" 2>/dev/null)\n if [[ \"$app_running\" != \"true\" ]]; then\n eval \"export $var_name=0\"\n return\n fi\n\n local console_user\n console_user=$(stat -f \"%Su\" /dev/console)\n if [[ -z \"$console_user\" || \"$console_user\" == \"root\" || \"$console_user\" == \"loginwindow\" ]]; then\n echo \"Not logged into a non-root GUI; skipping quitting application ID '$bundle_id'.\"\n eval \"export $var_name=0\"\n return\n fi\n\n # App was running, mark it for relaunch\n eval \"export $var_name=1\"\n echo \"Application '$bundle_id' was running; will relaunch after installation.\"\n\n echo \"Quitting application '$bundle_id'...\"\n\n # try to quit the application within the timeout period\n local quit_success=false\n SECONDS=0\n while (( SECONDS < timeout_duration )); do\n if osascript -e \"tell application id \\\"$bundle_id\\\" to quit\" >/dev/null 2>&1; then\n if ! pgrep -f \"$bundle_id\" >/dev/null 2>&1; then\n echo \"Application '$bundle_id' quit successfully.\"\n quit_success=true\n break\n fi\n fi\n sleep 1\n done\n\n if [[ \"$quit_success\" = false ]]; then\n echo \"Application '$bundle_id' did not quit.\"\n fi\n}\n\n\nrelaunch_application() {\n local bundle_id=\"$1\"\n local var_name=\"APP_WAS_RUNNING_$(echo \"$bundle_id\" | tr '.-' '__')\"\n local was_running\n\n # Check if the app was running before installation\n eval \"was_running=\\$$var_name\"\n if [[ \"$was_running\" != \"1\" ]]; then\n return\n fi\n\n local console_user\n console_user=$(stat -f \"%Su\" /dev/console)\n if [[ -z \"$console_user\" || \"$console_user\" == \"root\" || \"$console_user\" == \"loginwindow\" ]]; then\n echo \"Not logged into a non-root GUI; skipping relaunching application ID '$bundle_id'.\"\n return\n fi\n\n echo \"Relaunching application '$bundle_id'...\"\n\n # Launch the app in the logged-in user's GUI session. Apps launched by root\n # won't register with the user's Dock/GUI, so run 'open' as the console user.\n # Use 'launchctl asuser' to bootstrap into the console user's Mach namespace\n # and GUI session — 'sudo -u' alone doesn't do this, which can cause\n # LSOpenURLsWithRole() failures even when 'open' exits 0.\n local open_status=0\n if [[ $EUID -eq 0 ]]; then\n local console_uid\n console_uid=$(id -u \"$console_user\")\n /bin/launchctl asuser \"$console_uid\" sudo -u \"$console_user\" open -b \"$bundle_id\" >/dev/null 2>&1 || open_status=$?\n else\n open -b \"$bundle_id\" >/dev/null 2>&1 || open_status=$?\n fi\n\n if [[ $open_status -eq 0 ]]; then\n echo \"Application '$bundle_id' relaunched successfully.\"\n else\n echo \"Failed to relaunch application '$bundle_id'.\"\n fi\n}\n\n\n# extract contents\nunzip \"$INSTALLER_PATH\" -d \"$TMPDIR\"\n# copy to the applications folder\nquit_and_track_application 'best.swift.Notepad'\nif [ -d \"$APPDIR/Notepad.exe.app\" ]; then\n\tsudo mv \"$APPDIR/Notepad.exe.app\" \"$TMPDIR/Notepad.exe.app.bkp\"\nfi\nsudo cp -R \"$TMPDIR/Notepad.exe.app\" \"$APPDIR\"\nrelaunch_application 'best.swift.Notepad'\n", + "7d5a03ab": "#!/bin/bash\n\n# variables\nAPPDIR=\"/Applications/\"\nLOGGED_IN_USER=$(scutil <<< \"show State:/Users/ConsoleUser\" | awk '/Name :/ { print $3 }')\n# functions\n\ntrash() {\n local logged_in_user=\"$1\"\n local target_file=\"$2\"\n local timestamp=\"$(date +%Y-%m-%d-%s)\"\n local rand=\"$(jot -r 1 0 99999)\"\n\n # replace ~ with /Users/$logged_in_user\n if [[ \"$target_file\" == ~* ]]; then\n target_file=\"/Users/$logged_in_user${target_file:1}\"\n fi\n\n local trash=\"/Users/$logged_in_user/.Trash\"\n\n # If the target contains glob characters, expand it and move each match.\n if [[ \"$target_file\" == *[*?[]* ]]; then\n local file file_name\n local matched=false\n local i=0\n # compgen -G expands the (quoted) pattern itself, so paths containing\n # spaces glob correctly; reading line by line keeps each match intact.\n while IFS= read -r file; do\n [[ -n \"$file\" ]] || continue\n [[ -e \"$file\" || -L \"$file\" ]] || continue\n matched=true\n i=$((i + 1))\n file_name=\"$(basename \"$file\")\"\n echo \"removing $file.\"\n # The per-match counter keeps matches that share a basename from\n # overwriting each other in the trash.\n mv -f \"$file\" \"$trash/${file_name}_${timestamp}_${rand}_${i}\"\n done < <(compgen -G \"$target_file\" 2>/dev/null)\n if [[ \"$matched\" == false ]]; then\n echo \"$target_file doesn't exist.\"\n fi\n return\n fi\n\n local file_name=\"$(basename \"${target_file}\")\"\n\n if [[ -e \"$target_file\" ]]; then\n echo \"removing $target_file.\"\n mv -f \"$target_file\" \"$trash/${file_name}_${timestamp}_${rand}\"\n else\n echo \"$target_file doesn't exist.\"\n fi\n}\n\nsudo rm -rf \"$APPDIR/Notepad.exe.app\"\ntrash $LOGGED_IN_USER '~/Library/Application Support/com.apple.sharedfilelist/com.apple.LSSharedFileList.ApplicationRecentDocuments/best.swift.notepad.sfl*'\ntrash $LOGGED_IN_USER '~/Library/Application Support/Notepad.exe'\ntrash $LOGGED_IN_USER '~/Library/Autosave Information/Notepad.exe'\ntrash $LOGGED_IN_USER '~/Library/Caches/Notepad.exe'\ntrash $LOGGED_IN_USER '~/Library/Caches/SentryCrash/Notepad.exe'\ntrash $LOGGED_IN_USER '~/Library/HTTPStorages/best.swift.Notepad'\ntrash $LOGGED_IN_USER '~/Library/Notepad.exe'\ntrash $LOGGED_IN_USER '~/Library/Preferences/best.swift.Notepad.plist'\n" + } +} diff --git a/ee/maintained-apps/outputs/notesnook/darwin.json b/ee/maintained-apps/outputs/notesnook/darwin.json new file mode 100644 index 00000000000..1d88fe5663b --- /dev/null +++ b/ee/maintained-apps/outputs/notesnook/darwin.json @@ -0,0 +1,22 @@ +{ + "versions": [ + { + "version": "3.3.22", + "queries": { + "exists": "SELECT 1 FROM apps WHERE bundle_identifier = 'com.streetwriters.notesnook';", + "patched": "SELECT 1 WHERE NOT EXISTS (SELECT 1 FROM apps WHERE bundle_identifier = 'com.streetwriters.notesnook' AND version_compare(bundle_short_version, '3.3.22') < 0);" + }, + "installer_url": "https://github.com/streetwriters/notesnook/releases/download/v3.3.22/notesnook_mac_arm64.dmg", + "install_script_ref": "458f8fba", + "uninstall_script_ref": "181a288a", + "sha256": "78c7bfcc2d0895fc5be23d6d13f9818b7c3de3db1ce5161ea6c8ce9bc192212d", + "default_categories": [ + "Productivity" + ] + } + ], + "refs": { + "181a288a": "#!/bin/bash\n\n# variables\nAPPDIR=\"/Applications/\"\nLOGGED_IN_USER=$(scutil <<< \"show State:/Users/ConsoleUser\" | awk '/Name :/ { print $3 }')\n# functions\n\ntrash() {\n local logged_in_user=\"$1\"\n local target_file=\"$2\"\n local timestamp=\"$(date +%Y-%m-%d-%s)\"\n local rand=\"$(jot -r 1 0 99999)\"\n\n # replace ~ with /Users/$logged_in_user\n if [[ \"$target_file\" == ~* ]]; then\n target_file=\"/Users/$logged_in_user${target_file:1}\"\n fi\n\n local trash=\"/Users/$logged_in_user/.Trash\"\n\n # If the target contains glob characters, expand it and move each match.\n if [[ \"$target_file\" == *[*?[]* ]]; then\n local file file_name\n local matched=false\n local i=0\n # compgen -G expands the (quoted) pattern itself, so paths containing\n # spaces glob correctly; reading line by line keeps each match intact.\n while IFS= read -r file; do\n [[ -n \"$file\" ]] || continue\n [[ -e \"$file\" || -L \"$file\" ]] || continue\n matched=true\n i=$((i + 1))\n file_name=\"$(basename \"$file\")\"\n echo \"removing $file.\"\n # The per-match counter keeps matches that share a basename from\n # overwriting each other in the trash.\n mv -f \"$file\" \"$trash/${file_name}_${timestamp}_${rand}_${i}\"\n done < <(compgen -G \"$target_file\" 2>/dev/null)\n if [[ \"$matched\" == false ]]; then\n echo \"$target_file doesn't exist.\"\n fi\n return\n fi\n\n local file_name=\"$(basename \"${target_file}\")\"\n\n if [[ -e \"$target_file\" ]]; then\n echo \"removing $target_file.\"\n mv -f \"$target_file\" \"$trash/${file_name}_${timestamp}_${rand}\"\n else\n echo \"$target_file doesn't exist.\"\n fi\n}\n\nsudo rm -rf \"$APPDIR/Notesnook.app\"\ntrash $LOGGED_IN_USER '~/Library/Application Support/Notesnook'\ntrash $LOGGED_IN_USER '~/Library/Logs/Notesnook'\ntrash $LOGGED_IN_USER '~/Library/Preferences/com.streetwriters.notesnook.plist'\n", + "458f8fba": "#!/bin/bash\n\n# variables\nAPPDIR=\"/Applications/\"\nTMPDIR=$(dirname \"$(realpath \"$INSTALLER_PATH\")\")\n# functions\n\nquit_and_track_application() {\n local bundle_id=\"$1\"\n local var_name=\"APP_WAS_RUNNING_$(echo \"$bundle_id\" | tr '.-' '__')\"\n local timeout_duration=10\n\n # check if the application is running\n local app_running\n app_running=$(osascript -e \"application id \\\"$bundle_id\\\" is running\" 2>/dev/null)\n if [[ \"$app_running\" != \"true\" ]]; then\n eval \"export $var_name=0\"\n return\n fi\n\n local console_user\n console_user=$(stat -f \"%Su\" /dev/console)\n if [[ -z \"$console_user\" || \"$console_user\" == \"root\" || \"$console_user\" == \"loginwindow\" ]]; then\n echo \"Not logged into a non-root GUI; skipping quitting application ID '$bundle_id'.\"\n eval \"export $var_name=0\"\n return\n fi\n\n # App was running, mark it for relaunch\n eval \"export $var_name=1\"\n echo \"Application '$bundle_id' was running; will relaunch after installation.\"\n\n echo \"Quitting application '$bundle_id'...\"\n\n # try to quit the application within the timeout period\n local quit_success=false\n SECONDS=0\n while (( SECONDS < timeout_duration )); do\n if osascript -e \"tell application id \\\"$bundle_id\\\" to quit\" >/dev/null 2>&1; then\n if ! pgrep -f \"$bundle_id\" >/dev/null 2>&1; then\n echo \"Application '$bundle_id' quit successfully.\"\n quit_success=true\n break\n fi\n fi\n sleep 1\n done\n\n if [[ \"$quit_success\" = false ]]; then\n echo \"Application '$bundle_id' did not quit.\"\n fi\n}\n\n\nrelaunch_application() {\n local bundle_id=\"$1\"\n local var_name=\"APP_WAS_RUNNING_$(echo \"$bundle_id\" | tr '.-' '__')\"\n local was_running\n\n # Check if the app was running before installation\n eval \"was_running=\\$$var_name\"\n if [[ \"$was_running\" != \"1\" ]]; then\n return\n fi\n\n local console_user\n console_user=$(stat -f \"%Su\" /dev/console)\n if [[ -z \"$console_user\" || \"$console_user\" == \"root\" || \"$console_user\" == \"loginwindow\" ]]; then\n echo \"Not logged into a non-root GUI; skipping relaunching application ID '$bundle_id'.\"\n return\n fi\n\n echo \"Relaunching application '$bundle_id'...\"\n\n # Launch the app in the logged-in user's GUI session. Apps launched by root\n # won't register with the user's Dock/GUI, so run 'open' as the console user.\n # Use 'launchctl asuser' to bootstrap into the console user's Mach namespace\n # and GUI session — 'sudo -u' alone doesn't do this, which can cause\n # LSOpenURLsWithRole() failures even when 'open' exits 0.\n local open_status=0\n if [[ $EUID -eq 0 ]]; then\n local console_uid\n console_uid=$(id -u \"$console_user\")\n /bin/launchctl asuser \"$console_uid\" sudo -u \"$console_user\" open -b \"$bundle_id\" >/dev/null 2>&1 || open_status=$?\n else\n open -b \"$bundle_id\" >/dev/null 2>&1 || open_status=$?\n fi\n\n if [[ $open_status -eq 0 ]]; then\n echo \"Application '$bundle_id' relaunched successfully.\"\n else\n echo \"Failed to relaunch application '$bundle_id'.\"\n fi\n}\n\n\n# extract contents\nMOUNT_POINT=$(mktemp -d /tmp/dmg_mount_XXXXXX)\nyes | hdiutil attach -plist -nobrowse -readonly -mountpoint \"$MOUNT_POINT\" \"$INSTALLER_PATH\" || exit 1\nsudo cp -R \"$MOUNT_POINT\"/* \"$TMPDIR\"\nhdiutil detach \"$MOUNT_POINT\" || true\n# copy to the applications folder\nquit_and_track_application 'com.streetwriters.notesnook'\nif [ -d \"$APPDIR/Notesnook.app\" ]; then\n\tsudo mv \"$APPDIR/Notesnook.app\" \"$TMPDIR/Notesnook.app.bkp\"\nfi\nsudo cp -R \"$TMPDIR/Notesnook.app\" \"$APPDIR\"\nrelaunch_application 'com.streetwriters.notesnook'\n" + } +} diff --git a/ee/maintained-apps/outputs/notesollama/darwin.json b/ee/maintained-apps/outputs/notesollama/darwin.json new file mode 100644 index 00000000000..e9b232891fa --- /dev/null +++ b/ee/maintained-apps/outputs/notesollama/darwin.json @@ -0,0 +1,22 @@ +{ + "versions": [ + { + "version": "0.2.6", + "queries": { + "exists": "SELECT 1 FROM apps WHERE bundle_identifier = 'app.smallest.NotesOllama';", + "patched": "SELECT 1 WHERE NOT EXISTS (SELECT 1 FROM apps WHERE bundle_identifier = 'app.smallest.NotesOllama' AND version_compare(bundle_short_version, '0.2.6') < 0);" + }, + "installer_url": "https://smallest.app/notesollama/dist/NotesOllama-0.2.6.zip", + "install_script_ref": "31f5c074", + "uninstall_script_ref": "2c054134", + "sha256": "9b2a94e5d366686bee91942bad9967e6e00558024d78438b05efd92f3bee79b1", + "default_categories": [ + "Productivity" + ] + } + ], + "refs": { + "2c054134": "#!/bin/bash\n\n# variables\nAPPDIR=\"/Applications/\"\nLOGGED_IN_USER=$(scutil <<< \"show State:/Users/ConsoleUser\" | awk '/Name :/ { print $3 }')\n# functions\n\nquit_application() {\n local bundle_id=\"$1\"\n local timeout_duration=10\n\n # check if the application is running\n local app_running\n app_running=$(osascript -e \"application id \\\"$bundle_id\\\" is running\" 2>/dev/null)\n if [[ \"$app_running\" != \"true\" ]]; then\n return\n fi\n\n local console_user\n console_user=$(stat -f \"%Su\" /dev/console)\n if [[ -z \"$console_user\" || \"$console_user\" == \"root\" || \"$console_user\" == \"loginwindow\" ]]; then\n echo \"Not logged into a non-root GUI; skipping quitting application ID '$bundle_id'.\"\n return\n fi\n\n echo \"Quitting application '$bundle_id'...\"\n\n # try to quit the application within the timeout period\n local quit_success=false\n SECONDS=0\n while (( SECONDS < timeout_duration )); do\n if osascript -e \"tell application id \\\"$bundle_id\\\" to quit\" >/dev/null 2>&1; then\n if ! pgrep -f \"$bundle_id\" >/dev/null 2>&1; then\n echo \"Application '$bundle_id' quit successfully.\"\n quit_success=true\n break\n fi\n fi\n sleep 1\n done\n\n if [[ \"$quit_success\" = false ]]; then\n echo \"Application '$bundle_id' did not quit.\"\n fi\n}\n\n\ntrash() {\n local logged_in_user=\"$1\"\n local target_file=\"$2\"\n local timestamp=\"$(date +%Y-%m-%d-%s)\"\n local rand=\"$(jot -r 1 0 99999)\"\n\n # replace ~ with /Users/$logged_in_user\n if [[ \"$target_file\" == ~* ]]; then\n target_file=\"/Users/$logged_in_user${target_file:1}\"\n fi\n\n local trash=\"/Users/$logged_in_user/.Trash\"\n\n # If the target contains glob characters, expand it and move each match.\n if [[ \"$target_file\" == *[*?[]* ]]; then\n local file file_name\n local matched=false\n local i=0\n # compgen -G expands the (quoted) pattern itself, so paths containing\n # spaces glob correctly; reading line by line keeps each match intact.\n while IFS= read -r file; do\n [[ -n \"$file\" ]] || continue\n [[ -e \"$file\" || -L \"$file\" ]] || continue\n matched=true\n i=$((i + 1))\n file_name=\"$(basename \"$file\")\"\n echo \"removing $file.\"\n # The per-match counter keeps matches that share a basename from\n # overwriting each other in the trash.\n mv -f \"$file\" \"$trash/${file_name}_${timestamp}_${rand}_${i}\"\n done < <(compgen -G \"$target_file\" 2>/dev/null)\n if [[ \"$matched\" == false ]]; then\n echo \"$target_file doesn't exist.\"\n fi\n return\n fi\n\n local file_name=\"$(basename \"${target_file}\")\"\n\n if [[ -e \"$target_file\" ]]; then\n echo \"removing $target_file.\"\n mv -f \"$target_file\" \"$trash/${file_name}_${timestamp}_${rand}\"\n else\n echo \"$target_file doesn't exist.\"\n fi\n}\n\nquit_application 'NotesOllama'\nsudo rm -rf \"$APPDIR/NotesOllama.app\"\ntrash $LOGGED_IN_USER '~/Library/Caches/app.smallest.NotesOllama'\ntrash $LOGGED_IN_USER '~/Library/HTTPStorages/app.smallest.NotesOllama'\n", + "31f5c074": "#!/bin/bash\n\n# variables\nAPPDIR=\"/Applications/\"\nTMPDIR=$(dirname \"$(realpath \"$INSTALLER_PATH\")\")\n# functions\n\nquit_and_track_application() {\n local bundle_id=\"$1\"\n local var_name=\"APP_WAS_RUNNING_$(echo \"$bundle_id\" | tr '.-' '__')\"\n local timeout_duration=10\n\n # check if the application is running\n local app_running\n app_running=$(osascript -e \"application id \\\"$bundle_id\\\" is running\" 2>/dev/null)\n if [[ \"$app_running\" != \"true\" ]]; then\n eval \"export $var_name=0\"\n return\n fi\n\n local console_user\n console_user=$(stat -f \"%Su\" /dev/console)\n if [[ -z \"$console_user\" || \"$console_user\" == \"root\" || \"$console_user\" == \"loginwindow\" ]]; then\n echo \"Not logged into a non-root GUI; skipping quitting application ID '$bundle_id'.\"\n eval \"export $var_name=0\"\n return\n fi\n\n # App was running, mark it for relaunch\n eval \"export $var_name=1\"\n echo \"Application '$bundle_id' was running; will relaunch after installation.\"\n\n echo \"Quitting application '$bundle_id'...\"\n\n # try to quit the application within the timeout period\n local quit_success=false\n SECONDS=0\n while (( SECONDS < timeout_duration )); do\n if osascript -e \"tell application id \\\"$bundle_id\\\" to quit\" >/dev/null 2>&1; then\n if ! pgrep -f \"$bundle_id\" >/dev/null 2>&1; then\n echo \"Application '$bundle_id' quit successfully.\"\n quit_success=true\n break\n fi\n fi\n sleep 1\n done\n\n if [[ \"$quit_success\" = false ]]; then\n echo \"Application '$bundle_id' did not quit.\"\n fi\n}\n\n\nrelaunch_application() {\n local bundle_id=\"$1\"\n local var_name=\"APP_WAS_RUNNING_$(echo \"$bundle_id\" | tr '.-' '__')\"\n local was_running\n\n # Check if the app was running before installation\n eval \"was_running=\\$$var_name\"\n if [[ \"$was_running\" != \"1\" ]]; then\n return\n fi\n\n local console_user\n console_user=$(stat -f \"%Su\" /dev/console)\n if [[ -z \"$console_user\" || \"$console_user\" == \"root\" || \"$console_user\" == \"loginwindow\" ]]; then\n echo \"Not logged into a non-root GUI; skipping relaunching application ID '$bundle_id'.\"\n return\n fi\n\n echo \"Relaunching application '$bundle_id'...\"\n\n # Launch the app in the logged-in user's GUI session. Apps launched by root\n # won't register with the user's Dock/GUI, so run 'open' as the console user.\n # Use 'launchctl asuser' to bootstrap into the console user's Mach namespace\n # and GUI session — 'sudo -u' alone doesn't do this, which can cause\n # LSOpenURLsWithRole() failures even when 'open' exits 0.\n local open_status=0\n if [[ $EUID -eq 0 ]]; then\n local console_uid\n console_uid=$(id -u \"$console_user\")\n /bin/launchctl asuser \"$console_uid\" sudo -u \"$console_user\" open -b \"$bundle_id\" >/dev/null 2>&1 || open_status=$?\n else\n open -b \"$bundle_id\" >/dev/null 2>&1 || open_status=$?\n fi\n\n if [[ $open_status -eq 0 ]]; then\n echo \"Application '$bundle_id' relaunched successfully.\"\n else\n echo \"Failed to relaunch application '$bundle_id'.\"\n fi\n}\n\n\n# extract contents\nunzip \"$INSTALLER_PATH\" -d \"$TMPDIR\"\n# copy to the applications folder\nquit_and_track_application 'app.smallest.NotesOllama'\nif [ -d \"$APPDIR/NotesOllama.app\" ]; then\n\tsudo mv \"$APPDIR/NotesOllama.app\" \"$TMPDIR/NotesOllama.app.bkp\"\nfi\nsudo cp -R \"$TMPDIR/NotesOllama.app\" \"$APPDIR\"\nrelaunch_application 'app.smallest.NotesOllama'\n" + } +} diff --git a/ee/maintained-apps/outputs/noun-project/darwin.json b/ee/maintained-apps/outputs/noun-project/darwin.json new file mode 100644 index 00000000000..d91593395b5 --- /dev/null +++ b/ee/maintained-apps/outputs/noun-project/darwin.json @@ -0,0 +1,22 @@ +{ + "versions": [ + { + "version": "2.3", + "queries": { + "exists": "SELECT 1 FROM apps WHERE bundle_identifier = 'com.thenounproject.Noun-Project';", + "patched": "SELECT 1 WHERE NOT EXISTS (SELECT 1 FROM apps WHERE bundle_identifier = 'com.thenounproject.Noun-Project' AND version_compare(bundle_short_version, '2.3') < 0);" + }, + "installer_url": "https://nounproject.s3.amazonaws.com/mac/NounProject.dmg", + "install_script_ref": "0bf0670e", + "uninstall_script_ref": "bbd4da5a", + "sha256": "no_check", + "default_categories": [ + "Productivity" + ] + } + ], + "refs": { + "0bf0670e": "#!/bin/bash\n\n# variables\nAPPDIR=\"/Applications/\"\nTMPDIR=$(dirname \"$(realpath \"$INSTALLER_PATH\")\")\n# functions\n\nquit_and_track_application() {\n local bundle_id=\"$1\"\n local var_name=\"APP_WAS_RUNNING_$(echo \"$bundle_id\" | tr '.-' '__')\"\n local timeout_duration=10\n\n # check if the application is running\n local app_running\n app_running=$(osascript -e \"application id \\\"$bundle_id\\\" is running\" 2>/dev/null)\n if [[ \"$app_running\" != \"true\" ]]; then\n eval \"export $var_name=0\"\n return\n fi\n\n local console_user\n console_user=$(stat -f \"%Su\" /dev/console)\n if [[ -z \"$console_user\" || \"$console_user\" == \"root\" || \"$console_user\" == \"loginwindow\" ]]; then\n echo \"Not logged into a non-root GUI; skipping quitting application ID '$bundle_id'.\"\n eval \"export $var_name=0\"\n return\n fi\n\n # App was running, mark it for relaunch\n eval \"export $var_name=1\"\n echo \"Application '$bundle_id' was running; will relaunch after installation.\"\n\n echo \"Quitting application '$bundle_id'...\"\n\n # try to quit the application within the timeout period\n local quit_success=false\n SECONDS=0\n while (( SECONDS < timeout_duration )); do\n if osascript -e \"tell application id \\\"$bundle_id\\\" to quit\" >/dev/null 2>&1; then\n if ! pgrep -f \"$bundle_id\" >/dev/null 2>&1; then\n echo \"Application '$bundle_id' quit successfully.\"\n quit_success=true\n break\n fi\n fi\n sleep 1\n done\n\n if [[ \"$quit_success\" = false ]]; then\n echo \"Application '$bundle_id' did not quit.\"\n fi\n}\n\n\nrelaunch_application() {\n local bundle_id=\"$1\"\n local var_name=\"APP_WAS_RUNNING_$(echo \"$bundle_id\" | tr '.-' '__')\"\n local was_running\n\n # Check if the app was running before installation\n eval \"was_running=\\$$var_name\"\n if [[ \"$was_running\" != \"1\" ]]; then\n return\n fi\n\n local console_user\n console_user=$(stat -f \"%Su\" /dev/console)\n if [[ -z \"$console_user\" || \"$console_user\" == \"root\" || \"$console_user\" == \"loginwindow\" ]]; then\n echo \"Not logged into a non-root GUI; skipping relaunching application ID '$bundle_id'.\"\n return\n fi\n\n echo \"Relaunching application '$bundle_id'...\"\n\n # Launch the app in the logged-in user's GUI session. Apps launched by root\n # won't register with the user's Dock/GUI, so run 'open' as the console user.\n # Use 'launchctl asuser' to bootstrap into the console user's Mach namespace\n # and GUI session — 'sudo -u' alone doesn't do this, which can cause\n # LSOpenURLsWithRole() failures even when 'open' exits 0.\n local open_status=0\n if [[ $EUID -eq 0 ]]; then\n local console_uid\n console_uid=$(id -u \"$console_user\")\n /bin/launchctl asuser \"$console_uid\" sudo -u \"$console_user\" open -b \"$bundle_id\" >/dev/null 2>&1 || open_status=$?\n else\n open -b \"$bundle_id\" >/dev/null 2>&1 || open_status=$?\n fi\n\n if [[ $open_status -eq 0 ]]; then\n echo \"Application '$bundle_id' relaunched successfully.\"\n else\n echo \"Failed to relaunch application '$bundle_id'.\"\n fi\n}\n\n\n# extract contents\nMOUNT_POINT=$(mktemp -d /tmp/dmg_mount_XXXXXX)\nyes | hdiutil attach -plist -nobrowse -readonly -mountpoint \"$MOUNT_POINT\" \"$INSTALLER_PATH\" || exit 1\nsudo cp -R \"$MOUNT_POINT\"/* \"$TMPDIR\"\nhdiutil detach \"$MOUNT_POINT\" || true\n# copy to the applications folder\nquit_and_track_application 'com.thenounproject.Noun-Project'\nif [ -d \"$APPDIR/Noun Project.app\" ]; then\n\tsudo mv \"$APPDIR/Noun Project.app\" \"$TMPDIR/Noun Project.app.bkp\"\nfi\nsudo cp -R \"$TMPDIR/Noun Project.app\" \"$APPDIR\"\nrelaunch_application 'com.thenounproject.Noun-Project'\n", + "bbd4da5a": "#!/bin/bash\n\n# variables\nAPPDIR=\"/Applications/\"\nLOGGED_IN_USER=$(scutil <<< \"show State:/Users/ConsoleUser\" | awk '/Name :/ { print $3 }')\n# functions\n\ntrash() {\n local logged_in_user=\"$1\"\n local target_file=\"$2\"\n local timestamp=\"$(date +%Y-%m-%d-%s)\"\n local rand=\"$(jot -r 1 0 99999)\"\n\n # replace ~ with /Users/$logged_in_user\n if [[ \"$target_file\" == ~* ]]; then\n target_file=\"/Users/$logged_in_user${target_file:1}\"\n fi\n\n local trash=\"/Users/$logged_in_user/.Trash\"\n\n # If the target contains glob characters, expand it and move each match.\n if [[ \"$target_file\" == *[*?[]* ]]; then\n local file file_name\n local matched=false\n local i=0\n # compgen -G expands the (quoted) pattern itself, so paths containing\n # spaces glob correctly; reading line by line keeps each match intact.\n while IFS= read -r file; do\n [[ -n \"$file\" ]] || continue\n [[ -e \"$file\" || -L \"$file\" ]] || continue\n matched=true\n i=$((i + 1))\n file_name=\"$(basename \"$file\")\"\n echo \"removing $file.\"\n # The per-match counter keeps matches that share a basename from\n # overwriting each other in the trash.\n mv -f \"$file\" \"$trash/${file_name}_${timestamp}_${rand}_${i}\"\n done < <(compgen -G \"$target_file\" 2>/dev/null)\n if [[ \"$matched\" == false ]]; then\n echo \"$target_file doesn't exist.\"\n fi\n return\n fi\n\n local file_name=\"$(basename \"${target_file}\")\"\n\n if [[ -e \"$target_file\" ]]; then\n echo \"removing $target_file.\"\n mv -f \"$target_file\" \"$trash/${file_name}_${timestamp}_${rand}\"\n else\n echo \"$target_file doesn't exist.\"\n fi\n}\n\nsudo rm -rf \"$APPDIR/Noun Project.app\"\ntrash $LOGGED_IN_USER '~/Library/Application Support/com.thenounproject.Noun-Project'\ntrash $LOGGED_IN_USER '~/Library/Caches/com.thenounproject.Noun-Project'\ntrash $LOGGED_IN_USER '~/Library/HTTPStorages/com.thenounproject.Noun-Project'\ntrash $LOGGED_IN_USER '~/Library/Preferences/com.thenounproject.Noun-Project.plist'\ntrash $LOGGED_IN_USER '~/Library/Saved Application State/com.thenounproject.Noun-Project.savedState'\n" + } +} diff --git a/ee/maintained-apps/outputs/novabench/darwin.json b/ee/maintained-apps/outputs/novabench/darwin.json new file mode 100644 index 00000000000..9e43753a3f0 --- /dev/null +++ b/ee/maintained-apps/outputs/novabench/darwin.json @@ -0,0 +1,22 @@ +{ + "versions": [ + { + "version": "6.0.3", + "queries": { + "exists": "SELECT 1 FROM apps WHERE bundle_identifier = 'com.novabench.client';", + "patched": "SELECT 1 WHERE NOT EXISTS (SELECT 1 FROM apps WHERE bundle_identifier = 'com.novabench.client' AND version_compare(bundle_short_version, '6.0.3') < 0);" + }, + "installer_url": "https://novabench.com/files/novabench.dmg", + "install_script_ref": "02eaf90e", + "uninstall_script_ref": "2553a8d7", + "sha256": "no_check", + "default_categories": [ + "Productivity" + ] + } + ], + "refs": { + "02eaf90e": "#!/bin/bash\n\n# variables\nAPPDIR=\"/Applications/\"\nTMPDIR=$(dirname \"$(realpath \"$INSTALLER_PATH\")\")\n# functions\n\nquit_and_track_application() {\n local bundle_id=\"$1\"\n local var_name=\"APP_WAS_RUNNING_$(echo \"$bundle_id\" | tr '.-' '__')\"\n local timeout_duration=10\n\n # check if the application is running\n local app_running\n app_running=$(osascript -e \"application id \\\"$bundle_id\\\" is running\" 2>/dev/null)\n if [[ \"$app_running\" != \"true\" ]]; then\n eval \"export $var_name=0\"\n return\n fi\n\n local console_user\n console_user=$(stat -f \"%Su\" /dev/console)\n if [[ -z \"$console_user\" || \"$console_user\" == \"root\" || \"$console_user\" == \"loginwindow\" ]]; then\n echo \"Not logged into a non-root GUI; skipping quitting application ID '$bundle_id'.\"\n eval \"export $var_name=0\"\n return\n fi\n\n # App was running, mark it for relaunch\n eval \"export $var_name=1\"\n echo \"Application '$bundle_id' was running; will relaunch after installation.\"\n\n echo \"Quitting application '$bundle_id'...\"\n\n # try to quit the application within the timeout period\n local quit_success=false\n SECONDS=0\n while (( SECONDS < timeout_duration )); do\n if osascript -e \"tell application id \\\"$bundle_id\\\" to quit\" >/dev/null 2>&1; then\n if ! pgrep -f \"$bundle_id\" >/dev/null 2>&1; then\n echo \"Application '$bundle_id' quit successfully.\"\n quit_success=true\n break\n fi\n fi\n sleep 1\n done\n\n if [[ \"$quit_success\" = false ]]; then\n echo \"Application '$bundle_id' did not quit.\"\n fi\n}\n\n\nrelaunch_application() {\n local bundle_id=\"$1\"\n local var_name=\"APP_WAS_RUNNING_$(echo \"$bundle_id\" | tr '.-' '__')\"\n local was_running\n\n # Check if the app was running before installation\n eval \"was_running=\\$$var_name\"\n if [[ \"$was_running\" != \"1\" ]]; then\n return\n fi\n\n local console_user\n console_user=$(stat -f \"%Su\" /dev/console)\n if [[ -z \"$console_user\" || \"$console_user\" == \"root\" || \"$console_user\" == \"loginwindow\" ]]; then\n echo \"Not logged into a non-root GUI; skipping relaunching application ID '$bundle_id'.\"\n return\n fi\n\n echo \"Relaunching application '$bundle_id'...\"\n\n # Launch the app in the logged-in user's GUI session. Apps launched by root\n # won't register with the user's Dock/GUI, so run 'open' as the console user.\n # Use 'launchctl asuser' to bootstrap into the console user's Mach namespace\n # and GUI session — 'sudo -u' alone doesn't do this, which can cause\n # LSOpenURLsWithRole() failures even when 'open' exits 0.\n local open_status=0\n if [[ $EUID -eq 0 ]]; then\n local console_uid\n console_uid=$(id -u \"$console_user\")\n /bin/launchctl asuser \"$console_uid\" sudo -u \"$console_user\" open -b \"$bundle_id\" >/dev/null 2>&1 || open_status=$?\n else\n open -b \"$bundle_id\" >/dev/null 2>&1 || open_status=$?\n fi\n\n if [[ $open_status -eq 0 ]]; then\n echo \"Application '$bundle_id' relaunched successfully.\"\n else\n echo \"Failed to relaunch application '$bundle_id'.\"\n fi\n}\n\n\n# extract contents\nMOUNT_POINT=$(mktemp -d /tmp/dmg_mount_XXXXXX)\nyes | hdiutil attach -plist -nobrowse -readonly -mountpoint \"$MOUNT_POINT\" \"$INSTALLER_PATH\" || exit 1\nsudo cp -R \"$MOUNT_POINT\"/* \"$TMPDIR\"\nhdiutil detach \"$MOUNT_POINT\" || true\n# copy to the applications folder\nquit_and_track_application 'com.novabench.client'\nif [ -d \"$APPDIR/Novabench.app\" ]; then\n\tsudo mv \"$APPDIR/Novabench.app\" \"$TMPDIR/Novabench.app.bkp\"\nfi\nsudo cp -R \"$TMPDIR/Novabench.app\" \"$APPDIR\"\nrelaunch_application 'com.novabench.client'\n", + "2553a8d7": "#!/bin/bash\n\n# variables\nAPPDIR=\"/Applications/\"\nLOGGED_IN_USER=$(scutil <<< \"show State:/Users/ConsoleUser\" | awk '/Name :/ { print $3 }')\n# functions\n\ntrash() {\n local logged_in_user=\"$1\"\n local target_file=\"$2\"\n local timestamp=\"$(date +%Y-%m-%d-%s)\"\n local rand=\"$(jot -r 1 0 99999)\"\n\n # replace ~ with /Users/$logged_in_user\n if [[ \"$target_file\" == ~* ]]; then\n target_file=\"/Users/$logged_in_user${target_file:1}\"\n fi\n\n local trash=\"/Users/$logged_in_user/.Trash\"\n\n # If the target contains glob characters, expand it and move each match.\n if [[ \"$target_file\" == *[*?[]* ]]; then\n local file file_name\n local matched=false\n local i=0\n # compgen -G expands the (quoted) pattern itself, so paths containing\n # spaces glob correctly; reading line by line keeps each match intact.\n while IFS= read -r file; do\n [[ -n \"$file\" ]] || continue\n [[ -e \"$file\" || -L \"$file\" ]] || continue\n matched=true\n i=$((i + 1))\n file_name=\"$(basename \"$file\")\"\n echo \"removing $file.\"\n # The per-match counter keeps matches that share a basename from\n # overwriting each other in the trash.\n mv -f \"$file\" \"$trash/${file_name}_${timestamp}_${rand}_${i}\"\n done < <(compgen -G \"$target_file\" 2>/dev/null)\n if [[ \"$matched\" == false ]]; then\n echo \"$target_file doesn't exist.\"\n fi\n return\n fi\n\n local file_name=\"$(basename \"${target_file}\")\"\n\n if [[ -e \"$target_file\" ]]; then\n echo \"removing $target_file.\"\n mv -f \"$target_file\" \"$trash/${file_name}_${timestamp}_${rand}\"\n else\n echo \"$target_file doesn't exist.\"\n fi\n}\n\nsudo rm -rf \"$APPDIR/Novabench.app\"\ntrash $LOGGED_IN_USER '~/Library/Application Support/Novabench'\ntrash $LOGGED_IN_USER '~/Library/Caches/com.novabench.client'\ntrash $LOGGED_IN_USER '~/Library/Saved Application State/com.novabench.client.savedState'\ntrash $LOGGED_IN_USER '~/Library/WebKit/com.novabench.client'\n" + } +} diff --git a/ee/maintained-apps/outputs/nucleo/darwin.json b/ee/maintained-apps/outputs/nucleo/darwin.json new file mode 100644 index 00000000000..97fecca54b6 --- /dev/null +++ b/ee/maintained-apps/outputs/nucleo/darwin.json @@ -0,0 +1,22 @@ +{ + "versions": [ + { + "version": "4.2.0", + "queries": { + "exists": "SELECT 1 FROM apps WHERE bundle_identifier = 'co.ambercreative.nucleo';", + "patched": "SELECT 1 WHERE NOT EXISTS (SELECT 1 FROM apps WHERE bundle_identifier = 'co.ambercreative.nucleo' AND version_compare(bundle_short_version, '4.2.0') < 0);" + }, + "installer_url": "https://downloads.nucleoapp.com/mac-silicon/Nucleo_4.2.0.zip", + "install_script_ref": "561e8723", + "uninstall_script_ref": "8d0b7db2", + "sha256": "47bb642f3d0491326ae71096be3a5f97f5c3c997bdd2017669a1109bd90c10fd", + "default_categories": [ + "Productivity" + ] + } + ], + "refs": { + "561e8723": "#!/bin/bash\n\n# variables\nAPPDIR=\"/Applications/\"\nTMPDIR=$(dirname \"$(realpath \"$INSTALLER_PATH\")\")\n# functions\n\nquit_and_track_application() {\n local bundle_id=\"$1\"\n local var_name=\"APP_WAS_RUNNING_$(echo \"$bundle_id\" | tr '.-' '__')\"\n local timeout_duration=10\n\n # check if the application is running\n local app_running\n app_running=$(osascript -e \"application id \\\"$bundle_id\\\" is running\" 2>/dev/null)\n if [[ \"$app_running\" != \"true\" ]]; then\n eval \"export $var_name=0\"\n return\n fi\n\n local console_user\n console_user=$(stat -f \"%Su\" /dev/console)\n if [[ -z \"$console_user\" || \"$console_user\" == \"root\" || \"$console_user\" == \"loginwindow\" ]]; then\n echo \"Not logged into a non-root GUI; skipping quitting application ID '$bundle_id'.\"\n eval \"export $var_name=0\"\n return\n fi\n\n # App was running, mark it for relaunch\n eval \"export $var_name=1\"\n echo \"Application '$bundle_id' was running; will relaunch after installation.\"\n\n echo \"Quitting application '$bundle_id'...\"\n\n # try to quit the application within the timeout period\n local quit_success=false\n SECONDS=0\n while (( SECONDS < timeout_duration )); do\n if osascript -e \"tell application id \\\"$bundle_id\\\" to quit\" >/dev/null 2>&1; then\n if ! pgrep -f \"$bundle_id\" >/dev/null 2>&1; then\n echo \"Application '$bundle_id' quit successfully.\"\n quit_success=true\n break\n fi\n fi\n sleep 1\n done\n\n if [[ \"$quit_success\" = false ]]; then\n echo \"Application '$bundle_id' did not quit.\"\n fi\n}\n\n\nrelaunch_application() {\n local bundle_id=\"$1\"\n local var_name=\"APP_WAS_RUNNING_$(echo \"$bundle_id\" | tr '.-' '__')\"\n local was_running\n\n # Check if the app was running before installation\n eval \"was_running=\\$$var_name\"\n if [[ \"$was_running\" != \"1\" ]]; then\n return\n fi\n\n local console_user\n console_user=$(stat -f \"%Su\" /dev/console)\n if [[ -z \"$console_user\" || \"$console_user\" == \"root\" || \"$console_user\" == \"loginwindow\" ]]; then\n echo \"Not logged into a non-root GUI; skipping relaunching application ID '$bundle_id'.\"\n return\n fi\n\n echo \"Relaunching application '$bundle_id'...\"\n\n # Launch the app in the logged-in user's GUI session. Apps launched by root\n # won't register with the user's Dock/GUI, so run 'open' as the console user.\n # Use 'launchctl asuser' to bootstrap into the console user's Mach namespace\n # and GUI session — 'sudo -u' alone doesn't do this, which can cause\n # LSOpenURLsWithRole() failures even when 'open' exits 0.\n local open_status=0\n if [[ $EUID -eq 0 ]]; then\n local console_uid\n console_uid=$(id -u \"$console_user\")\n /bin/launchctl asuser \"$console_uid\" sudo -u \"$console_user\" open -b \"$bundle_id\" >/dev/null 2>&1 || open_status=$?\n else\n open -b \"$bundle_id\" >/dev/null 2>&1 || open_status=$?\n fi\n\n if [[ $open_status -eq 0 ]]; then\n echo \"Application '$bundle_id' relaunched successfully.\"\n else\n echo \"Failed to relaunch application '$bundle_id'.\"\n fi\n}\n\n\n# extract contents\nunzip \"$INSTALLER_PATH\" -d \"$TMPDIR\"\n# copy to the applications folder\nquit_and_track_application 'co.ambercreative.nucleo'\nif [ -d \"$APPDIR/Nucleo.app\" ]; then\n\tsudo mv \"$APPDIR/Nucleo.app\" \"$TMPDIR/Nucleo.app.bkp\"\nfi\nsudo cp -R \"$TMPDIR/Nucleo.app\" \"$APPDIR\"\nrelaunch_application 'co.ambercreative.nucleo'\n", + "8d0b7db2": "#!/bin/bash\n\n# variables\nAPPDIR=\"/Applications/\"\nLOGGED_IN_USER=$(scutil <<< \"show State:/Users/ConsoleUser\" | awk '/Name :/ { print $3 }')\n# functions\n\ntrash() {\n local logged_in_user=\"$1\"\n local target_file=\"$2\"\n local timestamp=\"$(date +%Y-%m-%d-%s)\"\n local rand=\"$(jot -r 1 0 99999)\"\n\n # replace ~ with /Users/$logged_in_user\n if [[ \"$target_file\" == ~* ]]; then\n target_file=\"/Users/$logged_in_user${target_file:1}\"\n fi\n\n local trash=\"/Users/$logged_in_user/.Trash\"\n\n # If the target contains glob characters, expand it and move each match.\n if [[ \"$target_file\" == *[*?[]* ]]; then\n local file file_name\n local matched=false\n local i=0\n # compgen -G expands the (quoted) pattern itself, so paths containing\n # spaces glob correctly; reading line by line keeps each match intact.\n while IFS= read -r file; do\n [[ -n \"$file\" ]] || continue\n [[ -e \"$file\" || -L \"$file\" ]] || continue\n matched=true\n i=$((i + 1))\n file_name=\"$(basename \"$file\")\"\n echo \"removing $file.\"\n # The per-match counter keeps matches that share a basename from\n # overwriting each other in the trash.\n mv -f \"$file\" \"$trash/${file_name}_${timestamp}_${rand}_${i}\"\n done < <(compgen -G \"$target_file\" 2>/dev/null)\n if [[ \"$matched\" == false ]]; then\n echo \"$target_file doesn't exist.\"\n fi\n return\n fi\n\n local file_name=\"$(basename \"${target_file}\")\"\n\n if [[ -e \"$target_file\" ]]; then\n echo \"removing $target_file.\"\n mv -f \"$target_file\" \"$trash/${file_name}_${timestamp}_${rand}\"\n else\n echo \"$target_file doesn't exist.\"\n fi\n}\n\nsudo rm -rf \"$APPDIR/Nucleo.app\"\ntrash $LOGGED_IN_USER '~/Library/Application Support/Nucleo'\ntrash $LOGGED_IN_USER '~/Library/Logs/Nucleo'\ntrash $LOGGED_IN_USER '~/Library/Preferences/co.ambercreative.nucleo.plist'\ntrash $LOGGED_IN_USER '~/Library/Saved Application State/co.ambercreative.nucleo.savedState'\n" + } +} diff --git a/ee/maintained-apps/outputs/numi/darwin.json b/ee/maintained-apps/outputs/numi/darwin.json new file mode 100644 index 00000000000..62ea10079f1 --- /dev/null +++ b/ee/maintained-apps/outputs/numi/darwin.json @@ -0,0 +1,22 @@ +{ + "versions": [ + { + "version": "3.32.721", + "queries": { + "exists": "SELECT 1 FROM apps WHERE bundle_identifier = 'com.dmitrynikolaev.numi';", + "patched": "SELECT 1 WHERE NOT EXISTS (SELECT 1 FROM apps WHERE bundle_identifier = 'com.dmitrynikolaev.numi' AND version_compare(bundle_short_version, '3.32.721') < 0);" + }, + "installer_url": "https://s3.numi.app/updates/3.32.721/Numi.dmg", + "install_script_ref": "0f6b5da5", + "uninstall_script_ref": "362f72e8", + "sha256": "21b5f89ecacfab039295874d24b79a450c080d526bcdf31716a46a8b11dddb30", + "default_categories": [ + "Productivity" + ] + } + ], + "refs": { + "0f6b5da5": "#!/bin/bash\n\n# variables\nAPPDIR=\"/Applications/\"\nTMPDIR=$(dirname \"$(realpath \"$INSTALLER_PATH\")\")\n# functions\n\nquit_and_track_application() {\n local bundle_id=\"$1\"\n local var_name=\"APP_WAS_RUNNING_$(echo \"$bundle_id\" | tr '.-' '__')\"\n local timeout_duration=10\n\n # check if the application is running\n local app_running\n app_running=$(osascript -e \"application id \\\"$bundle_id\\\" is running\" 2>/dev/null)\n if [[ \"$app_running\" != \"true\" ]]; then\n eval \"export $var_name=0\"\n return\n fi\n\n local console_user\n console_user=$(stat -f \"%Su\" /dev/console)\n if [[ -z \"$console_user\" || \"$console_user\" == \"root\" || \"$console_user\" == \"loginwindow\" ]]; then\n echo \"Not logged into a non-root GUI; skipping quitting application ID '$bundle_id'.\"\n eval \"export $var_name=0\"\n return\n fi\n\n # App was running, mark it for relaunch\n eval \"export $var_name=1\"\n echo \"Application '$bundle_id' was running; will relaunch after installation.\"\n\n echo \"Quitting application '$bundle_id'...\"\n\n # try to quit the application within the timeout period\n local quit_success=false\n SECONDS=0\n while (( SECONDS < timeout_duration )); do\n if osascript -e \"tell application id \\\"$bundle_id\\\" to quit\" >/dev/null 2>&1; then\n if ! pgrep -f \"$bundle_id\" >/dev/null 2>&1; then\n echo \"Application '$bundle_id' quit successfully.\"\n quit_success=true\n break\n fi\n fi\n sleep 1\n done\n\n if [[ \"$quit_success\" = false ]]; then\n echo \"Application '$bundle_id' did not quit.\"\n fi\n}\n\n\nrelaunch_application() {\n local bundle_id=\"$1\"\n local var_name=\"APP_WAS_RUNNING_$(echo \"$bundle_id\" | tr '.-' '__')\"\n local was_running\n\n # Check if the app was running before installation\n eval \"was_running=\\$$var_name\"\n if [[ \"$was_running\" != \"1\" ]]; then\n return\n fi\n\n local console_user\n console_user=$(stat -f \"%Su\" /dev/console)\n if [[ -z \"$console_user\" || \"$console_user\" == \"root\" || \"$console_user\" == \"loginwindow\" ]]; then\n echo \"Not logged into a non-root GUI; skipping relaunching application ID '$bundle_id'.\"\n return\n fi\n\n echo \"Relaunching application '$bundle_id'...\"\n\n # Launch the app in the logged-in user's GUI session. Apps launched by root\n # won't register with the user's Dock/GUI, so run 'open' as the console user.\n # Use 'launchctl asuser' to bootstrap into the console user's Mach namespace\n # and GUI session — 'sudo -u' alone doesn't do this, which can cause\n # LSOpenURLsWithRole() failures even when 'open' exits 0.\n local open_status=0\n if [[ $EUID -eq 0 ]]; then\n local console_uid\n console_uid=$(id -u \"$console_user\")\n /bin/launchctl asuser \"$console_uid\" sudo -u \"$console_user\" open -b \"$bundle_id\" >/dev/null 2>&1 || open_status=$?\n else\n open -b \"$bundle_id\" >/dev/null 2>&1 || open_status=$?\n fi\n\n if [[ $open_status -eq 0 ]]; then\n echo \"Application '$bundle_id' relaunched successfully.\"\n else\n echo \"Failed to relaunch application '$bundle_id'.\"\n fi\n}\n\n\n# extract contents\nMOUNT_POINT=$(mktemp -d /tmp/dmg_mount_XXXXXX)\nyes | hdiutil attach -plist -nobrowse -readonly -mountpoint \"$MOUNT_POINT\" \"$INSTALLER_PATH\" || exit 1\nsudo cp -R \"$MOUNT_POINT\"/* \"$TMPDIR\"\nhdiutil detach \"$MOUNT_POINT\" || true\n# copy to the applications folder\nquit_and_track_application 'com.dmitrynikolaev.numi'\nif [ -d \"$APPDIR/Numi.app\" ]; then\n\tsudo mv \"$APPDIR/Numi.app\" \"$TMPDIR/Numi.app.bkp\"\nfi\nsudo cp -R \"$TMPDIR/Numi.app\" \"$APPDIR\"\nrelaunch_application 'com.dmitrynikolaev.numi'\n", + "362f72e8": "#!/bin/bash\n\n# variables\nAPPDIR=\"/Applications/\"\nLOGGED_IN_USER=$(scutil <<< \"show State:/Users/ConsoleUser\" | awk '/Name :/ { print $3 }')\n# functions\n\nquit_application() {\n local bundle_id=\"$1\"\n local timeout_duration=10\n\n # check if the application is running\n local app_running\n app_running=$(osascript -e \"application id \\\"$bundle_id\\\" is running\" 2>/dev/null)\n if [[ \"$app_running\" != \"true\" ]]; then\n return\n fi\n\n local console_user\n console_user=$(stat -f \"%Su\" /dev/console)\n if [[ -z \"$console_user\" || \"$console_user\" == \"root\" || \"$console_user\" == \"loginwindow\" ]]; then\n echo \"Not logged into a non-root GUI; skipping quitting application ID '$bundle_id'.\"\n return\n fi\n\n echo \"Quitting application '$bundle_id'...\"\n\n # try to quit the application within the timeout period\n local quit_success=false\n SECONDS=0\n while (( SECONDS < timeout_duration )); do\n if osascript -e \"tell application id \\\"$bundle_id\\\" to quit\" >/dev/null 2>&1; then\n if ! pgrep -f \"$bundle_id\" >/dev/null 2>&1; then\n echo \"Application '$bundle_id' quit successfully.\"\n quit_success=true\n break\n fi\n fi\n sleep 1\n done\n\n if [[ \"$quit_success\" = false ]]; then\n echo \"Application '$bundle_id' did not quit.\"\n fi\n}\n\n\nremove_launchctl_service() {\n local service=\"$1\"\n local booleans=(\"true\" \"false\")\n local plist_status\n local paths\n local should_sudo\n\n echo \"Removing launchctl service ${service}\"\n\n for should_sudo in \"${booleans[@]}\"; do\n plist_status=$(launchctl list \"${service}\" 2>/dev/null)\n\n if [[ $plist_status == \\{* ]]; then\n if [[ $should_sudo == \"true\" ]]; then\n sudo launchctl remove \"${service}\"\n else\n launchctl remove \"${service}\"\n fi\n sleep 1\n fi\n\n paths=(\n \"/Library/LaunchAgents/${service}.plist\"\n \"/Library/LaunchDaemons/${service}.plist\"\n )\n\n # if not using sudo, prepend the home directory to the paths\n if [[ $should_sudo == \"false\" ]]; then\n for i in \"${!paths[@]}\"; do\n paths[i]=\"${HOME}${paths[i]}\"\n done\n fi\n\n for path in \"${paths[@]}\"; do\n if [[ -e \"$path\" ]]; then\n if [[ $should_sudo == \"true\" ]]; then\n sudo rm -f -- \"$path\"\n else\n rm -f -- \"$path\"\n fi\n fi\n done\n done\n}\n\ntrash() {\n local logged_in_user=\"$1\"\n local target_file=\"$2\"\n local timestamp=\"$(date +%Y-%m-%d-%s)\"\n local rand=\"$(jot -r 1 0 99999)\"\n\n # replace ~ with /Users/$logged_in_user\n if [[ \"$target_file\" == ~* ]]; then\n target_file=\"/Users/$logged_in_user${target_file:1}\"\n fi\n\n local trash=\"/Users/$logged_in_user/.Trash\"\n\n # If the target contains glob characters, expand it and move each match.\n if [[ \"$target_file\" == *[*?[]* ]]; then\n local file file_name\n local matched=false\n local i=0\n # compgen -G expands the (quoted) pattern itself, so paths containing\n # spaces glob correctly; reading line by line keeps each match intact.\n while IFS= read -r file; do\n [[ -n \"$file\" ]] || continue\n [[ -e \"$file\" || -L \"$file\" ]] || continue\n matched=true\n i=$((i + 1))\n file_name=\"$(basename \"$file\")\"\n echo \"removing $file.\"\n # The per-match counter keeps matches that share a basename from\n # overwriting each other in the trash.\n mv -f \"$file\" \"$trash/${file_name}_${timestamp}_${rand}_${i}\"\n done < <(compgen -G \"$target_file\" 2>/dev/null)\n if [[ \"$matched\" == false ]]; then\n echo \"$target_file doesn't exist.\"\n fi\n return\n fi\n\n local file_name=\"$(basename \"${target_file}\")\"\n\n if [[ -e \"$target_file\" ]]; then\n echo \"removing $target_file.\"\n mv -f \"$target_file\" \"$trash/${file_name}_${timestamp}_${rand}\"\n else\n echo \"$target_file doesn't exist.\"\n fi\n}\n\nremove_launchctl_service 'com.dmitrynikolaev.numi3helper'\nquit_application 'com.dmitrynikolaev.numi'\nsudo rm -rf \"$APPDIR/Numi.app\"\ntrash $LOGGED_IN_USER '/Users/Shared/Numi'\ntrash $LOGGED_IN_USER '~/Library/Application Support/com.dmitrynikolaev.numi'\ntrash $LOGGED_IN_USER '~/Library/Application Support/CrashReporter/Numi_*.plist'\ntrash $LOGGED_IN_USER '~/Library/Application Support/Numi'\ntrash $LOGGED_IN_USER '~/Library/Caches/com.crashlytics.data/com.dmitrynikolaev.numi'\ntrash $LOGGED_IN_USER '~/Library/Caches/com.dmitrynikolaev.numi'\ntrash $LOGGED_IN_USER '~/Library/Caches/io.fabric.sdk.mac.data/com.dmitrynikolaev.numi'\ntrash $LOGGED_IN_USER '~/Library/Containers/com.dmitrynikolaev.numi.NumiExtension'\ntrash $LOGGED_IN_USER '~/Library/Preferences/com.dmitrynikolaev.numi.plist'\n" + } +} diff --git a/ee/maintained-apps/outputs/nvidia-geforce-now/darwin.json b/ee/maintained-apps/outputs/nvidia-geforce-now/darwin.json new file mode 100644 index 00000000000..457f4041ca3 --- /dev/null +++ b/ee/maintained-apps/outputs/nvidia-geforce-now/darwin.json @@ -0,0 +1,22 @@ +{ + "versions": [ + { + "version": "2.0.85.133", + "queries": { + "exists": "SELECT 1 FROM apps WHERE bundle_identifier = 'com.nvidia.gfnpc.mall';", + "patched": "SELECT 1 WHERE NOT EXISTS (SELECT 1 FROM apps WHERE bundle_identifier = 'com.nvidia.gfnpc.mall' AND version_compare(bundle_short_version, '2.0.85.133') < 0);" + }, + "installer_url": "https://download.nvidia.com/gfnpc/GeForceNOW-release.dmg", + "install_script_ref": "a9979922", + "uninstall_script_ref": "289b999e", + "sha256": "no_check", + "default_categories": [ + "Productivity" + ] + } + ], + "refs": { + "289b999e": "#!/bin/bash\n\n# variables\nAPPDIR=\"/Applications/\"\nLOGGED_IN_USER=$(scutil <<< \"show State:/Users/ConsoleUser\" | awk '/Name :/ { print $3 }')\n# functions\n\ntrash() {\n local logged_in_user=\"$1\"\n local target_file=\"$2\"\n local timestamp=\"$(date +%Y-%m-%d-%s)\"\n local rand=\"$(jot -r 1 0 99999)\"\n\n # replace ~ with /Users/$logged_in_user\n if [[ \"$target_file\" == ~* ]]; then\n target_file=\"/Users/$logged_in_user${target_file:1}\"\n fi\n\n local trash=\"/Users/$logged_in_user/.Trash\"\n\n # If the target contains glob characters, expand it and move each match.\n if [[ \"$target_file\" == *[*?[]* ]]; then\n local file file_name\n local matched=false\n local i=0\n # compgen -G expands the (quoted) pattern itself, so paths containing\n # spaces glob correctly; reading line by line keeps each match intact.\n while IFS= read -r file; do\n [[ -n \"$file\" ]] || continue\n [[ -e \"$file\" || -L \"$file\" ]] || continue\n matched=true\n i=$((i + 1))\n file_name=\"$(basename \"$file\")\"\n echo \"removing $file.\"\n # The per-match counter keeps matches that share a basename from\n # overwriting each other in the trash.\n mv -f \"$file\" \"$trash/${file_name}_${timestamp}_${rand}_${i}\"\n done < <(compgen -G \"$target_file\" 2>/dev/null)\n if [[ \"$matched\" == false ]]; then\n echo \"$target_file doesn't exist.\"\n fi\n return\n fi\n\n local file_name=\"$(basename \"${target_file}\")\"\n\n if [[ -e \"$target_file\" ]]; then\n echo \"removing $target_file.\"\n mv -f \"$target_file\" \"$trash/${file_name}_${timestamp}_${rand}\"\n else\n echo \"$target_file doesn't exist.\"\n fi\n}\n\nsudo rm -rf \"$APPDIR/GeForceNOW.app\"\nsudo rmdir '~/Movies/NVIDIA'\ntrash $LOGGED_IN_USER '~/Library/Application Support/NVIDIA Corporation/MessageBus_GFN_session*.conf'\ntrash $LOGGED_IN_USER '~/Library/Application Support/NVIDIA/GeForceNOW'\ntrash $LOGGED_IN_USER '~/Library/Caches/com.apple.nsurlsessiond/Downloads/com.nvidia.gfnpc.mall'\ntrash $LOGGED_IN_USER '~/Library/Caches/com.nvidia.nvcontainer'\ntrash $LOGGED_IN_USER '~/Library/Caches/NVIDIA/GeForceNOW'\ntrash $LOGGED_IN_USER '~/Library/HTTPStorages/com.nvidia.gfnpc.mall'\ntrash $LOGGED_IN_USER '~/Library/Preferences/com.nvidia.gfnpc.mall.helper.plist'\ntrash $LOGGED_IN_USER '~/Library/Preferences/com.nvidia.gfnpc.mall.helper.renderer.plist'\ntrash $LOGGED_IN_USER '~/Library/Saved Application State/com.nvidia.gfnpc.mall.savedState'\n", + "a9979922": "#!/bin/bash\n\n# variables\nAPPDIR=\"/Applications/\"\nTMPDIR=$(dirname \"$(realpath \"$INSTALLER_PATH\")\")\n# functions\n\nquit_and_track_application() {\n local bundle_id=\"$1\"\n local var_name=\"APP_WAS_RUNNING_$(echo \"$bundle_id\" | tr '.-' '__')\"\n local timeout_duration=10\n\n # check if the application is running\n local app_running\n app_running=$(osascript -e \"application id \\\"$bundle_id\\\" is running\" 2>/dev/null)\n if [[ \"$app_running\" != \"true\" ]]; then\n eval \"export $var_name=0\"\n return\n fi\n\n local console_user\n console_user=$(stat -f \"%Su\" /dev/console)\n if [[ -z \"$console_user\" || \"$console_user\" == \"root\" || \"$console_user\" == \"loginwindow\" ]]; then\n echo \"Not logged into a non-root GUI; skipping quitting application ID '$bundle_id'.\"\n eval \"export $var_name=0\"\n return\n fi\n\n # App was running, mark it for relaunch\n eval \"export $var_name=1\"\n echo \"Application '$bundle_id' was running; will relaunch after installation.\"\n\n echo \"Quitting application '$bundle_id'...\"\n\n # try to quit the application within the timeout period\n local quit_success=false\n SECONDS=0\n while (( SECONDS < timeout_duration )); do\n if osascript -e \"tell application id \\\"$bundle_id\\\" to quit\" >/dev/null 2>&1; then\n if ! pgrep -f \"$bundle_id\" >/dev/null 2>&1; then\n echo \"Application '$bundle_id' quit successfully.\"\n quit_success=true\n break\n fi\n fi\n sleep 1\n done\n\n if [[ \"$quit_success\" = false ]]; then\n echo \"Application '$bundle_id' did not quit.\"\n fi\n}\n\n\nrelaunch_application() {\n local bundle_id=\"$1\"\n local var_name=\"APP_WAS_RUNNING_$(echo \"$bundle_id\" | tr '.-' '__')\"\n local was_running\n\n # Check if the app was running before installation\n eval \"was_running=\\$$var_name\"\n if [[ \"$was_running\" != \"1\" ]]; then\n return\n fi\n\n local console_user\n console_user=$(stat -f \"%Su\" /dev/console)\n if [[ -z \"$console_user\" || \"$console_user\" == \"root\" || \"$console_user\" == \"loginwindow\" ]]; then\n echo \"Not logged into a non-root GUI; skipping relaunching application ID '$bundle_id'.\"\n return\n fi\n\n echo \"Relaunching application '$bundle_id'...\"\n\n # Launch the app in the logged-in user's GUI session. Apps launched by root\n # won't register with the user's Dock/GUI, so run 'open' as the console user.\n # Use 'launchctl asuser' to bootstrap into the console user's Mach namespace\n # and GUI session — 'sudo -u' alone doesn't do this, which can cause\n # LSOpenURLsWithRole() failures even when 'open' exits 0.\n local open_status=0\n if [[ $EUID -eq 0 ]]; then\n local console_uid\n console_uid=$(id -u \"$console_user\")\n /bin/launchctl asuser \"$console_uid\" sudo -u \"$console_user\" open -b \"$bundle_id\" >/dev/null 2>&1 || open_status=$?\n else\n open -b \"$bundle_id\" >/dev/null 2>&1 || open_status=$?\n fi\n\n if [[ $open_status -eq 0 ]]; then\n echo \"Application '$bundle_id' relaunched successfully.\"\n else\n echo \"Failed to relaunch application '$bundle_id'.\"\n fi\n}\n\n\n# extract contents\nMOUNT_POINT=$(mktemp -d /tmp/dmg_mount_XXXXXX)\nyes | hdiutil attach -plist -nobrowse -readonly -mountpoint \"$MOUNT_POINT\" \"$INSTALLER_PATH\" || exit 1\nsudo cp -R \"$MOUNT_POINT\"/* \"$TMPDIR\"\nhdiutil detach \"$MOUNT_POINT\" || true\n# copy to the applications folder\nquit_and_track_application 'com.nvidia.gfnpc.mall'\nif [ -d \"$APPDIR/GeForceNOW.app\" ]; then\n\tsudo mv \"$APPDIR/GeForceNOW.app\" \"$TMPDIR/GeForceNOW.app.bkp\"\nfi\nsudo cp -R \"$TMPDIR/GeForceNOW.app\" \"$APPDIR\"\nrelaunch_application 'com.nvidia.gfnpc.mall'\n" + } +} diff --git a/frontend/pages/SoftwarePage/components/icons/Nagstamon.tsx b/frontend/pages/SoftwarePage/components/icons/Nagstamon.tsx new file mode 100644 index 00000000000..b65b5d5627a --- /dev/null +++ b/frontend/pages/SoftwarePage/components/icons/Nagstamon.tsx @@ -0,0 +1,14 @@ +import * as React from "react"; + +import type { SVGProps } from "react"; + +const Nagstamon = (props: SVGProps) => ( + + + +); +export default Nagstamon; diff --git a/frontend/pages/SoftwarePage/components/icons/NameMangler.tsx b/frontend/pages/SoftwarePage/components/icons/NameMangler.tsx new file mode 100644 index 00000000000..ee2a1d8d188 --- /dev/null +++ b/frontend/pages/SoftwarePage/components/icons/NameMangler.tsx @@ -0,0 +1,14 @@ +import * as React from "react"; + +import type { SVGProps } from "react"; + +const NameMangler = (props: SVGProps) => ( + + + +); +export default NameMangler; diff --git a/frontend/pages/SoftwarePage/components/icons/Naps2.tsx b/frontend/pages/SoftwarePage/components/icons/Naps2.tsx new file mode 100644 index 00000000000..e364e3c0e74 --- /dev/null +++ b/frontend/pages/SoftwarePage/components/icons/Naps2.tsx @@ -0,0 +1,14 @@ +import * as React from "react"; + +import type { SVGProps } from "react"; + +const Naps2 = (props: SVGProps) => ( + + + +); +export default Naps2; diff --git a/frontend/pages/SoftwarePage/components/icons/NdiTools.tsx b/frontend/pages/SoftwarePage/components/icons/NdiTools.tsx new file mode 100644 index 00000000000..8fa89bb782f --- /dev/null +++ b/frontend/pages/SoftwarePage/components/icons/NdiTools.tsx @@ -0,0 +1,14 @@ +import * as React from "react"; + +import type { SVGProps } from "react"; + +const NdiTools = (props: SVGProps) => ( + + + +); +export default NdiTools; diff --git a/frontend/pages/SoftwarePage/components/icons/Neofinder.tsx b/frontend/pages/SoftwarePage/components/icons/Neofinder.tsx new file mode 100644 index 00000000000..e3494c21ef6 --- /dev/null +++ b/frontend/pages/SoftwarePage/components/icons/Neofinder.tsx @@ -0,0 +1,14 @@ +import * as React from "react"; + +import type { SVGProps } from "react"; + +const Neofinder = (props: SVGProps) => ( + + + +); +export default Neofinder; diff --git a/frontend/pages/SoftwarePage/components/icons/Netiquette.tsx b/frontend/pages/SoftwarePage/components/icons/Netiquette.tsx new file mode 100644 index 00000000000..4050403a0e0 --- /dev/null +++ b/frontend/pages/SoftwarePage/components/icons/Netiquette.tsx @@ -0,0 +1,14 @@ +import * as React from "react"; + +import type { SVGProps } from "react"; + +const Netiquette = (props: SVGProps) => ( + + + +); +export default Netiquette; diff --git a/frontend/pages/SoftwarePage/components/icons/Netnewswire.tsx b/frontend/pages/SoftwarePage/components/icons/Netnewswire.tsx new file mode 100644 index 00000000000..cc42d770ed5 --- /dev/null +++ b/frontend/pages/SoftwarePage/components/icons/Netnewswire.tsx @@ -0,0 +1,14 @@ +import * as React from "react"; + +import type { SVGProps } from "react"; + +const Netnewswire = (props: SVGProps) => ( + + + +); +export default Netnewswire; diff --git a/frontend/pages/SoftwarePage/components/icons/Netron.tsx b/frontend/pages/SoftwarePage/components/icons/Netron.tsx new file mode 100644 index 00000000000..320c42540a9 --- /dev/null +++ b/frontend/pages/SoftwarePage/components/icons/Netron.tsx @@ -0,0 +1,14 @@ +import * as React from "react"; + +import type { SVGProps } from "react"; + +const Netron = (props: SVGProps) => ( + + + +); +export default Netron; diff --git a/frontend/pages/SoftwarePage/components/icons/Netspot.tsx b/frontend/pages/SoftwarePage/components/icons/Netspot.tsx new file mode 100644 index 00000000000..98d16e0f0a1 --- /dev/null +++ b/frontend/pages/SoftwarePage/components/icons/Netspot.tsx @@ -0,0 +1,14 @@ +import * as React from "react"; + +import type { SVGProps } from "react"; + +const Netspot = (props: SVGProps) => ( + + + +); +export default Netspot; diff --git a/frontend/pages/SoftwarePage/components/icons/NextcloudTalk.tsx b/frontend/pages/SoftwarePage/components/icons/NextcloudTalk.tsx new file mode 100644 index 00000000000..263bedf2834 --- /dev/null +++ b/frontend/pages/SoftwarePage/components/icons/NextcloudTalk.tsx @@ -0,0 +1,14 @@ +import * as React from "react"; + +import type { SVGProps } from "react"; + +const NextcloudTalk = (props: SVGProps) => ( + + + +); +export default NextcloudTalk; diff --git a/frontend/pages/SoftwarePage/components/icons/Nightfall.tsx b/frontend/pages/SoftwarePage/components/icons/Nightfall.tsx new file mode 100644 index 00000000000..a23baafabf2 --- /dev/null +++ b/frontend/pages/SoftwarePage/components/icons/Nightfall.tsx @@ -0,0 +1,14 @@ +import * as React from "react"; + +import type { SVGProps } from "react"; + +const Nightfall = (props: SVGProps) => ( + + + +); +export default Nightfall; diff --git a/frontend/pages/SoftwarePage/components/icons/NitroPdfPro.tsx b/frontend/pages/SoftwarePage/components/icons/NitroPdfPro.tsx new file mode 100644 index 00000000000..66c2ee20f3f --- /dev/null +++ b/frontend/pages/SoftwarePage/components/icons/NitroPdfPro.tsx @@ -0,0 +1,14 @@ +import * as React from "react"; + +import type { SVGProps } from "react"; + +const NitroPdfPro = (props: SVGProps) => ( + + + +); +export default NitroPdfPro; diff --git a/frontend/pages/SoftwarePage/components/icons/Nocturnal.tsx b/frontend/pages/SoftwarePage/components/icons/Nocturnal.tsx new file mode 100644 index 00000000000..0d677d3b8da --- /dev/null +++ b/frontend/pages/SoftwarePage/components/icons/Nocturnal.tsx @@ -0,0 +1,14 @@ +import * as React from "react"; + +import type { SVGProps } from "react"; + +const Nocturnal = (props: SVGProps) => ( + + + +); +export default Nocturnal; diff --git a/frontend/pages/SoftwarePage/components/icons/Nordlayer.tsx b/frontend/pages/SoftwarePage/components/icons/Nordlayer.tsx new file mode 100644 index 00000000000..cf435732975 --- /dev/null +++ b/frontend/pages/SoftwarePage/components/icons/Nordlayer.tsx @@ -0,0 +1,14 @@ +import * as React from "react"; + +import type { SVGProps } from "react"; + +const Nordlayer = (props: SVGProps) => ( + + + +); +export default Nordlayer; diff --git a/frontend/pages/SoftwarePage/components/icons/NosqlWorkbench.tsx b/frontend/pages/SoftwarePage/components/icons/NosqlWorkbench.tsx new file mode 100644 index 00000000000..d1d42b9c032 --- /dev/null +++ b/frontend/pages/SoftwarePage/components/icons/NosqlWorkbench.tsx @@ -0,0 +1,14 @@ +import * as React from "react"; + +import type { SVGProps } from "react"; + +const NosqlWorkbench = (props: SVGProps) => ( + + + +); +export default NosqlWorkbench; diff --git a/frontend/pages/SoftwarePage/components/icons/Notchnook.tsx b/frontend/pages/SoftwarePage/components/icons/Notchnook.tsx new file mode 100644 index 00000000000..5b6c644b293 --- /dev/null +++ b/frontend/pages/SoftwarePage/components/icons/Notchnook.tsx @@ -0,0 +1,14 @@ +import * as React from "react"; + +import type { SVGProps } from "react"; + +const Notchnook = (props: SVGProps) => ( + + + +); +export default Notchnook; diff --git a/frontend/pages/SoftwarePage/components/icons/Notepadexe.tsx b/frontend/pages/SoftwarePage/components/icons/Notepadexe.tsx new file mode 100644 index 00000000000..e17b67288d9 --- /dev/null +++ b/frontend/pages/SoftwarePage/components/icons/Notepadexe.tsx @@ -0,0 +1,14 @@ +import * as React from "react"; + +import type { SVGProps } from "react"; + +const Notepadexe = (props: SVGProps) => ( + + + +); +export default Notepadexe; diff --git a/frontend/pages/SoftwarePage/components/icons/Notesnook.tsx b/frontend/pages/SoftwarePage/components/icons/Notesnook.tsx new file mode 100644 index 00000000000..bac153f7441 --- /dev/null +++ b/frontend/pages/SoftwarePage/components/icons/Notesnook.tsx @@ -0,0 +1,14 @@ +import * as React from "react"; + +import type { SVGProps } from "react"; + +const Notesnook = (props: SVGProps) => ( + + + +); +export default Notesnook; diff --git a/frontend/pages/SoftwarePage/components/icons/Notesollama.tsx b/frontend/pages/SoftwarePage/components/icons/Notesollama.tsx new file mode 100644 index 00000000000..41abfff74c3 --- /dev/null +++ b/frontend/pages/SoftwarePage/components/icons/Notesollama.tsx @@ -0,0 +1,14 @@ +import * as React from "react"; + +import type { SVGProps } from "react"; + +const Notesollama = (props: SVGProps) => ( + + + +); +export default Notesollama; diff --git a/frontend/pages/SoftwarePage/components/icons/NounProject.tsx b/frontend/pages/SoftwarePage/components/icons/NounProject.tsx new file mode 100644 index 00000000000..064af1a0a23 --- /dev/null +++ b/frontend/pages/SoftwarePage/components/icons/NounProject.tsx @@ -0,0 +1,14 @@ +import * as React from "react"; + +import type { SVGProps } from "react"; + +const NounProject = (props: SVGProps) => ( + + + +); +export default NounProject; diff --git a/frontend/pages/SoftwarePage/components/icons/Novabench.tsx b/frontend/pages/SoftwarePage/components/icons/Novabench.tsx new file mode 100644 index 00000000000..b2c50bbe0bc --- /dev/null +++ b/frontend/pages/SoftwarePage/components/icons/Novabench.tsx @@ -0,0 +1,14 @@ +import * as React from "react"; + +import type { SVGProps } from "react"; + +const Novabench = (props: SVGProps) => ( + + + +); +export default Novabench; diff --git a/frontend/pages/SoftwarePage/components/icons/Nucleo.tsx b/frontend/pages/SoftwarePage/components/icons/Nucleo.tsx new file mode 100644 index 00000000000..69ff639ce66 --- /dev/null +++ b/frontend/pages/SoftwarePage/components/icons/Nucleo.tsx @@ -0,0 +1,14 @@ +import * as React from "react"; + +import type { SVGProps } from "react"; + +const Nucleo = (props: SVGProps) => ( + + + +); +export default Nucleo; diff --git a/frontend/pages/SoftwarePage/components/icons/Numi.tsx b/frontend/pages/SoftwarePage/components/icons/Numi.tsx new file mode 100644 index 00000000000..f94f4356869 --- /dev/null +++ b/frontend/pages/SoftwarePage/components/icons/Numi.tsx @@ -0,0 +1,14 @@ +import * as React from "react"; + +import type { SVGProps } from "react"; + +const Numi = (props: SVGProps) => ( + + + +); +export default Numi; diff --git a/frontend/pages/SoftwarePage/components/icons/NvidiaGeforceNow.tsx b/frontend/pages/SoftwarePage/components/icons/NvidiaGeforceNow.tsx new file mode 100644 index 00000000000..1d1c15c158f --- /dev/null +++ b/frontend/pages/SoftwarePage/components/icons/NvidiaGeforceNow.tsx @@ -0,0 +1,14 @@ +import * as React from "react"; + +import type { SVGProps } from "react"; + +const NvidiaGeforceNow = (props: SVGProps) => ( + + + +); +export default NvidiaGeforceNow; diff --git a/frontend/pages/SoftwarePage/components/icons/index.ts b/frontend/pages/SoftwarePage/components/icons/index.ts index f0c4b9c93c5..9188fe56f0a 100644 --- a/frontend/pages/SoftwarePage/components/icons/index.ts +++ b/frontend/pages/SoftwarePage/components/icons/index.ts @@ -530,16 +530,40 @@ import Museeks from "./Museeks"; import Musescore from "./Musescore"; import MxPowerGadget from "./MxPowerGadget"; import MySqlWorkbench from "./MySqlWorkbench"; +import Nagstamon from "./Nagstamon"; +import NameMangler from "./NameMangler"; +import Naps2 from "./Naps2"; +import NdiTools from "./NdiTools"; +import Neofinder from "./Neofinder"; import NessusAgent from "./NessusAgent"; +import Netiquette from "./Netiquette"; +import Netnewswire from "./Netnewswire"; +import Netron from "./Netron"; +import Netspot from "./Netspot"; import Nextcloud from "./Nextcloud"; +import NextcloudTalk from "./NextcloudTalk"; +import Nightfall from "./Nightfall"; +import NitroPdfPro from "./NitroPdfPro"; +import Nocturnal from "./Nocturnal"; import Nodejs from "./Nodejs"; +import Nordlayer from "./Nordlayer"; import Nordpass from "./Nordpass"; import NordVpn from "./NordVpn"; +import NosqlWorkbench from "./NosqlWorkbench"; +import Notchnook from "./Notchnook"; import Notepad from "./Notepad++"; +import Notepadexe from "./Notepadexe"; +import Notesnook from "./Notesnook"; +import Notesollama from "./Notesollama"; import Notion from "./Notion"; import NotionCalendar from "./NotionCalendar"; +import NounProject from "./NounProject"; import Nova from "./Nova"; +import Novabench from "./Novabench"; +import Nucleo from "./Nucleo"; import Nudge from "./Nudge"; +import Numi from "./Numi"; +import NvidiaGeforceNow from "./NvidiaGeforceNow"; import Obs from "./Obs"; import Obsidian from "./Obsidian"; import Ocenaudio from "./Ocenaudio"; @@ -1492,18 +1516,42 @@ export const SOFTWARE_NAME_TO_ICON_MAP = { musescore: Musescore, "mx power gadget": MxPowerGadget, "mysql workbench": MySqlWorkbench, + nagstamon: Nagstamon, + "name mangler": NameMangler, + naps2: Naps2, + "ndi tools": NdiTools, + neofinder: Neofinder, "nessus agent": NessusAgent, + netiquette: Netiquette, + netnewswire: Netnewswire, + netron: Netron, + netspot: Netspot, nextcloud: Nextcloud, + "nextcloud talk desktop": NextcloudTalk, + nightfall: Nightfall, + "nitro pdf pro": NitroPdfPro, + nocturnal: Nocturnal, "node.js": Nodejs, "nord vpn": NordVpn, + nordlayer: Nordlayer, nordpass: Nordpass, nordvpn: NordVpn, + "nosql workbench": NosqlWorkbench, "nota gyazo gif": Gyazo, + notchnook: Notchnook, "notepad++": Notepad, + "notepad.exe": Notepadexe, + notesnook: Notesnook, + notesollama: Notesollama, notion: Notion, "notion calendar": NotionCalendar, + "noun project": NounProject, nova: Nova, + novabench: Novabench, + nucleo: Nucleo, nudge: Nudge, + numi: Numi, + "nvidia geforce now": NvidiaGeforceNow, obs: Obs, obsidian: Obsidian, ocenaudio: Ocenaudio, diff --git a/website/assets/images/app-icon-nagstamon-60x60@2x.png b/website/assets/images/app-icon-nagstamon-60x60@2x.png new file mode 100644 index 00000000000..e86e7b066f5 Binary files /dev/null and b/website/assets/images/app-icon-nagstamon-60x60@2x.png differ diff --git a/website/assets/images/app-icon-name-mangler-60x60@2x.png b/website/assets/images/app-icon-name-mangler-60x60@2x.png new file mode 100644 index 00000000000..a39f36d6d31 Binary files /dev/null and b/website/assets/images/app-icon-name-mangler-60x60@2x.png differ diff --git a/website/assets/images/app-icon-naps2-60x60@2x.png b/website/assets/images/app-icon-naps2-60x60@2x.png new file mode 100644 index 00000000000..3492d33973d Binary files /dev/null and b/website/assets/images/app-icon-naps2-60x60@2x.png differ diff --git a/website/assets/images/app-icon-native-access-60x60@2x.png b/website/assets/images/app-icon-native-access-60x60@2x.png new file mode 100644 index 00000000000..8ac0f31a68a Binary files /dev/null and b/website/assets/images/app-icon-native-access-60x60@2x.png differ diff --git a/website/assets/images/app-icon-ndi-tools-60x60@2x.png b/website/assets/images/app-icon-ndi-tools-60x60@2x.png new file mode 100644 index 00000000000..91a8b30731b Binary files /dev/null and b/website/assets/images/app-icon-ndi-tools-60x60@2x.png differ diff --git a/website/assets/images/app-icon-neofinder-60x60@2x.png b/website/assets/images/app-icon-neofinder-60x60@2x.png new file mode 100644 index 00000000000..2fd27b298a2 Binary files /dev/null and b/website/assets/images/app-icon-neofinder-60x60@2x.png differ diff --git a/website/assets/images/app-icon-netiquette-60x60@2x.png b/website/assets/images/app-icon-netiquette-60x60@2x.png new file mode 100644 index 00000000000..4c7cb2e0c39 Binary files /dev/null and b/website/assets/images/app-icon-netiquette-60x60@2x.png differ diff --git a/website/assets/images/app-icon-netnewswire-60x60@2x.png b/website/assets/images/app-icon-netnewswire-60x60@2x.png new file mode 100644 index 00000000000..eeb0a04536e Binary files /dev/null and b/website/assets/images/app-icon-netnewswire-60x60@2x.png differ diff --git a/website/assets/images/app-icon-netron-60x60@2x.png b/website/assets/images/app-icon-netron-60x60@2x.png new file mode 100644 index 00000000000..68f26a52891 Binary files /dev/null and b/website/assets/images/app-icon-netron-60x60@2x.png differ diff --git a/website/assets/images/app-icon-netspot-60x60@2x.png b/website/assets/images/app-icon-netspot-60x60@2x.png new file mode 100644 index 00000000000..aee9260f3ab Binary files /dev/null and b/website/assets/images/app-icon-netspot-60x60@2x.png differ diff --git a/website/assets/images/app-icon-nextcloud-talk-60x60@2x.png b/website/assets/images/app-icon-nextcloud-talk-60x60@2x.png new file mode 100644 index 00000000000..8ddbfeec9f1 Binary files /dev/null and b/website/assets/images/app-icon-nextcloud-talk-60x60@2x.png differ diff --git a/website/assets/images/app-icon-nightfall-60x60@2x.png b/website/assets/images/app-icon-nightfall-60x60@2x.png new file mode 100644 index 00000000000..e88789208f9 Binary files /dev/null and b/website/assets/images/app-icon-nightfall-60x60@2x.png differ diff --git a/website/assets/images/app-icon-nitro-pdf-pro-60x60@2x.png b/website/assets/images/app-icon-nitro-pdf-pro-60x60@2x.png new file mode 100644 index 00000000000..318dc939f98 Binary files /dev/null and b/website/assets/images/app-icon-nitro-pdf-pro-60x60@2x.png differ diff --git a/website/assets/images/app-icon-nocturnal-60x60@2x.png b/website/assets/images/app-icon-nocturnal-60x60@2x.png new file mode 100644 index 00000000000..5f8141a15a8 Binary files /dev/null and b/website/assets/images/app-icon-nocturnal-60x60@2x.png differ diff --git a/website/assets/images/app-icon-nordlayer-60x60@2x.png b/website/assets/images/app-icon-nordlayer-60x60@2x.png new file mode 100644 index 00000000000..7a15b8922f3 Binary files /dev/null and b/website/assets/images/app-icon-nordlayer-60x60@2x.png differ diff --git a/website/assets/images/app-icon-nosql-workbench-60x60@2x.png b/website/assets/images/app-icon-nosql-workbench-60x60@2x.png new file mode 100644 index 00000000000..3f0a730e615 Binary files /dev/null and b/website/assets/images/app-icon-nosql-workbench-60x60@2x.png differ diff --git a/website/assets/images/app-icon-notchnook-60x60@2x.png b/website/assets/images/app-icon-notchnook-60x60@2x.png new file mode 100644 index 00000000000..b563f2e2260 Binary files /dev/null and b/website/assets/images/app-icon-notchnook-60x60@2x.png differ diff --git a/website/assets/images/app-icon-notepadexe-60x60@2x.png b/website/assets/images/app-icon-notepadexe-60x60@2x.png new file mode 100644 index 00000000000..f02a169f956 Binary files /dev/null and b/website/assets/images/app-icon-notepadexe-60x60@2x.png differ diff --git a/website/assets/images/app-icon-notesnook-60x60@2x.png b/website/assets/images/app-icon-notesnook-60x60@2x.png new file mode 100644 index 00000000000..d2775b4277e Binary files /dev/null and b/website/assets/images/app-icon-notesnook-60x60@2x.png differ diff --git a/website/assets/images/app-icon-notesollama-60x60@2x.png b/website/assets/images/app-icon-notesollama-60x60@2x.png new file mode 100644 index 00000000000..83549d16d4c Binary files /dev/null and b/website/assets/images/app-icon-notesollama-60x60@2x.png differ diff --git a/website/assets/images/app-icon-noun-project-60x60@2x.png b/website/assets/images/app-icon-noun-project-60x60@2x.png new file mode 100644 index 00000000000..0cd691c7fb4 Binary files /dev/null and b/website/assets/images/app-icon-noun-project-60x60@2x.png differ diff --git a/website/assets/images/app-icon-novabench-60x60@2x.png b/website/assets/images/app-icon-novabench-60x60@2x.png new file mode 100644 index 00000000000..27eeeb3ffce Binary files /dev/null and b/website/assets/images/app-icon-novabench-60x60@2x.png differ diff --git a/website/assets/images/app-icon-nucleo-60x60@2x.png b/website/assets/images/app-icon-nucleo-60x60@2x.png new file mode 100644 index 00000000000..a5f7e092c4a Binary files /dev/null and b/website/assets/images/app-icon-nucleo-60x60@2x.png differ diff --git a/website/assets/images/app-icon-numi-60x60@2x.png b/website/assets/images/app-icon-numi-60x60@2x.png new file mode 100644 index 00000000000..ed1057232fd Binary files /dev/null and b/website/assets/images/app-icon-numi-60x60@2x.png differ diff --git a/website/assets/images/app-icon-nvidia-geforce-now-60x60@2x.png b/website/assets/images/app-icon-nvidia-geforce-now-60x60@2x.png new file mode 100644 index 00000000000..96ac916cc66 Binary files /dev/null and b/website/assets/images/app-icon-nvidia-geforce-now-60x60@2x.png differ