├── .gitignore
├── vendor
├── joetannenbaum
│ └── alfred-workflow
│ │ ├── .gitignore
│ │ ├── composer.json
│ │ ├── .travis.yml
│ │ ├── phpunit.xml
│ │ ├── LICENSE.md
│ │ ├── src
│ │ ├── Workflow.php
│ │ └── Result.php
│ │ ├── README.md
│ │ ├── tests
│ │ └── WorkflowTest.php
│ │ └── composer.lock
├── autoload.php
└── composer
│ ├── autoload_classmap.php
│ ├── autoload_namespaces.php
│ ├── autoload_psr4.php
│ ├── autoload_static.php
│ ├── LICENSE
│ ├── installed.json
│ ├── autoload_real.php
│ └── ClassLoader.php
├── icon.png
├── screenshot.png
├── workflow-variables.png
├── composer.json
├── LICENSE
├── composer.lock
├── README.md
├── find-messages.php
└── info.plist
/.gitignore:
--------------------------------------------------------------------------------
1 | .idea/
2 | .git/
3 | .DS_Store
4 |
5 |
--------------------------------------------------------------------------------
/vendor/joetannenbaum/alfred-workflow/.gitignore:
--------------------------------------------------------------------------------
1 | vendor
2 |
--------------------------------------------------------------------------------
/icon.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/squatto/alfred-imessage-2fa/HEAD/icon.png
--------------------------------------------------------------------------------
/screenshot.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/squatto/alfred-imessage-2fa/HEAD/screenshot.png
--------------------------------------------------------------------------------
/workflow-variables.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/squatto/alfred-imessage-2fa/HEAD/workflow-variables.png
--------------------------------------------------------------------------------
/vendor/autoload.php:
--------------------------------------------------------------------------------
1 | array($vendorDir . '/joetannenbaum/alfred-workflow/src'),
10 | );
11 |
--------------------------------------------------------------------------------
/vendor/joetannenbaum/alfred-workflow/composer.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "joetannenbaum/alfred-workflow",
3 | "description": "PHP helper for creating Alfred Workflows.",
4 | "license": "MIT",
5 | "authors": [
6 | {
7 | "name": "Joe Tannenbaum",
8 | "email": "joe@joe.codes"
9 | }
10 | ],
11 | "require": {
12 | "php": ">=5.4.0"
13 | },
14 | "autoload": {
15 | "psr-4": {
16 | "Alfred\\Workflows\\": "src/"
17 | }
18 | },
19 | "require-dev": {
20 | "phpunit/phpunit": "^5.3|~4.8"
21 | }
22 | }
23 |
--------------------------------------------------------------------------------
/vendor/joetannenbaum/alfred-workflow/.travis.yml:
--------------------------------------------------------------------------------
1 | language: php
2 | sudo: false
3 |
4 | php:
5 | - 5.4
6 | - 5.5
7 | - 5.6
8 | - 7
9 |
10 | env:
11 | - COMPOSER_OPTS=""
12 | - COMPOSER_OPTS="--prefer-lowest"
13 |
14 | before_script:
15 | - travis_retry composer self-update
16 | - travis_retry composer update $COMPOSER_OPTS
17 |
18 | script:
19 | - vendor/bin/phpunit --coverage-text --coverage-clover=coverage.clover
20 |
21 | after_script:
22 | - wget https://scrutinizer-ci.com/ocular.phar
23 | - if [ "$TRAVIS_PHP_VERSION" != 7 ]; then php ocular.phar code-coverage:upload --format=php-clover coverage.clover; fi
24 |
--------------------------------------------------------------------------------
/composer.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "squatto/alfred-imessage-2fa",
3 | "description": "Find two-factor authentication codes in your recent iMessage messages",
4 | "version": "1.3.0",
5 | "keywords": [
6 | "alfred",
7 | "alfred-workflow",
8 | "2fa",
9 | "imessage"
10 | ],
11 | "homepage": "https://github.com/squatto/alfred-imessage-2fa",
12 | "support": {
13 | "source": "https://github.com/squatto/alfred-imessage-2fa",
14 | "issues": "https://github.com/squatto/alfred-imessage-2fa/issues"
15 | },
16 | "license": "MIT",
17 | "require": {
18 | "joetannenbaum/alfred-workflow": "^0.1.0",
19 | "ext-pdo": "*"
20 | }
21 | }
22 |
--------------------------------------------------------------------------------
/vendor/joetannenbaum/alfred-workflow/phpunit.xml:
--------------------------------------------------------------------------------
1 |
2 |
13 |
14 |
15 | ./tests/
16 |
17 |
18 |
19 |
--------------------------------------------------------------------------------
/vendor/composer/autoload_static.php:
--------------------------------------------------------------------------------
1 |
11 | array (
12 | 'Alfred\\Workflows\\' => 17,
13 | ),
14 | );
15 |
16 | public static $prefixDirsPsr4 = array (
17 | 'Alfred\\Workflows\\' =>
18 | array (
19 | 0 => __DIR__ . '/..' . '/joetannenbaum/alfred-workflow/src',
20 | ),
21 | );
22 |
23 | public static function getInitializer(ClassLoader $loader)
24 | {
25 | return \Closure::bind(function () use ($loader) {
26 | $loader->prefixLengthsPsr4 = ComposerStaticInitd16a52b940a8c8cb97d16149984b3c2b::$prefixLengthsPsr4;
27 | $loader->prefixDirsPsr4 = ComposerStaticInitd16a52b940a8c8cb97d16149984b3c2b::$prefixDirsPsr4;
28 |
29 | }, null, ClassLoader::class);
30 | }
31 | }
32 |
--------------------------------------------------------------------------------
/vendor/joetannenbaum/alfred-workflow/LICENSE.md:
--------------------------------------------------------------------------------
1 | The MIT License (MIT)
2 |
3 | Copyright (c) 2016 Joe Tannenbaum
4 |
5 | Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
6 |
7 | The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
8 |
9 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
10 |
--------------------------------------------------------------------------------
/LICENSE:
--------------------------------------------------------------------------------
1 | MIT License
2 |
3 | Copyright (c) 2016 Till Krüss
4 |
5 | Permission is hereby granted, free of charge, to any person obtaining a copy
6 | of this software and associated documentation files (the "Software"), to deal
7 | in the Software without restriction, including without limitation the rights
8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9 | copies of the Software, and to permit persons to whom the Software is
10 | furnished to do so, subject to the following conditions:
11 |
12 | The above copyright notice and this permission notice shall be included in all
13 | copies or substantial portions of the Software.
14 |
15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21 | SOFTWARE.
22 |
--------------------------------------------------------------------------------
/vendor/composer/LICENSE:
--------------------------------------------------------------------------------
1 |
2 | Copyright (c) Nils Adermann, Jordi Boggiano
3 |
4 | Permission is hereby granted, free of charge, to any person obtaining a copy
5 | of this software and associated documentation files (the "Software"), to deal
6 | in the Software without restriction, including without limitation the rights
7 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
8 | copies of the Software, and to permit persons to whom the Software is furnished
9 | to do so, subject to the following conditions:
10 |
11 | The above copyright notice and this permission notice shall be included in all
12 | copies or substantial portions of the Software.
13 |
14 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
15 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
16 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
17 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
18 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
19 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
20 | THE SOFTWARE.
21 |
22 |
--------------------------------------------------------------------------------
/vendor/composer/installed.json:
--------------------------------------------------------------------------------
1 | [
2 | {
3 | "name": "joetannenbaum/alfred-workflow",
4 | "version": "0.1.2",
5 | "version_normalized": "0.1.2.0",
6 | "source": {
7 | "type": "git",
8 | "url": "https://github.com/joetannenbaum/alfred-workflow.git",
9 | "reference": "88e042db9cad0c95ab80e87c69d7f1e15340e7ac"
10 | },
11 | "dist": {
12 | "type": "zip",
13 | "url": "https://api.github.com/repos/joetannenbaum/alfred-workflow/zipball/88e042db9cad0c95ab80e87c69d7f1e15340e7ac",
14 | "reference": "88e042db9cad0c95ab80e87c69d7f1e15340e7ac",
15 | "shasum": ""
16 | },
17 | "require": {
18 | "php": ">=5.4.0"
19 | },
20 | "require-dev": {
21 | "phpunit/phpunit": "^5.3|~4.8"
22 | },
23 | "time": "2018-08-14T14:25:53+00:00",
24 | "type": "library",
25 | "installation-source": "dist",
26 | "autoload": {
27 | "psr-4": {
28 | "Alfred\\Workflows\\": "src/"
29 | }
30 | },
31 | "notification-url": "https://packagist.org/downloads/",
32 | "license": [
33 | "MIT"
34 | ],
35 | "authors": [
36 | {
37 | "name": "Joe Tannenbaum",
38 | "email": "joe@joe.codes"
39 | }
40 | ],
41 | "description": "PHP helper for creating Alfred Workflows."
42 | }
43 | ]
44 |
--------------------------------------------------------------------------------
/vendor/composer/autoload_real.php:
--------------------------------------------------------------------------------
1 | = 50600 && !defined('HHVM_VERSION') && (!function_exists('zend_loader_file_encoded') || !zend_loader_file_encoded());
27 | if ($useStaticLoader) {
28 | require_once __DIR__ . '/autoload_static.php';
29 |
30 | call_user_func(\Composer\Autoload\ComposerStaticInitd16a52b940a8c8cb97d16149984b3c2b::getInitializer($loader));
31 | } else {
32 | $map = require __DIR__ . '/autoload_namespaces.php';
33 | foreach ($map as $namespace => $path) {
34 | $loader->set($namespace, $path);
35 | }
36 |
37 | $map = require __DIR__ . '/autoload_psr4.php';
38 | foreach ($map as $namespace => $path) {
39 | $loader->setPsr4($namespace, $path);
40 | }
41 |
42 | $classMap = require __DIR__ . '/autoload_classmap.php';
43 | if ($classMap) {
44 | $loader->addClassMap($classMap);
45 | }
46 | }
47 |
48 | $loader->register(true);
49 |
50 | return $loader;
51 | }
52 | }
53 |
--------------------------------------------------------------------------------
/composer.lock:
--------------------------------------------------------------------------------
1 | {
2 | "_readme": [
3 | "This file locks the dependencies of your project to a known state",
4 | "Read more about it at https://getcomposer.org/doc/01-basic-usage.md#installing-dependencies",
5 | "This file is @generated automatically"
6 | ],
7 | "content-hash": "62218709de0c661d17242c7833d1fef1",
8 | "packages": [
9 | {
10 | "name": "joetannenbaum/alfred-workflow",
11 | "version": "0.1.2",
12 | "source": {
13 | "type": "git",
14 | "url": "https://github.com/joetannenbaum/alfred-workflow.git",
15 | "reference": "88e042db9cad0c95ab80e87c69d7f1e15340e7ac"
16 | },
17 | "dist": {
18 | "type": "zip",
19 | "url": "https://api.github.com/repos/joetannenbaum/alfred-workflow/zipball/88e042db9cad0c95ab80e87c69d7f1e15340e7ac",
20 | "reference": "88e042db9cad0c95ab80e87c69d7f1e15340e7ac",
21 | "shasum": ""
22 | },
23 | "require": {
24 | "php": ">=5.4.0"
25 | },
26 | "require-dev": {
27 | "phpunit/phpunit": "^5.3|~4.8"
28 | },
29 | "type": "library",
30 | "autoload": {
31 | "psr-4": {
32 | "Alfred\\Workflows\\": "src/"
33 | }
34 | },
35 | "notification-url": "https://packagist.org/downloads/",
36 | "license": [
37 | "MIT"
38 | ],
39 | "authors": [
40 | {
41 | "name": "Joe Tannenbaum",
42 | "email": "joe@joe.codes"
43 | }
44 | ],
45 | "description": "PHP helper for creating Alfred Workflows.",
46 | "time": "2018-08-14T14:25:53+00:00"
47 | }
48 | ],
49 | "packages-dev": [],
50 | "aliases": [],
51 | "minimum-stability": "stable",
52 | "stability-flags": [],
53 | "prefer-stable": false,
54 | "prefer-lowest": false,
55 | "platform": {
56 | "ext-pdo": "*"
57 | },
58 | "platform-dev": []
59 | }
60 |
--------------------------------------------------------------------------------
/vendor/joetannenbaum/alfred-workflow/src/Workflow.php:
--------------------------------------------------------------------------------
1 | results[] = $result;
20 |
21 | return $result;
22 | }
23 |
24 | /**
25 | * Add a variables to the workflow
26 | *
27 | * @param string $key
28 | * @param string $value
29 | *
30 | * @return \Alfred\Workflows\Workflow
31 | */
32 | public function variable($key, $value)
33 | {
34 | $this->variables[$key] = $value;
35 |
36 | return $this;
37 | }
38 |
39 | /**
40 | * Sort the current results
41 | *
42 | * @param string $direction
43 | * @param string $property
44 | *
45 | * @return \Alfred\Workflows\Workflow
46 | */
47 | public function sortResults($direction = 'asc', $property = 'title')
48 | {
49 | usort($this->results, function ($a, $b) use ($direction, $property) {
50 | if ($direction === 'asc') {
51 | return $a->$property > $b->$property;
52 | }
53 |
54 | return $a->$property < $b->$property;
55 | });
56 |
57 | return $this;
58 | }
59 |
60 | /**
61 | * Filter current results (destructive)
62 | *
63 | * @param string $query
64 | * @param string $property
65 | *
66 | * @return \Alfred\Workflows\Workflow
67 | */
68 | public function filterResults($query, $property = 'title')
69 | {
70 | if ($query === null || trim($query) === '') {
71 | return $this;
72 | }
73 |
74 | $query = (string) $query;
75 |
76 | $this->results = array_filter($this->results, function ($result) use ($query, $property) {
77 | return stristr($result->$property, $query) !== false;
78 | });
79 |
80 | return $this;
81 | }
82 |
83 | /**
84 | * Output the results as JSON
85 | *
86 | * @return string
87 | */
88 | public function output()
89 | {
90 | $output = [
91 | 'items' => array_map(function ($result) {
92 | return $result->toArray();
93 | }, array_values($this->results)),
94 | ];
95 |
96 | if(!empty($this->variables)){
97 | $output['variables'] = $this->variables;
98 | };
99 |
100 | return json_encode($output);
101 | }
102 | }
103 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | # iMessage 2FA Workflow for Alfred
2 |
3 | Find two-factor authentication codes in your recent iMessage messages.
4 |
5 | 
6 |
7 | ## Requirements
8 |
9 | * `php` must be installed on your system
10 | * macOS has not had `php` preinstalled since Monterey (v12)
11 | * This is also the case for macOS Ventura (v13), Sonoma (v14), and Sequoia (v15)
12 | * We recommend using [Homebrew](https://brew.sh) to install `php`
13 | * To install Homebrew, follow the instructions on the "Install Homebrew" section of the [Homebrew website](https://brew.sh)
14 | * Once you have installed Homebrew, install `php` by running `brew install php`
15 | * You **MUST** grant Full Disk Access to Alfred
16 | * This is required because your messages are stored in the file `~/Library/Messages/chat.db`, which Alfred cannot read without having Full Disk Access
17 | * [See here for instructions on granting Full Disk Access to Alfred](https://www.alfredapp.com/help/getting-started/permissions/#full-disk)
18 |
19 | ## Installation
20 |
21 | 1. [Download the latest version of the workflow](https://github.com/squatto/alfred-imessage-2fa/releases/latest/download/iMessage.2FA.alfredworkflow)
22 | 2. Install the workflow by double-clicking the `.alfredworkflow` file
23 | 3. You can add the workflow to a category, then click "Import" to finish importing. You'll now see the workflow listed in the left sidebar of your Workflows preferences pane.
24 |
25 | ## Configuration
26 |
27 | * By default, only messages received in the past 15 minutes will be searched
28 | * You can change how many minutes to look back by changing the `look_back_minutes` workflow variable
29 | * Tutorial: [How to set workflow variables](https://www.alfredapp.com/help/workflows/advanced/variables/#environment)
30 |
31 | 
32 |
33 | ## Usage
34 |
35 | Type `2fm` to view the most recent two-factor authentication codes from iMessage messages.
36 |
37 | Select a 2FA code and do one of the following:
38 |
39 | * Press `` to copy it to your clipboard
40 | * Press `⌘+` (command + enter) to copy it to your clipboard and paste it into the active app window using simulated keystrokes
41 | * Some websites (e.g. Wells Fargo online banking) don't support pasting a 2FA code, so this will instead simulate typing the code
42 | * In order for this to work, you MUST grant Alfred automation access to `System Events`. If you haven't already done so, you will be prompted to grant access. [See here for more information about Alfred automation.](https://www.alfredapp.com/help/getting-started/permissions/#automation)
43 | * Press `⌥+` (option + enter) to copy it to your clipboard and paste it into the active app window using the system paste (similar to pressing `⌘+V`)
44 |
45 | ## Compatibility
46 |
47 | This workflow was developed for use with Alfred 5. It also works with Alfred 4.
48 |
49 | ## Contributors
50 |
51 | A huge thank you to our contributors!
52 |
53 | * [luckman212](https://github.com/luckman212)
54 | * [manonstreet](https://github.com/manonstreet)
55 | * [cmer](https://github.com/cmer)
56 | * [eruizdechavez](https://github.com/eruizdechavez)
57 |
--------------------------------------------------------------------------------
/vendor/joetannenbaum/alfred-workflow/README.md:
--------------------------------------------------------------------------------
1 | # Alfred 3 Workflows PHP Helper
2 |
3 | [](https://github.com/joetannenbaum/alfred-workflow/tags)
4 | [](LICENSE.md)
5 | [](https://travis-ci.org/joetannenbaum/alfred-workflow)
6 | [](https://packagist.org/packages/league/climate)
7 |
8 | This package simplifies PHP development for **Alfred 3** workflows.
9 |
10 | ## Installation
11 |
12 | ```
13 | composer require joetannenbaum/alfred-workflow
14 | ```
15 |
16 | ## Usage
17 |
18 | To understand the following properties, please reference the [official Alfred 3 documentation](https://www.alfredapp.com/help/workflows/inputs/script-filter/json/).
19 |
20 | The library is not doing any validation for required properties, so all of the following are optional. Please refer to the documentation above for required properties. All of the properties will default to the official defaults if excluded.
21 |
22 | ```php
23 | use Alfred\Workflows\Workflow;
24 |
25 | require 'vendor/autoload.php';
26 |
27 | $workflow = new Workflow;
28 |
29 | // add variables
30 | $workflow->variable('fruit','apple')
31 | ->variable('vegetables','carrots');
32 |
33 | $workflow->result()
34 | ->uid('bob-belcher')
35 | ->title('Bob')
36 | ->subtitle('Head Burger Chef')
37 | ->quicklookurl('http://www.bobsburgers.com')
38 | ->type('default')
39 | ->arg('bob')
40 | ->valid(true)
41 | ->icon('bob.png')
42 | ->mod('cmd', 'Search for Bob', 'search')
43 | ->text('copy', 'Bob is the best!')
44 | ->autocomplete('Bob Belcher');
45 |
46 | $workflow->result()
47 | ->uid('linda-belcher')
48 | ->title('Linda')
49 | ->subtitle('Wife')
50 | ->quicklookurl('http://www.bobsburgers.com')
51 | ->type('default')
52 | ->arg('linda')
53 | ->valid(true)
54 | ->icon('linda.png')
55 | ->mod('cmd', 'Search for Linda', 'search')
56 | ->text('largetype', 'Linda is the best!')
57 | ->autocomplete('Linda Belcher');
58 |
59 | echo $workflow->output();
60 | ```
61 |
62 | Results in:
63 |
64 | ```json
65 | {
66 | "items": [
67 | {
68 | "arg": "bob",
69 | "autocomplete": "Bob Belcher",
70 | "icon": {
71 | "path": "bob.png"
72 | },
73 | "mods": {
74 | "cmd": {
75 | "subtitle": "Search for Bob",
76 | "arg": "search",
77 | "valid": true
78 | }
79 | },
80 | "quicklookurl": "http://www.bobsburgers.com",
81 | "subtitle": "Head Burger Chef",
82 | "text": {
83 | "copy": "Bob is the best!"
84 | },
85 | "title": "Bob",
86 | "type": "default",
87 | "uid": "bob-belcher",
88 | "valid": true
89 | },
90 | {
91 | "arg": "linda",
92 | "autocomplete": "Linda Belcher",
93 | "icon": {
94 | "path": "linda.png"
95 | },
96 | "mods": {
97 | "cmd": {
98 | "subtitle": "Search for Linda",
99 | "arg": "search",
100 | "valid": true
101 | }
102 | },
103 | "quicklookurl": "http://www.bobsburgers.com",
104 | "subtitle": "Wife",
105 | "text": {
106 | "largetype": "LINDA IS THE BEST!"
107 | },
108 | "title": "Linda",
109 | "type": "default",
110 | "uid": "linda-belcher",
111 | "valid": true
112 | }
113 | ],
114 | "variables": {
115 | "fruit": "apple",
116 | "vegetables": "carrots"
117 | }
118 | }
119 | ```
120 |
121 | ## Helper Methods
122 |
123 | Just for clarity, some helper methods exist.
124 |
125 | ```php
126 | // This...
127 | $workflow->result()->mod('cmd', 'Search for Bob', 'search');
128 | // ...is the same as this.
129 | $workflow->result()->cmd('Search for Bob', 'search');
130 | // And these are all available as well:
131 | $workflow->result()->shift('Search for Bob', 'search');
132 | $workflow->result()->fn('Search for Bob', 'search');
133 | $workflow->result()->ctrl('Search for Bob', 'search');
134 | $workflow->result()->alt('Search for Bob', 'search');
135 | ```
136 |
137 | ```php
138 | // This...
139 | $workflow->result()->text('largetype', 'Linda is the best!')
140 | // ...is the same as this.
141 | $workflow->result()->largetype('Linda is the best!');
142 | // Also works:
143 | $workflow->result()->copy('Linda is the best!');
144 | ```
145 |
146 | ```php
147 | // This...
148 | $workflow->result()->icon('bob.png', 'fileicon')
149 | // ...is the same as this.
150 | $workflow->result()->fileiconIcon('bob.png')
151 | // Also works:
152 | $workflow->result()->filetypeIcon('bob.png')
153 | ```
154 |
155 | ## Sorting
156 |
157 | If you'd like to sort your results:
158 |
159 | ```php
160 | // Default is by title asc:
161 | $workflow->sortResults();
162 | // Title desc:
163 | $workflow->sortResults('desc');
164 | // By property asc:
165 | $workflow->sortResults('asc', 'subtitle');
166 | ```
167 |
168 | ## Filtering
169 |
170 | You can filter your results as well if Alfred isn't doing it for you:
171 |
172 | **Please note** this is a very simple filtering, literally looking for the string within the string. For anything more complex filter before creating results.
173 |
174 | ```php
175 | // Default is searching in title:
176 | $workflow->filterResults('bob');
177 | // By property:
178 | $workflow->filterResults('bob', 'subtitle');
179 | ```
180 |
--------------------------------------------------------------------------------
/vendor/joetannenbaum/alfred-workflow/src/Result.php:
--------------------------------------------------------------------------------
1 | valid = !!$valid;
39 |
40 | return $this;
41 | }
42 |
43 | /**
44 | * @param string $type (deafult|file|file:skipcheck)
45 | * @param bool $verify_existence When used with $type 'file'
46 | *
47 | * @return \Alfred\Workflows\Result
48 | */
49 | protected function setType($type, $verify_existence = true)
50 | {
51 | if (in_array($type, ['default', 'file', 'file:skipcheck'])) {
52 | if ($type === 'file' && $verify_existence === false) {
53 | $type = 'file:skipcheck';
54 | }
55 |
56 | $this->type = $type;
57 | }
58 |
59 | return $this;
60 | }
61 |
62 | /**
63 | * @param string $path
64 | * @param string|null $type (fileicon|filetype)
65 | *
66 | * @return \Alfred\Workflows\Result
67 | */
68 | protected function setIcon($path, $type = null)
69 | {
70 | $this->icon = [
71 | 'path' => $path,
72 | ];
73 |
74 | if (in_array($type, ['fileicon', 'filetype'])) {
75 | $this->icon['type'] = $type;
76 | }
77 |
78 | return $this;
79 | }
80 |
81 | /**
82 | * @param string $path
83 | *
84 | * @return \Alfred\Workflows\Result
85 | */
86 | protected function setFileiconIcon($path)
87 | {
88 | return $this->setIcon($path, 'fileicon');
89 | }
90 |
91 | /**
92 | * @param string $path
93 | *
94 | * @return \Alfred\Workflows\Result
95 | */
96 | protected function setFiletypeIcon($path)
97 | {
98 | return $this->setIcon($path, 'filetype');
99 | }
100 |
101 | /**
102 | * @param string $subtitle
103 | *
104 | * @return \Alfred\Workflows\Result
105 | */
106 | protected function setSubtitle($subtitle)
107 | {
108 | $this->subtitle = $subtitle;
109 |
110 | return $this;
111 | }
112 |
113 | /**
114 | * @param string $type (copy|largetype)
115 | * @param string $text
116 | *
117 | * @return \Alfred\Workflows\Result
118 | */
119 | protected function setText($type, $text)
120 | {
121 | if (!in_array($type, ['copy', 'largetype'])) {
122 | return $this;
123 | }
124 |
125 | $this->text[$type] = $text;
126 |
127 | return $this;
128 | }
129 |
130 | /**
131 | * @param string $copy
132 | *
133 | * @return \Alfred\Workflows\Result
134 | */
135 | protected function setCopy($copy)
136 | {
137 | return $this->setText('copy', $copy);
138 | }
139 |
140 | /**
141 | * @param string $largetype
142 | *
143 | * @return \Alfred\Workflows\Result
144 | */
145 | protected function setLargetype($largetype)
146 | {
147 | return $this->setText('largetype', $largetype);
148 | }
149 |
150 | /**
151 | * @param string $mod (shift|fn|ctrl|alt|cmd)
152 | * @param string $subtitle
153 | * @param string $arg
154 | * @param bool $valid
155 | *
156 | * @return \Alfred\Workflows\Result
157 | */
158 | protected function setMod($mod, $subtitle, $arg, $valid = true)
159 | {
160 | if (!in_array($mod, ['shift', 'fn', 'ctrl', 'alt', 'cmd'])) {
161 | return $this;
162 | }
163 |
164 | $this->mods[$mod] = compact('subtitle', 'arg', 'valid');
165 |
166 | return $this;
167 | }
168 |
169 | /**
170 | * @param string $subtitle
171 | * @param string $arg
172 | * @param bool $valid
173 | *
174 | * @return \Alfred\Workflows\Result
175 | */
176 | protected function setCmd($subtitle, $arg, $valid = true)
177 | {
178 | return $this->setMod('cmd', $subtitle, $arg, $valid);
179 | }
180 |
181 | /**
182 | * @param string $subtitle
183 | * @param string $arg
184 | * @param bool $valid
185 | *
186 | * @return \Alfred\Workflows\Result
187 | */
188 | protected function setShift($subtitle, $arg, $valid = true)
189 | {
190 | return $this->setMod('shift', $subtitle, $arg, $valid);
191 | }
192 |
193 | /**
194 | * @param string $subtitle
195 | * @param string $arg
196 | * @param bool $valid
197 | *
198 | * @return \Alfred\Workflows\Result
199 | */
200 | protected function setFn($subtitle, $arg, $valid = true)
201 | {
202 | return $this->setMod('fn', $subtitle, $arg, $valid);
203 | }
204 |
205 | /**
206 | * @param string $subtitle
207 | * @param string $arg
208 | * @param bool $valid
209 | *
210 | * @return \Alfred\Workflows\Result
211 | */
212 | protected function setCtrl($subtitle, $arg, $valid = true)
213 | {
214 | return $this->setMod('ctrl', $subtitle, $arg, $valid);
215 | }
216 |
217 | /**
218 | * @param string $subtitle
219 | * @param string $arg
220 | * @param bool $valid
221 | *
222 | * @return \Alfred\Workflows\Result
223 | */
224 | protected function setAlt($subtitle, $arg, $valid = true)
225 | {
226 | return $this->setMod('alt', $subtitle, $arg, $valid);
227 | }
228 |
229 | /**
230 | * Converts the results to an array structured for Alfred
231 | *
232 | * @return array
233 | */
234 | public function toArray()
235 | {
236 | $attrs = [
237 | 'uid',
238 | 'arg',
239 | 'autocomplete',
240 | 'title',
241 | 'subtitle',
242 | 'type',
243 | 'valid',
244 | 'quicklookurl',
245 | 'icon',
246 | 'mods',
247 | 'text',
248 | ];
249 |
250 | $result = [];
251 |
252 | foreach ($attrs as $attr) {
253 | if (is_array($this->$attr)) {
254 | if (count($this->$attr) > 0) {
255 | $result[$attr] = $this->$attr;
256 | }
257 | continue;
258 | }
259 |
260 | if ($this->$attr !== null) {
261 | $result[$attr] = $this->$attr;
262 | }
263 | }
264 |
265 | ksort($result);
266 |
267 | return $result;
268 | }
269 |
270 | public function __get($property)
271 | {
272 | return $this->$property;
273 | }
274 |
275 | public function __call($method, $args)
276 | {
277 | $setter = 'set' . ucwords($method);
278 |
279 | if (method_exists($this, $setter)) {
280 | call_user_func_array([$this, $setter], $args);
281 |
282 | return $this;
283 | }
284 |
285 | if (property_exists($this, $method)) {
286 | $this->$method = reset($args);
287 |
288 | return $this;
289 | }
290 | }
291 | }
292 |
--------------------------------------------------------------------------------
/find-messages.php:
--------------------------------------------------------------------------------
1 | result()
16 | ->title('ERROR: Unable to Access Your Messages')
17 | ->subtitle('We were unable to access the file that contains your text messages')
18 | ->arg('')
19 | ->valid(true);
20 | echo $workflow->output();
21 | exit;
22 | }
23 |
24 | try {
25 | $db = new PDO('sqlite:' . $dbPath);
26 | $db->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
27 | } catch (PDOException $e) {
28 | $workflow->result()
29 | ->title('ERROR: Unable to Access Your Messages')
30 | ->subtitle('We were unable to access the file that contains your text messages')
31 | ->arg('')
32 | ->valid(true);
33 | $workflow->result()
34 | ->title('Error Message:')
35 | ->subtitle($e->getMessage())
36 | ->arg('')
37 | ->valid(true);
38 | echo $workflow->output();
39 | exit;
40 | }
41 |
42 | try {
43 | $query = $db->query("
44 | select
45 | message.rowid,
46 | ifnull(handle.uncanonicalized_id, chat.chat_identifier) AS sender,
47 | message.service,
48 | datetime(message.date / 1000000000 + 978307200, 'unixepoch', 'localtime') AS message_date,
49 | message.text
50 | from
51 | message
52 | left join chat_message_join
53 | on chat_message_join.message_id = message.ROWID
54 | left join chat
55 | on chat.ROWID = chat_message_join.chat_id
56 | left join handle
57 | on message.handle_id = handle.ROWID
58 | where
59 | message.is_from_me = 0
60 | and message.text is not null
61 | and length(message.text) > 0
62 | and (
63 | message.text glob '*[0-9][0-9][0-9]*'
64 | or message.text glob '*[0-9][0-9][0-9][0-9]*'
65 | or message.text glob '*[0-9][0-9][0-9][0-9][0-9]*'
66 | or message.text glob '*[0-9][0-9][0-9][0-9][0-9][0-9]*'
67 | or message.text glob '*[0-9][0-9][0-9]-[0-9][0-9][0-9]*'
68 | or message.text glob '*[0-9][0-9][0-9][0-9][0-9][0-9][0-9]*'
69 | or message.text glob '*[0-9][0-9][0-9][0-9][0-9][0-9][0-9][0-9]*'
70 | )
71 | and datetime(message.date / 1000000000 + strftime('%s', '2001-01-01'), 'unixepoch', 'localtime')
72 | >= datetime('now', '-$lookBackMinutes minutes', 'localtime')
73 | order by
74 | message.date desc
75 | limit 100
76 | ");
77 | } catch (PDOException $e) {
78 | $workflow->result()
79 | ->title('ERROR: Unable to Query Your Messages')
80 | ->subtitle('We were unable to run the query that reads your text messages')
81 | ->arg('')
82 | ->valid(true);
83 | $workflow->result()
84 | ->title('Error Message:')
85 | ->subtitle($e->getMessage())
86 | ->arg('')
87 | ->valid(true);
88 | echo $workflow->output();
89 | exit;
90 | }
91 |
92 | $found = 0;
93 | $max = 8;
94 |
95 | while ($message = $query->fetch(PDO::FETCH_ASSOC)) {
96 | $code = null;
97 | $text = $message['text'];
98 |
99 | // remove URLs
100 | $text = preg_replace('/\b((https?|ftp|file):\/\/|www\.)[-A-Z0-9+&@#\/%?=~_|$!:,.;]*[A-Z0-9+&@#\/%=~_|$]/i', '', $text);
101 |
102 | // skip now-empty messages
103 | $text = trim($text);
104 |
105 | if (empty($text)) {
106 | continue;
107 | }
108 |
109 | if (preg_match('/(^|\s|\R|\t|\b|G-|:)(\d{5,8})($|\s|\R|\t|\b|\.|,)/', $text, $matches)) {
110 | // 5-8 consecutive digits
111 | // examples:
112 | // "您的验证码是 199035,10分钟内有效,请勿泄露"
113 | // "登录验证码:627823,您正在尝试【登录】,10分钟内有效"
114 | // "【赛验】验证码 54538"
115 | // "Enter this code to log in:59678."
116 | // "G-315643 is your Google verification code"
117 | // "Enter the code 765432, and then click the button to log in."
118 | // "Your code is 45678!"
119 | // "Your code is:98765!"
120 | $code = $matches[2];
121 | } elseif (preg_match('/^(\d{4,8})(\sis your.*code)/', $text, $matches)) {
122 | // 4-8 digits followed by "is your [...] code"
123 | // examples:
124 | // "2773 is your Microsoft account verification code"
125 | $code = $matches[1];
126 | } elseif (preg_match('/(code:|is:)\s*(\d{4,8})($|\s|\R|\t|\b|\.|,)/i', $text, $matches)) {
127 | // "code:" OR "is:", optional whitespace, then 4-8 consecutive digits
128 | // examples:
129 | // "Your Airbnb verification code is: 1234."
130 | // "Your verification code is: 1234, use it to log in"
131 | // "Here is your authorization code:9384"
132 | $code = $matches[2];
133 | } elseif (preg_match('/(code|is):?\s*(\d{3,8})($|\s|\R|\t|\b|\.|,)/i', $text, $matches)) {
134 | // "code" OR "is" followed by an optional ":" + optional whitespace, then 3-8 consecutive digits
135 | // examples:
136 | // "Please enter code 548 on Zocdoc."
137 | $code = $matches[2];
138 | } elseif (preg_match('/(^|code:|is:|\b)\s*(\d{3})-(\d{3})($|\s|\R|\t|\b|\.|,)/', $text, $matches)) {
139 | // line beginning OR "code:" OR "is:" OR word boundary, optional whitespace, 3 consecutive digits, a hyphen, then 3 consecutive digits
140 | // but NOT a phone number (###-###-####)
141 | // examples:
142 | // "123-456"
143 | // "Your Stripe verification code is: 719-839."
144 | $first = $matches[2];
145 | $second = $matches[3];
146 |
147 | // make sure it isn't a phone number
148 | // doesn't match: --<4 consecutive digits>
149 | if (! preg_match('/(^|code:|is:|\b)\s*' . $first . '-' . $second . '-(\d{4})($|\s|\R|\t|\b|\.|,)/', $text, $matches)) {
150 | $code = $first . $second;
151 | }
152 | }
153 |
154 | if ($code) {
155 | $found++;
156 | $date = formatDate($message['message_date']);
157 | $text = formatText($message['text']);
158 | $sender = formatSender($message['sender']);
159 |
160 | $workflow->result()
161 | ->title($code)
162 | ->subtitle("$date from $sender: $text")
163 | ->arg($code)
164 | ->valid(true);
165 |
166 | if ($found >= $max) {
167 | break;
168 | }
169 | }
170 | }
171 |
172 | if (! $found) {
173 | $workflow->result()
174 | ->title('No 2FA Codes Found')
175 | ->subtitle("No two-factor auth codes were found in your text messages from the past $lookBackMinutes minutes")
176 | ->arg('')
177 | ->valid(true);
178 | }
179 |
180 | echo $workflow->output();
181 |
182 | /**
183 | * Format the date of the message
184 | *
185 | * @param string $date
186 | *
187 | * @return string
188 | */
189 | function formatDate($date)
190 | {
191 | $time = strtotime($date);
192 |
193 | if (date('m/d/Y', $time) === date('m/d/Y')) {
194 | return 'Today @ ' . date('g:ia', $time);
195 | }
196 |
197 | return date('M j @ g:ia', $time);
198 | }
199 |
200 | /**
201 | * Format the text of the message
202 | *
203 | * @param string $text
204 | *
205 | * @return string
206 | */
207 | function formatText($text)
208 | {
209 | return str_replace(
210 | ["\n", ':;'],
211 | ['; ', ':'],
212 | trim($text)
213 | );
214 | }
215 |
216 | /**
217 | * Format a sender number
218 | *
219 | * @param string $sender
220 | *
221 | * @return string
222 | */
223 | function formatSender($sender)
224 | {
225 | $sender = trim($sender, '+');
226 |
227 | if (strlen($sender) === 11 && substr($sender, 0, 1) === '1') {
228 | $sender = substr($sender, 1);
229 | }
230 |
231 | if (strlen($sender) === 10) {
232 | return substr($sender, 0, 3) . '-' . substr($sender, 3, 3) . '-' . substr($sender, 6, 4);
233 | }
234 |
235 | return $sender;
236 | }
237 |
--------------------------------------------------------------------------------
/info.plist:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | bundleid
6 | co.bluehelix.imessage-2fa
7 | category
8 | Tools
9 | connections
10 |
11 | 7B86D057-DA8E-4302-AF17-83B889B48EE2
12 |
13 |
14 | destinationuid
15 | 579C566A-EAC9-4F0C-A398-0A4D25EB7251
16 | modifiers
17 | 0
18 | modifiersubtext
19 |
20 | vitoclose
21 |
22 |
23 |
24 | destinationuid
25 | 3D26FE0D-9464-426E-8EAA-03376F20B9CA
26 | modifiers
27 | 0
28 | modifiersubtext
29 |
30 | vitoclose
31 |
32 |
33 |
34 | destinationuid
35 | F66B4E67-AAD4-4597-9902-E084CCFAE32F
36 | modifiers
37 | 1048576
38 | modifiersubtext
39 | Copy the code and paste it into the active app with simulated keystrokes
40 | vitoclose
41 |
42 |
43 |
44 | destinationuid
45 | 42B9D6A1-ACF9-4562-9718-B4A1C983D5AA
46 | modifiers
47 | 524288
48 | modifiersubtext
49 | Copy the code and paste it into the active app with a system paste
50 | vitoclose
51 |
52 |
53 |
54 | F66B4E67-AAD4-4597-9902-E084CCFAE32F
55 |
56 |
57 | destinationuid
58 | 3E71F597-EA2F-4B39-B8E4-69A3D625872E
59 | modifiers
60 | 0
61 | modifiersubtext
62 |
63 | vitoclose
64 |
65 |
66 |
67 |
68 | createdby
69 | Scott Carpenter
70 | description
71 | Find two-factor authentication codes in your recent iMessage messages
72 | disabled
73 |
74 | name
75 | iMessage 2FA
76 | objects
77 |
78 |
79 | config
80 |
81 | alfredfiltersresults
82 |
83 | alfredfiltersresultsmatchmode
84 | 0
85 | argumenttreatemptyqueryasnil
86 |
87 | argumenttrimmode
88 | 0
89 | argumenttype
90 | 2
91 | escaping
92 | 4
93 | keyword
94 | 2fm
95 | queuedelaycustom
96 | 3
97 | queuedelayimmediatelyinitially
98 |
99 | queuedelaymode
100 | 0
101 | queuemode
102 | 1
103 | runningsubtext
104 | Finding two-factor authentication codes...
105 | script
106 | #!/bin/bash
107 |
108 | if ! hash php 2> /dev/null; then
109 | cat <<- EOB
110 | {"items": [
111 | {
112 | "arg": "https://brew.sh",
113 | "title": "ERROR: PHP is not installed on your system",
114 | "subtitle": "Please install php. We recommend using Homebrew: https://brew.sh",
115 | "valid": true
116 | }
117 | ]}
118 | EOB
119 |
120 | exit 1
121 | fi
122 |
123 | php find-messages.php $look_back_minutes
124 |
125 | scriptargtype
126 | 1
127 | scriptfile
128 |
129 | subtext
130 | Find two-factor authentication codes...
131 | title
132 | iMessage 2FA
133 | type
134 | 0
135 | withspace
136 |
137 |
138 | type
139 | alfred.workflow.input.scriptfilter
140 | uid
141 | 7B86D057-DA8E-4302-AF17-83B889B48EE2
142 | version
143 | 3
144 |
145 |
146 | config
147 |
148 | lastpathcomponent
149 |
150 | onlyshowifquerypopulated
151 |
152 | removeextension
153 |
154 | text
155 | Copied 2FA code "{query}" to clipboard
156 | title
157 | iMessage 2FA
158 |
159 | type
160 | alfred.workflow.output.notification
161 | uid
162 | 579C566A-EAC9-4F0C-A398-0A4D25EB7251
163 | version
164 | 1
165 |
166 |
167 | config
168 |
169 | autopaste
170 |
171 | clipboardtext
172 | {query}
173 | ignoredynamicplaceholders
174 |
175 | transient
176 |
177 |
178 | type
179 | alfred.workflow.output.clipboard
180 | uid
181 | 3D26FE0D-9464-426E-8EAA-03376F20B9CA
182 | version
183 | 3
184 |
185 |
186 | config
187 |
188 | autopaste
189 |
190 | clipboardtext
191 | {query}
192 | ignoredynamicplaceholders
193 |
194 | transient
195 |
196 |
197 | type
198 | alfred.workflow.output.clipboard
199 | uid
200 | F66B4E67-AAD4-4597-9902-E084CCFAE32F
201 | version
202 | 3
203 |
204 |
205 | config
206 |
207 | concurrently
208 |
209 | escaping
210 | 102
211 | script
212 | osascript -e 'tell application "System Events" to keystroke the clipboard as text'
213 | scriptargtype
214 | 1
215 | scriptfile
216 |
217 | type
218 | 0
219 |
220 | type
221 | alfred.workflow.action.script
222 | uid
223 | 3E71F597-EA2F-4B39-B8E4-69A3D625872E
224 | version
225 | 2
226 |
227 |
228 | config
229 |
230 | autopaste
231 |
232 | clipboardtext
233 | {query}
234 | ignoredynamicplaceholders
235 |
236 | transient
237 |
238 |
239 | type
240 | alfred.workflow.output.clipboard
241 | uid
242 | 42B9D6A1-ACF9-4562-9718-B4A1C983D5AA
243 | version
244 | 3
245 |
246 |
247 | readme
248 | Find two-factor authentication codes in your recent iMessage messages.
249 |
250 | ## Requirements
251 |
252 | * `php` must be installed on your system
253 | * macOS has not had `php` preinstalled since Monterey (v12)
254 | * This is also the case for macOS Ventura (v13), Sonoma (v14), and Sequoia (v15)
255 | * We recommend using [Homebrew](https://brew.sh) to install `php`
256 | * To install Homebrew, follow the instructions on the "Install Homebrew" section of the [Homebrew website](https://brew.sh)
257 | * Once you have installed Homebrew, install `php` by running `brew install php`
258 | * You **MUST** grant Full Disk Access to Alfred
259 | * This is required because your messages are stored in the file `~/Library/Messages/chat.db`, which Alfred cannot read without having Full Disk Access
260 | * [See here for instructions on granting Full Disk Access to Alfred](https://www.alfredapp.com/help/getting-started/permissions/#full-disk)
261 |
262 | ## Configuration
263 |
264 | * By default, only messages received in the past 15 minutes will be searched
265 | * You can change how many minutes to look back by changing the `look_back_minutes` workflow variable
266 | * Tutorial: [How to set workflow variables](https://www.alfredapp.com/help/workflows/advanced/variables/#environment)
267 |
268 | ## Usage
269 |
270 | Type `2fm` to view the most recent two-factor authentication codes from iMessage messages.
271 |
272 | Select a 2FA code and do one of the following:
273 |
274 | * Press `<enter>` to copy it to your clipboard
275 | * Press `⌘+<enter>` (command + enter) to copy it to your clipboard and paste it into the active app window using simulated keystrokes
276 | * Some websites (e.g. Wells Fargo online banking) don't support pasting a 2FA code, so this will instead simulate typing the code
277 | * In order for this to work, you MUST grant Alfred automation access to `System Events`. If you haven't already done so, you will be prompted to grant access. [See here for more information about Alfred automation.](https://www.alfredapp.com/help/getting-started/permissions/#automation)
278 | * Press `⌥+<enter>` (option + enter) to copy it to your clipboard and paste it into the active app window using the system paste (similar to pressing `⌘+V`)
279 | uidata
280 |
281 | 3D26FE0D-9464-426E-8EAA-03376F20B9CA
282 |
283 | note
284 | Only copy to clipboard
285 | xpos
286 | 325
287 | ypos
288 | 190
289 |
290 | 3E71F597-EA2F-4B39-B8E4-69A3D625872E
291 |
292 | xpos
293 | 485
294 | ypos
295 | 335
296 |
297 | 42B9D6A1-ACF9-4562-9718-B4A1C983D5AA
298 |
299 | note
300 | Method 2: Alfred paste
301 | xpos
302 | 325
303 | ypos
304 | 505
305 |
306 | 579C566A-EAC9-4F0C-A398-0A4D25EB7251
307 |
308 | xpos
309 | 325
310 | ypos
311 | 70
312 |
313 | 7B86D057-DA8E-4302-AF17-83B889B48EE2
314 |
315 | xpos
316 | 70
317 | ypos
318 | 70
319 |
320 | F66B4E67-AAD4-4597-9902-E084CCFAE32F
321 |
322 | note
323 | Method 1: AppleScript paste to simulate keystrokes
324 | xpos
325 | 325
326 | ypos
327 | 335
328 |
329 |
330 | userconfigurationconfig
331 |
332 | variables
333 |
334 | look_back_minutes
335 | 15
336 |
337 | version
338 | 1.3.0
339 | webaddress
340 | https://github.com/squatto/alfred-imessage-2fa/
341 |
342 |
343 |
--------------------------------------------------------------------------------
/vendor/composer/ClassLoader.php:
--------------------------------------------------------------------------------
1 |
7 | * Jordi Boggiano
8 | *
9 | * For the full copyright and license information, please view the LICENSE
10 | * file that was distributed with this source code.
11 | */
12 |
13 | namespace Composer\Autoload;
14 |
15 | /**
16 | * ClassLoader implements a PSR-0, PSR-4 and classmap class loader.
17 | *
18 | * $loader = new \Composer\Autoload\ClassLoader();
19 | *
20 | * // register classes with namespaces
21 | * $loader->add('Symfony\Component', __DIR__.'/component');
22 | * $loader->add('Symfony', __DIR__.'/framework');
23 | *
24 | * // activate the autoloader
25 | * $loader->register();
26 | *
27 | * // to enable searching the include path (eg. for PEAR packages)
28 | * $loader->setUseIncludePath(true);
29 | *
30 | * In this example, if you try to use a class in the Symfony\Component
31 | * namespace or one of its children (Symfony\Component\Console for instance),
32 | * the autoloader will first look for the class under the component/
33 | * directory, and it will then fallback to the framework/ directory if not
34 | * found before giving up.
35 | *
36 | * This class is loosely based on the Symfony UniversalClassLoader.
37 | *
38 | * @author Fabien Potencier
39 | * @author Jordi Boggiano
40 | * @see http://www.php-fig.org/psr/psr-0/
41 | * @see http://www.php-fig.org/psr/psr-4/
42 | */
43 | class ClassLoader
44 | {
45 | // PSR-4
46 | private $prefixLengthsPsr4 = array();
47 | private $prefixDirsPsr4 = array();
48 | private $fallbackDirsPsr4 = array();
49 |
50 | // PSR-0
51 | private $prefixesPsr0 = array();
52 | private $fallbackDirsPsr0 = array();
53 |
54 | private $useIncludePath = false;
55 | private $classMap = array();
56 | private $classMapAuthoritative = false;
57 | private $missingClasses = array();
58 | private $apcuPrefix;
59 |
60 | public function getPrefixes()
61 | {
62 | if (!empty($this->prefixesPsr0)) {
63 | return call_user_func_array('array_merge', $this->prefixesPsr0);
64 | }
65 |
66 | return array();
67 | }
68 |
69 | public function getPrefixesPsr4()
70 | {
71 | return $this->prefixDirsPsr4;
72 | }
73 |
74 | public function getFallbackDirs()
75 | {
76 | return $this->fallbackDirsPsr0;
77 | }
78 |
79 | public function getFallbackDirsPsr4()
80 | {
81 | return $this->fallbackDirsPsr4;
82 | }
83 |
84 | public function getClassMap()
85 | {
86 | return $this->classMap;
87 | }
88 |
89 | /**
90 | * @param array $classMap Class to filename map
91 | */
92 | public function addClassMap(array $classMap)
93 | {
94 | if ($this->classMap) {
95 | $this->classMap = array_merge($this->classMap, $classMap);
96 | } else {
97 | $this->classMap = $classMap;
98 | }
99 | }
100 |
101 | /**
102 | * Registers a set of PSR-0 directories for a given prefix, either
103 | * appending or prepending to the ones previously set for this prefix.
104 | *
105 | * @param string $prefix The prefix
106 | * @param array|string $paths The PSR-0 root directories
107 | * @param bool $prepend Whether to prepend the directories
108 | */
109 | public function add($prefix, $paths, $prepend = false)
110 | {
111 | if (!$prefix) {
112 | if ($prepend) {
113 | $this->fallbackDirsPsr0 = array_merge(
114 | (array) $paths,
115 | $this->fallbackDirsPsr0
116 | );
117 | } else {
118 | $this->fallbackDirsPsr0 = array_merge(
119 | $this->fallbackDirsPsr0,
120 | (array) $paths
121 | );
122 | }
123 |
124 | return;
125 | }
126 |
127 | $first = $prefix[0];
128 | if (!isset($this->prefixesPsr0[$first][$prefix])) {
129 | $this->prefixesPsr0[$first][$prefix] = (array) $paths;
130 |
131 | return;
132 | }
133 | if ($prepend) {
134 | $this->prefixesPsr0[$first][$prefix] = array_merge(
135 | (array) $paths,
136 | $this->prefixesPsr0[$first][$prefix]
137 | );
138 | } else {
139 | $this->prefixesPsr0[$first][$prefix] = array_merge(
140 | $this->prefixesPsr0[$first][$prefix],
141 | (array) $paths
142 | );
143 | }
144 | }
145 |
146 | /**
147 | * Registers a set of PSR-4 directories for a given namespace, either
148 | * appending or prepending to the ones previously set for this namespace.
149 | *
150 | * @param string $prefix The prefix/namespace, with trailing '\\'
151 | * @param array|string $paths The PSR-4 base directories
152 | * @param bool $prepend Whether to prepend the directories
153 | *
154 | * @throws \InvalidArgumentException
155 | */
156 | public function addPsr4($prefix, $paths, $prepend = false)
157 | {
158 | if (!$prefix) {
159 | // Register directories for the root namespace.
160 | if ($prepend) {
161 | $this->fallbackDirsPsr4 = array_merge(
162 | (array) $paths,
163 | $this->fallbackDirsPsr4
164 | );
165 | } else {
166 | $this->fallbackDirsPsr4 = array_merge(
167 | $this->fallbackDirsPsr4,
168 | (array) $paths
169 | );
170 | }
171 | } elseif (!isset($this->prefixDirsPsr4[$prefix])) {
172 | // Register directories for a new namespace.
173 | $length = strlen($prefix);
174 | if ('\\' !== $prefix[$length - 1]) {
175 | throw new \InvalidArgumentException("A non-empty PSR-4 prefix must end with a namespace separator.");
176 | }
177 | $this->prefixLengthsPsr4[$prefix[0]][$prefix] = $length;
178 | $this->prefixDirsPsr4[$prefix] = (array) $paths;
179 | } elseif ($prepend) {
180 | // Prepend directories for an already registered namespace.
181 | $this->prefixDirsPsr4[$prefix] = array_merge(
182 | (array) $paths,
183 | $this->prefixDirsPsr4[$prefix]
184 | );
185 | } else {
186 | // Append directories for an already registered namespace.
187 | $this->prefixDirsPsr4[$prefix] = array_merge(
188 | $this->prefixDirsPsr4[$prefix],
189 | (array) $paths
190 | );
191 | }
192 | }
193 |
194 | /**
195 | * Registers a set of PSR-0 directories for a given prefix,
196 | * replacing any others previously set for this prefix.
197 | *
198 | * @param string $prefix The prefix
199 | * @param array|string $paths The PSR-0 base directories
200 | */
201 | public function set($prefix, $paths)
202 | {
203 | if (!$prefix) {
204 | $this->fallbackDirsPsr0 = (array) $paths;
205 | } else {
206 | $this->prefixesPsr0[$prefix[0]][$prefix] = (array) $paths;
207 | }
208 | }
209 |
210 | /**
211 | * Registers a set of PSR-4 directories for a given namespace,
212 | * replacing any others previously set for this namespace.
213 | *
214 | * @param string $prefix The prefix/namespace, with trailing '\\'
215 | * @param array|string $paths The PSR-4 base directories
216 | *
217 | * @throws \InvalidArgumentException
218 | */
219 | public function setPsr4($prefix, $paths)
220 | {
221 | if (!$prefix) {
222 | $this->fallbackDirsPsr4 = (array) $paths;
223 | } else {
224 | $length = strlen($prefix);
225 | if ('\\' !== $prefix[$length - 1]) {
226 | throw new \InvalidArgumentException("A non-empty PSR-4 prefix must end with a namespace separator.");
227 | }
228 | $this->prefixLengthsPsr4[$prefix[0]][$prefix] = $length;
229 | $this->prefixDirsPsr4[$prefix] = (array) $paths;
230 | }
231 | }
232 |
233 | /**
234 | * Turns on searching the include path for class files.
235 | *
236 | * @param bool $useIncludePath
237 | */
238 | public function setUseIncludePath($useIncludePath)
239 | {
240 | $this->useIncludePath = $useIncludePath;
241 | }
242 |
243 | /**
244 | * Can be used to check if the autoloader uses the include path to check
245 | * for classes.
246 | *
247 | * @return bool
248 | */
249 | public function getUseIncludePath()
250 | {
251 | return $this->useIncludePath;
252 | }
253 |
254 | /**
255 | * Turns off searching the prefix and fallback directories for classes
256 | * that have not been registered with the class map.
257 | *
258 | * @param bool $classMapAuthoritative
259 | */
260 | public function setClassMapAuthoritative($classMapAuthoritative)
261 | {
262 | $this->classMapAuthoritative = $classMapAuthoritative;
263 | }
264 |
265 | /**
266 | * Should class lookup fail if not found in the current class map?
267 | *
268 | * @return bool
269 | */
270 | public function isClassMapAuthoritative()
271 | {
272 | return $this->classMapAuthoritative;
273 | }
274 |
275 | /**
276 | * APCu prefix to use to cache found/not-found classes, if the extension is enabled.
277 | *
278 | * @param string|null $apcuPrefix
279 | */
280 | public function setApcuPrefix($apcuPrefix)
281 | {
282 | $this->apcuPrefix = function_exists('apcu_fetch') && filter_var(ini_get('apc.enabled'), FILTER_VALIDATE_BOOLEAN) ? $apcuPrefix : null;
283 | }
284 |
285 | /**
286 | * The APCu prefix in use, or null if APCu caching is not enabled.
287 | *
288 | * @return string|null
289 | */
290 | public function getApcuPrefix()
291 | {
292 | return $this->apcuPrefix;
293 | }
294 |
295 | /**
296 | * Registers this instance as an autoloader.
297 | *
298 | * @param bool $prepend Whether to prepend the autoloader or not
299 | */
300 | public function register($prepend = false)
301 | {
302 | spl_autoload_register(array($this, 'loadClass'), true, $prepend);
303 | }
304 |
305 | /**
306 | * Unregisters this instance as an autoloader.
307 | */
308 | public function unregister()
309 | {
310 | spl_autoload_unregister(array($this, 'loadClass'));
311 | }
312 |
313 | /**
314 | * Loads the given class or interface.
315 | *
316 | * @param string $class The name of the class
317 | * @return bool|null True if loaded, null otherwise
318 | */
319 | public function loadClass($class)
320 | {
321 | if ($file = $this->findFile($class)) {
322 | includeFile($file);
323 |
324 | return true;
325 | }
326 | }
327 |
328 | /**
329 | * Finds the path to the file where the class is defined.
330 | *
331 | * @param string $class The name of the class
332 | *
333 | * @return string|false The path if found, false otherwise
334 | */
335 | public function findFile($class)
336 | {
337 | // class map lookup
338 | if (isset($this->classMap[$class])) {
339 | return $this->classMap[$class];
340 | }
341 | if ($this->classMapAuthoritative || isset($this->missingClasses[$class])) {
342 | return false;
343 | }
344 | if (null !== $this->apcuPrefix) {
345 | $file = apcu_fetch($this->apcuPrefix.$class, $hit);
346 | if ($hit) {
347 | return $file;
348 | }
349 | }
350 |
351 | $file = $this->findFileWithExtension($class, '.php');
352 |
353 | // Search for Hack files if we are running on HHVM
354 | if (false === $file && defined('HHVM_VERSION')) {
355 | $file = $this->findFileWithExtension($class, '.hh');
356 | }
357 |
358 | if (null !== $this->apcuPrefix) {
359 | apcu_add($this->apcuPrefix.$class, $file);
360 | }
361 |
362 | if (false === $file) {
363 | // Remember that this class does not exist.
364 | $this->missingClasses[$class] = true;
365 | }
366 |
367 | return $file;
368 | }
369 |
370 | private function findFileWithExtension($class, $ext)
371 | {
372 | // PSR-4 lookup
373 | $logicalPathPsr4 = strtr($class, '\\', DIRECTORY_SEPARATOR) . $ext;
374 |
375 | $first = $class[0];
376 | if (isset($this->prefixLengthsPsr4[$first])) {
377 | $subPath = $class;
378 | while (false !== $lastPos = strrpos($subPath, '\\')) {
379 | $subPath = substr($subPath, 0, $lastPos);
380 | $search = $subPath . '\\';
381 | if (isset($this->prefixDirsPsr4[$search])) {
382 | $pathEnd = DIRECTORY_SEPARATOR . substr($logicalPathPsr4, $lastPos + 1);
383 | foreach ($this->prefixDirsPsr4[$search] as $dir) {
384 | if (file_exists($file = $dir . $pathEnd)) {
385 | return $file;
386 | }
387 | }
388 | }
389 | }
390 | }
391 |
392 | // PSR-4 fallback dirs
393 | foreach ($this->fallbackDirsPsr4 as $dir) {
394 | if (file_exists($file = $dir . DIRECTORY_SEPARATOR . $logicalPathPsr4)) {
395 | return $file;
396 | }
397 | }
398 |
399 | // PSR-0 lookup
400 | if (false !== $pos = strrpos($class, '\\')) {
401 | // namespaced class name
402 | $logicalPathPsr0 = substr($logicalPathPsr4, 0, $pos + 1)
403 | . strtr(substr($logicalPathPsr4, $pos + 1), '_', DIRECTORY_SEPARATOR);
404 | } else {
405 | // PEAR-like class name
406 | $logicalPathPsr0 = strtr($class, '_', DIRECTORY_SEPARATOR) . $ext;
407 | }
408 |
409 | if (isset($this->prefixesPsr0[$first])) {
410 | foreach ($this->prefixesPsr0[$first] as $prefix => $dirs) {
411 | if (0 === strpos($class, $prefix)) {
412 | foreach ($dirs as $dir) {
413 | if (file_exists($file = $dir . DIRECTORY_SEPARATOR . $logicalPathPsr0)) {
414 | return $file;
415 | }
416 | }
417 | }
418 | }
419 | }
420 |
421 | // PSR-0 fallback dirs
422 | foreach ($this->fallbackDirsPsr0 as $dir) {
423 | if (file_exists($file = $dir . DIRECTORY_SEPARATOR . $logicalPathPsr0)) {
424 | return $file;
425 | }
426 | }
427 |
428 | // PSR-0 include paths.
429 | if ($this->useIncludePath && $file = stream_resolve_include_path($logicalPathPsr0)) {
430 | return $file;
431 | }
432 |
433 | return false;
434 | }
435 | }
436 |
437 | /**
438 | * Scope isolated include.
439 | *
440 | * Prevents access to $this/self from included files.
441 | */
442 | function includeFile($file)
443 | {
444 | include $file;
445 | }
446 |
--------------------------------------------------------------------------------
/vendor/joetannenbaum/alfred-workflow/tests/WorkflowTest.php:
--------------------------------------------------------------------------------
1 | result()
13 | ->uid('THE ID')
14 | ->title('Item Title')
15 | ->subtitle('Item Subtitle')
16 | ->quicklookurl('https://www.google.com')
17 | ->type('file')
18 | ->arg('ARGUMENT')
19 | ->valid(false)
20 | ->icon('icon.png')
21 | ->mod('cmd', 'Do Something Different', 'something-different')
22 | ->mod('shift', 'Another Different', 'another-different', false)
23 | ->copy('Please copy this')
24 | ->largetype('This will be huge')
25 | ->autocomplete('AutoComplete This');
26 |
27 | $expected = [
28 | 'items' => [
29 | [
30 | 'arg' => 'ARGUMENT',
31 | 'autocomplete' => 'AutoComplete This',
32 | 'icon' => [
33 | 'path' => 'icon.png',
34 | ],
35 | 'mods' => [
36 | 'cmd' => [
37 | 'subtitle' => 'Do Something Different',
38 | 'arg' => 'something-different',
39 | 'valid' => true,
40 | ],
41 | 'shift' => [
42 | 'subtitle' => 'Another Different',
43 | 'arg' => 'another-different',
44 | 'valid' => false,
45 | ],
46 | ],
47 | 'quicklookurl' => 'https://www.google.com',
48 | 'subtitle' => 'Item Subtitle',
49 | 'text' => [
50 | 'copy' => 'Please copy this',
51 | 'largetype' => 'This will be huge',
52 | ],
53 | 'title' => 'Item Title',
54 | 'type' => 'file',
55 | 'uid' => 'THE ID',
56 | 'valid' => false,
57 | ],
58 | ],
59 | ];
60 |
61 | $this->assertSame(json_encode($expected), $workflow->output());
62 | }
63 |
64 | /** @test */
65 | public function it_can_add_multiple_results()
66 | {
67 | $workflow = new Workflow;
68 |
69 | $workflow->result()
70 | ->uid('THE ID')
71 | ->title('Item Title')
72 | ->subtitle('Item Subtitle')
73 | ->quicklookurl('https://www.google.com')
74 | ->type('file')
75 | ->arg('ARGUMENT')
76 | ->valid(false)
77 | ->icon('icon.png')
78 | ->mod('cmd', 'Do Something Different', 'something-different')
79 | ->mod('shift', 'Another Different', 'another-different', false)
80 | ->copy('Please copy this')
81 | ->largetype('This will be huge')
82 | ->autocomplete('AutoComplete This');
83 |
84 | $workflow->result()
85 | ->uid('THE ID 2')
86 | ->title('Item Title 2')
87 | ->subtitle('Item Subtitle 2')
88 | ->quicklookurl('https://www.google.com/2')
89 | ->type('file')
90 | ->arg('ARGUMENT 2')
91 | ->valid(true)
92 | ->icon('icon2.png')
93 | ->mod('cmd', 'Do Something Different 2', 'something-different 2')
94 | ->mod('shift', 'Another Different 2', 'another-different 2', false)
95 | ->copy('Please copy this 2')
96 | ->largetype('This will be huge 2')
97 | ->autocomplete('AutoComplete This 2');
98 |
99 | $expected = [
100 | 'items' => [
101 | [
102 | 'arg' => 'ARGUMENT',
103 | 'autocomplete' => 'AutoComplete This',
104 | 'icon' => [
105 | 'path' => 'icon.png',
106 | ],
107 | 'mods' => [
108 | 'cmd' => [
109 | 'subtitle' => 'Do Something Different',
110 | 'arg' => 'something-different',
111 | 'valid' => true,
112 | ],
113 | 'shift' => [
114 | 'subtitle' => 'Another Different',
115 | 'arg' => 'another-different',
116 | 'valid' => false,
117 | ],
118 | ],
119 | 'quicklookurl' => 'https://www.google.com',
120 | 'subtitle' => 'Item Subtitle',
121 | 'text' => [
122 | 'copy' => 'Please copy this',
123 | 'largetype' => 'This will be huge',
124 | ],
125 | 'title' => 'Item Title',
126 | 'type' => 'file',
127 | 'uid' => 'THE ID',
128 | 'valid' => false,
129 | ],
130 | [
131 | 'arg' => 'ARGUMENT 2',
132 | 'autocomplete' => 'AutoComplete This 2',
133 | 'icon' => [
134 | 'path' => 'icon2.png',
135 | ],
136 | 'mods' => [
137 | 'cmd' => [
138 | 'subtitle' => 'Do Something Different 2',
139 | 'arg' => 'something-different 2',
140 | 'valid' => true,
141 | ],
142 | 'shift' => [
143 | 'subtitle' => 'Another Different 2',
144 | 'arg' => 'another-different 2',
145 | 'valid' => false,
146 | ],
147 | ],
148 | 'quicklookurl' => 'https://www.google.com/2',
149 | 'subtitle' => 'Item Subtitle 2',
150 | 'text' => [
151 | 'copy' => 'Please copy this 2',
152 | 'largetype' => 'This will be huge 2',
153 | ],
154 | 'title' => 'Item Title 2',
155 | 'type' => 'file',
156 | 'uid' => 'THE ID 2',
157 | 'valid' => true,
158 | ],
159 | ],
160 | ];
161 |
162 | $this->assertSame(json_encode($expected), $workflow->output());
163 | }
164 |
165 | /** @test */
166 | public function it_can_handle_a_file_skipcheck_via_arguments()
167 | {
168 | $workflow = new Workflow;
169 |
170 | $workflow->result()->type('file', false);
171 |
172 | $expected = [
173 | 'items' => [
174 | [
175 | 'type' => 'file:skipcheck',
176 | 'valid' => true,
177 | ],
178 | ],
179 | ];
180 |
181 | $this->assertSame(json_encode($expected), $workflow->output());
182 | }
183 |
184 | /** @test */
185 | public function it_can_add_mods_via_shortcuts()
186 | {
187 | $workflow = new Workflow;
188 |
189 | $workflow->result()->cmd('Hit Command', 'command-it', false)
190 | ->shift('Hit Shift', 'shift-it', true);
191 |
192 | $expected = [
193 | 'items' => [
194 | [
195 | 'mods' => [
196 | 'cmd' => [
197 | 'subtitle' => 'Hit Command',
198 | 'arg' => 'command-it',
199 | 'valid' => false,
200 | ],
201 | 'shift' => [
202 | 'subtitle' => 'Hit Shift',
203 | 'arg' => 'shift-it',
204 | 'valid' => true,
205 | ],
206 | ],
207 | 'valid' => true,
208 | ],
209 | ],
210 | ];
211 |
212 | $this->assertSame(json_encode($expected), $workflow->output());
213 | }
214 |
215 | /** @test */
216 | public function it_can_handle_file_icon_via_shortcut()
217 | {
218 | $workflow = new Workflow;
219 |
220 | $workflow->result()->fileiconIcon('icon.png');
221 |
222 | $expected = [
223 | 'items' => [
224 | [
225 | 'icon' => [
226 | 'path' => 'icon.png',
227 | 'type' => 'fileicon',
228 | ],
229 | 'valid' => true,
230 | ],
231 | ],
232 | ];
233 |
234 | $this->assertSame(json_encode($expected), $workflow->output());
235 | }
236 |
237 | /** @test */
238 | public function it_can_handle_file_type_via_shortcut()
239 | {
240 | $workflow = new Workflow;
241 |
242 | $workflow->result()->filetypeIcon('icon.png');
243 |
244 | $expected = [
245 | 'items' => [
246 | [
247 | 'icon' => [
248 | 'path' => 'icon.png',
249 | 'type' => 'filetype',
250 | ],
251 | 'valid' => true,
252 | ],
253 | ],
254 | ];
255 |
256 | $this->assertSame(json_encode($expected), $workflow->output());
257 | }
258 |
259 | /** @test */
260 | public function it_can_sort_results_by_defaults()
261 | {
262 | $workflow = new Workflow;
263 |
264 | $workflow->result()
265 | ->uid('THE ID')
266 | ->title('Item Title')
267 | ->subtitle('Item Subtitle');
268 |
269 | $workflow->result()
270 | ->uid('THE ID 2')
271 | ->title('Item Title 2')
272 | ->subtitle('Item Subtitle 2');
273 |
274 | $expected = [
275 | 'items' => [
276 | [
277 | 'subtitle' => 'Item Subtitle',
278 | 'title' => 'Item Title',
279 | 'uid' => 'THE ID',
280 | 'valid' => true,
281 | ],
282 | [
283 | 'subtitle' => 'Item Subtitle 2',
284 | 'title' => 'Item Title 2',
285 | 'uid' => 'THE ID 2',
286 | 'valid' => true,
287 | ],
288 | ],
289 | ];
290 |
291 | $this->assertSame(json_encode($expected), $workflow->sortResults()->output());
292 | }
293 |
294 | /** @test */
295 | public function it_can_sort_results_desc()
296 | {
297 | $workflow = new Workflow;
298 |
299 | $workflow->result()
300 | ->uid('THE ID')
301 | ->title('Item Title')
302 | ->subtitle('Item Subtitle');
303 |
304 | $workflow->result()
305 | ->uid('THE ID 2')
306 | ->title('Item Title 2')
307 | ->subtitle('Item Subtitle 2');
308 |
309 | $expected = [
310 | 'items' => [
311 | [
312 | 'subtitle' => 'Item Subtitle 2',
313 | 'title' => 'Item Title 2',
314 | 'uid' => 'THE ID 2',
315 | 'valid' => true,
316 | ],
317 | [
318 | 'subtitle' => 'Item Subtitle',
319 | 'title' => 'Item Title',
320 | 'uid' => 'THE ID',
321 | 'valid' => true,
322 | ],
323 | ],
324 | ];
325 |
326 | $this->assertSame(json_encode($expected), $workflow->sortResults('desc')->output());
327 | }
328 |
329 | /** @test */
330 | public function it_can_sort_results_by_field()
331 | {
332 | $workflow = new Workflow;
333 |
334 | $workflow->result()
335 | ->uid('456')
336 | ->title('Item Title')
337 | ->subtitle('Item Subtitle');
338 |
339 | $workflow->result()
340 | ->uid('123')
341 | ->title('Item Title 2')
342 | ->subtitle('Item Subtitle 2');
343 |
344 | $expected = [
345 | 'items' => [
346 | [
347 | 'subtitle' => 'Item Subtitle 2',
348 | 'title' => 'Item Title 2',
349 | 'uid' => '123',
350 | 'valid' => true,
351 | ],
352 | [
353 | 'subtitle' => 'Item Subtitle',
354 | 'title' => 'Item Title',
355 | 'uid' => '456',
356 | 'valid' => true,
357 | ],
358 | ],
359 | ];
360 |
361 | $this->assertSame(json_encode($expected), $workflow->sortResults('asc', 'uid')->output());
362 | }
363 |
364 | /** @test */
365 | public function it_can_filter_results()
366 | {
367 | $workflow = new Workflow;
368 |
369 | $workflow->result()
370 | ->uid('THE ID')
371 | ->title('Item Title')
372 | ->subtitle('Item Subtitle');
373 |
374 | $workflow->result()
375 | ->uid('THE ID 2')
376 | ->title('Item Title 2')
377 | ->subtitle('Item Subtitle 2');
378 |
379 | $expected = [
380 | 'items' => [
381 | [
382 | 'subtitle' => 'Item Subtitle 2',
383 | 'title' => 'Item Title 2',
384 | 'uid' => 'THE ID 2',
385 | 'valid' => true,
386 | ],
387 | ],
388 | ];
389 |
390 | $this->assertSame(json_encode($expected), $workflow->filterResults(2)->output());
391 | }
392 |
393 | /** @test */
394 | public function it_can_filter_results_by_a_different_key()
395 | {
396 | $workflow = new Workflow;
397 |
398 | $workflow->result()
399 | ->uid('THE ID')
400 | ->title('Item Title')
401 | ->subtitle('Item Subtitle');
402 |
403 | $workflow->result()
404 | ->uid('THE ID 2')
405 | ->title('Item Title 2')
406 | ->subtitle('Item Subtitle 2');
407 |
408 | $expected = [
409 | 'items' => [
410 | [
411 | 'subtitle' => 'Item Subtitle 2',
412 | 'title' => 'Item Title 2',
413 | 'uid' => 'THE ID 2',
414 | 'valid' => true,
415 | ],
416 | ],
417 | ];
418 |
419 | $this->assertSame(json_encode($expected), $workflow->filterResults('ID 2', 'uid')->output());
420 | }
421 |
422 | /** @test */
423 | public function it_can_add_variables()
424 | {
425 | $workflow = new Workflow;
426 |
427 | $workflow->variable('fruit','apple')
428 | ->variable('vegetables','carrots');
429 |
430 | $workflow->result()
431 | ->uid('THE ID')
432 | ->title('Item Title')
433 | ->subtitle('Item Subtitle')
434 | ->quicklookurl('https://www.google.com')
435 | ->type('file')
436 | ->arg('ARGUMENT')
437 | ->valid(false)
438 | ->icon('icon.png')
439 | ->mod('cmd', 'Do Something Different', 'something-different')
440 | ->mod('shift', 'Another Different', 'another-different', false)
441 | ->copy('Please copy this')
442 | ->largetype('This will be huge')
443 | ->autocomplete('AutoComplete This');
444 |
445 | $expected = [
446 | 'items' => [
447 | [
448 | 'arg' => 'ARGUMENT',
449 | 'autocomplete' => 'AutoComplete This',
450 | 'icon' => [
451 | 'path' => 'icon.png',
452 | ],
453 | 'mods' => [
454 | 'cmd' => [
455 | 'subtitle' => 'Do Something Different',
456 | 'arg' => 'something-different',
457 | 'valid' => true,
458 | ],
459 | 'shift' => [
460 | 'subtitle' => 'Another Different',
461 | 'arg' => 'another-different',
462 | 'valid' => false,
463 | ],
464 | ],
465 | 'quicklookurl' => 'https://www.google.com',
466 | 'subtitle' => 'Item Subtitle',
467 | 'text' => [
468 | 'copy' => 'Please copy this',
469 | 'largetype' => 'This will be huge',
470 | ],
471 | 'title' => 'Item Title',
472 | 'type' => 'file',
473 | 'uid' => 'THE ID',
474 | 'valid' => false,
475 | ],
476 | ],
477 | 'variables' => [
478 | 'fruit' => 'apple',
479 | 'vegetables' => 'carrots'
480 | ]
481 | ];
482 |
483 | $this->assertSame(json_encode($expected), $workflow->output());
484 | }
485 | }
486 |
--------------------------------------------------------------------------------
/vendor/joetannenbaum/alfred-workflow/composer.lock:
--------------------------------------------------------------------------------
1 | {
2 | "_readme": [
3 | "This file locks the dependencies of your project to a known state",
4 | "Read more about it at https://getcomposer.org/doc/01-basic-usage.md#composer-lock-the-lock-file",
5 | "This file is @generated automatically"
6 | ],
7 | "hash": "86d8b89e2e3aec5dbb790f43ac8c1169",
8 | "content-hash": "b3abb59d86e4ce2ad1f9368fd77f65c9",
9 | "packages": [],
10 | "packages-dev": [
11 | {
12 | "name": "doctrine/instantiator",
13 | "version": "1.0.5",
14 | "source": {
15 | "type": "git",
16 | "url": "https://github.com/doctrine/instantiator.git",
17 | "reference": "8e884e78f9f0eb1329e445619e04456e64d8051d"
18 | },
19 | "dist": {
20 | "type": "zip",
21 | "url": "https://api.github.com/repos/doctrine/instantiator/zipball/8e884e78f9f0eb1329e445619e04456e64d8051d",
22 | "reference": "8e884e78f9f0eb1329e445619e04456e64d8051d",
23 | "shasum": ""
24 | },
25 | "require": {
26 | "php": ">=5.3,<8.0-DEV"
27 | },
28 | "require-dev": {
29 | "athletic/athletic": "~0.1.8",
30 | "ext-pdo": "*",
31 | "ext-phar": "*",
32 | "phpunit/phpunit": "~4.0",
33 | "squizlabs/php_codesniffer": "~2.0"
34 | },
35 | "type": "library",
36 | "extra": {
37 | "branch-alias": {
38 | "dev-master": "1.0.x-dev"
39 | }
40 | },
41 | "autoload": {
42 | "psr-4": {
43 | "Doctrine\\Instantiator\\": "src/Doctrine/Instantiator/"
44 | }
45 | },
46 | "notification-url": "https://packagist.org/downloads/",
47 | "license": [
48 | "MIT"
49 | ],
50 | "authors": [
51 | {
52 | "name": "Marco Pivetta",
53 | "email": "ocramius@gmail.com",
54 | "homepage": "http://ocramius.github.com/"
55 | }
56 | ],
57 | "description": "A small, lightweight utility to instantiate objects in PHP without invoking their constructors",
58 | "homepage": "https://github.com/doctrine/instantiator",
59 | "keywords": [
60 | "constructor",
61 | "instantiate"
62 | ],
63 | "time": "2015-06-14 21:17:01"
64 | },
65 | {
66 | "name": "myclabs/deep-copy",
67 | "version": "1.5.1",
68 | "source": {
69 | "type": "git",
70 | "url": "https://github.com/myclabs/DeepCopy.git",
71 | "reference": "a8773992b362b58498eed24bf85005f363c34771"
72 | },
73 | "dist": {
74 | "type": "zip",
75 | "url": "https://api.github.com/repos/myclabs/DeepCopy/zipball/a8773992b362b58498eed24bf85005f363c34771",
76 | "reference": "a8773992b362b58498eed24bf85005f363c34771",
77 | "shasum": ""
78 | },
79 | "require": {
80 | "php": ">=5.4.0"
81 | },
82 | "require-dev": {
83 | "doctrine/collections": "1.*",
84 | "phpunit/phpunit": "~4.1"
85 | },
86 | "type": "library",
87 | "autoload": {
88 | "psr-4": {
89 | "DeepCopy\\": "src/DeepCopy/"
90 | }
91 | },
92 | "notification-url": "https://packagist.org/downloads/",
93 | "license": [
94 | "MIT"
95 | ],
96 | "description": "Create deep copies (clones) of your objects",
97 | "homepage": "https://github.com/myclabs/DeepCopy",
98 | "keywords": [
99 | "clone",
100 | "copy",
101 | "duplicate",
102 | "object",
103 | "object graph"
104 | ],
105 | "time": "2015-11-20 12:04:31"
106 | },
107 | {
108 | "name": "phpdocumentor/reflection-docblock",
109 | "version": "2.0.4",
110 | "source": {
111 | "type": "git",
112 | "url": "https://github.com/phpDocumentor/ReflectionDocBlock.git",
113 | "reference": "d68dbdc53dc358a816f00b300704702b2eaff7b8"
114 | },
115 | "dist": {
116 | "type": "zip",
117 | "url": "https://api.github.com/repos/phpDocumentor/ReflectionDocBlock/zipball/d68dbdc53dc358a816f00b300704702b2eaff7b8",
118 | "reference": "d68dbdc53dc358a816f00b300704702b2eaff7b8",
119 | "shasum": ""
120 | },
121 | "require": {
122 | "php": ">=5.3.3"
123 | },
124 | "require-dev": {
125 | "phpunit/phpunit": "~4.0"
126 | },
127 | "suggest": {
128 | "dflydev/markdown": "~1.0",
129 | "erusev/parsedown": "~1.0"
130 | },
131 | "type": "library",
132 | "extra": {
133 | "branch-alias": {
134 | "dev-master": "2.0.x-dev"
135 | }
136 | },
137 | "autoload": {
138 | "psr-0": {
139 | "phpDocumentor": [
140 | "src/"
141 | ]
142 | }
143 | },
144 | "notification-url": "https://packagist.org/downloads/",
145 | "license": [
146 | "MIT"
147 | ],
148 | "authors": [
149 | {
150 | "name": "Mike van Riel",
151 | "email": "mike.vanriel@naenius.com"
152 | }
153 | ],
154 | "time": "2015-02-03 12:10:50"
155 | },
156 | {
157 | "name": "phpspec/prophecy",
158 | "version": "v1.6.0",
159 | "source": {
160 | "type": "git",
161 | "url": "https://github.com/phpspec/prophecy.git",
162 | "reference": "3c91bdf81797d725b14cb62906f9a4ce44235972"
163 | },
164 | "dist": {
165 | "type": "zip",
166 | "url": "https://api.github.com/repos/phpspec/prophecy/zipball/3c91bdf81797d725b14cb62906f9a4ce44235972",
167 | "reference": "3c91bdf81797d725b14cb62906f9a4ce44235972",
168 | "shasum": ""
169 | },
170 | "require": {
171 | "doctrine/instantiator": "^1.0.2",
172 | "php": "^5.3|^7.0",
173 | "phpdocumentor/reflection-docblock": "~2.0",
174 | "sebastian/comparator": "~1.1",
175 | "sebastian/recursion-context": "~1.0"
176 | },
177 | "require-dev": {
178 | "phpspec/phpspec": "~2.0"
179 | },
180 | "type": "library",
181 | "extra": {
182 | "branch-alias": {
183 | "dev-master": "1.5.x-dev"
184 | }
185 | },
186 | "autoload": {
187 | "psr-0": {
188 | "Prophecy\\": "src/"
189 | }
190 | },
191 | "notification-url": "https://packagist.org/downloads/",
192 | "license": [
193 | "MIT"
194 | ],
195 | "authors": [
196 | {
197 | "name": "Konstantin Kudryashov",
198 | "email": "ever.zet@gmail.com",
199 | "homepage": "http://everzet.com"
200 | },
201 | {
202 | "name": "Marcello Duarte",
203 | "email": "marcello.duarte@gmail.com"
204 | }
205 | ],
206 | "description": "Highly opinionated mocking framework for PHP 5.3+",
207 | "homepage": "https://github.com/phpspec/prophecy",
208 | "keywords": [
209 | "Double",
210 | "Dummy",
211 | "fake",
212 | "mock",
213 | "spy",
214 | "stub"
215 | ],
216 | "time": "2016-02-15 07:46:21"
217 | },
218 | {
219 | "name": "phpunit/php-code-coverage",
220 | "version": "3.3.1",
221 | "source": {
222 | "type": "git",
223 | "url": "https://github.com/sebastianbergmann/php-code-coverage.git",
224 | "reference": "2431befdd451fac43fbcde94d1a92fb3b8b68f86"
225 | },
226 | "dist": {
227 | "type": "zip",
228 | "url": "https://api.github.com/repos/sebastianbergmann/php-code-coverage/zipball/2431befdd451fac43fbcde94d1a92fb3b8b68f86",
229 | "reference": "2431befdd451fac43fbcde94d1a92fb3b8b68f86",
230 | "shasum": ""
231 | },
232 | "require": {
233 | "php": "^5.6 || ^7.0",
234 | "phpunit/php-file-iterator": "~1.3",
235 | "phpunit/php-text-template": "~1.2",
236 | "phpunit/php-token-stream": "^1.4.2",
237 | "sebastian/code-unit-reverse-lookup": "~1.0",
238 | "sebastian/environment": "^1.3.2",
239 | "sebastian/version": "~1.0|~2.0"
240 | },
241 | "require-dev": {
242 | "ext-xdebug": ">=2.1.4",
243 | "phpunit/phpunit": "~5"
244 | },
245 | "suggest": {
246 | "ext-dom": "*",
247 | "ext-xdebug": ">=2.4.0",
248 | "ext-xmlwriter": "*"
249 | },
250 | "type": "library",
251 | "extra": {
252 | "branch-alias": {
253 | "dev-master": "3.3.x-dev"
254 | }
255 | },
256 | "autoload": {
257 | "classmap": [
258 | "src/"
259 | ]
260 | },
261 | "notification-url": "https://packagist.org/downloads/",
262 | "license": [
263 | "BSD-3-Clause"
264 | ],
265 | "authors": [
266 | {
267 | "name": "Sebastian Bergmann",
268 | "email": "sb@sebastian-bergmann.de",
269 | "role": "lead"
270 | }
271 | ],
272 | "description": "Library that provides collection, processing, and rendering functionality for PHP code coverage information.",
273 | "homepage": "https://github.com/sebastianbergmann/php-code-coverage",
274 | "keywords": [
275 | "coverage",
276 | "testing",
277 | "xunit"
278 | ],
279 | "time": "2016-04-08 08:14:53"
280 | },
281 | {
282 | "name": "phpunit/php-file-iterator",
283 | "version": "1.4.1",
284 | "source": {
285 | "type": "git",
286 | "url": "https://github.com/sebastianbergmann/php-file-iterator.git",
287 | "reference": "6150bf2c35d3fc379e50c7602b75caceaa39dbf0"
288 | },
289 | "dist": {
290 | "type": "zip",
291 | "url": "https://api.github.com/repos/sebastianbergmann/php-file-iterator/zipball/6150bf2c35d3fc379e50c7602b75caceaa39dbf0",
292 | "reference": "6150bf2c35d3fc379e50c7602b75caceaa39dbf0",
293 | "shasum": ""
294 | },
295 | "require": {
296 | "php": ">=5.3.3"
297 | },
298 | "type": "library",
299 | "extra": {
300 | "branch-alias": {
301 | "dev-master": "1.4.x-dev"
302 | }
303 | },
304 | "autoload": {
305 | "classmap": [
306 | "src/"
307 | ]
308 | },
309 | "notification-url": "https://packagist.org/downloads/",
310 | "license": [
311 | "BSD-3-Clause"
312 | ],
313 | "authors": [
314 | {
315 | "name": "Sebastian Bergmann",
316 | "email": "sb@sebastian-bergmann.de",
317 | "role": "lead"
318 | }
319 | ],
320 | "description": "FilterIterator implementation that filters files based on a list of suffixes.",
321 | "homepage": "https://github.com/sebastianbergmann/php-file-iterator/",
322 | "keywords": [
323 | "filesystem",
324 | "iterator"
325 | ],
326 | "time": "2015-06-21 13:08:43"
327 | },
328 | {
329 | "name": "phpunit/php-text-template",
330 | "version": "1.2.1",
331 | "source": {
332 | "type": "git",
333 | "url": "https://github.com/sebastianbergmann/php-text-template.git",
334 | "reference": "31f8b717e51d9a2afca6c9f046f5d69fc27c8686"
335 | },
336 | "dist": {
337 | "type": "zip",
338 | "url": "https://api.github.com/repos/sebastianbergmann/php-text-template/zipball/31f8b717e51d9a2afca6c9f046f5d69fc27c8686",
339 | "reference": "31f8b717e51d9a2afca6c9f046f5d69fc27c8686",
340 | "shasum": ""
341 | },
342 | "require": {
343 | "php": ">=5.3.3"
344 | },
345 | "type": "library",
346 | "autoload": {
347 | "classmap": [
348 | "src/"
349 | ]
350 | },
351 | "notification-url": "https://packagist.org/downloads/",
352 | "license": [
353 | "BSD-3-Clause"
354 | ],
355 | "authors": [
356 | {
357 | "name": "Sebastian Bergmann",
358 | "email": "sebastian@phpunit.de",
359 | "role": "lead"
360 | }
361 | ],
362 | "description": "Simple template engine.",
363 | "homepage": "https://github.com/sebastianbergmann/php-text-template/",
364 | "keywords": [
365 | "template"
366 | ],
367 | "time": "2015-06-21 13:50:34"
368 | },
369 | {
370 | "name": "phpunit/php-timer",
371 | "version": "1.0.8",
372 | "source": {
373 | "type": "git",
374 | "url": "https://github.com/sebastianbergmann/php-timer.git",
375 | "reference": "38e9124049cf1a164f1e4537caf19c99bf1eb260"
376 | },
377 | "dist": {
378 | "type": "zip",
379 | "url": "https://api.github.com/repos/sebastianbergmann/php-timer/zipball/38e9124049cf1a164f1e4537caf19c99bf1eb260",
380 | "reference": "38e9124049cf1a164f1e4537caf19c99bf1eb260",
381 | "shasum": ""
382 | },
383 | "require": {
384 | "php": ">=5.3.3"
385 | },
386 | "require-dev": {
387 | "phpunit/phpunit": "~4|~5"
388 | },
389 | "type": "library",
390 | "autoload": {
391 | "classmap": [
392 | "src/"
393 | ]
394 | },
395 | "notification-url": "https://packagist.org/downloads/",
396 | "license": [
397 | "BSD-3-Clause"
398 | ],
399 | "authors": [
400 | {
401 | "name": "Sebastian Bergmann",
402 | "email": "sb@sebastian-bergmann.de",
403 | "role": "lead"
404 | }
405 | ],
406 | "description": "Utility class for timing",
407 | "homepage": "https://github.com/sebastianbergmann/php-timer/",
408 | "keywords": [
409 | "timer"
410 | ],
411 | "time": "2016-05-12 18:03:57"
412 | },
413 | {
414 | "name": "phpunit/php-token-stream",
415 | "version": "1.4.8",
416 | "source": {
417 | "type": "git",
418 | "url": "https://github.com/sebastianbergmann/php-token-stream.git",
419 | "reference": "3144ae21711fb6cac0b1ab4cbe63b75ce3d4e8da"
420 | },
421 | "dist": {
422 | "type": "zip",
423 | "url": "https://api.github.com/repos/sebastianbergmann/php-token-stream/zipball/3144ae21711fb6cac0b1ab4cbe63b75ce3d4e8da",
424 | "reference": "3144ae21711fb6cac0b1ab4cbe63b75ce3d4e8da",
425 | "shasum": ""
426 | },
427 | "require": {
428 | "ext-tokenizer": "*",
429 | "php": ">=5.3.3"
430 | },
431 | "require-dev": {
432 | "phpunit/phpunit": "~4.2"
433 | },
434 | "type": "library",
435 | "extra": {
436 | "branch-alias": {
437 | "dev-master": "1.4-dev"
438 | }
439 | },
440 | "autoload": {
441 | "classmap": [
442 | "src/"
443 | ]
444 | },
445 | "notification-url": "https://packagist.org/downloads/",
446 | "license": [
447 | "BSD-3-Clause"
448 | ],
449 | "authors": [
450 | {
451 | "name": "Sebastian Bergmann",
452 | "email": "sebastian@phpunit.de"
453 | }
454 | ],
455 | "description": "Wrapper around PHP's tokenizer extension.",
456 | "homepage": "https://github.com/sebastianbergmann/php-token-stream/",
457 | "keywords": [
458 | "tokenizer"
459 | ],
460 | "time": "2015-09-15 10:49:45"
461 | },
462 | {
463 | "name": "phpunit/phpunit",
464 | "version": "5.3.4",
465 | "source": {
466 | "type": "git",
467 | "url": "https://github.com/sebastianbergmann/phpunit.git",
468 | "reference": "00dd95ffb48805503817ced06399017df315fe5c"
469 | },
470 | "dist": {
471 | "type": "zip",
472 | "url": "https://api.github.com/repos/sebastianbergmann/phpunit/zipball/00dd95ffb48805503817ced06399017df315fe5c",
473 | "reference": "00dd95ffb48805503817ced06399017df315fe5c",
474 | "shasum": ""
475 | },
476 | "require": {
477 | "ext-dom": "*",
478 | "ext-json": "*",
479 | "ext-pcre": "*",
480 | "ext-reflection": "*",
481 | "ext-spl": "*",
482 | "myclabs/deep-copy": "~1.3",
483 | "php": "^5.6 || ^7.0",
484 | "phpspec/prophecy": "^1.3.1",
485 | "phpunit/php-code-coverage": "^3.3.0",
486 | "phpunit/php-file-iterator": "~1.4",
487 | "phpunit/php-text-template": "~1.2",
488 | "phpunit/php-timer": "^1.0.6",
489 | "phpunit/phpunit-mock-objects": "^3.1",
490 | "sebastian/comparator": "~1.1",
491 | "sebastian/diff": "~1.2",
492 | "sebastian/environment": "~1.3",
493 | "sebastian/exporter": "~1.2",
494 | "sebastian/global-state": "~1.0",
495 | "sebastian/object-enumerator": "~1.0",
496 | "sebastian/resource-operations": "~1.0",
497 | "sebastian/version": "~1.0|~2.0",
498 | "symfony/yaml": "~2.1|~3.0"
499 | },
500 | "suggest": {
501 | "phpunit/php-invoker": "~1.1"
502 | },
503 | "bin": [
504 | "phpunit"
505 | ],
506 | "type": "library",
507 | "extra": {
508 | "branch-alias": {
509 | "dev-master": "5.3.x-dev"
510 | }
511 | },
512 | "autoload": {
513 | "classmap": [
514 | "src/"
515 | ]
516 | },
517 | "notification-url": "https://packagist.org/downloads/",
518 | "license": [
519 | "BSD-3-Clause"
520 | ],
521 | "authors": [
522 | {
523 | "name": "Sebastian Bergmann",
524 | "email": "sebastian@phpunit.de",
525 | "role": "lead"
526 | }
527 | ],
528 | "description": "The PHP Unit Testing framework.",
529 | "homepage": "https://phpunit.de/",
530 | "keywords": [
531 | "phpunit",
532 | "testing",
533 | "xunit"
534 | ],
535 | "time": "2016-05-11 13:28:45"
536 | },
537 | {
538 | "name": "phpunit/phpunit-mock-objects",
539 | "version": "3.1.3",
540 | "source": {
541 | "type": "git",
542 | "url": "https://github.com/sebastianbergmann/phpunit-mock-objects.git",
543 | "reference": "151c96874bff6fe61a25039df60e776613a61489"
544 | },
545 | "dist": {
546 | "type": "zip",
547 | "url": "https://api.github.com/repos/sebastianbergmann/phpunit-mock-objects/zipball/151c96874bff6fe61a25039df60e776613a61489",
548 | "reference": "151c96874bff6fe61a25039df60e776613a61489",
549 | "shasum": ""
550 | },
551 | "require": {
552 | "doctrine/instantiator": "^1.0.2",
553 | "php": ">=5.6",
554 | "phpunit/php-text-template": "~1.2",
555 | "sebastian/exporter": "~1.2"
556 | },
557 | "require-dev": {
558 | "phpunit/phpunit": "~5"
559 | },
560 | "suggest": {
561 | "ext-soap": "*"
562 | },
563 | "type": "library",
564 | "extra": {
565 | "branch-alias": {
566 | "dev-master": "3.1.x-dev"
567 | }
568 | },
569 | "autoload": {
570 | "classmap": [
571 | "src/"
572 | ]
573 | },
574 | "notification-url": "https://packagist.org/downloads/",
575 | "license": [
576 | "BSD-3-Clause"
577 | ],
578 | "authors": [
579 | {
580 | "name": "Sebastian Bergmann",
581 | "email": "sb@sebastian-bergmann.de",
582 | "role": "lead"
583 | }
584 | ],
585 | "description": "Mock Object library for PHPUnit",
586 | "homepage": "https://github.com/sebastianbergmann/phpunit-mock-objects/",
587 | "keywords": [
588 | "mock",
589 | "xunit"
590 | ],
591 | "time": "2016-04-20 14:39:26"
592 | },
593 | {
594 | "name": "sebastian/code-unit-reverse-lookup",
595 | "version": "1.0.0",
596 | "source": {
597 | "type": "git",
598 | "url": "https://github.com/sebastianbergmann/code-unit-reverse-lookup.git",
599 | "reference": "c36f5e7cfce482fde5bf8d10d41a53591e0198fe"
600 | },
601 | "dist": {
602 | "type": "zip",
603 | "url": "https://api.github.com/repos/sebastianbergmann/code-unit-reverse-lookup/zipball/c36f5e7cfce482fde5bf8d10d41a53591e0198fe",
604 | "reference": "c36f5e7cfce482fde5bf8d10d41a53591e0198fe",
605 | "shasum": ""
606 | },
607 | "require": {
608 | "php": ">=5.6"
609 | },
610 | "require-dev": {
611 | "phpunit/phpunit": "~5"
612 | },
613 | "type": "library",
614 | "extra": {
615 | "branch-alias": {
616 | "dev-master": "1.0.x-dev"
617 | }
618 | },
619 | "autoload": {
620 | "classmap": [
621 | "src/"
622 | ]
623 | },
624 | "notification-url": "https://packagist.org/downloads/",
625 | "license": [
626 | "BSD-3-Clause"
627 | ],
628 | "authors": [
629 | {
630 | "name": "Sebastian Bergmann",
631 | "email": "sebastian@phpunit.de"
632 | }
633 | ],
634 | "description": "Looks up which function or method a line of code belongs to",
635 | "homepage": "https://github.com/sebastianbergmann/code-unit-reverse-lookup/",
636 | "time": "2016-02-13 06:45:14"
637 | },
638 | {
639 | "name": "sebastian/comparator",
640 | "version": "1.2.0",
641 | "source": {
642 | "type": "git",
643 | "url": "https://github.com/sebastianbergmann/comparator.git",
644 | "reference": "937efb279bd37a375bcadf584dec0726f84dbf22"
645 | },
646 | "dist": {
647 | "type": "zip",
648 | "url": "https://api.github.com/repos/sebastianbergmann/comparator/zipball/937efb279bd37a375bcadf584dec0726f84dbf22",
649 | "reference": "937efb279bd37a375bcadf584dec0726f84dbf22",
650 | "shasum": ""
651 | },
652 | "require": {
653 | "php": ">=5.3.3",
654 | "sebastian/diff": "~1.2",
655 | "sebastian/exporter": "~1.2"
656 | },
657 | "require-dev": {
658 | "phpunit/phpunit": "~4.4"
659 | },
660 | "type": "library",
661 | "extra": {
662 | "branch-alias": {
663 | "dev-master": "1.2.x-dev"
664 | }
665 | },
666 | "autoload": {
667 | "classmap": [
668 | "src/"
669 | ]
670 | },
671 | "notification-url": "https://packagist.org/downloads/",
672 | "license": [
673 | "BSD-3-Clause"
674 | ],
675 | "authors": [
676 | {
677 | "name": "Jeff Welch",
678 | "email": "whatthejeff@gmail.com"
679 | },
680 | {
681 | "name": "Volker Dusch",
682 | "email": "github@wallbash.com"
683 | },
684 | {
685 | "name": "Bernhard Schussek",
686 | "email": "bschussek@2bepublished.at"
687 | },
688 | {
689 | "name": "Sebastian Bergmann",
690 | "email": "sebastian@phpunit.de"
691 | }
692 | ],
693 | "description": "Provides the functionality to compare PHP values for equality",
694 | "homepage": "http://www.github.com/sebastianbergmann/comparator",
695 | "keywords": [
696 | "comparator",
697 | "compare",
698 | "equality"
699 | ],
700 | "time": "2015-07-26 15:48:44"
701 | },
702 | {
703 | "name": "sebastian/diff",
704 | "version": "1.4.1",
705 | "source": {
706 | "type": "git",
707 | "url": "https://github.com/sebastianbergmann/diff.git",
708 | "reference": "13edfd8706462032c2f52b4b862974dd46b71c9e"
709 | },
710 | "dist": {
711 | "type": "zip",
712 | "url": "https://api.github.com/repos/sebastianbergmann/diff/zipball/13edfd8706462032c2f52b4b862974dd46b71c9e",
713 | "reference": "13edfd8706462032c2f52b4b862974dd46b71c9e",
714 | "shasum": ""
715 | },
716 | "require": {
717 | "php": ">=5.3.3"
718 | },
719 | "require-dev": {
720 | "phpunit/phpunit": "~4.8"
721 | },
722 | "type": "library",
723 | "extra": {
724 | "branch-alias": {
725 | "dev-master": "1.4-dev"
726 | }
727 | },
728 | "autoload": {
729 | "classmap": [
730 | "src/"
731 | ]
732 | },
733 | "notification-url": "https://packagist.org/downloads/",
734 | "license": [
735 | "BSD-3-Clause"
736 | ],
737 | "authors": [
738 | {
739 | "name": "Kore Nordmann",
740 | "email": "mail@kore-nordmann.de"
741 | },
742 | {
743 | "name": "Sebastian Bergmann",
744 | "email": "sebastian@phpunit.de"
745 | }
746 | ],
747 | "description": "Diff implementation",
748 | "homepage": "https://github.com/sebastianbergmann/diff",
749 | "keywords": [
750 | "diff"
751 | ],
752 | "time": "2015-12-08 07:14:41"
753 | },
754 | {
755 | "name": "sebastian/environment",
756 | "version": "1.3.7",
757 | "source": {
758 | "type": "git",
759 | "url": "https://github.com/sebastianbergmann/environment.git",
760 | "reference": "4e8f0da10ac5802913afc151413bc8c53b6c2716"
761 | },
762 | "dist": {
763 | "type": "zip",
764 | "url": "https://api.github.com/repos/sebastianbergmann/environment/zipball/4e8f0da10ac5802913afc151413bc8c53b6c2716",
765 | "reference": "4e8f0da10ac5802913afc151413bc8c53b6c2716",
766 | "shasum": ""
767 | },
768 | "require": {
769 | "php": ">=5.3.3"
770 | },
771 | "require-dev": {
772 | "phpunit/phpunit": "~4.4"
773 | },
774 | "type": "library",
775 | "extra": {
776 | "branch-alias": {
777 | "dev-master": "1.3.x-dev"
778 | }
779 | },
780 | "autoload": {
781 | "classmap": [
782 | "src/"
783 | ]
784 | },
785 | "notification-url": "https://packagist.org/downloads/",
786 | "license": [
787 | "BSD-3-Clause"
788 | ],
789 | "authors": [
790 | {
791 | "name": "Sebastian Bergmann",
792 | "email": "sebastian@phpunit.de"
793 | }
794 | ],
795 | "description": "Provides functionality to handle HHVM/PHP environments",
796 | "homepage": "http://www.github.com/sebastianbergmann/environment",
797 | "keywords": [
798 | "Xdebug",
799 | "environment",
800 | "hhvm"
801 | ],
802 | "time": "2016-05-17 03:18:57"
803 | },
804 | {
805 | "name": "sebastian/exporter",
806 | "version": "1.2.1",
807 | "source": {
808 | "type": "git",
809 | "url": "https://github.com/sebastianbergmann/exporter.git",
810 | "reference": "7ae5513327cb536431847bcc0c10edba2701064e"
811 | },
812 | "dist": {
813 | "type": "zip",
814 | "url": "https://api.github.com/repos/sebastianbergmann/exporter/zipball/7ae5513327cb536431847bcc0c10edba2701064e",
815 | "reference": "7ae5513327cb536431847bcc0c10edba2701064e",
816 | "shasum": ""
817 | },
818 | "require": {
819 | "php": ">=5.3.3",
820 | "sebastian/recursion-context": "~1.0"
821 | },
822 | "require-dev": {
823 | "phpunit/phpunit": "~4.4"
824 | },
825 | "type": "library",
826 | "extra": {
827 | "branch-alias": {
828 | "dev-master": "1.2.x-dev"
829 | }
830 | },
831 | "autoload": {
832 | "classmap": [
833 | "src/"
834 | ]
835 | },
836 | "notification-url": "https://packagist.org/downloads/",
837 | "license": [
838 | "BSD-3-Clause"
839 | ],
840 | "authors": [
841 | {
842 | "name": "Jeff Welch",
843 | "email": "whatthejeff@gmail.com"
844 | },
845 | {
846 | "name": "Volker Dusch",
847 | "email": "github@wallbash.com"
848 | },
849 | {
850 | "name": "Bernhard Schussek",
851 | "email": "bschussek@2bepublished.at"
852 | },
853 | {
854 | "name": "Sebastian Bergmann",
855 | "email": "sebastian@phpunit.de"
856 | },
857 | {
858 | "name": "Adam Harvey",
859 | "email": "aharvey@php.net"
860 | }
861 | ],
862 | "description": "Provides the functionality to export PHP variables for visualization",
863 | "homepage": "http://www.github.com/sebastianbergmann/exporter",
864 | "keywords": [
865 | "export",
866 | "exporter"
867 | ],
868 | "time": "2015-06-21 07:55:53"
869 | },
870 | {
871 | "name": "sebastian/global-state",
872 | "version": "1.1.1",
873 | "source": {
874 | "type": "git",
875 | "url": "https://github.com/sebastianbergmann/global-state.git",
876 | "reference": "bc37d50fea7d017d3d340f230811c9f1d7280af4"
877 | },
878 | "dist": {
879 | "type": "zip",
880 | "url": "https://api.github.com/repos/sebastianbergmann/global-state/zipball/bc37d50fea7d017d3d340f230811c9f1d7280af4",
881 | "reference": "bc37d50fea7d017d3d340f230811c9f1d7280af4",
882 | "shasum": ""
883 | },
884 | "require": {
885 | "php": ">=5.3.3"
886 | },
887 | "require-dev": {
888 | "phpunit/phpunit": "~4.2"
889 | },
890 | "suggest": {
891 | "ext-uopz": "*"
892 | },
893 | "type": "library",
894 | "extra": {
895 | "branch-alias": {
896 | "dev-master": "1.0-dev"
897 | }
898 | },
899 | "autoload": {
900 | "classmap": [
901 | "src/"
902 | ]
903 | },
904 | "notification-url": "https://packagist.org/downloads/",
905 | "license": [
906 | "BSD-3-Clause"
907 | ],
908 | "authors": [
909 | {
910 | "name": "Sebastian Bergmann",
911 | "email": "sebastian@phpunit.de"
912 | }
913 | ],
914 | "description": "Snapshotting of global state",
915 | "homepage": "http://www.github.com/sebastianbergmann/global-state",
916 | "keywords": [
917 | "global state"
918 | ],
919 | "time": "2015-10-12 03:26:01"
920 | },
921 | {
922 | "name": "sebastian/object-enumerator",
923 | "version": "1.0.0",
924 | "source": {
925 | "type": "git",
926 | "url": "https://github.com/sebastianbergmann/object-enumerator.git",
927 | "reference": "d4ca2fb70344987502567bc50081c03e6192fb26"
928 | },
929 | "dist": {
930 | "type": "zip",
931 | "url": "https://api.github.com/repos/sebastianbergmann/object-enumerator/zipball/d4ca2fb70344987502567bc50081c03e6192fb26",
932 | "reference": "d4ca2fb70344987502567bc50081c03e6192fb26",
933 | "shasum": ""
934 | },
935 | "require": {
936 | "php": ">=5.6",
937 | "sebastian/recursion-context": "~1.0"
938 | },
939 | "require-dev": {
940 | "phpunit/phpunit": "~5"
941 | },
942 | "type": "library",
943 | "extra": {
944 | "branch-alias": {
945 | "dev-master": "1.0.x-dev"
946 | }
947 | },
948 | "autoload": {
949 | "classmap": [
950 | "src/"
951 | ]
952 | },
953 | "notification-url": "https://packagist.org/downloads/",
954 | "license": [
955 | "BSD-3-Clause"
956 | ],
957 | "authors": [
958 | {
959 | "name": "Sebastian Bergmann",
960 | "email": "sebastian@phpunit.de"
961 | }
962 | ],
963 | "description": "Traverses array structures and object graphs to enumerate all referenced objects",
964 | "homepage": "https://github.com/sebastianbergmann/object-enumerator/",
965 | "time": "2016-01-28 13:25:10"
966 | },
967 | {
968 | "name": "sebastian/recursion-context",
969 | "version": "1.0.2",
970 | "source": {
971 | "type": "git",
972 | "url": "https://github.com/sebastianbergmann/recursion-context.git",
973 | "reference": "913401df809e99e4f47b27cdd781f4a258d58791"
974 | },
975 | "dist": {
976 | "type": "zip",
977 | "url": "https://api.github.com/repos/sebastianbergmann/recursion-context/zipball/913401df809e99e4f47b27cdd781f4a258d58791",
978 | "reference": "913401df809e99e4f47b27cdd781f4a258d58791",
979 | "shasum": ""
980 | },
981 | "require": {
982 | "php": ">=5.3.3"
983 | },
984 | "require-dev": {
985 | "phpunit/phpunit": "~4.4"
986 | },
987 | "type": "library",
988 | "extra": {
989 | "branch-alias": {
990 | "dev-master": "1.0.x-dev"
991 | }
992 | },
993 | "autoload": {
994 | "classmap": [
995 | "src/"
996 | ]
997 | },
998 | "notification-url": "https://packagist.org/downloads/",
999 | "license": [
1000 | "BSD-3-Clause"
1001 | ],
1002 | "authors": [
1003 | {
1004 | "name": "Jeff Welch",
1005 | "email": "whatthejeff@gmail.com"
1006 | },
1007 | {
1008 | "name": "Sebastian Bergmann",
1009 | "email": "sebastian@phpunit.de"
1010 | },
1011 | {
1012 | "name": "Adam Harvey",
1013 | "email": "aharvey@php.net"
1014 | }
1015 | ],
1016 | "description": "Provides functionality to recursively process PHP variables",
1017 | "homepage": "http://www.github.com/sebastianbergmann/recursion-context",
1018 | "time": "2015-11-11 19:50:13"
1019 | },
1020 | {
1021 | "name": "sebastian/resource-operations",
1022 | "version": "1.0.0",
1023 | "source": {
1024 | "type": "git",
1025 | "url": "https://github.com/sebastianbergmann/resource-operations.git",
1026 | "reference": "ce990bb21759f94aeafd30209e8cfcdfa8bc3f52"
1027 | },
1028 | "dist": {
1029 | "type": "zip",
1030 | "url": "https://api.github.com/repos/sebastianbergmann/resource-operations/zipball/ce990bb21759f94aeafd30209e8cfcdfa8bc3f52",
1031 | "reference": "ce990bb21759f94aeafd30209e8cfcdfa8bc3f52",
1032 | "shasum": ""
1033 | },
1034 | "require": {
1035 | "php": ">=5.6.0"
1036 | },
1037 | "type": "library",
1038 | "extra": {
1039 | "branch-alias": {
1040 | "dev-master": "1.0.x-dev"
1041 | }
1042 | },
1043 | "autoload": {
1044 | "classmap": [
1045 | "src/"
1046 | ]
1047 | },
1048 | "notification-url": "https://packagist.org/downloads/",
1049 | "license": [
1050 | "BSD-3-Clause"
1051 | ],
1052 | "authors": [
1053 | {
1054 | "name": "Sebastian Bergmann",
1055 | "email": "sebastian@phpunit.de"
1056 | }
1057 | ],
1058 | "description": "Provides a list of PHP built-in functions that operate on resources",
1059 | "homepage": "https://www.github.com/sebastianbergmann/resource-operations",
1060 | "time": "2015-07-28 20:34:47"
1061 | },
1062 | {
1063 | "name": "sebastian/version",
1064 | "version": "2.0.0",
1065 | "source": {
1066 | "type": "git",
1067 | "url": "https://github.com/sebastianbergmann/version.git",
1068 | "reference": "c829badbd8fdf16a0bad8aa7fa7971c029f1b9c5"
1069 | },
1070 | "dist": {
1071 | "type": "zip",
1072 | "url": "https://api.github.com/repos/sebastianbergmann/version/zipball/c829badbd8fdf16a0bad8aa7fa7971c029f1b9c5",
1073 | "reference": "c829badbd8fdf16a0bad8aa7fa7971c029f1b9c5",
1074 | "shasum": ""
1075 | },
1076 | "require": {
1077 | "php": ">=5.6"
1078 | },
1079 | "type": "library",
1080 | "extra": {
1081 | "branch-alias": {
1082 | "dev-master": "2.0.x-dev"
1083 | }
1084 | },
1085 | "autoload": {
1086 | "classmap": [
1087 | "src/"
1088 | ]
1089 | },
1090 | "notification-url": "https://packagist.org/downloads/",
1091 | "license": [
1092 | "BSD-3-Clause"
1093 | ],
1094 | "authors": [
1095 | {
1096 | "name": "Sebastian Bergmann",
1097 | "email": "sebastian@phpunit.de",
1098 | "role": "lead"
1099 | }
1100 | ],
1101 | "description": "Library that helps with managing the version number of Git-hosted PHP projects",
1102 | "homepage": "https://github.com/sebastianbergmann/version",
1103 | "time": "2016-02-04 12:56:52"
1104 | },
1105 | {
1106 | "name": "symfony/yaml",
1107 | "version": "v3.0.6",
1108 | "source": {
1109 | "type": "git",
1110 | "url": "https://github.com/symfony/yaml.git",
1111 | "reference": "0047c8366744a16de7516622c5b7355336afae96"
1112 | },
1113 | "dist": {
1114 | "type": "zip",
1115 | "url": "https://api.github.com/repos/symfony/yaml/zipball/0047c8366744a16de7516622c5b7355336afae96",
1116 | "reference": "0047c8366744a16de7516622c5b7355336afae96",
1117 | "shasum": ""
1118 | },
1119 | "require": {
1120 | "php": ">=5.5.9"
1121 | },
1122 | "type": "library",
1123 | "extra": {
1124 | "branch-alias": {
1125 | "dev-master": "3.0-dev"
1126 | }
1127 | },
1128 | "autoload": {
1129 | "psr-4": {
1130 | "Symfony\\Component\\Yaml\\": ""
1131 | },
1132 | "exclude-from-classmap": [
1133 | "/Tests/"
1134 | ]
1135 | },
1136 | "notification-url": "https://packagist.org/downloads/",
1137 | "license": [
1138 | "MIT"
1139 | ],
1140 | "authors": [
1141 | {
1142 | "name": "Fabien Potencier",
1143 | "email": "fabien@symfony.com"
1144 | },
1145 | {
1146 | "name": "Symfony Community",
1147 | "homepage": "https://symfony.com/contributors"
1148 | }
1149 | ],
1150 | "description": "Symfony Yaml Component",
1151 | "homepage": "https://symfony.com",
1152 | "time": "2016-03-04 07:55:57"
1153 | }
1154 | ],
1155 | "aliases": [],
1156 | "minimum-stability": "stable",
1157 | "stability-flags": [],
1158 | "prefer-stable": false,
1159 | "prefer-lowest": false,
1160 | "platform": {
1161 | "php": ">=5.4.0"
1162 | },
1163 | "platform-dev": []
1164 | }
1165 |
--------------------------------------------------------------------------------