feat: add open function to api

Add OpenMessageSchema and OpenPayloadSchema for handling messages to open an application. Decided to implement actual opening functionality in frontend for Tauri's security model
This commit is contained in:
ByteAtATime 2025-06-16 22:00:17 -07:00
parent 907051e883
commit a15db4946c
No known key found for this signature in database
5 changed files with 51 additions and 4 deletions

View file

@ -123,12 +123,22 @@ export const GoBackToPluginListSchema = z.object({
});
export type GoBackToPluginList = z.infer<typeof GoBackToPluginListSchema>;
const OpenPayloadSchema = z.object({
target: z.string(),
application: z.string().optional()
});
const OpenMessageSchema = z.object({
type: z.literal('open'),
payload: OpenPayloadSchema
});
export const SidecarMessageWithPluginsSchema = z.union([
BatchUpdateSchema,
CommandSchema,
LogMessageSchema,
PluginListSchema,
PreferenceValuesSchema,
GoBackToPluginListSchema
GoBackToPluginListSchema,
OpenMessageSchema
]);
export type SidecarMessageWithPlugins = z.infer<typeof SidecarMessageWithPluginsSchema>;

View file

@ -1,5 +1,7 @@
import { LaunchType } from './types';
import * as fs from 'fs';
import { writeOutput } from '../io';
import type { Application } from './types';
const supportPath = '/home/byte/code/raycast-linux/sidecar/dist/plugin/support/';
try {
@ -38,3 +40,21 @@ export async function getSelectedFinderItems(): Promise<FileSystemItem[]> {
export async function getSelectedText(): Promise<string> {
return Promise.reject(new Error('No text selected in the frontmost application.'));
}
export async function open(target: string, application?: Application | string): Promise<void> {
let openWith: string | undefined;
if (typeof application === 'string') {
openWith = application;
} else if (application) {
openWith = application.path;
}
writeOutput({
type: 'open',
payload: {
target,
application: openWith
}
});
}

View file

@ -10,7 +10,7 @@ import { Grid } from './components/grid';
import { Form } from './components/form';
import { Action, ActionPanel } from './components/actions';
import { Detail } from './components/detail';
import { environment, getSelectedFinderItems, getSelectedText } from './environment';
import { environment, getSelectedFinderItems, getSelectedText, open } from './environment';
import { preferencesStore } from '../preferences';
let currentPluginName: string | null = null;
@ -70,6 +70,7 @@ export const getRaycastApi = () => {
ActionPanel,
Detail,
Form,
Icon
Icon,
open
};
};

View file

@ -10,3 +10,10 @@ export const Toast = {
Animated: 'ANIMATED'
}
};
export type Application = {
name: string;
path: string;
bundleId?: string;
localizedName?: string;
};

View file

@ -1,4 +1,4 @@
import { Command, type Child } from '@tauri-apps/plugin-shell';
import { Command, type Child, open as shellOpen } from '@tauri-apps/plugin-shell';
import { Unpackr } from 'msgpackr';
import { uiStore } from '$lib/ui.svelte';
import { SidecarMessageWithPluginsSchema } from '@raycast-linux/protocol';
@ -123,6 +123,15 @@ class SidecarService {
return;
}
if (typedMessage.type === 'open') {
const { target, application } = typedMessage.payload;
shellOpen(target, application).catch((err) => {
this.#log(`ERROR: Failed to open '${target}': ${err}`);
console.error(`Failed to open '${target}':`, err);
});
return;
}
if (typedMessage.type === 'plugin-list') {
uiStore.setPluginList(typedMessage.payload);
return;