Giter Club home page Giter Club logo

alfy's Introduction

alfy's People

Contributors

abdul avatar adamkiss avatar adriantoine avatar adriantombu avatar afzalive avatar antonniklasson avatar briangonzalez avatar calpa avatar colinf avatar dameck avatar davidmondok avatar demartini avatar dev99problems avatar fregante avatar gil avatar importre avatar jeppestaerk avatar jhilker avatar jopemachine avatar nguyenvanduocit avatar nicklayb avatar radibit avatar rizowski avatar samverschueren avatar sindresorhus avatar sonicdoe avatar spinscale avatar tofrankie avatar vinkla avatar wolasss avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

alfy's Issues

Alfy eats errors from Run Script action

Issuehunt badges

Alfred's workflow debugger only shows output from stderr. These lines redirect all output from stderr to alfy.error(), which then uses console.log() to print it to stdout:

loudRejection(alfy.error);
process.on('uncaughtException', alfy.error);
hookStd.stderr(alfy.error);

This means that any errors that occur inside a Run Script action are never displayed in the workflow debugger.


IssueHunt Summary

Backers (Total: $20.00)

Submitted pull Requests


Become a backer now!

Or submit a pull request to get the deposits!

Tips


IssueHunt has been backed by the following sponsors. Become a sponsor

ERROR: alfred.workflow.input.scriptfilter

[ERROR: alfred.workflow.input.scriptfilter] XML Parse Error 'The operation couldn’t be completed. (NSXMLParserErrorDomain error 4.)'. Row (null), Col (null): 'Document is empty' in XML:

index.js code:

const alfy = require('alfy');
alfy.output([{
        title: 'Unicorn'
}, {
        title: 'Rainbow'
}]);

slow to exit

While testing I've found that there's a noticable lag after the script outputs the final JSON. My solution was to add a .then(() => process.exit(0)) which speeded up results being outputted since Alfed seems to wait for the script to exit before returning anything.

Configuring workflows

Issuehunt badges

So, a couple of weeks back I thought we could make much more powerfull workflows if there was a way to configure them individually per user.

For instance, if someone creates a git workflow, the user installing that workflow should be able to put an API key somewhere. It's very dirty if he needs to change the workflow in that visual workflow editor and put the API key somewhere.

I have a couple of ideas for this, not sure if all that easy to do.

Configure script

We could allow a user to create a configure.js script which could use Inquirer.js or something to ask questions to the user. In the git workflow example for instance, either we create a new activation keyword, for instance configure-git which opens the terminal and executes configure.js. Or git configure for instance.

The name of that script could be set via package.json

{
  "name": "alfred-git",
  "alfy": {
    "configure": "configure.js"
  }
}

Configure questions

A second approach would be easier to add for the user. This would allow someone to define the questions in package.json and will store them in the config of the workflow. This way, in your workflow, you could just grab them from the config.

{
  "name": "alfred-git",
  "alfy": {
    "configure": {
      "api_key": {
        "type": "input",
        "message": "GitHub API key?"
      },
      "foo": {
        "type": "list",
        "message": "Some list here?",
        "choices": ["foo", "bar"]
      }
    }
  }
}

The first option offers the most flexibility in terms of the package you use to ask your questions (although 2 would offer more consistency).

The second one would definitely be easier for the developer, though less flexible. This would also mean every workflow is packaged with Inquirer.js, not sure how "heavy" it is. Although, it might be an idea to extract this in a separate package called alfy-configure and keep this the core. Something like alfy-test.


Note: This issue has a bounty, so it's expected that you are an experienced programmer and that you give it your best effort if you intend to tackle this. Don't forget, if applicable, to add tests, docs (double-check for typos), and update TypeScript definitions. And don't be sloppy. Review your own diff multiple times and try to find ways to improve and simplify your code. Instead of asking too many questions, present solutions. The point of an issue bounty is to reduce my workload, not give me more. Include a 🦄 in your PR description to indicate that you've read this. Thanks for helping out 🙌 - @sindresorhus


IssueHunt Summary

samverschueren samverschueren has been rewarded.

Backers (Total: $100.00)

Submitted pull Requests


Tips

Remove broken links in Users section

There are 5 broken links in Users section.

I think it is good to remove these lines in Users section if possible to avoid misclicks.

> blc https://github.com/sindresorhus/alfy | grep HTTP_404
├─BROKEN─ https://github.com/vinkla/alfred-kaomoji (HTTP_404)
├─BROKEN─ https://github.com/jacc/alfred-clap (HTTP_404)
├─BROKEN─ https://github.com/vinkla/alfred-reference (HTTP_404)
├─BROKEN─ https://github.com/vinkla/alfred-homebrew (HTTP_404)
├─BROKEN─ https://github.com/adriantombu/alfred-travis-ci (HTTP_404)

FYI: I used blc to check broken links

Install it globally

Hi there,

I'm quite new to node.js / npm so please excuse my rookie question.

Are there any drawbacks to install it with --global?

ERR_INPUT_TYPE_NOT_ALLOWED with example script

Using:
Alfred version 4.5.1 with Powerpack
Node version 14.17.5

After following all steps as described under Usage, when running the example workflow I get the following error in Alfred debugger:

Alfy[Script Filter] Queuing argument 'h'
Alfy[Script Filter] Script with argv 'h' finished
ERROR: Alfy[Script Filter] Code 1: internal/process/esm_loader.js:74
    internalBinding('errors').triggerUncaughtException(
                              ^

Error [ERR_INPUT_TYPE_NOT_ALLOWED]: --input-type can only be used with string input via --eval, --print, or STDIN
    at Loader.defaultResolve [as _resolve] (internal/modules/esm/resolve.js:813:13)
    at Loader.resolve (internal/modules/esm/loader.js:89:40)
    at Loader.getModuleJob (internal/modules/esm/loader.js:242:28)
    at Loader.import (internal/modules/esm/loader.js:177:28)
    at internal/modules/run_main.js:50:28
    at Object.loadESM (internal/process/esm_loader.js:68:11) {
  code: 'ERR_INPUT_TYPE_NOT_ALLOWED'
}

When I navigate to the workflow folder in terminal and run the javascript file with node index.js {query} I do get the expected result (JSON is returned).

Running basic script takes 5s and throws error

Hey,
I've created a new workflow with yeoman generator:

'use strict';
const alfy = require('alfy');

alfy.output([
	{
		title: 'Unicorn',
		subtitle: alfy.input
	}
]);

output

[00:16:30.984] alfy-pkc[Script Filter] Script with argv 'test' finished
[00:16:30.990] STDERR: alfy-pkc[Script Filter] /Users/pk/Library/Caches/com.runningwithcrayons.Alfred/Workflow Data/com.google.alfy-pkc/node_path: line 1: unexpected EOF while looking for matching `"'
/Users/pk/Library/Caches/com.runningwithcrayons.Alfred/Workflow Data/com.google.alfy-pkc/node_path: line 2: syntax error: unexpected end of file
[00:16:30.991] alfy-pkc[Script Filter] {
	"items": [
		{
			"title": "Unicorn",
			"subtitle": "test"
		}
	]

I'm using node 14 from nvm. Symlinked it to /usr/local/bin. Content of 'node_path' file:

PATH="/usr/local/opt/coreutils/libexec/gnubin

(missing " is not a typo)

run failed if index.js is esm module

error

[ERR_REQUIRE_ESM]: Must use import to load ES Module: /Users/jiangwei/.nvm/versions/node/v14.17.3/lib/node_modules/@ifu/emoji/index.js
at Object.Module._extensions..js (internal/modules/cjs/loader.js:1102:13) {
code: 'ERR_REQUIRE_ESM'
}

node: v14.17.3
alfy: 0.11.1

i try to remove --require esm in run-node.sh, will not throw this error anymore. so what --require esm doing

Cannot read property 'alfy' of undefined

the index.js is

const alfy = require('alfy');
alfy.output([{
title: 'Unicorn'
}, {
title: 'Rainbow'
}]);

and the console outputs the error:

[ERROR: input.scriptfilter] Code 1: {
  "items": [
    {
      "title": "Unicorn"
    },
    {
      "title": "Rainbow"
    }
  ]
}
{
  "items": [
    {
      "title": "TypeError: Cannot read property 'alfy' of undefined\n    at readPkgUp.then.result (/Users/pro/Library/Application Support/Alfred 3/Alfred.alfredpreferences/workflows/user.workflow.0408C61C-45B8-474D-B77D-B3C6691E4024/node_modules/alfy/lib/update-notification.js:7:26)",
      "subtitle": "Press ⌘L to see the full error and ⌘C to copy it.",
      "valid": false,
      "text": {
        "copy": "```\nTypeError: Cannot read property 'alfy' of undefined\n    at readPkgUp.then.result (/Users/pro/Library/Application Support/Alfred 3/Alfred.alfredpreferences/workflows/user.workflow.0408C61C-45B8-474D-B77D-B3C6691E4024/node_modules/alfy/lib/update-notification.js:7:26)\n```\n\n-\nregurl undefined\nAlfred 3.3.2\ndarwin x64 15.6.0",
        "largetype": "TypeError: Cannot read property 'alfy' of undefined\n    at readPkgUp.then.result (/Users/pro/Library/Application Support/Alfred 3/Alfred.alfredpreferences/workflows/user.workflow.0408C61C-45B8-474D-B77D-B3C6691E4024/node_modules/alfy/lib/update-notification.js:7:26)"
      },
      "icon": {
        "path": "/System/Library/CoreServices/CoreTypes.bundle/Contents/Resources/AlertStopIcon.icns"
      }
    }
  ]
}
[2017-06-03 16:11:59][ERROR: input.scriptfilter] JSON error: Garbage at end. in JSON:
{
  "items": [
    {
      "title": "Unicorn"
    },
    {
      "title": "Rainbow"
    }
  ]
}
{
  "items": [
    {
      "title": "TypeError: Cannot read property 'alfy' of undefined\n    at readPkgUp.then.result (/Users/pro/Library/Application Support/Alfred 3/Alfred.alfredpreferences/workflows/user.workflow.0408C61C-45B8-474D-B77D-B3C6691E4024/node_modules/alfy/lib/update-notification.js:7:26)",
      "subtitle": "Press ⌘L to see the full error and ⌘C to copy it.",
      "valid": false,
      "text": {
        "copy": "```\nTypeError: Cannot read property 'alfy' of undefined\n    at readPkgUp.then.result (/Users/pro/Library/Application Support/Alfred 3/Alfred.alfredpreferences/workflows/user.workflow.0408C61C-45B8-474D-B77D-B3C6691E4024/node_modules/alfy/lib/update-notification.js:7:26)\n```\n\n-\nregurl undefined\nAlfred 3.3.2\ndarwin x64 15.6.0",
        "largetype": "TypeError: Cannot read property 'alfy' of undefined\n    at readPkgUp.then.result (/Users/pro/Library/Application Support/Alfred 3/Alfred.alfredpreferences/workflows/user.workflow.0408C61C-45B8-474D-B77D-B3C6691E4024/node_modules/alfy/lib/update-notification.js:7:26)"
      },
      "icon": {
        "path": "/System/Library/CoreServices/CoreTypes.bundle/Contents/Resources/AlertStopIcon.icns"
      }
    }
  ]
}

Flaky tests

The tests are flaky because of these two lines

They are both working on the same instance of CacheConf. Is there anyway we can work around this problem without merging everything in one test file or run the test serially?

Add alfy-init script

Original comment: #24 (comment)

Basically it would just be a proxy to alfred-link. This would make the dev experience much better because it doesn't require installing alfred-link separately (assuming they know about alfred-link in the first place). Hopefully this encourages people to publish their workflows to npm instead of to Packal. Publishing to npm has much more benefits (which should be all described in my to-do blogpost :)).

Issue Updating Alfy Workflow

Yesterday we released a new version of the alfred-packagist. When we tried to update the package locally with npm i -g alfred-packagist we get the following error:

> [email protected] preuninstall /usr/local/lib/node_modules/alfred-packagist
> alfy-cleanup

{ Error: Command failed: alfred-unlink
module.js:529
    throw err;
    ^

Error: Cannot find module './'
    at Function.Module._resolveFilename (module.js:527:15)
    at Function.Module._load (module.js:476:23)
    at Module.require (module.js:568:17)
    at require (internal/module.js:11:18)
    at Object.<anonymous> (/usr/local/lib/node_modules/alfred-packagist/node_modules/.bin/alfred-unlink:3:20)
    at Module._compile (module.js:624:30)
    at Object.Module._extensions..js (module.js:635:10)
    at Module.load (module.js:545:32)
    at tryModuleLoad (module.js:508:12)
    at Function.Module._load (module.js:500:3)

    at Promise.all.then.arr (/usr/local/lib/node_modules/alfred-packagist/node_modules/execa/index.js:201:11)
    at <anonymous>
    at process._tickCallback (internal/process/next_tick.js:188:7)
  code: 1,
  killed: false,
  stdout: '',
  stderr: 'module.js:529\n    throw err;\n    ^\n\nError: Cannot find module \'./\'\n    at Function.Module._resolveFilename (module.js:527:15)\n    at Function.Module._load (module.js:476:23)\n    at Module.require (module.js:568:17)\n    at require (internal/module.js:11:18)\n    at Object.<anonymous> (/usr/local/lib/node_modules/alfred-packagist/node_modules/.bin/alfred-unlink:3:20)\n    at Module._compile (module.js:624:30)\n    at Object.Module._extensions..js (module.js:635:10)\n    at Module.load (module.js:545:32)\n    at tryModuleLoad (module.js:508:12)\n    at Function.Module._load (module.js:500:3)\n',
  failed: true,
  signal: null,
  cmd: 'alfred-unlink',
  timedOut: false }
npm WARN lifecycle [email protected]~preuninstall: continuing anyway [email protected] preuninstall: `alfy-cleanup`
npm WARN lifecycle Exit status 1
npm ERR! path /usr/local/lib/node_modules/alfred-packagist/node_modules/.bin/rimraf
npm ERR! code EEXIST
npm ERR! Refusing to delete /usr/local/lib/node_modules/alfred-packagist/node_modules/.bin/rimraf: is outside /usr/local/lib/node_modules/alfred-packagist/node_modules/rimraf and not a link
npm ERR! File exists: /usr/local/lib/node_modules/alfred-packagist/node_modules/.bin/rimraf
npm ERR! Move it away, and try again.

We're using node v8.7.0 and npm v5.5.1 on macOS.

Is this something we have done wrong when we implemented Alfy into alfred-packagist? What is your thoughts on this issue?

add `transform` function to `fetch` method

alfy.fetch allows someone to cache network requests for some time. An example is my alfred-ng2 workflow.

The json returned from the endpoint looks like this

{
  "@angular/common": [
    {
      "title": "APP_BASE_HREF",
      "path": "common/index/APP_BASE_HREF-let.html",
      "docType": "let",
      "stability": "stable",
      "secure": "false",
      "howToUse": "",
      "whatItDoes": "Not Done",
      "barrel" : "@angular/common"
    }
  ],
  "@angular/core": [
    {
      "title": "APPLICATION_COMMON_PROVIDERS",
      "path": "core/index/APPLICATION_COMMON_PROVIDERS-let.html",
      "docType": "let",
      "stability": "stable",
      "secure": "false",
      "howToUse": "",
      "whatItDoes": "Not Done",
      "barrel" : "@angular/core"
    }
  ]
}

I transform that data into one single list of items. Instead of doing the transformation every time a user searches through the packages, it could be done once before caching the data and directly work with the cached data instead. This could be very useful for large datasets or even for APIs returning xml and transform them to json before caching.

My suggestion is to add a transform option to the alfy.fetch options object.

alfy.fetch('https://my-xml-api.com/some-feed.xml', {
    maxAge: 86400000,    // 24 hours
    transform: result => xml2js.parseString(result)
}).then(jsonResult => {
     console.log(jsonResult);
     //=> some best-effort xml-2-json converted json
});

Feel free to provide (useful) feedback of any kind.

Extract and open source `run-node.sh`?

This would help with an issue we've had for a long time on ghooks.

I'd be happy to do it. I notice there's some specific Alfred stuff in there. Do you have any tips on how to make it in a way that works cross-platform and agnostic of Alfred?

Using `npm-registry-client` with alfy

I don't think this is an alfy issue but since this was the only way to reach you, I thought I'd post my question here.

To clarify, npm registry client is built to work with the browser only and I can't use their request methods?

Easiest to just highlight the work -- I've marked out most of it but this method is trying to fetch npm starred repos: https://github.com/artivilla/alfred-starred/blob/master/index.js#L28

Using postman, I get this response:
{"rows":[{"value":"basscss"},{"value":"bl"},{"value":"bluebird"},{"value":"fetch"},{"value":"jest-serializer-enzyme"},{"value":"json-web-token"},{"value":"kue"},{"value":"longjohn"},{"value":"mongoose-softdelete"},{"value":"nconf"},{"value":"nib"},{"value":"nodemon"},{"value":"v8-profiler"},{"value":"vinyl-source-stream"}]}

Support setting Alfred variables with alfy.output

Issuehunt badges

You can set variables in Alfred by writing to stdout using a special JSON format. It would be handy if alfy.output supported this, perhaps in a special variables key:

alfy.output([
  { title: 'Google', arg: 'https://www.google.com', variables: { browser: 'Chrome' },
  { title: 'Mozilla', arg: 'https://www.mozilla.org', variables:  { browser: 'Firefox' } }
])

Or as a second argument:

// backwards compatible, but less elegant
alfy.output([
  { title: 'Google', arg: 'https://www.google.com' },
  { title: 'Mozilla', arg: 'https://www.mozilla.org' }
], [
  { browser: 'Chrome' },
  { browser: 'Firefox' }
])

I'm happy to write a pull request if this seems worthwhile.

JSON Format

The format for emitting variables isn't complicated, but life would be easier if Alfy handled it.

Emit a string and set variables

// The root `alfredworkflow` key is required.
// Without it, Alfred will pass the object to the next node in the workflow like normal.
{
  "alfredworkflow": {
    "arg": "https://www.google.com",
    "variables": {"browser": "Chrome"}
  }
}

Emit multiple items and set variables

// `arg` is a stringified `alfredworkflow` object
{
  "items": [{
    "title": "Google",
    "arg": "{\"alfredworkflow\": {\"arg\": \"https://www.google.com\", \"variables\": {\"browser\": \"Chrome\"}}}"
  }]
}

Note, you can access Alfred variables through the environment:

const browser = process.env.browser

IssueHunt Summary

Backers (Total: $60.00)

Submitted pull Requests


Become a backer now!

Or submit a pull request to get the deposits!

Tips

How can i output a function?

Hello! How can i run a function (for example execa) when user select an item from list?

That's my code:

alfy.output([
	{
		title: 'Random',
		body: 'Get random photo'
	}, {
               title: 'ID',
               body: 'Pick photo by id'
        }
])  

Maybe not quite understand how it works

How to copy output to clipboard?

This repo hasn't gotten a commit in a month so I'm assuming it won't get a response, but I might as well try.

alfy.output(
	[{
		title: `👏🏻 ${alfy.input.replace(/ /g, ' 👏🏻 ')} 👏🏻 `,
	}]);

This is my code. How do I copy the title to the clipboard?

screen shot 2017-11-22 at 8 38 53 pm

That's my workflow. What am I doing wrong?

Support Alfred 4

npm install --global alfred-lock

Errors:

> [email protected] postinstall /Users/vivaxy/.npm-packages/lib/node_modules/alfred-lock
> alfy-init

{ Error: Command failed: alfred-link
Error: Alfred preferences not found at location /Users/vivaxy/Library/Preferences/com.runningwithcrayons.Alfred-Preferences-3.plist
    at pathExists.then.exists (/Users/vivaxy/.npm-packages/lib/node_modules/alfred-lock/node_modules/resolve-alfred-prefs/index.js:15:10)


    at makeError (/Users/vivaxy/.npm-packages/lib/node_modules/alfred-lock/node_modules/execa/index.js:174:9)
    at Promise.all.then.arr (/Users/vivaxy/.npm-packages/lib/node_modules/alfred-lock/node_modules/execa/index.js:278:16)
    at processTicksAndRejections (internal/process/next_tick.js:81:5)
  code: 1,
  stdout: '',
  stderr:
   'Error: Alfred preferences not found at location /Users/vivaxy/Library/Preferences/com.runningwithcrayons.Alfred-Preferences-3.plist\n    at pathExists.then.exists (/Users/vivaxy/.npm-packages/lib/node_modules/alfred-lock/node_modules/resolve-alfred-prefs/index.js:15:10)\n',
  failed: true,
  signal: null,
  cmd: 'alfred-link',
  timedOut: false,
  killed: false }
npm ERR! code ELIFECYCLE
npm ERR! errno 1
npm ERR! [email protected] postinstall: `alfy-init`
npm ERR! Exit status 1
npm ERR! 
npm ERR! Failed at the [email protected] postinstall script.
npm ERR! This is probably not a problem with npm. There is likely additional logging output above.

npm ERR! A complete log of this run can be found in:
npm ERR!     /Users/vivaxy/.npm/_logs/2019-05-31T14_25_10_280Z-debug.log

Plist Error

I've made a copy of the alfred-npms package and I'm trying to use the same workflow for another API. Though, the error below is thrown.

TypeError: Cannot read property '1' of null
    return /<key>version<\/key>[\s\S]*<string>([\d.]+)<\/string>/.exec(fs.readFileSync(infoPlist, 'utf8'))[1];
                                                                                                          ^

If I take the line below and remove the [1] in the end…

return /<key>version<\/key>[\s\S]*<string>([\d.]+)<\/string>/.exec(fs.readFileSync(infoPlist, 'utf8'))[1];

…it works. Then my package is executed as expected. What am I doing wrong? Any thoughts?

Error: Alfred preferences not found at location

Tried:
npm install --global alfred-npms

Got:

> [email protected] postinstall /usr/local/lib/node_modules/alfred-npms
> alfy-init

{ Error: Command failed: alfred-link
Error: Alfred preferences not found at location /Users/velocityzen/Library/Preferences/com.runningwithcrayons.Alfred-Preferences-3.plist
    at pathExists.then.exists (/usr/local/lib/node_modules/alfred-npms/node_modules/resolve-alfred-prefs/index.js:15:10)
    at <anonymous>

    at Promise.all.then.arr (/usr/local/lib/node_modules/alfred-npms/node_modules/execa/index.js:201:11)
    at <anonymous>
    at process._tickCallback (internal/process/next_tick.js:160:7)
  code: 1,
  killed: false,
  stdout: '',
  stderr: 'Error: Alfred preferences not found at location /Users/velocityzen/Library/Preferences/com.runningwithcrayons.Alfred-Preferences-3.plist\n    at pathExists.then.exists (/usr/local/lib/node_modules/alfred-npms/node_modules/resolve-alfred-prefs/index.js:15:10)\n    at <anonymous>\n',
  failed: true,
  signal: null,
  cmd: 'alfred-link',
  timedOut: false }
npm ERR! code ELIFECYCLE
npm ERR! errno 1
npm ERR! [email protected] postinstall: `alfy-init`
npm ERR! Exit status 1
npm ERR! 
npm ERR! Failed at the [email protected] postinstall script.
npm ERR! This is probably not a problem with npm. There is likely additional logging output above.

npm ERR! A complete log of this run can be found in:
npm ERR!     /Users/velocityzen/.npm/_logs/2018-03-01T04_44_12_239Z-debug.log

My preferences file is in dropbox for synchronization.

Access environment variables

#36 will likely resolve my issue so I can gather the users token to use to make API calls but for the short term is there a way to I can access the users system env variables?

require("alfy") takes ~120ms

I noticed that a very simple script of mine (just returning a query from a JSON file) was much slower than expected.
It turns out that just require('alfy') adds about 120ms to a script's execution time.

Since I only used alfy for outputs I replaced

const alfy = require('alfy');

with

const alfy = {
    output: (items) => {
        console.log(JSON.stringify({items}, null, '\t'));
    }
}

Now Alfred feels snappy again. :-)

"Couldn't find binary node" error in two packages using alfy

Hey @sindresorhus,

On a 1h fresh Mac OS setup, I cannot use any alfred workflow relying on alfy.

Here's my setup:

  • Iterm with zsh and oh-my-zshrc
  • yarn installed through brew install yarn --without-node
  • nvm with version 9 and 10 installed.

I've tried command -v node from zsh, bash and sh and they all return the path to the nvm installed binary.

I think installing yarn without node, and using nvm as the only way to install node breaks something with how alfy calls the scripts.

npm can not install

npm install alfy -S -D
npm ERR! code E404
npm ERR! 404 Not Found: resolve-alfred-prefs@^1.0.0

Logging prevents results from appearing

If I use alfy.log in my script, I can't get any valid results in the workflow. I get an error like this when trying to log some results during development:

[2017-12-07 15:27:10][ERROR: input.scriptfilter] JSON error: No string key for value in object around character 4. in JSON:

I know that alfy.log just goes to STDOUT (though console.error); is the issue that Alfred is reading that and trying to parse it for results? Or something in the way that my workflow is configured?

The search will be more quik without wifi

here is the code , the url is a visual host
I wonder why , when I shut down the wifi , the alfred will return the result more quickly?
If turn on the wifi,will be more slow, I have logged the url in alfy.fetch function,which shows
they both use the cached data .

alfy.fetch('http://linuxcmd.com/data.json',
           {maxAge: 86400000}).then(result => {
    var commands = [];
    var e = 0;
    for(var a in result){
      ++e;
      result[a]['id'] = e;
      commands.push(result[a]);
  }
  var i=0,
  page_size = commands.length,
  arrResult = [],
  query=alfy.input;
  if(commands&&commands.length&&toString.call(commands).indexOf('Array')>-1){
    var count = 0
    for (; i < page_size; i++) {
      if(isSreachIndexOF(commands[i].n,query)
       || isSreachIndexOF(commands[i].d,query) 
      ){
        if(count < page_size){
          arrResult.push(commands[i]);
          ++count;
        }
      }
    }
  }
  var items = [];
  for(var i = 0;i< arrResult.length;i++){
    items.push({
      title: arrResult[i].n,
      subtitle: arrResult[i].d,
      arg: arrResult[i].n
    })
  }

  if(items.length < 1){
    items.push({
      title: "没有搜素到内容",
      subtitle: "请尝试其它关键字",
    })
  }
  alfy.output(items);
});

Add possibility to fetch from network with caching

We already discussed something like this here #4 (comment).

Here's a small wrap-up. We want to add got to alfy by default in order to make network requests. But not only that, it should be possible to cache the network requests. If later on, the same network request is performed and the cache is still valid, the cache will be returned. If the cache is not valid, a new network request is performed and the cache is updated.

Bonus feature: If the cache is not valid BUT the network request fails (user might be working offline), the cached data is still returned.

alfy.fetch('https://myapi.com/foo/bar.json', {maxAge: 5000}).then(res => {
    console.log(res.body);
    // {foo: 'bar'}
});

Some extra notes: fetch is just calling got. So you can just pass the method property with value POST if a post request has to be performed.

@sindresorhus Did I cover everything?

Error: workflows directory does not exist

When installing a workflow for the first time with Alfy (when no other workflows have been installed yet), I get an error saying that the workflows directory in Alfred.alfredpreferences doesn't exist yet.

Error: Command failed: alfred-link
Error: Workflow directory `/Users/adriaan/stack/share/backups/Alfred 3/Alfred.alfredpreferences/workflows` does not exist
    at pathExists.then.exists (/Users/adriaan/.npm-packages/lib/node_modules/alfred-google-translate/node_modules/alfred-link/index.js:19:10)
    at <anonymous>

    at Promise.all.then.arr (/Users/adriaan/.npm-packages/lib/node_modules/alfred-google-translate/node_modules/execa/index.js:201:11)
    at <anonymous>
    at process._tickCallback (internal/process/next_tick.js:160:7)
  code: 1,
  killed: false,
  stdout: '',
  stderr: 'Error: Workflow directory `/Users/adriaan/stack/share/backups/Alfred 3/Alfred.alfredpreferences/workflows` does not exist\n    at pathExists.then.exists (/Users/adriaan/.npm-packages/lib/node_modules/alfred-google-translate/node_modules/alfred-link/index.js:19:10)\n    at <anonymous>\n',
  failed: true,
  signal: null,
  cmd: 'alfred-link',
  timedOut: false

The solution would be simple: just create the workflows directory when it does not exist yet.

[ERROR: input.scriptfilter] JSON error: JSON text did not start with array or object and option to allow fragments not set.

Alfred v3.5 [876]

Having this in my index.js,

"use strict";

const alfy = require("alfy");
const myConfig = require("./src/config.js");

alfy.output([
	{
		title: "Unicorn"
	},
	{
		title: "Rainbow"
	}
]);

I'm getting an error in Alfred debugger:

[ERROR: input.scriptfilter] JSON error: JSON text did not start with array or object and option to allow fragments not set. in JSON:
called
{
	"items": [
		{
			"title": "Unicorn"
		},
		{
			"title": "Rainbow"
		}
	]
}

If I require custom file const myConfig = require("./src/config.js");, error does show up.
If I require npm package (for example const notifier = require("node-notifier");), error does not show up.

Content of my config.js:

const alfy = require('alfy');

const config = alfy.config;

const getTimerObject = () => {
	return config.get('timerObject') || null;
};

const setTimerObject = newTimerObject => {
	config.set('timerObject', newTimerObject);
	return getTimerObject();
};

console.log('called');

module.exports = {
	setTimerObject,
	getTimerObject
};

Any way I can solve this?

non-bundlable with webpack

I've tried webpack, parcel, rollup and they all seem to fail at some stage.

I've gotten webpack to work by altering the way conf and cache-conf are given parentDir. By passing this explicitly in the constructor instead of relying on the module.parent object, webpack can resolve almost* all of the dependencies.

From conf/index.js:21

opts = Object.assign({
  projectName: pkgPath && JSON.parse(fs.readFileSync(pkgPath, 'utf8')).name
}, opts);

to

opts = Object.assign({
  projectName: opts.name
}, opts);

almost* refers to a dynamic require of electron in the got package. got/index.js:91

[ERROR: input.scriptfilter] JSON error: JSON text did not start with array or object and option to allow fragments not set. in JSON:

Issuehunt badges

I'm getting the following error when just trying to log a string with alfy.log:

[ERROR: input.scriptfilter] JSON error: JSON text did not start with array or object and option to allow fragments not set. in JSON:

Project built with yo alfred and development linked with alfred-link

There is a $20.00 open bounty on this issue. Add more on Issuehunt.

GraphQL Support?

As more and more sites and services are using graphql it would be great if alfy would support graphql queries & mutations.

// edit: saw that alfy used got under the hood. So you can make POST requests to the graphq api 🙈

Prevent cache failures on workflow update

I was implementing the transform function of the alfy.fetch method in alfred-ng2 and noticed a subtle area that could cause your workflow from failing a certain amount of time due to the cache being invalid.

Let me give you an example first to make it easier to understand. Let's assume I was calling an XML API that I transformed to JSON. At first (pre-transform), it would look like this.

alfy.fetch(`https://my-api.com/resources.xml`, {maxAge: ONE_WEEK})
    .then(result => xml2js(result))
    .then(jsonResult => {
         // transform the jsonResult to alfred items
    });

The XML data is cached for one day. Now let's assume I upgrade to the transform function. This could be beneficiel because it only has to run the xml2js call once before caching.

alfy.fetch(`https://my-api.com/resources.xml`, {
    maxAge: ONE_WEEK,
    transform: result => xml2js(result)
})
.then(jsonResult => {
    // transform the jsonResult to alfred items
});

An important thing to notice here is that in the second example, not the XML result is cached, but the result of the transform function and thus the JSON result is being cached. Pretty straightforward.

BUT, without knowing it, we could break everyones workflow now for one day. The thing is that if I had used this workflow quite recently, the XML data would still be cached and the fetch promise will not return JSON but XML. Boom, workflow explodes! Adding a function to (transform in this case), doesn't change anything to the cache key.

How did I solve this? By adding a version property to the options object.

alfy.fetch(`https://my-api.com/resources.xml`, {
    maxAge: ONE_WEEK,
    version: pkg.version,
    transform: result => xml2js(result)
})
.then(jsonResult => {
    // transform the jsonResult to alfred items
});

This will make sure that my cache key is different on every release and will invalidate the old cache.

Is this something we could add in alfy? Could we detect the callers package.json version number? In my case alfred-ng2 so that the developer doesn't have to worry about this issue? I'm quite sure that this issue will be overlooked by almost everyone if it was not tested properly.

A downside of this is that the cache could grow quite rapidly depending on the release cycles of the workflow.

Getting alfy-init: command not found

I was about to make an update to my Alfredinary, but now getting alfy-init: command not found. I have "postinstall": "alfy-init", in my package.json.

Using Node.js v14.8.0, Alfred 4.3.2 and these are my dependencies to the Alfred workflow

  "dependencies": {
    "alfy": "^0.10.0",
    "cloudinary": "^1.25.0",
    "dotenv": "^8.2.0"
  }

Embed alfred-notifier

It would totally make sense to embed alfred-notifier. It's easy to miss the possibility of notifying your users when you have a new version, no one reads the docs (entirely). Notifying your users of a new version is best practice after all and I always want to know if a new version is available.

However, there should always be a way to turn this feature off. The question is, how? Some ways I can think off.

  1. alfy.disableUpdateNotification()
  2. alfy.configure({updateNotification: false});

Built version caching into CacheConf

Currently, alfy.fetch will invalidate the cache if you update your workflow which is pretty nice. But maybe we should built this into cache-conf. The reason I'm thinking about this is because I'm creating a new workflow that does not fetch the data from a server, but from different files in a dependency. Reading all those files and transforming the data takes some time and I want to cache it. But if I want to do it correctly, I will have to write the versioned caching myself. So maybe we should add an optional version property to cache-conf which will invalidate older caches and just overwrite them.

Another suggestion of fixing this is if we would allow to read local files with alfy.fetch as well.

alfy.fetch('my-file.json', {
    maxAge: ONE_DAY,
    transform: data => {
       return {data};
    }
});

This way you will have the same benefits as URLs but for local files, as well as the transform function. Maybe this suggestion is a separate enhancement from the initial idea. But either one of them would solve my use case.

Allow top-level await

Issuehunt badges

Would be a nice convenience as a lot of Alfy workflows use promises.

We could use esm for this.


IssueHunt Summary

[
<
i
m
g

s
r
c

'
h
t
t
p
s
:
/
/
a
v
a
t
a
r
s
3
.
g
i
t
h
u
b
u
s
e
r
c
o
n
t
e
n
t
.
c
o
m
/
u
/
1
4
0
2
2
4
1
?
v

4
'

a
l
t

'
b
f
r
e
d

i
t
'

w
i
d
t
h

2
4

h
e
i
g
h
t

2
4

b
f
r
e
d

i
t
]
(
h
t
t
p
s
:
/
/
i
s
s
u
e
h
u
n
t
.
i
o
/
u
/
b
f
r
e
d

i
t
)

h
a
s

b
e
e
n

r
e
w
a
r
d
e
d
.

Backers (Total: $40.00)

Submitted pull Requests


Tips


IssueHunt has been backed by the following sponsors. Become a sponsor

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.