Créez des flux de travail Alfred avec facilité
node binaire.await de haut niveau..catch() de haut niveau. Vous avez besoin de Node.js 18+ et Alfred 4 ou version ultérieure avec la mise à niveau PowerPack payante.
npm install alfyIMPORTANT: Votre script sera exécuté en tant qu'ESM.
Créez un nouveau flux de travail Alfred vide.
Ajoutez un Script Filter (cliquez avec le bouton droit sur le canevas → Inputs → Script Filter ), définissez Language sur /bin/bash et ajoutez le script suivant:
./node_modules/.bin/run-node index.js "$1"
Nous ne pouvons pas appeler node directement car les applications GUI sur macOS n'héritent pas le chemin $.
Astuce: vous pouvez utiliser le générateur-alfred pour échafauner un flux de travail basé sur
alfy. Si c'est le cas, vous pouvez sauter le reste des étapes, aller directement à l'index.jset faire votre truc.
Définissez le Keyword par lequel vous souhaitez invoquer votre flux de travail.
Accédez à votre nouveau répertoire de workflow (cliquez avec le bouton droit sur le workflow dans la barre latérale → Open in Finder ).
Initialisez un repo avec npm init .
Ajouter "type": "module" sur package.json.
Installez Alfy avec npm install alfy .
Dans le répertoire de workflow, créez un fichier index.js , importez alfy et faites votre truc.
Ici, nous récupérons un JSON à partir d'une API d'espace réservé et présentons des éléments correspondants à l'utilisateur:
import alfy from 'alfy' ;
const data = await alfy . fetch ( 'https://jsonplaceholder.typicode.com/posts' ) ;
const items = alfy
. inputMatches ( data , 'title' )
. map ( element => ( {
title : element . title ,
subtitle : element . body ,
arg : element . id
} ) ) ;
alfy . output ( items ) ; 
Quelques exemples d'utilisation dans la nature: alfred-npms , alfred-emoj , alfred-ng .
Alfy utilise Alfred-Notificateur en arrière-plan pour afficher une notification lorsqu'une mise à jour pour votre flux de travail est disponible.

Alfy offre la possibilité de mettre en cache des données, soit avec le fetch, soit directement via l'objet Cache.
Une chose importante à noter est que les données en cache sont invalidées automatiquement lorsque vous mettez à jour votre flux de travail. Cela offre aux développeurs de la flexibilité de modifier la structure des données en cache entre les flux de travail sans avoir à se soucier des données plus anciennes invalides.
En ajoutant alfy-init en tant que postinstall et alfy-cleanup comme script preuninstall , vous pouvez publier votre package sur NPM au lieu de Packal. De cette façon, vos packages ne sont qu'une simple commande npm install .
{
"name" : " alfred-unicorn " ,
"version" : " 1.0.0 " ,
"description" : " My awesome unicorn workflow " ,
"author" : {
"name" : " Sindre Sorhus " ,
"email" : " [email protected] " ,
"url" : " https://sindresorhus.com "
},
"scripts" : {
"postinstall" : " alfy-init " ,
"preuninstall" : " alfy-cleanup "
},
"dependencies" : {
"alfy" : " * "
}
}Astuce: préfixez votre flux de travail avec
alfred-pour les rendre faciles à consultation via NPM.
Vous pouvez supprimer ces propriétés de votre fichier info.plist car ils sont ajoutés automatiquement au moment de l'installation.
Après avoir publié votre flux de travail à NPM, vos utilisateurs peuvent facilement installer ou mettre à jour le flux de travail.
npm install --global alfred-unicornAstuce: Au lieu de mettre à jour manuellement chaque flux de travail vous-même, utilisez le flux de travail Alfred-UpDater pour le faire pour vous.
Les workflows peuvent facilement être testés avec un test alfy. Voici un petit exemple.
import test from 'ava' ;
import alfyTest from 'alfy-test' ;
test ( 'main' , async t => {
const alfy = alfyTest ( ) ;
const result = await alfy ( 'workflow input' ) ;
t . deepEqual ( result , [
{
title : 'foo' ,
subtitle : 'bar'
}
] ) ;
} ) ; Lorsque vous développez votre flux de travail, il peut être utile de pouvoir le déboguer lorsque quelque chose ne fonctionne pas. C'est à ce moment que le débogueur de workflow est utile. Vous pouvez le trouver dans votre vue de flux de travail dans Alfred. Appuyez sur l'icône des insectes pour l'ouvrir. Il vous montrera la sortie en texte brut d' alfy.output() et de tout ce que vous vous connectez avec alfy.log() :
import alfy from 'alfy' ;
const unicorn = getUnicorn ( ) ;
alfy . log ( unicorn ) ; Alfred permet aux utilisateurs de définir des variables d'environnement pour un flux de travail qui peut ensuite être utilisé par ce flux de travail. Cela peut être utile si vous avez, par exemple, vous avez besoin de l'utilisateur pour spécifier un jeton API pour un service. Vous pouvez accéder aux variables d'environnement du flux de travail à partir de process.env . Par exemple process.env.apiToken .
Type: string
Entrée d'Alfred. Ce que l'utilisateur a écrit dans la zone d'entrée.
Retourne la sortie à Alfred.
Type: object[]
Liste de object avec l'une des propriétés prises en charge.
Exemple:
import alfy from 'alfy' ;
alfy . output ( [
{
title : 'Unicorn'
} ,
{
title : 'Rainbow'
}
] ) ; Type: object
Type: number (secondes)
Valeurs: 0.1...5.0
Un script peut être défini pour ré-cours automatiquement après un intervalle. Le script ne sera réécrit que si le filtre de script est toujours actif et que l'utilisateur n'a pas changé l'état du filtre en tapant et en déclenchant une réévaluation. Plus d'informations.
Par exemple, il pourrait être utilisé pour mettre à jour les progrès d'une tâche particulière:
import alfy from 'alfy' ;
alfy . output (
[
{
title : 'Downloading Unicorns…' ,
subtitle : ` ${ progress } %` ,
}
] ,
{
// Re-run and update progress every 3 seconds.
rerunInterval : 3
}
) ; 
value du journal au débogueur du flux de travail Alfred.
Renvoie une string[] des éléments dans list que le cas contient input .
import alfy from 'alfy' ;
alfy . matches ( 'Corn' , [ 'foo' , 'unicorn' ] ) ;
//=> ['unicorn'] Type: string
Texte à correspondre par rapport aux éléments list .
Type: string[]
Liste à égaler.
Type: string | Function
Par défaut, il correspondra aux éléments list .
Spécifiez une chaîne pour correspondre à une propriété d'objet:
import alfy from 'alfy' ;
const list = [
{
title : 'foo'
} ,
{
title : 'unicorn'
}
] ;
alfy . matches ( 'Unicorn' , list , 'title' ) ;
//=> [{title: 'unicorn'}]Ou biens imbriqués:
import alfy from 'alfy' ;
const list = [
{
name : {
first : 'John' ,
last : 'Doe'
}
} ,
{
name : {
first : 'Sindre' ,
last : 'Sorhus'
}
}
] ;
alfy . matches ( 'sindre' , list , 'name.first' ) ;
//=> [{name: {first: 'Sindre', last: 'Sorhus'}}]Spécifiez une fonction pour gérer vous-même. La fonction reçoit l'élément de liste et l'entrée, à la fois en inférieure, comme arguments, et devrait renvoyer un booléen pour savoir s'il correspond:
import alfy from 'alfy' ;
const list = [ 'foo' , 'unicorn' ] ;
// Here we do an exact match.
// `Foo` matches the item since it's lowercased for you.
alfy . matches ( 'Foo' , list , ( item , input ) => item === input ) ;
//=> ['foo'] Identique à matches() , mais avec alfy.input en input .
Si vous souhaitez correspondre à plusieurs éléments, vous devez définir votre propre fonction de correspondance (comme indiqué ici). Étendons l'exemple depuis le début pour rechercher un mot-clé qui apparaît dans la propriété title ou body ou les deux.
import alfy from 'alfy' ;
const data = await alfy . fetch ( 'https://jsonplaceholder.typicode.com/posts' ) ;
const items = alfy
. inputMatches (
data ,
( item , input ) =>
item . title ?. toLowerCase ( ) . includes ( input ) ||
item . body ?. toLowerCase ( ) . includes ( input )
)
. map ( ( element ) => ( {
title : element . title ,
subtitle : element . body ,
arg : element . id ,
} ) ) ;
alfy . output ( items ) ; Affichez une erreur ou un message d'erreur dans Alfred.
Remarque: vous n'avez pas besoin de promesses de niveau .catch() . Alfy gère cela pour vous.
Type: Error | string
Erreur ou message d'erreur à afficher.

Renvoie une Promise qui renvoie le corps de la réponse.
Type: string
URL à récupérer.
Type: object
Toutes les options got et les options ci-dessous.
Type: boolean
Par défaut: true
Analyse du corps de réponse avec JSON.parse et définissez accept de l'en-tête vers application/json .
Type: number
Nombre de millisecondes Cette demande doit être mise en cache.
Type: boolean
Par défaut: true
Que ce soit à résoudre avec seulement le corps ou une réponse complète.
import alfy from 'alfy' ;
await alfy . fetch ( 'https://api.foo.com' ) ;
//=> {foo: 'bar'}
await alfy . fetch ( 'https://api.foo.com' , {
resolveBodyOnly : false
} ) ;
/*
{
body: {
foo: 'bar'
},
headers: {
'content-type': 'application/json'
}
}
*/ Type: Function
Transformez le corps de réponse avant qu'il ne soit mis en cache.
import alfy from 'alfy' ;
await alfy . fetch ( 'https://api.foo.com' , {
transform : body => {
body . foo = 'bar' ;
return body ;
}
} )Transformez la réponse.
import alfy from 'alfy' ;
await alfy . fetch ( 'https://api.foo.com' , {
resolveBodyOnly : false ,
transform : response => {
response . body . foo = 'bar' ;
return response ;
}
} )Vous pouvez également retourner une promesse.
import alfy from 'alfy' ;
import xml2js from 'xml2js' ;
import pify from 'pify' ;
const parseString = pify ( xml2js . parseString ) ;
await alfy . fetch ( 'https://api.foo.com' , {
transform : body => parseString ( body )
} ) Type: object
Persister les données de configuration.
Exporte une instance conf avec le jeu de chemin de configuration correct.
Exemple:
import alfy from 'alfy' ;
alfy . config . set ( 'unicorn' , '?' ) ;
alfy . config . get ( 'unicorn' ) ;
//=> '?' Type: Map
Exporte une carte avec la configuration du flux de travail de l'utilisateur. Une configuration de workflow permet à vos utilisateurs de fournir des informations de configuration pour le workflow. Par exemple, si vous développez un flux de travail GitHub, vous pouvez laisser vos utilisateurs fournir leurs propres jetons API.
Voir alfred-config pour plus de détails.
Exemple:
import alfy from 'alfy' ;
alfy . userConfig . get ( 'apiKey' ) ;
//=> '16811cad1b8547478b3e53eae2e0f083' Type: object
Persister les données de cache.
Exporte une instance conf modifiée avec le jeu de chemin de cache correct.
Exemple:
import alfy from 'alfy' ;
alfy . cache . set ( 'unicorn' , '?' ) ;
alfy . cache . get ( 'unicorn' ) ;
//=> '?' La méthode set de cette instance accepte un troisième argument facultatif où vous pouvez fournir une option maxAge . maxAge est le nombre de millisecondes La valeur est valide dans le cache.
Exemple:
import alfy from 'alfy' ;
import delay from 'delay' ;
alfy . cache . set ( 'foo' , 'bar' , { maxAge : 5000 } ) ;
alfy . cache . get ( 'foo' ) ;
//=> 'bar'
// Wait 5 seconds
await delay ( 5000 ) ;
alfy . cache . get ( 'foo' ) ;
//=> undefined Type: boolean
Si l'utilisateur a actuellement le débogueur de flux de travail ouvert.
Type: object
Clés: 'info' | 'warning' | 'error' | 'alert' | 'like' | 'delete'
Obtenez diverses icônes système par défaut.
Les plus utiles sont inclus comme clés. Le reste que vous pouvez obtenir avec icon.get() . Allez sur /System/Library/CoreServices/CoreTypes.bundle/Contents/Resources dans Finder pour les voir tous.
Exemple:
import alfy from 'alfy' ;
console . log ( alfy . icon . error ) ;
//=> '/System/Library/CoreServices/CoreTypes.bundle/Contents/Resources/AlertStopIcon.icns'
console . log ( alfy . icon . get ( 'Clock' ) ) ;
//=> '/System/Library/CoreServices/CoreTypes.bundle/Contents/Resources/Clock.icns' Type: object
Exemple:
{
name : 'Emoj' ,
version : '0.2.5' ,
uid : 'user.workflow.B0AC54EC-601C-479A-9428-01F9FD732959' ,
bundleId : 'com.sindresorhus.emoj'
} Type: object
Métadonnées Alfred.
Exemple: '3.0.2'
Découvrez quelle version utilise actuellement. Cela peut être utile si votre flux de travail dépend des fonctionnalités d'une version Alfred particulière.
Exemple: 'alfred.theme.yosemite'
Thème actuel utilisé.
Exemple: 'rgba(255,255,255,0.98)'
Si vous créez des icônes à la volée, cela vous permet de découvrir la couleur de l'arrière-plan du thème.
Exemple: 'rgba(255,255,255,0.98)'
La couleur du résultat sélectionné.
Exemple: 3
Découvrez quel mode sous-texte l'utilisateur a sélectionné dans les préférences d'apparence.
Remarque de l'utilisabilité: Ceci est disponible afin que les développeurs puissent modifier le texte de résultat en fonction du mode sélectionné de l'utilisateur, mais le texte de résultat d'un workflow ne doit pas être gonflé inutilement sur la base de cela, car la principale raison pour laquelle les utilisateurs cachent généralement le sous-texte est de rendre Alfred un aspect plus propre.
Exemple: '/Users/sindresorhus/Library/Application Support/Alfred/Workflow Data/com.sindresorhus.npms'
Emplacement recommandé pour les données non volatiles. Utilisez simplement alfy.data qui utilise ce chemin.
Exemple: '/Users/sindresorhus/Library/Caches/com.runningwithcrayons.Alfred/Workflow Data/com.sindresorhus.npms'
Emplacement recommandé pour les données volatiles. Utilisez simplement alfy.cache qui utilise ce chemin.
Exemple: '/Users/sindresorhus/Dropbox/Alfred/Alfred.alfredpreferences'
Ceci est l'emplacement de l' Alfred.alfredpreferences . Si un utilisateur a synchronisé ses paramètres, cela vous permettra de savoir où se trouvent ses paramètres quel que soit l'état de synchronisation.
Exemple: 'adbd4f66bc3ae8493832af61a41ee609b20d8705'
Les préférences locales non synchronisées sont stockées dans Alfred.alfredpreferences sous …/preferences/local/${preferencesLocalHash}/ .
Flux de travail Alfred en utilisant Alfy