alfy 2.0.0 → 3.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/index.d.ts +4 -2
- package/index.js +18 -10
- package/lib/update-notification.js +2 -2
- package/package.json +13 -11
- package/readme.md +29 -3
package/index.d.ts
CHANGED
|
@@ -36,6 +36,8 @@ export type CacheConfSetOptions = {
|
|
|
36
36
|
readonly maxAge?: number;
|
|
37
37
|
};
|
|
38
38
|
|
|
39
|
+
// TODO: Rename this in the next major version.
|
|
40
|
+
|
|
39
41
|
export type CacheConf<T extends Record<string, any> = Record<string, unknown>> = {
|
|
40
42
|
isExpired: (key: keyof T) => boolean;
|
|
41
43
|
|
|
@@ -363,9 +365,9 @@ export type Alfy = {
|
|
|
363
365
|
/**
|
|
364
366
|
Log value to the Alfred workflow debugger.
|
|
365
367
|
|
|
366
|
-
@param
|
|
368
|
+
@param value
|
|
367
369
|
*/
|
|
368
|
-
log: (
|
|
370
|
+
log: (value: unknown) => void;
|
|
369
371
|
|
|
370
372
|
/**
|
|
371
373
|
Display an error or error message in Alfred.
|
package/index.js
CHANGED
|
@@ -3,18 +3,20 @@ import process from 'node:process';
|
|
|
3
3
|
import {createRequire} from 'node:module';
|
|
4
4
|
import Conf from 'conf';
|
|
5
5
|
import got from 'got';
|
|
6
|
-
import {hookStderr} from 'hook-std';
|
|
7
6
|
import loudRejection from 'loud-rejection';
|
|
8
7
|
import cleanStack from 'clean-stack';
|
|
9
8
|
import {getProperty} from 'dot-prop';
|
|
10
9
|
import AlfredConfig from 'alfred-config';
|
|
11
|
-
import updateNotification from './lib/update-notification.js'; // eslint-disable-line import/order
|
|
10
|
+
import updateNotification from './lib/update-notification.js'; // eslint-disable-line import-x/order
|
|
12
11
|
|
|
13
12
|
const require = createRequire(import.meta.url);
|
|
14
13
|
const CacheConf = require('cache-conf');
|
|
15
14
|
|
|
16
15
|
const alfy = {};
|
|
17
16
|
|
|
17
|
+
// Track if output has been generated to avoid empty JSON
|
|
18
|
+
let hasOutput = false;
|
|
19
|
+
|
|
18
20
|
updateNotification();
|
|
19
21
|
|
|
20
22
|
const getIcon = name => `/System/Library/CoreServices/CoreTypes.bundle/Contents/Resources/${name}.icns`;
|
|
@@ -42,6 +44,7 @@ alfy.alfred = {
|
|
|
42
44
|
alfy.input = process.argv[2];
|
|
43
45
|
|
|
44
46
|
alfy.output = (items, {rerunInterval} = {}) => {
|
|
47
|
+
hasOutput = true;
|
|
45
48
|
console.log(JSON.stringify({items, rerun: rerunInterval}, null, '\t'));
|
|
46
49
|
};
|
|
47
50
|
|
|
@@ -73,6 +76,7 @@ alfy.log = text => {
|
|
|
73
76
|
|
|
74
77
|
alfy.error = error => {
|
|
75
78
|
const stack = cleanStack(error.stack || error);
|
|
79
|
+
const title = error.stack ? `${error.name}: ${error.message}` : String(error);
|
|
76
80
|
|
|
77
81
|
const copy = `
|
|
78
82
|
\`\`\`
|
|
@@ -86,7 +90,7 @@ ${process.platform} ${os.release()}
|
|
|
86
90
|
`.trim();
|
|
87
91
|
|
|
88
92
|
alfy.output([{
|
|
89
|
-
title
|
|
93
|
+
title,
|
|
90
94
|
subtitle: 'Press ⌘L to see the full error and ⌘C to copy it.',
|
|
91
95
|
valid: false,
|
|
92
96
|
text: {
|
|
@@ -97,6 +101,9 @@ ${process.platform} ${os.release()}
|
|
|
97
101
|
path: alfy.icon.error,
|
|
98
102
|
},
|
|
99
103
|
}]);
|
|
104
|
+
|
|
105
|
+
// Also output to stderr for the debugger (as requested in issue #86)
|
|
106
|
+
console.error(stack);
|
|
100
107
|
};
|
|
101
108
|
|
|
102
109
|
alfy.config = new Conf({
|
|
@@ -118,11 +125,6 @@ alfy.fetch = async (url, options) => {
|
|
|
118
125
|
...options,
|
|
119
126
|
};
|
|
120
127
|
|
|
121
|
-
// TODO: Remove this in 2024.
|
|
122
|
-
if (options.query) {
|
|
123
|
-
throw new Error('The `query` option was renamed to `searchParams`.');
|
|
124
|
-
}
|
|
125
|
-
|
|
126
128
|
if (typeof url !== 'string') {
|
|
127
129
|
throw new TypeError(`Expected \`url\` to be a \`string\`, got \`${typeof url}\``);
|
|
128
130
|
}
|
|
@@ -138,7 +140,7 @@ alfy.fetch = async (url, options) => {
|
|
|
138
140
|
delete options.transform;
|
|
139
141
|
delete options.maxAge;
|
|
140
142
|
|
|
141
|
-
const key = rawKey.replaceAll('.',
|
|
143
|
+
const key = rawKey.replaceAll('.', String.raw`\.`);
|
|
142
144
|
const cachedResponse = alfy.cache.get(key, {ignoreMaxAge: true});
|
|
143
145
|
|
|
144
146
|
if (cachedResponse && !alfy.cache.isExpired(key)) {
|
|
@@ -186,6 +188,12 @@ alfy.icon = {
|
|
|
186
188
|
|
|
187
189
|
loudRejection(alfy.error);
|
|
188
190
|
process.on('uncaughtException', alfy.error);
|
|
189
|
-
|
|
191
|
+
|
|
192
|
+
// Ensure valid JSON output even if user forgets to call alfy.output() (fixes #82)
|
|
193
|
+
process.on('beforeExit', () => {
|
|
194
|
+
if (!hasOutput) {
|
|
195
|
+
alfy.output([]);
|
|
196
|
+
}
|
|
197
|
+
});
|
|
190
198
|
|
|
191
199
|
export default alfy;
|
|
@@ -2,8 +2,8 @@ import {readPackageUp} from 'read-package-up';
|
|
|
2
2
|
import alfredNotifier from 'alfred-notifier';
|
|
3
3
|
|
|
4
4
|
export default async function updateNotification() {
|
|
5
|
-
const {package:
|
|
6
|
-
const alfy =
|
|
5
|
+
const {package: package_} = (await readPackageUp()) ?? {};
|
|
6
|
+
const alfy = package_?.alfy ?? {};
|
|
7
7
|
|
|
8
8
|
if (alfy.updateNotification !== false) {
|
|
9
9
|
alfredNotifier();
|
package/package.json
CHANGED
|
@@ -1,9 +1,10 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "alfy",
|
|
3
|
-
"version": "
|
|
3
|
+
"version": "3.0.0",
|
|
4
4
|
"description": "Create Alfred workflows with ease",
|
|
5
5
|
"license": "MIT",
|
|
6
6
|
"repository": "sindresorhus/alfy",
|
|
7
|
+
"funding": "https://github.com/sponsors/sindresorhus",
|
|
7
8
|
"type": "module",
|
|
8
9
|
"bin": {
|
|
9
10
|
"run-node": "./run-node.sh",
|
|
@@ -14,8 +15,9 @@
|
|
|
14
15
|
"types": "./index.d.ts",
|
|
15
16
|
"default": "./index.js"
|
|
16
17
|
},
|
|
18
|
+
"sideEffects": false,
|
|
17
19
|
"engines": {
|
|
18
|
-
"node": ">=
|
|
20
|
+
"node": ">=20"
|
|
19
21
|
},
|
|
20
22
|
"scripts": {
|
|
21
23
|
"test": "xo && ava && tsd"
|
|
@@ -45,21 +47,21 @@
|
|
|
45
47
|
"alfred-notifier": "^0.2.3",
|
|
46
48
|
"cache-conf": "^0.6.0",
|
|
47
49
|
"clean-stack": "^5.2.0",
|
|
48
|
-
"conf": "^
|
|
49
|
-
"dot-prop": "^
|
|
50
|
-
"execa": "^
|
|
51
|
-
"got": "^
|
|
52
|
-
"hook-std": "^
|
|
50
|
+
"conf": "^14.0.0",
|
|
51
|
+
"dot-prop": "^10.0.0",
|
|
52
|
+
"execa": "^9.6.0",
|
|
53
|
+
"got": "^14.4.8",
|
|
54
|
+
"hook-std": "^4.0.0",
|
|
53
55
|
"loud-rejection": "^2.2.0",
|
|
54
56
|
"read-package-up": "^11.0.0"
|
|
55
57
|
},
|
|
56
58
|
"devDependencies": {
|
|
57
|
-
"ava": "^
|
|
59
|
+
"ava": "^6.4.1",
|
|
58
60
|
"delay": "^6.0.0",
|
|
59
|
-
"nock": "^
|
|
61
|
+
"nock": "^14.0.10",
|
|
60
62
|
"tempfile": "^5.0.0",
|
|
61
|
-
"tsd": "^0.
|
|
62
|
-
"xo": "^
|
|
63
|
+
"tsd": "^0.33.0",
|
|
64
|
+
"xo": "^1.2.2"
|
|
63
65
|
},
|
|
64
66
|
"tsd": {
|
|
65
67
|
"compilerOptions": {
|
package/readme.md
CHANGED
|
@@ -103,7 +103,7 @@ By adding `alfy-init` as `postinstall` and `alfy-cleanup` as `preuninstall` scri
|
|
|
103
103
|
"author": {
|
|
104
104
|
"name": "Sindre Sorhus",
|
|
105
105
|
"email": "sindresorhus@gmail.com",
|
|
106
|
-
"url": "sindresorhus.com"
|
|
106
|
+
"url": "https://sindresorhus.com"
|
|
107
107
|
},
|
|
108
108
|
"scripts": {
|
|
109
109
|
"postinstall": "alfy-init",
|
|
@@ -151,13 +151,16 @@ test('main', async t => {
|
|
|
151
151
|
|
|
152
152
|
## Debugging
|
|
153
153
|
|
|
154
|
-
When developing your workflow it can be useful to be able to debug it when something is not working. This is when the [workflow debugger](https://www.alfredapp.com/help/workflows/advanced/debugger/) comes in handy. You can find it in your workflow view in Alfred. Press the insect icon to open it. It will show you the plain text output of `alfy.output()` and anything you log with `alfy.log()`:
|
|
154
|
+
When developing your workflow it can be useful to be able to debug it when something is not working. This is when the [workflow debugger](https://www.alfredapp.com/help/workflows/advanced/debugger/) comes in handy. You can find it in your workflow view in Alfred. Press the insect icon to open it. It will show you the plain text output of `alfy.output()` and anything you log with `alfy.log()` or `console.error()`:
|
|
155
155
|
|
|
156
156
|
```js
|
|
157
157
|
import alfy from 'alfy';
|
|
158
158
|
|
|
159
159
|
const unicorn = getUnicorn();
|
|
160
160
|
alfy.log(unicorn);
|
|
161
|
+
|
|
162
|
+
// You can also use console.error() for debugging
|
|
163
|
+
console.error('Debug info:', {data: someData});
|
|
161
164
|
```
|
|
162
165
|
|
|
163
166
|
## Environment variables
|
|
@@ -237,7 +240,7 @@ Log `value` to the [Alfred workflow debugger](https://www.alfredapp.com/help/wor
|
|
|
237
240
|
|
|
238
241
|
#### matches(input, list, item?)
|
|
239
242
|
|
|
240
|
-
Returns
|
|
243
|
+
Returns a `string[]` of items in `list` that case-insensitively contains `input`.
|
|
241
244
|
|
|
242
245
|
```js
|
|
243
246
|
import alfy from 'alfy';
|
|
@@ -323,6 +326,29 @@ alfy.matches('Foo', list, (item, input) => item === input);
|
|
|
323
326
|
|
|
324
327
|
Same as `matches()`, but with `alfy.input` as `input`.
|
|
325
328
|
|
|
329
|
+
If you want to match against multiple items, you must define your own matching function ([as shown here](#item)). Let’s extend the [example from the beginning](#example) to search for a keyword that appears either within the `title` or `body` property or both.
|
|
330
|
+
|
|
331
|
+
```js
|
|
332
|
+
import alfy from 'alfy';
|
|
333
|
+
|
|
334
|
+
const data = await alfy.fetch('https://jsonplaceholder.typicode.com/posts');
|
|
335
|
+
|
|
336
|
+
const items = alfy
|
|
337
|
+
.inputMatches(
|
|
338
|
+
data,
|
|
339
|
+
(item, input) =>
|
|
340
|
+
item.title?.toLowerCase().includes(input) ||
|
|
341
|
+
item.body?.toLowerCase().includes(input)
|
|
342
|
+
)
|
|
343
|
+
.map((element) => ({
|
|
344
|
+
title: element.title,
|
|
345
|
+
subtitle: element.body,
|
|
346
|
+
arg: element.id,
|
|
347
|
+
}));
|
|
348
|
+
|
|
349
|
+
alfy.output(items);
|
|
350
|
+
```
|
|
351
|
+
|
|
326
352
|
#### error(error)
|
|
327
353
|
|
|
328
354
|
Display an error or error message in Alfred.
|