From 56bc42ebec5e9b3e6115f457b67ede43e36d1c2e Mon Sep 17 00:00:00 2001 From: Mitch Francese <2227948+tux234@users.noreply.github.com> Date: Mon, 15 Dec 2025 22:15:13 -0500 Subject: [PATCH] Add TextExpander as an FMA for Fleet (#37296) Co-authored-by: Allen Houchins <32207388+allenhouchins@users.noreply.github.com> --- .../inputs/homebrew/textexpander.json | 8 +++++++ ee/maintained-apps/outputs/apps.json | 7 ++++++ .../outputs/textexpander/darwin.json | 21 ++++++++++++++++++ .../components/icons/TextExpander.tsx | 14 ++++++++++++ .../SoftwarePage/components/icons/index.ts | 2 ++ .../images/app-icon-textexpander-60x60@2x.png | Bin 0 -> 3624 bytes 6 files changed, 52 insertions(+) create mode 100644 ee/maintained-apps/inputs/homebrew/textexpander.json create mode 100644 ee/maintained-apps/outputs/textexpander/darwin.json create mode 100644 frontend/pages/SoftwarePage/components/icons/TextExpander.tsx create mode 100644 website/assets/images/app-icon-textexpander-60x60@2x.png diff --git a/ee/maintained-apps/inputs/homebrew/textexpander.json b/ee/maintained-apps/inputs/homebrew/textexpander.json new file mode 100644 index 0000000000..49c13f7616 --- /dev/null +++ b/ee/maintained-apps/inputs/homebrew/textexpander.json @@ -0,0 +1,8 @@ +{ + "name": "TextExpander", + "unique_identifier": "com.smileonmymac.textexpander", + "token": "textexpander", + "installer_format": "dmg", + "slug": "textexpander/darwin", + "default_categories": ["Productivity"] +} diff --git a/ee/maintained-apps/outputs/apps.json b/ee/maintained-apps/outputs/apps.json index 830575fda5..80c04c9e43 100644 --- a/ee/maintained-apps/outputs/apps.json +++ b/ee/maintained-apps/outputs/apps.json @@ -1443,6 +1443,13 @@ "unique_identifier": "com.gravitational.teleport.tsh", "description": "Teleport Suite is a modern SSH server for teams managing distributed infrastructure." }, + { + "name": "TextExpander", + "slug": "textexpander/darwin", + "platform": "darwin", + "unique_identifier": "com.smileonmymac.textexpander", + "description": "TextExpander is an application that let's you create and insert pre-made snippets of text anywhere." + }, { "name": "Thunderbird", "slug": "thunderbird/darwin", diff --git a/ee/maintained-apps/outputs/textexpander/darwin.json b/ee/maintained-apps/outputs/textexpander/darwin.json new file mode 100644 index 0000000000..059f45f615 --- /dev/null +++ b/ee/maintained-apps/outputs/textexpander/darwin.json @@ -0,0 +1,21 @@ +{ + "versions": [ + { + "version": "8.4", + "queries": { + "exists": "SELECT 1 FROM apps WHERE bundle_identifier = 'com.smileonmymac.textexpander';" + }, + "installer_url": "https://cdn.textexpander.com/mac/840.8/TextExpander_8.4.dmg", + "install_script_ref": "56427f61", + "uninstall_script_ref": "e0155221", + "sha256": "bf99688d6c5b88a6a8b6aa0e107069e19db96d4626cab9cdc31163a69df81a18", + "default_categories": [ + "Productivity" + ] + } + ], + "refs": { + "56427f61": "#!/bin/sh\n\n# variables\nAPPDIR=\"/Applications/\"\nTMPDIR=$(dirname \"$(realpath $INSTALLER_PATH)\")\n# functions\n\nquit_application() {\n local bundle_id=\"$1\"\n local timeout_duration=10\n\n # check if the application is running\n if ! osascript -e \"application id \\\"$bundle_id\\\" is running\" 2>/dev/null; then\n return\n fi\n\n local console_user\n console_user=$(stat -f \"%Su\" /dev/console)\n if [[ $EUID -eq 0 && \"$console_user\" == \"root\" ]]; 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\n# extract contents\nMOUNT_POINT=$(mktemp -d /tmp/dmg_mount_XXXXXX)\nhdiutil attach -plist -nobrowse -readonly -mountpoint \"$MOUNT_POINT\" \"$INSTALLER_PATH\"\nsudo cp -R \"$MOUNT_POINT\"/* \"$TMPDIR\"\nhdiutil detach \"$MOUNT_POINT\"\n# copy to the applications folder\nquit_application 'com.smileonmymac.textexpander'\nif [ -d \"$APPDIR/TextExpander.app\" ]; then\n\tsudo mv \"$APPDIR/TextExpander.app\" \"$TMPDIR/TextExpander.app.bkp\"\nfi\nsudo cp -R \"$TMPDIR/TextExpander.app\" \"$APPDIR\"\n", + "e0155221": "#!/bin/sh\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 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/TextExpander.app\"\ntrash $LOGGED_IN_USER '~/Library/Application Support/Google/Chrome/NativeMessagingHosts/com.smileonmymac.textexpander.json'\ntrash $LOGGED_IN_USER '~/Library/Application Support/TextExpander'\ntrash $LOGGED_IN_USER '~/Library/Caches/com.smileonmymac.textexpander'\ntrash $LOGGED_IN_USER '~/Library/Preferences/com.smileonmymac.textexpander.plist'\ntrash $LOGGED_IN_USER '~/Library/Saved Application State/com.smileonmymac.textexpander.savedState'\ntrash $LOGGED_IN_USER '~/Library/Webkit/com.smileonmymac.textexpander'\n" + } +} diff --git a/frontend/pages/SoftwarePage/components/icons/TextExpander.tsx b/frontend/pages/SoftwarePage/components/icons/TextExpander.tsx new file mode 100644 index 0000000000..4ac93d1c8b --- /dev/null +++ b/frontend/pages/SoftwarePage/components/icons/TextExpander.tsx @@ -0,0 +1,14 @@ +import * as React from "react"; + +import type { SVGProps } from "react"; + +const TextExpander = (props: SVGProps) => ( + + + +); +export default TextExpander; diff --git a/frontend/pages/SoftwarePage/components/icons/index.ts b/frontend/pages/SoftwarePage/components/icons/index.ts index f596bd3472..4a0716a9c8 100644 --- a/frontend/pages/SoftwarePage/components/icons/index.ts +++ b/frontend/pages/SoftwarePage/components/icons/index.ts @@ -189,6 +189,7 @@ import Teams from "./Teams"; import Telegram from "./Telegram"; import TeleportConnect from "./TeleportConnect"; import Terminal from "./Terminal"; +import TextExpander from "./TextExpander"; import Thunderbird from "./Thunderbird"; import Todoist from "./Todoist"; import Tower from "./Tower"; @@ -408,6 +409,7 @@ export const SOFTWARE_NAME_TO_ICON_MAP = { teleport: TeleportConnect, terminal: Terminal, teamviewer: TeamViewer, + textexpander: TextExpander, thunderbird: Thunderbird, todoist: Todoist, tower: Tower, diff --git a/website/assets/images/app-icon-textexpander-60x60@2x.png b/website/assets/images/app-icon-textexpander-60x60@2x.png new file mode 100644 index 0000000000000000000000000000000000000000..a1270743128e43cd482cc8070c86b329387b6dcf GIT binary patch literal 3624 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 literal 0 HcmV?d00001