alfy 1.1.0 → 2.1.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/cleanup.js +9 -11
- package/index.d.ts +31 -27
- package/index.js +3 -7
- package/init.js +14 -17
- package/lib/update-notification.js +3 -3
- package/package.json +25 -16
- package/readme.md +25 -2
package/cleanup.js
CHANGED
|
@@ -6,14 +6,12 @@ import {execa} from 'execa';
|
|
|
6
6
|
|
|
7
7
|
const __dirname = path.dirname(fileURLToPath(import.meta.url));
|
|
8
8
|
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
}
|
|
19
|
-
})();
|
|
9
|
+
try {
|
|
10
|
+
await execa('alfred-unlink', {
|
|
11
|
+
preferLocal: true,
|
|
12
|
+
localDir: __dirname,
|
|
13
|
+
});
|
|
14
|
+
} catch (error) {
|
|
15
|
+
console.error(error);
|
|
16
|
+
process.exit(1);
|
|
17
|
+
}
|
package/index.d.ts
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
|
-
import Conf from 'conf';
|
|
2
|
-
import {Options} from 'got';
|
|
1
|
+
import type Conf from 'conf';
|
|
2
|
+
import {type Options} from 'got';
|
|
3
3
|
|
|
4
|
-
export
|
|
4
|
+
export type FetchOptions = {
|
|
5
5
|
/**
|
|
6
6
|
Number of milliseconds this request should be cached.
|
|
7
7
|
*/
|
|
@@ -11,33 +11,37 @@ export interface FetchOptions extends Partial<Options> {
|
|
|
11
11
|
Transform the response before it gets cached.
|
|
12
12
|
*/
|
|
13
13
|
readonly transform?: (body: unknown) => unknown;
|
|
14
|
-
}
|
|
14
|
+
} & Partial<Options>;
|
|
15
15
|
|
|
16
|
-
export
|
|
16
|
+
export type OutputOptions = {
|
|
17
17
|
/**
|
|
18
18
|
A script can be set to re-run automatically after some interval.
|
|
19
19
|
|
|
20
20
|
The script will only be re-run if the script filter is still active and the user hasn't changed the state of the filter by typing and triggering a re-run. For example, it could be used to update the progress of a particular task:
|
|
21
21
|
*/
|
|
22
22
|
readonly rerunInterval?: number;
|
|
23
|
-
}
|
|
23
|
+
};
|
|
24
24
|
|
|
25
|
-
|
|
25
|
+
// eslint-disable-next-line unicorn/prevent-abbreviations
|
|
26
|
+
export type CacheConfGetOptions = {
|
|
26
27
|
/**
|
|
27
28
|
Get the item for the key provided without taking the `maxAge` of the item into account.
|
|
28
29
|
*/
|
|
29
30
|
readonly ignoreMaxAge?: boolean;
|
|
30
|
-
}
|
|
31
|
+
};
|
|
31
32
|
|
|
32
|
-
|
|
33
|
+
// eslint-disable-next-line unicorn/prevent-abbreviations
|
|
34
|
+
export type CacheConfSetOptions = {
|
|
33
35
|
/**
|
|
34
36
|
Number of milliseconds the cached value is valid.
|
|
35
37
|
*/
|
|
36
38
|
readonly maxAge?: number;
|
|
37
|
-
}
|
|
39
|
+
};
|
|
38
40
|
|
|
39
|
-
|
|
40
|
-
|
|
41
|
+
// TODO: Rename this in the next major version.
|
|
42
|
+
// eslint-disable-next-line unicorn/prevent-abbreviations
|
|
43
|
+
export type CacheConf<T extends Record<string, any> = Record<string, unknown>> = {
|
|
44
|
+
isExpired: (key: keyof T) => boolean;
|
|
41
45
|
|
|
42
46
|
get<Key extends keyof T>(key: Key, options?: CacheConfGetOptions): T[Key];
|
|
43
47
|
get<Key extends keyof T>(key: Key, defaultValue: Required<T>[Key], options?: CacheConfGetOptions): Required<T>[Key];
|
|
@@ -48,7 +52,7 @@ export interface CacheConf<T> extends Conf<T> {
|
|
|
48
52
|
set(key: string, value: unknown, options: CacheConfSetOptions): void;
|
|
49
53
|
set(object: Partial<T>, options: CacheConfSetOptions): void;
|
|
50
54
|
set<Key extends keyof T>(key: Partial<T> | Key | string, value?: T[Key] | unknown, options?: CacheConfSetOptions): void;
|
|
51
|
-
}
|
|
55
|
+
} & Conf<T>;
|
|
52
56
|
|
|
53
57
|
/**
|
|
54
58
|
The icon displayed in the result row. Workflows are run from their workflow folder, so you can reference icons stored in your workflow relatively.
|
|
@@ -59,17 +63,17 @@ By using `{type: 'fileicon}`, Alfred will get the icon for the specified path.
|
|
|
59
63
|
|
|
60
64
|
Finally, by using `{type: 'filetype'}`, you can get the icon of a specific file. For example, `{path: 'public.png'}`.
|
|
61
65
|
*/
|
|
62
|
-
export
|
|
66
|
+
export type IconElement = {
|
|
63
67
|
readonly path?: string;
|
|
64
68
|
readonly type?: 'fileicon' | 'filetype';
|
|
65
|
-
}
|
|
69
|
+
};
|
|
66
70
|
|
|
67
71
|
/**
|
|
68
72
|
The text element defines the text the user will get when copying the selected result row with `⌘C` or displaying large type with `⌘L`.
|
|
69
73
|
|
|
70
74
|
If these are not defined, you will inherit Alfred's standard behaviour where the argument is copied to the Clipboard or used for Large Type.
|
|
71
75
|
*/
|
|
72
|
-
export
|
|
76
|
+
export type TextElement = {
|
|
73
77
|
/**
|
|
74
78
|
User will get when copying the selected result row with `⌘C`.
|
|
75
79
|
*/
|
|
@@ -79,28 +83,28 @@ export interface TextElement {
|
|
|
79
83
|
User will get displaying large type with `⌘L`.
|
|
80
84
|
*/
|
|
81
85
|
readonly largetype?: string;
|
|
82
|
-
}
|
|
86
|
+
};
|
|
83
87
|
|
|
84
88
|
/**
|
|
85
89
|
Defines what to change when the modifier key is pressed.
|
|
86
90
|
|
|
87
91
|
When you release the modifier key, it returns to the original item.
|
|
88
92
|
*/
|
|
89
|
-
export
|
|
93
|
+
export type ModifierKeyItem = {
|
|
90
94
|
readonly valid?: boolean;
|
|
91
95
|
readonly title?: string;
|
|
92
96
|
readonly subtitle?: string;
|
|
93
97
|
readonly arg?: string;
|
|
94
98
|
readonly icon?: string;
|
|
95
99
|
readonly variables?: Record<string, string>;
|
|
96
|
-
}
|
|
100
|
+
};
|
|
97
101
|
|
|
98
102
|
/**
|
|
99
103
|
This element defines the Universal Action items used when actioning the result, and overrides arg being used for actioning.
|
|
100
104
|
|
|
101
105
|
The action key can take a string or array for simple types, and the content type will automatically be derived by Alfred to file, URL or text.
|
|
102
106
|
*/
|
|
103
|
-
export
|
|
107
|
+
export type ActionElement = {
|
|
104
108
|
/**
|
|
105
109
|
Forward text to Alfred.
|
|
106
110
|
*/
|
|
@@ -120,14 +124,14 @@ export interface ActionElement {
|
|
|
120
124
|
Forward some value and let the value type be infered from Alfred.
|
|
121
125
|
*/
|
|
122
126
|
readonly auto?: string | string[];
|
|
123
|
-
}
|
|
127
|
+
};
|
|
124
128
|
|
|
125
129
|
type PossibleModifiers = 'fn' | 'ctrl' | 'opt' | 'cmd' | 'shift';
|
|
126
130
|
|
|
127
131
|
/**
|
|
128
132
|
Each item describes a result row displayed in Alfred.
|
|
129
133
|
*/
|
|
130
|
-
export
|
|
134
|
+
export type ScriptFilterItem = {
|
|
131
135
|
/**
|
|
132
136
|
This is a unique identifier for the item which allows help Alfred to learn about this item for subsequent sorting and ordering of the user's actioned results.
|
|
133
137
|
|
|
@@ -289,7 +293,7 @@ export interface ScriptFilterItem {
|
|
|
289
293
|
Variables can be passed out of the script filter within a variables object.
|
|
290
294
|
*/
|
|
291
295
|
readonly variables?: Record<string, string>;
|
|
292
|
-
}
|
|
296
|
+
};
|
|
293
297
|
|
|
294
298
|
/**
|
|
295
299
|
Create Alfred workflows with ease
|
|
@@ -311,7 +315,7 @@ const items = alfy
|
|
|
311
315
|
alfy.output(items);
|
|
312
316
|
```
|
|
313
317
|
*/
|
|
314
|
-
export
|
|
318
|
+
export type Alfy = {
|
|
315
319
|
/**
|
|
316
320
|
Return output to Alfred.
|
|
317
321
|
|
|
@@ -433,7 +437,7 @@ export interface Alfy {
|
|
|
433
437
|
//=> '🦄'
|
|
434
438
|
```
|
|
435
439
|
*/
|
|
436
|
-
config: Conf
|
|
440
|
+
config: Conf;
|
|
437
441
|
|
|
438
442
|
/**
|
|
439
443
|
Persist cache data.
|
|
@@ -450,7 +454,7 @@ export interface Alfy {
|
|
|
450
454
|
//=> '🦄'
|
|
451
455
|
```
|
|
452
456
|
*/
|
|
453
|
-
cache: CacheConf
|
|
457
|
+
cache: CacheConf;
|
|
454
458
|
|
|
455
459
|
/**
|
|
456
460
|
Get various default system icons.
|
|
@@ -542,7 +546,7 @@ export interface Alfy {
|
|
|
542
546
|
```
|
|
543
547
|
*/
|
|
544
548
|
userConfig: Map<string, string>;
|
|
545
|
-
}
|
|
549
|
+
};
|
|
546
550
|
|
|
547
551
|
declare const alfy: Alfy;
|
|
548
552
|
|
package/index.js
CHANGED
|
@@ -8,7 +8,7 @@ import loudRejection from 'loud-rejection';
|
|
|
8
8
|
import cleanStack from 'clean-stack';
|
|
9
9
|
import {getProperty} from 'dot-prop';
|
|
10
10
|
import AlfredConfig from 'alfred-config';
|
|
11
|
-
import updateNotification from './lib/update-notification.js';
|
|
11
|
+
import updateNotification from './lib/update-notification.js'; // eslint-disable-line import/order
|
|
12
12
|
|
|
13
13
|
const require = createRequire(import.meta.url);
|
|
14
14
|
const CacheConf = require('cache-conf');
|
|
@@ -100,6 +100,7 @@ ${process.platform} ${os.release()}
|
|
|
100
100
|
};
|
|
101
101
|
|
|
102
102
|
alfy.config = new Conf({
|
|
103
|
+
projectName: 'alfy',
|
|
103
104
|
cwd: alfy.alfred.data,
|
|
104
105
|
});
|
|
105
106
|
|
|
@@ -117,11 +118,6 @@ alfy.fetch = async (url, options) => {
|
|
|
117
118
|
...options,
|
|
118
119
|
};
|
|
119
120
|
|
|
120
|
-
// TODO: Remove this in 2024.
|
|
121
|
-
if (options.query) {
|
|
122
|
-
throw new Error('The `query` option was renamed to `searchParams`.');
|
|
123
|
-
}
|
|
124
|
-
|
|
125
121
|
if (typeof url !== 'string') {
|
|
126
122
|
throw new TypeError(`Expected \`url\` to be a \`string\`, got \`${typeof url}\``);
|
|
127
123
|
}
|
|
@@ -137,7 +133,7 @@ alfy.fetch = async (url, options) => {
|
|
|
137
133
|
delete options.transform;
|
|
138
134
|
delete options.maxAge;
|
|
139
135
|
|
|
140
|
-
const key = rawKey.
|
|
136
|
+
const key = rawKey.replaceAll('.', '\\.');
|
|
141
137
|
const cachedResponse = alfy.cache.get(key, {ignoreMaxAge: true});
|
|
142
138
|
|
|
143
139
|
if (cachedResponse && !alfy.cache.isExpired(key)) {
|
package/init.js
CHANGED
|
@@ -6,21 +6,18 @@ import {execa} from 'execa';
|
|
|
6
6
|
|
|
7
7
|
const __dirname = path.dirname(fileURLToPath(import.meta.url));
|
|
8
8
|
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
});
|
|
15
|
-
|
|
16
|
-
await execa('alfred-config', {
|
|
17
|
-
preferLocal: true,
|
|
18
|
-
localDir: __dirname,
|
|
19
|
-
stdio: 'inherit',
|
|
20
|
-
});
|
|
21
|
-
} catch (error) {
|
|
22
|
-
console.error(error);
|
|
23
|
-
process.exit(1);
|
|
24
|
-
}
|
|
25
|
-
})();
|
|
9
|
+
try {
|
|
10
|
+
await execa('alfred-link', {
|
|
11
|
+
preferLocal: true,
|
|
12
|
+
localDir: __dirname,
|
|
13
|
+
});
|
|
26
14
|
|
|
15
|
+
await execa('alfred-config', {
|
|
16
|
+
preferLocal: true,
|
|
17
|
+
localDir: __dirname,
|
|
18
|
+
stdio: 'inherit',
|
|
19
|
+
});
|
|
20
|
+
} catch (error) {
|
|
21
|
+
console.error(error);
|
|
22
|
+
process.exit(1);
|
|
23
|
+
}
|
|
@@ -1,9 +1,9 @@
|
|
|
1
|
-
import {readPackageUp} from 'read-
|
|
1
|
+
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,18 +1,23 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "alfy",
|
|
3
|
-
"version": "
|
|
3
|
+
"version": "2.1.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
|
-
"exports": "./index.js",
|
|
9
9
|
"bin": {
|
|
10
10
|
"run-node": "./run-node.sh",
|
|
11
11
|
"alfy-init": "./init.js",
|
|
12
12
|
"alfy-cleanup": "./cleanup.js"
|
|
13
13
|
},
|
|
14
|
+
"exports": {
|
|
15
|
+
"types": "./index.d.ts",
|
|
16
|
+
"default": "./index.js"
|
|
17
|
+
},
|
|
18
|
+
"sideEffects": false,
|
|
14
19
|
"engines": {
|
|
15
|
-
"node": ">=
|
|
20
|
+
"node": ">=18"
|
|
16
21
|
},
|
|
17
22
|
"scripts": {
|
|
18
23
|
"test": "xo && ava && tsd"
|
|
@@ -41,22 +46,26 @@
|
|
|
41
46
|
"alfred-link": "^0.3.1",
|
|
42
47
|
"alfred-notifier": "^0.2.3",
|
|
43
48
|
"cache-conf": "^0.6.0",
|
|
44
|
-
"clean-stack": "^
|
|
45
|
-
"conf": "^
|
|
46
|
-
"dot-prop": "^
|
|
47
|
-
"execa": "^
|
|
48
|
-
"got": "^
|
|
49
|
+
"clean-stack": "^5.2.0",
|
|
50
|
+
"conf": "^13.0.1",
|
|
51
|
+
"dot-prop": "^9.0.0",
|
|
52
|
+
"execa": "^9.3.0",
|
|
53
|
+
"got": "^14.4.2",
|
|
49
54
|
"hook-std": "^3.0.0",
|
|
50
55
|
"loud-rejection": "^2.2.0",
|
|
51
|
-
"read-
|
|
56
|
+
"read-package-up": "^11.0.0"
|
|
52
57
|
},
|
|
53
58
|
"devDependencies": {
|
|
54
|
-
"ava": "^
|
|
55
|
-
"delay": "^
|
|
56
|
-
"nock": "^13.
|
|
57
|
-
"tempfile": "^
|
|
58
|
-
"tsd": "^0.
|
|
59
|
-
"
|
|
60
|
-
|
|
59
|
+
"ava": "^6.1.3",
|
|
60
|
+
"delay": "^6.0.0",
|
|
61
|
+
"nock": "^13.5.4",
|
|
62
|
+
"tempfile": "^5.0.0",
|
|
63
|
+
"tsd": "^0.31.1",
|
|
64
|
+
"xo": "^0.59.2"
|
|
65
|
+
},
|
|
66
|
+
"tsd": {
|
|
67
|
+
"compilerOptions": {
|
|
68
|
+
"module": "node16"
|
|
69
|
+
}
|
|
61
70
|
}
|
|
62
71
|
}
|
package/readme.md
CHANGED
|
@@ -17,7 +17,7 @@
|
|
|
17
17
|
|
|
18
18
|
## Prerequisites
|
|
19
19
|
|
|
20
|
-
You need [Node.js
|
|
20
|
+
You need [Node.js 18+](https://nodejs.org) and [Alfred 4 or later](https://www.alfredapp.com) with the paid [Powerpack](https://www.alfredapp.com/powerpack/) upgrade.
|
|
21
21
|
|
|
22
22
|
## Install
|
|
23
23
|
|
|
@@ -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",
|
|
@@ -323,6 +323,29 @@ alfy.matches('Foo', list, (item, input) => item === input);
|
|
|
323
323
|
|
|
324
324
|
Same as `matches()`, but with `alfy.input` as `input`.
|
|
325
325
|
|
|
326
|
+
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.
|
|
327
|
+
|
|
328
|
+
```js
|
|
329
|
+
import alfy from 'alfy';
|
|
330
|
+
|
|
331
|
+
const data = await alfy.fetch('https://jsonplaceholder.typicode.com/posts');
|
|
332
|
+
|
|
333
|
+
const items = alfy
|
|
334
|
+
.inputMatches(
|
|
335
|
+
data,
|
|
336
|
+
(item, input) =>
|
|
337
|
+
item.title?.toLowerCase().includes(input) ||
|
|
338
|
+
item.body?.toLowerCase().includes(input)
|
|
339
|
+
)
|
|
340
|
+
.map((element) => ({
|
|
341
|
+
title: element.title,
|
|
342
|
+
subtitle: element.body,
|
|
343
|
+
arg: element.id,
|
|
344
|
+
}));
|
|
345
|
+
|
|
346
|
+
alfy.output(items);
|
|
347
|
+
```
|
|
348
|
+
|
|
326
349
|
#### error(error)
|
|
327
350
|
|
|
328
351
|
Display an error or error message in Alfred.
|