UNPKG

open-finder-dialog

Version:

Open a finder dialog window (finder prompt) programmatically. Only works on MacOS.

133 lines (125 loc) 5.26 kB
"use strict"; var __create = Object.create; var __defProp = Object.defineProperty; var __getOwnPropDesc = Object.getOwnPropertyDescriptor; var __getOwnPropNames = Object.getOwnPropertyNames; var __getProtoOf = Object.getPrototypeOf; var __hasOwnProp = Object.prototype.hasOwnProperty; var __name = (target, value) => __defProp(target, "name", { value, configurable: true }); var __export = (target, all) => { for (var name in all) __defProp(target, name, { get: all[name], enumerable: true }); }; var __copyProps = (to, from, except, desc) => { if (from && typeof from === "object" || typeof from === "function") { for (let key of __getOwnPropNames(from)) if (!__hasOwnProp.call(to, key) && key !== except) __defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable }); } return to; }; var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__getProtoOf(mod)) : {}, __copyProps( // If the importer is in node compatibility mode or this is not an ESM // file that has been converted to a CommonJS file using a Babel- // compatible transform (i.e. "__esModule" has not been set), then set // "default" to the CommonJS "module.exports" for node compatibility. isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", { value: mod, enumerable: true }) : target, mod )); var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod); // index.ts var open_finder_dialog_exports = {}; __export(open_finder_dialog_exports, { default: () => open_finder_dialog_default, openFinderDialog: () => openFinderDialog }); module.exports = __toCommonJS(open_finder_dialog_exports); var import_node_child_process = __toESM(require("child_process")); var import_detect_terminal = require("detect-terminal"); var escapeQuotedPath = /* @__PURE__ */ __name((input) => { return input.replace(/(?<!\\(?<!\\))"/g, "\\$&"); }, "escapeQuotedPath"); var isCanceled = /* @__PURE__ */ __name((v) => /cancell?ed/i.test(v), "isCanceled"); var buildCommand = /* @__PURE__ */ __name((allowMultiple, filters) => { const base = "choose file"; const withPrompt = ' with prompt "Select files to open"'; const ofType = filters.length > 0 ? ` of type {${filters.map((f) => `"${f}"`).join(", ")}}` : ""; const multi = allowMultiple ? " with multiple selections allowed" : ""; return base + withPrompt + ofType + multi; }, "buildCommand"); var openFinderDialog = /* @__PURE__ */ __name(async (initialDirectory = process.cwd(), options = {}) => { return new Promise((resolve, reject) => { const { filters = [], terminal = (0, import_detect_terminal.detectTerminal)(), limit = 100 } = options; const maxFiles = Math.max(1, limit); const command = buildCommand(limit > 1, filters); const escapedPath = escapeQuotedPath(initialDirectory); const pathSeparator = "<__PATH_SEPARATOR__>"; const appleScript = ` set defaultPath to POSIX file "${escapedPath}" set limit to ${maxFiles} try -- Open the file dialog within SystemUIServer to bring it to focus tell application "SystemUIServer" activate delay 0.2 -- Allow SystemUIServer to activate set file_list to ${command} default location defaultPath if limit = 1 then set file_list to {file_list} end if end tell -- Apply the maximum-files rule if limit > 0 and (count of file_list) > limit then set file_list to items 1 thru limit of file_list end if -- Process the selected files set posixPaths to {} repeat with aFile in file_list set end of posixPaths to POSIX path of aFile & "${pathSeparator}" end repeat -- Return focus to ${terminal} tell application "${terminal}" activate end tell set text item delimiters to "" set posixPathsString to posixPaths as string return posixPathsString on error -- Return focus to terminal app even if the dialog is canceled tell application "${terminal}" activate end tell return "CANCELLED" end try `; const child = import_node_child_process.default.spawn("osascript", ["-"]); let stdoutData = ""; let stderrData = ""; child.stdout.on("data", (data) => { stdoutData += data.toString(); }); child.stderr.on("data", (data) => { stderrData += data.toString(); }); child.on("close", (code) => { if (code !== 0 && stderrData) { reject(new Error(stderrData.trim())); return; } const output = stdoutData.trim(); if (isCanceled(output)) { resolve({ files: [], canceled: true }); return; } const files = output.split(pathSeparator).map((s) => s.trim()).filter((s) => s !== ""); resolve({ files, canceled: false }); }); child.stdin.write(appleScript); child.stdin.end(); }); }, "openFinderDialog"); var open_finder_dialog_default = openFinderDialog; // Annotate the CommonJS export names for ESM import in node: 0 && (module.exports = { openFinderDialog }); //# sourceMappingURL=index.js.map