From ee07a95a8e59ea2975b26f7cd029ca5f4caf87e7 Mon Sep 17 00:00:00 2001 From: Till Sanders Date: Mon, 24 Feb 2020 23:30:12 +0100 Subject: [PATCH 01/13] Add hugo.feedback() to items example code --- docs/items.md | 3 +++ 1 file changed, 3 insertions(+) diff --git a/docs/items.md b/docs/items.md index 9b71d75..8c722da 100644 --- a/docs/items.md +++ b/docs/items.md @@ -35,6 +35,9 @@ const items = [ ]; hugo.items = hugo.items.concat(items); + +// Flush output buffer +hugo.feedack(); ``` #### Variables From ccbec419cfedb745d3a8158d0f61d3f6745ebdc8 Mon Sep 17 00:00:00 2001 From: Till Sanders Date: Mon, 24 Feb 2020 23:31:14 +0100 Subject: [PATCH 02/13] Improve error message for invalid workflow version --- src/hugo.ts | 2 +- test/meta/workflow.ts | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/src/hugo.ts b/src/hugo.ts index 0183893..d6a37c8 100644 --- a/src/hugo.ts +++ b/src/hugo.ts @@ -175,7 +175,7 @@ export class Hugo { // Check if version is valid if (version === null) { if (process.env.alfred_debug === '1') { - console.error(`Invalid workflow version: ${process.env.alfred_workflow_version}`); + console.error(`Invalid workflow version: ${process.env.alfred_workflow_version}. Open your workflow in Alfred, click on the [x]-Symbol and set a semantic version number.`); } version = undefined; diff --git a/test/meta/workflow.ts b/test/meta/workflow.ts index 392dfc0..e561de0 100644 --- a/test/meta/workflow.ts +++ b/test/meta/workflow.ts @@ -52,7 +52,7 @@ test.serial("no version", (t) => { t.is(typeof h.workflowMeta, "object"); t.falsy(h.workflowMeta.version); - t.true(consoleStub.calledWith("Invalid workflow version: undefined")); + t.true(consoleStub.calledWith(sinon.match("Invalid workflow version: undefined"))); }); test.serial("invalid version", (t) => { @@ -72,7 +72,7 @@ test.serial("invalid version", (t) => { t.is(typeof h.workflowMeta, "object"); t.falsy(h.workflowMeta.version); - t.true(consoleStub.calledWith("Invalid workflow version: foobar")); + t.true(consoleStub.calledWith(sinon.match("Invalid workflow version: foobar"))); }); test.afterEach.always(() => { From 3d6408428a2e2a735e3fc8298f8ce62b11853ad3 Mon Sep 17 00:00:00 2001 From: Maarten de Boer Date: Sat, 21 Mar 2020 19:44:40 +0100 Subject: [PATCH 03/13] Style fixes on tests --- test/actions.ts | 194 ++++++++++++++++++++-------------------- test/feedback.ts | 22 ++--- test/fetch.ts | 50 +++++------ test/file-cache.ts | 52 +++++------ test/helpers/init.ts | 38 ++++---- test/helpers/mock.ts | 50 +++++------ test/helpers/types.ts | 2 +- test/hugo.ts | 128 +++++++++++++------------- test/matching.ts | 52 +++++------ test/meta/alfred.ts | 88 +++++++++--------- test/meta/theme.ts | 24 ++--- test/meta/workflow.ts | 60 ++++++------- test/output.ts | 58 ++++++------ test/updates/npm.ts | 166 +++++++++++++++++----------------- test/updates/packal.ts | 78 ++++++++-------- test/updates/updater.ts | 94 +++++++++---------- test/utils.ts | 94 +++++++++---------- 17 files changed, 625 insertions(+), 625 deletions(-) diff --git a/test/actions.ts b/test/actions.ts index 3c91b98..c21c3fd 100644 --- a/test/actions.ts +++ b/test/actions.ts @@ -1,70 +1,70 @@ -import test from "ava"; -import { hugo } from "./helpers/init"; +import test from 'ava'; +import { hugo } from './helpers/init'; -test.serial("no actions defined", (t) => { +test.serial('no actions defined', (t) => { process.argv = [ - "node", - "index.js", - "foo", + 'node', + 'index.js', + 'foo', ]; const h = hugo(); t.is(h.input.length, 1); - t.is(h.input[0], "foo"); + t.is(h.input[0], 'foo'); h.run(); // Now run with custom args process.argv = []; - h.run(["foo"]); + h.run(['foo']); }); -test.serial("actions defined but no matching action", (t) => { +test.serial('actions defined but no matching action', (t) => { process.argv = [ - "node", - "index.js", - "foo", + 'node', + 'index.js', + 'foo', ]; const h = hugo(); - h.action("bar", (query) => { + h.action('bar', (query) => { t.log(query); t.fail(); }); - h.action("soap", (query) => { + h.action('soap', (query) => { t.log(query); t.fail(); }); t.is(h.input.length, 1); - t.is(h.input[0], "foo"); + t.is(h.input[0], 'foo'); h.run(); // Now run with custom args process.argv = []; - h.run(["foo"]); + h.run(['foo']); }); -test.serial("actions defined but no action given", (t) => { +test.serial('actions defined but no action given', (t) => { process.argv = [ - "node", - "index.js", + 'node', + 'index.js', ]; const h = hugo(); - h.action("bar", (query) => { + h.action('bar', (query) => { t.log(query); t.fail(); }); - h.action("soap", (query) => { + h.action('soap', (query) => { t.log(query); t.fail(); }); @@ -79,23 +79,23 @@ test.serial("actions defined but no action given", (t) => { h.run([]); }); -test.serial("actions defined and matching action with no query", (t) => { +test.serial('actions defined and matching action with no query', (t) => { t.plan(2); process.argv = [ - "node", - "index.js", - "foo", + 'node', + 'index.js', + 'foo', ]; const h = hugo(); - h.action("bar", (query) => { + h.action('bar', (query) => { t.log(query); t.fail(); }); - h.action("foo", (query) => { + h.action('foo', (query) => { t.is(query.length, 0); }); @@ -104,29 +104,29 @@ test.serial("actions defined and matching action with no query", (t) => { // Now run with custom args process.argv = []; - h.run(["foo"]); + h.run(['foo']); }); -test.serial("actions defined and matching action with query", (t) => { +test.serial('actions defined and matching action with query', (t) => { t.plan(4); process.argv = [ - "node", - "index.js", - "foo", - "bar", + 'node', + 'index.js', + 'foo', + 'bar', ]; const h = hugo(); - h.action("bar", (query) => { + h.action('bar', (query) => { t.log(query); t.fail(); }); - h.action("foo", (query) => { + h.action('foo', (query) => { t.is(query.length, 1); - t.is(query[0], "bar"); + t.is(query[0], 'bar'); }); h.run(); @@ -134,85 +134,85 @@ test.serial("actions defined and matching action with query", (t) => { // Now run with custom args process.argv = []; - h.run(["foo", "bar"]); + h.run(['foo', 'bar']); }); -test("run actions with custom arguments instead of argv", (t) => { +test('run actions with custom arguments instead of argv', (t) => { t.plan(2); const h = hugo(); - h.action("bar", (query) => { + h.action('bar', (query) => { t.log(query); t.fail(); }); - h.action("foo", (query) => { + h.action('foo', (query) => { t.is(query.length, 1); - t.is(query[0], "bar"); + t.is(query[0], 'bar'); }); - h.run(["foo", "bar"]); + h.run(['foo', 'bar']); }); -test.serial("main action without callback and no matching sub-action", (t) => { +test.serial('main action without callback and no matching sub-action', (t) => { process.argv = [ - "node", - "index.js", - "foo", - "hello", - "world", + 'node', + 'index.js', + 'foo', + 'hello', + 'world', ]; const h = hugo(); // Foo with bar sub-action h - .action("foo") - .action("bar", (query) => { + .action('foo') + .action('bar', (query) => { t.fail(); }) ; t.is(h.input.length, 3); - t.is(h.input[0], "foo"); - t.is(h.input[1], "hello"); - t.is(h.input[2], "world"); + t.is(h.input[0], 'foo'); + t.is(h.input[1], 'hello'); + t.is(h.input[2], 'world'); h.run(); // Now run with custom args process.argv = []; - h.run(["foo", "hello", "world"]); + h.run(['foo', 'hello', 'world']); }); -test.serial("main action with matching sub-action", (t) => { +test.serial('main action with matching sub-action', (t) => { t.plan(6); process.argv = [ - "node", - "index.js", - "foo", - "bar", - "hello", - "world", + 'node', + 'index.js', + 'foo', + 'bar', + 'hello', + 'world', ]; const h = hugo(); // Foo action with bar sub-action - const fooAction = h.action("foo", (query) => { + const fooAction = h.action('foo', (query) => { t.fail(); }); // Bar sub-action with floop sub-action - const barAction = fooAction.action("bar", (query) => { + const barAction = fooAction.action('bar', (query) => { t.is(query.length, 2); - t.is(query[0], "hello"); - t.is(query[1], "world"); + t.is(query[0], 'hello'); + t.is(query[1], 'world'); }); - barAction.action("floop", (query) => { + barAction.action('floop', (query) => { t.fail(); }); @@ -221,38 +221,38 @@ test.serial("main action with matching sub-action", (t) => { // Now run with custom args process.argv = []; - h.run(["foo", "bar", "hello", "world"]); + h.run(['foo', 'bar', 'hello', 'world']); }); -test.serial("main action with matching sub-sub-action", (t) => { +test.serial('main action with matching sub-sub-action', (t) => { t.plan(6); process.argv = [ - "node", - "index.js", - "foo", - "bar", - "floop", - "hello", - "world", + 'node', + 'index.js', + 'foo', + 'bar', + 'floop', + 'hello', + 'world', ]; const h = hugo(); // Foo action with bar sub-action - const fooAction = h.action("foo", (query) => { + const fooAction = h.action('foo', (query) => { t.fail(); }); // Bar sub-action with floop sub-action - const barAction = fooAction.action("bar", (query) => { + const barAction = fooAction.action('bar', (query) => { t.fail(); }); - barAction.action("floop", (query) => { + barAction.action('floop', (query) => { t.is(query.length, 2); - t.is(query[0], "hello"); - t.is(query[1], "world"); + t.is(query[0], 'hello'); + t.is(query[1], 'world'); }); h.run(); @@ -260,26 +260,26 @@ test.serial("main action with matching sub-sub-action", (t) => { // Now run with custom args process.argv = []; - h.run(["foo", "bar", "floop", "hello", "world"]); + h.run(['foo', 'bar', 'floop', 'hello', 'world']); }); -test.serial("main action with sub-actions defined, without query", (t) => { +test.serial('main action with sub-actions defined, without query', (t) => { t.plan(2); process.argv = [ - "node", - "index.js", - "foo", + 'node', + 'index.js', + 'foo', ]; const h = hugo(); // Foo with bar sub-action h - .action("foo", (query) => { + .action('foo', (query) => { t.is(query.length, 0); }) - .action("bar", (query) => { + .action('bar', (query) => { t.fail(); }) ; @@ -289,28 +289,28 @@ test.serial("main action with sub-actions defined, without query", (t) => { // Now run with custom args process.argv = []; - h.run(["foo"]); + h.run(['foo']); }); -test.serial("main action with sub-actions defined, with query but no sub-action match", (t) => { +test.serial('main action with sub-actions defined, with query but no sub-action match', (t) => { t.plan(4); process.argv = [ - "node", - "index.js", - "foo", - "hello", + 'node', + 'index.js', + 'foo', + 'hello', ]; const h = hugo(); // Foo with bar sub-action h - .action("foo", (query) => { + .action('foo', (query) => { t.is(query.length, 1); - t.is(query[0], "hello"); + t.is(query[0], 'hello'); }) - .action("bar", (query) => { + .action('bar', (query) => { t.fail(); }) ; @@ -320,5 +320,5 @@ test.serial("main action with sub-actions defined, with query but no sub-action // Now run with custom args process.argv = []; - h.run(["foo", "hello"]); + h.run(['foo', 'hello']); }); diff --git a/test/feedback.ts b/test/feedback.ts index 2412433..b48e304 100644 --- a/test/feedback.ts +++ b/test/feedback.ts @@ -1,8 +1,8 @@ -import test from "ava"; -import sinon from "sinon"; +import test from 'ava'; +import sinon from 'sinon'; -import { hugo } from "./helpers/init"; -import * as mock from "./helpers/mock"; +import { hugo } from './helpers/init'; +import * as mock from './helpers/mock'; const backupConsoleLog = console.log; const backupConsoleError = console.error; @@ -11,8 +11,8 @@ test.beforeEach(() => { mock.date(); }); -test.serial("feedback without checking for updates", async (t) => { - const consoleStub = sinon.stub(console, "log"); +test.serial('feedback without checking for updates', async (t) => { + const consoleStub = sinon.stub(console, 'log'); const h = hugo({ checkUpdates: false, @@ -20,9 +20,9 @@ test.serial("feedback without checking for updates", async (t) => { h.rerun = 3.2; h.items.push({ - title: "foo", + title: 'foo', }); - h.variables.foo = "bar"; + h.variables.foo = 'bar'; await h.feedback(); @@ -36,11 +36,11 @@ test.serial("feedback without checking for updates", async (t) => { t.falsy(h.rerun); }); -test.serial("check for updates on feedback", async (t) => { - const consoleStub = sinon.stub(console, "log"); +test.serial('check for updates on feedback', async (t) => { + const consoleStub = sinon.stub(console, 'log'); const h = hugo({ - updateSource: "packal", + updateSource: 'packal', updateNotification: false, }); diff --git a/test/fetch.ts b/test/fetch.ts index 5fbeee9..c12fb0f 100644 --- a/test/fetch.ts +++ b/test/fetch.ts @@ -1,58 +1,58 @@ -import Test, { TestInterface } from "ava"; -import nock from "nock"; -import crypto from "crypto"; +import Test, { TestInterface } from 'ava'; +import nock from 'nock'; +import crypto from 'crypto'; -import { hugo } from "./helpers/init"; -import { TestContext } from "./helpers/types"; -import * as mock from "./helpers/mock"; +import { hugo } from './helpers/init'; +import { TestContext } from './helpers/types'; +import * as mock from './helpers/mock'; const test = Test as TestInterface; test.beforeEach((t) => { - t.context.url = "http://foo.bar"; - t.context.urlHash = crypto.createHash("md5").update(t.context.url).digest("hex"); + t.context.url = 'http://foo.bar'; + t.context.urlHash = crypto.createHash('md5').update(t.context.url).digest('hex'); // Mock requests nock(t.context.url) - .get("/") + .get('/') .once() - .reply(200, {message: "hello" }); + .reply(200, {message: 'hello' }); nock(t.context.url) - .get("/") + .get('/') .once() - .reply(200, {message: "world"}); + .reply(200, {message: 'world'}); mock.date(); }); -test.serial("fetch uncached", async (t) => { +test.serial('fetch uncached', async (t) => { const h = hugo(); // Fetch with caching implicitely disabled - t.deepEqual(await h.fetch(t.context.url), { message: "hello" }); + t.deepEqual(await h.fetch(t.context.url), { message: 'hello' }); t.false(h.cache.has(t.context.urlHash)); // Fetch with caching explicitely disabled - t.deepEqual(await h.fetch(t.context.url, null, false), { message: "world" }); + t.deepEqual(await h.fetch(t.context.url, null, false), { message: 'world' }); t.false(h.cache.has(t.context.urlHash)); }); -test.serial("fetch cached", async (t) => { +test.serial('fetch cached', async (t) => { const h = hugo(); // Fetch cached with empty cache t.false(h.cache.has(t.context.url)); - t.deepEqual(await h.fetch(t.context.url, null, 300), { message: "hello" }); - t.deepEqual(h.cache.get(t.context.urlHash), { message: "hello" }); + t.deepEqual(await h.fetch(t.context.url, null, 300), { message: 'hello' }); + t.deepEqual(h.cache.get(t.context.urlHash), { message: 'hello' }); // Fetch cached with warm cache and assert we have the right output. // Nock is set to only return 'hello' once. So if the request is not cached, it would return 'world'. - t.deepEqual(await h.fetch(t.context.url, null, 300), { message: "hello" }); - t.deepEqual(h.cache.get(t.context.urlHash), { message: "hello" }); + t.deepEqual(await h.fetch(t.context.url, null, 300), { message: 'hello' }); + t.deepEqual(h.cache.get(t.context.urlHash), { message: 'hello' }); // Let the cache expire - mock.forwardTime(1, "hour"); + mock.forwardTime(1, 'hour'); // Assert cache is expired t.false(h.cache.has(t.context.url)); @@ -60,12 +60,12 @@ test.serial("fetch cached", async (t) => { // Fetch cached with empty cache one more time and assert that the request is done. // Nock is set to only return 'hello' once, which we received before. This time it should return 'world' to complete // our sentence. If not, this would indicate the request is still cached somehow. - t.deepEqual(await h.fetch(t.context.url, null, 300), { message: "world" }); - t.deepEqual(h.cache.get(t.context.urlHash), { message: "world" }); + t.deepEqual(await h.fetch(t.context.url, null, 300), { message: 'world' }); + t.deepEqual(h.cache.get(t.context.urlHash), { message: 'world' }); // Fetch cached with a warm cache again. - t.deepEqual(await h.fetch(t.context.url, null, 300), { message: "world" }); - t.deepEqual(h.cache.get(t.context.urlHash), { message: "world" }); + t.deepEqual(await h.fetch(t.context.url, null, 300), { message: 'world' }); + t.deepEqual(h.cache.get(t.context.urlHash), { message: 'world' }); }); test.afterEach.always(() => { diff --git a/test/file-cache.ts b/test/file-cache.ts index 56dcf82..279ede0 100644 --- a/test/file-cache.ts +++ b/test/file-cache.ts @@ -1,38 +1,38 @@ -import fs from "fs-extra"; -import path from "path"; -import test from "ava"; +import fs from 'fs-extra'; +import path from 'path'; +import test from 'ava'; -import { hugo } from "./helpers/init"; -import * as mock from "./helpers/mock"; +import { hugo } from './helpers/init'; +import * as mock from './helpers/mock'; -test.serial("process file and cache it", (t) => { +test.serial('process file and cache it', (t) => { const h = hugo(); const tmpFile = mock.file(); // Create file - fs.writeFileSync(tmpFile, "Hello world!"); + fs.writeFileSync(tmpFile, 'Hello world!'); // Get FileCache instance const cachedFile = h.cacheFile(tmpFile); // Listen to change event to process data - cachedFile.once("change", (cache, file) => { - t.is(cache.constructor.name, "Cache"); - t.is("Hello world!", file); + cachedFile.once('change', (cache, file) => { + t.is(cache.constructor.name, 'Cache'); + t.is('Hello world!', file); - cache.set("hello", "world!"); + cache.set('hello', 'world!'); }); // Fetch data let data = cachedFile.get(); // Verify data - t.is(typeof data, "object"); - t.is(data.hello, "world!"); + t.is(typeof data, 'object'); + t.is(data.hello, 'world!'); // Listen to change event (which should not be emitted now) - cachedFile.once("change", () => { - t.fail("Data has not been cached."); + cachedFile.once('change', () => { + t.fail('Data has not been cached.'); }); // Fetch data again and verify it @@ -41,33 +41,33 @@ test.serial("process file and cache it", (t) => { cachedFile.removeAllListeners(); // Listen to change event to process data - cachedFile.once("change", (cache, file) => { - t.is(cache.constructor.name, "Cache"); - t.is("Foobar", file); + cachedFile.once('change', (cache, file) => { + t.is(cache.constructor.name, 'Cache'); + t.is('Foobar', file); - cache.set("foo", "bar"); + cache.set('foo', 'bar'); }); // Change file to trigger change on next get - fs.writeFileSync(tmpFile, "Foobar"); + fs.writeFileSync(tmpFile, 'Foobar'); // Fetch data data = cachedFile.get(); // Verify data - t.is(typeof data, "object"); - t.is(data.foo, "bar"); + t.is(typeof data, 'object'); + t.is(data.foo, 'bar'); }); -test.serial("process non-existing file", (t) => { +test.serial('process non-existing file', (t) => { const h = hugo(); // Get FileCache instance - const cachedFile = h.cacheFile(path.resolve(__dirname, "idontexist.txt")); + const cachedFile = h.cacheFile(path.resolve(__dirname, 'idontexist.txt')); // Listen to change event to process data - cachedFile.on("change", () => { - t.fail("File does not exist and this should not be called."); + cachedFile.on('change', () => { + t.fail('File does not exist and this should not be called.'); }); // Fetch data diff --git a/test/helpers/init.ts b/test/helpers/init.ts index 5815543..63e2264 100644 --- a/test/helpers/init.ts +++ b/test/helpers/init.ts @@ -1,28 +1,28 @@ -import { Cache } from "@cloudstek/cache"; -import crypto from "crypto"; -import path from "path"; -import moment from "moment"; -import fs from "fs-extra"; -import nock from "nock"; -import sinon from "sinon"; +import { Cache } from '@cloudstek/cache'; +import crypto from 'crypto'; +import path from 'path'; +import moment from 'moment'; +import fs from 'fs-extra'; +import nock from 'nock'; +import sinon from 'sinon'; -import { Updater, Hugo, HugoOptions } from "../../src"; +import { Updater, Hugo, HugoOptions } from '../../src'; export function setAlfredEnv() { - process.env.alfred_version = "4.0.0"; - process.env.alfred_workflow_version = "1.0.0"; - process.env.alfred_workflow_bundleid = "my.work.flow"; - process.env.alfred_preferences = path.join("build", "cache", crypto.randomBytes(8).toString("hex")); - process.env.alfred_workflow_data = path.join("build", "cache", crypto.randomBytes(8).toString("hex")); - process.env.alfred_workflow_cache = path.join("build", "cache", crypto.randomBytes(8).toString("hex")); - process.env.alfred_debug = "0"; + process.env.alfred_version = '4.0.0'; + process.env.alfred_workflow_version = '1.0.0'; + process.env.alfred_workflow_bundleid = 'my.work.flow'; + process.env.alfred_preferences = path.join('build', 'cache', crypto.randomBytes(8).toString('hex')); + process.env.alfred_workflow_data = path.join('build', 'cache', crypto.randomBytes(8).toString('hex')); + process.env.alfred_workflow_cache = path.join('build', 'cache', crypto.randomBytes(8).toString('hex')); + process.env.alfred_debug = '0'; fs.ensureDirSync(process.env.alfred_preferences); fs.ensureDirSync(process.env.alfred_workflow_data); fs.ensureDirSync(process.env.alfred_workflow_cache); // Set up fake home dir - process.env.HOME = path.join("build", "cache", crypto.randomBytes(8).toString("hex")); + process.env.HOME = path.join('build', 'cache', crypto.randomBytes(8).toString('hex')); } export function hugo(options?: HugoOptions) { @@ -43,11 +43,11 @@ export function hugo(options?: HugoOptions) { // Init another Hugo that has no stubs and stuff const originalHugo = new Hugo(options); - sinon.stub(h, "workflowMeta").get(() => { + sinon.stub(h, 'workflowMeta').get(() => { const workflowMeta = originalHugo.workflowMeta; // Give workflow icon a fixed path - workflowMeta.icon = "/foo/bar/icon.png"; + workflowMeta.icon = '/foo/bar/icon.png'; return workflowMeta; }); @@ -65,5 +65,5 @@ export function updater(cacheTtl?: number | moment.Duration) { dir: process.env.alfred_workflow_cache, }); - return new Updater(cache, cacheTtl || moment.duration(1, "hour")); + return new Updater(cache, cacheTtl || moment.duration(1, 'hour')); } diff --git a/test/helpers/mock.ts b/test/helpers/mock.ts index ac68a72..87cf295 100644 --- a/test/helpers/mock.ts +++ b/test/helpers/mock.ts @@ -1,32 +1,32 @@ -import readPkg from "read-pkg-up"; -import semver from "semver"; -import nock from "nock"; -import path from "path"; -import fs from "fs-extra"; -import crypto from "crypto"; -import mockdate from "mockdate"; -import moment, { DurationInputArg1, DurationInputArg2 } from "moment"; +import readPkg from 'read-pkg-up'; +import semver from 'semver'; +import nock from 'nock'; +import path from 'path'; +import fs from 'fs-extra'; +import crypto from 'crypto'; +import mockdate from 'mockdate'; +import moment, { DurationInputArg1, DurationInputArg2 } from 'moment'; export function date() { - mockdate.set(moment.utc("2019-01-01T14:00:00").valueOf()); + mockdate.set(moment.utc('2019-01-01T14:00:00').valueOf()); } export function forwardTime(amount?: DurationInputArg1, unit?: DurationInputArg2) { mockdate.set(moment.utc().add(amount, unit).toDate()); } -export function npm(times: number, pkg?: any, code: number = 200, latestVersion?: string) { +export function npm(times: number, pkg?: any, code = 200, latestVersion?: string) { pkg = pkg || readPkg.sync().packageJson; if (latestVersion !== null) { - latestVersion = latestVersion || semver.parse(pkg.version).inc("major").toString(); + latestVersion = latestVersion || semver.parse(pkg.version).inc('major').toString(); } // Build versions response const versions: { [key: string]: any } = { - "1.0.0": { + '1.0.0': { name: pkg.name, - version: "1.0.0", + version: '1.0.0', }, }; @@ -47,19 +47,19 @@ export function npm(times: number, pkg?: any, code: number = 200, latestVersion? } // Response body - let body = ""; + let body = ''; if (code >= 200 && code <= 299) { body = JSON.stringify({ - "name": pkg.name, - "dist-tags": distTags, + 'name': pkg.name, + 'dist-tags': distTags, versions, }); } // Mock requests - const url = "https://registry.npmjs.org"; - const urlPath = "/" + pkg.name; + const url = 'https://registry.npmjs.org'; + const urlPath = '/' + pkg.name; if (times >= 0) { for (let i = 0; i < times; i++) { @@ -79,19 +79,19 @@ export function npm(times: number, pkg?: any, code: number = 200, latestVersion? ; } -export function packal(times: number, code: number = 200, filename: string = "appcast.xml") { - filename = path.join("test", "helpers", "mocks", filename); +export function packal(times: number, code = 200, filename = 'appcast.xml') { + filename = path.join('test', 'helpers', 'mocks', filename); // Response body - let body = ""; + let body = ''; if (code >= 200 && code <= 299) { - body = fs.readFileSync(filename, { encoding: "utf8" }); + body = fs.readFileSync(filename, { encoding: 'utf8' }); } // Mock requests - const url = "https://github.com"; - const urlPath = "/packal/repository/blob/master/my.work.flow/appcast.xml"; + const url = 'https://github.com'; + const urlPath = '/packal/repository/blob/master/my.work.flow/appcast.xml'; if (times >= 0) { for (let i = 0; i < times; i++) { @@ -112,7 +112,7 @@ export function packal(times: number, code: number = 200, filename: string = "ap } export function file() { - const filePath = path.join("build", "cache", crypto.randomBytes(8).toString("hex")); + const filePath = path.join('build', 'cache', crypto.randomBytes(8).toString('hex')); fs.ensureFileSync(filePath); diff --git a/test/helpers/types.ts b/test/helpers/types.ts index 9c7b3a7..f90250d 100644 --- a/test/helpers/types.ts +++ b/test/helpers/types.ts @@ -1,4 +1,4 @@ -import { Hugo, Item } from "../../src"; +import { Hugo, Item } from '../../src'; export interface TestContext { hugo?: Hugo; diff --git a/test/hugo.ts b/test/hugo.ts index 59036cd..c195c4a 100644 --- a/test/hugo.ts +++ b/test/hugo.ts @@ -1,21 +1,21 @@ -import test from "ava"; -import moment from "moment"; -import fs from "fs-extra"; -import path from "path"; -import os from "os"; +import test from 'ava'; +import moment from 'moment'; +import fs from 'fs-extra'; +import path from 'path'; +import os from 'os'; -import utils from "../src/utils"; +import utils from '../src/utils'; -import { hugo } from "./helpers/init"; +import { hugo } from './helpers/init'; -import { UpdateSource, Hugo } from "../src"; +import { UpdateSource, Hugo } from '../src'; -test("initialize with options through constructor", (t) => { +test('initialize with options through constructor', (t) => { const hugoDefaults = (new Hugo() as any).options; const h = hugo({ checkUpdates: false, - updateInterval: moment.duration(2, "hours"), + updateInterval: moment.duration(2, 'hours'), updateItem: false, updateNotification: false, updateSource: UpdateSource.Packal, @@ -24,14 +24,14 @@ test("initialize with options through constructor", (t) => { t.notDeepEqual((h as any).options, hugoDefaults); t.deepEqual((h as any).options, { checkUpdates: false, - updateInterval: moment.duration(2, "hours"), + updateInterval: moment.duration(2, 'hours'), updateItem: false, updateNotification: false, updateSource: UpdateSource.Packal, }); }); -test("initialize with update interval as number", (t) => { +test('initialize with update interval as number', (t) => { const hugoDefaults = (new Hugo() as any).options; const h = hugo({ @@ -39,11 +39,11 @@ test("initialize with update interval as number", (t) => { }); t.deepEqual((h as any).options, Object.assign({}, hugoDefaults, { - updateInterval: moment.duration(4010, "seconds"), + updateInterval: moment.duration(4010, 'seconds'), })); }); -test("initialize with invalid update interval as number", (t) => { +test('initialize with invalid update interval as number', (t) => { const h = hugo({ updateInterval: -100, }); @@ -52,43 +52,43 @@ test("initialize with invalid update interval as number", (t) => { t.false((h as any).options.checkUpdates); }); -test("initialize with update interval as duration", (t) => { +test('initialize with update interval as duration', (t) => { const hugoDefaults = (new Hugo() as any).options; const h = hugo({ - updateInterval: moment.duration(3, "hours"), + updateInterval: moment.duration(3, 'hours'), }); t.deepEqual((h as any).options, Object.assign({}, hugoDefaults, { - updateInterval: moment.duration(3, "hours"), + updateInterval: moment.duration(3, 'hours'), })); }); -test("initialize with invalid update interval as duration", (t) => { +test('initialize with invalid update interval as duration', (t) => { const h = hugo({ - updateInterval: moment.duration(-10, "seconds"), + updateInterval: moment.duration(-10, 'seconds'), }); t.falsy((h as any).options.updateInterval); t.false((h as any).options.checkUpdates); }); -test("test reset", (t) => { +test('test reset', (t) => { const h = hugo(); // Add item h.items.push({ - title: "foo", + title: 'foo', }); // Add variable - h.variables.foo = "bar"; + h.variables.foo = 'bar'; // Set rerun h.rerun = 3.1; t.is(h.items.length, 1); - t.is(h.variables.foo, "bar"); + t.is(h.variables.foo, 'bar'); t.is(h.rerun, 3.1); h.reset(); @@ -98,29 +98,29 @@ test("test reset", (t) => { t.falsy(h.rerun); }); -test("input with no actions", (t) => { +test('input with no actions', (t) => { process.argv = [ - "node", - "index.js", - "foo", - "bar", - "hello", - "world", + 'node', + 'index.js', + 'foo', + 'bar', + 'hello', + 'world', ]; const h = hugo(); t.is(h.input.length, 4); - t.is(h.input[0], "foo"); - t.is(h.input[1], "bar"); - t.is(h.input[2], "hello"); - t.is(h.input[3], "world"); + t.is(h.input[0], 'foo'); + t.is(h.input[1], 'bar'); + t.is(h.input[2], 'hello'); + t.is(h.input[3], 'world'); }); -test("input with no input", (t) => { +test('input with no input', (t) => { process.argv = [ - "node", - "index.js", + 'node', + 'index.js', ]; const h = hugo(); @@ -128,9 +128,9 @@ test("input with no input", (t) => { t.is(h.input.length, 0); }); -test("notify", async (t) => { - if (os.platform() !== "darwin") { - t.pass("Notifications only work on MacOS."); +test('notify', async (t) => { + if (os.platform() !== 'darwin') { + t.pass('Notifications only work on MacOS.'); return; } @@ -138,16 +138,16 @@ test("notify", async (t) => { await t.notThrowsAsync(async () => { return h.notify({ - title: "Foo", - message: "Bar", + title: 'Foo', + message: 'Bar', timeout: 1, }); }); }); -test("notify with missing options", async (t) => { - if (os.platform() !== "darwin") { - t.pass("Notifications only work on MacOS."); +test('notify with missing options', async (t) => { + if (os.platform() !== 'darwin') { + t.pass('Notifications only work on MacOS.'); return; } @@ -155,50 +155,50 @@ test("notify with missing options", async (t) => { await t.throwsAsync(async () => { return h.notify({ - title: "Foo", + title: 'Foo', }); }); }); -test("clear cache dir", async (t) => { +test('clear cache dir', async (t) => { const h = hugo(); - fs.writeJsonSync(path.join(h.workflowMeta.cache, "foo.json"), { - foo: "bar", + fs.writeJsonSync(path.join(h.workflowMeta.cache, 'foo.json'), { + foo: 'bar', }); - fs.writeFileSync(path.join(h.workflowMeta.cache, "bar"), "foo"); + fs.writeFileSync(path.join(h.workflowMeta.cache, 'bar'), 'foo'); - t.true(utils.fileExists(path.join(h.workflowMeta.cache, "foo.json"))); - t.true(utils.fileExists(path.join(h.workflowMeta.cache, "bar"))); + t.true(utils.fileExists(path.join(h.workflowMeta.cache, 'foo.json'))); + t.true(utils.fileExists(path.join(h.workflowMeta.cache, 'bar'))); await h.clearCache(); - t.false(utils.fileExists(path.join(h.workflowMeta.cache, "foo.json"))); - t.false(utils.fileExists(path.join(h.workflowMeta.cache, "bar"))); + t.false(utils.fileExists(path.join(h.workflowMeta.cache, 'foo.json'))); + t.false(utils.fileExists(path.join(h.workflowMeta.cache, 'bar'))); t.true(utils.fileExists(h.workflowMeta.cache)); }); -test("clear cache dir sync", (t) => { +test('clear cache dir sync', (t) => { const h = hugo(); - fs.writeJsonSync(path.join(h.workflowMeta.cache, "foo.json"), { - foo: "bar", + fs.writeJsonSync(path.join(h.workflowMeta.cache, 'foo.json'), { + foo: 'bar', }); - fs.writeFileSync(path.join(h.workflowMeta.cache, "bar"), "foo"); + fs.writeFileSync(path.join(h.workflowMeta.cache, 'bar'), 'foo'); - t.true(utils.fileExists(path.join(h.workflowMeta.cache, "foo.json"))); - t.true(utils.fileExists(path.join(h.workflowMeta.cache, "bar"))); + t.true(utils.fileExists(path.join(h.workflowMeta.cache, 'foo.json'))); + t.true(utils.fileExists(path.join(h.workflowMeta.cache, 'bar'))); h.clearCacheSync(); - t.false(utils.fileExists(path.join(h.workflowMeta.cache, "foo.json"))); - t.false(utils.fileExists(path.join(h.workflowMeta.cache, "bar"))); + t.false(utils.fileExists(path.join(h.workflowMeta.cache, 'foo.json'))); + t.false(utils.fileExists(path.join(h.workflowMeta.cache, 'bar'))); t.true(utils.fileExists(h.workflowMeta.cache)); }); -test.serial("clear cache dir without cache dir set", async (t) => { +test.serial('clear cache dir without cache dir set', async (t) => { const h = hugo(); delete process.env.alfred_workflow_cache; @@ -210,7 +210,7 @@ test.serial("clear cache dir without cache dir set", async (t) => { }); }); -test.serial("clear cache dir sync without cache dir set", async (t) => { +test.serial('clear cache dir sync without cache dir set', async (t) => { const h = hugo(); delete process.env.alfred_workflow_cache; diff --git a/test/matching.ts b/test/matching.ts index 76beba6..f3caa5d 100644 --- a/test/matching.ts +++ b/test/matching.ts @@ -1,40 +1,40 @@ -import Test, { TestInterface } from "ava"; +import Test, { TestInterface } from 'ava'; -import { hugo } from "./helpers/init"; -import { TestContext } from "./helpers/types"; +import { hugo } from './helpers/init'; +import { TestContext } from './helpers/types'; const test = Test as TestInterface; test.beforeEach((t) => { t.context.items = [ { - title: "Foo", - subtitle: "foo bar", + title: 'Foo', + subtitle: 'foo bar', }, { - title: "Bar", - subtitle: "foo bar bleep", + title: 'Bar', + subtitle: 'foo bar bleep', }, { - title: "Eep", - match: "Abra", - subtitle: "eep foo blep", + title: 'Eep', + match: 'Abra', + subtitle: 'eep foo blep', }, { - title: "Foo bar", - subtitle: "ploop", + title: 'Foo bar', + subtitle: 'ploop', }, { - title: "Abra", - subtitle: "cadabra", + title: 'Abra', + subtitle: 'cadabra', }, ]; }); -test("exact match", (t) => { +test('exact match', (t) => { const h = hugo(); - const matches = h.match(t.context.items, "Abra", { + const matches = h.match(t.context.items, 'Abra', { threshold: 0, shouldSort: false, }); @@ -48,11 +48,11 @@ test("exact match", (t) => { t.deepEqual(matches[1], t.context.items[4]); }); -test("exact match by single key", (t) => { +test('exact match by single key', (t) => { const h = hugo(); - const matches = h.match(t.context.items, "foo bar bleep", { - keys: ["subtitle"], + const matches = h.match(t.context.items, 'foo bar bleep', { + keys: ['subtitle'], threshold: 0, }); @@ -61,11 +61,11 @@ test("exact match by single key", (t) => { t.deepEqual(matches[0], t.context.items[1]); }); -test("exact match multiple keys", (t) => { +test('exact match multiple keys', (t) => { const h = hugo(); - const matches = h.match(t.context.items, "foo", { - keys: ["title", "subtitle"], + const matches = h.match(t.context.items, 'foo', { + keys: ['title', 'subtitle'], }); t.true(Array.isArray(matches)); @@ -73,10 +73,10 @@ test("exact match multiple keys", (t) => { t.snapshot(matches); }); -test("no matches", (t) => { +test('no matches', (t) => { const h = hugo(); - const matches = h.match(t.context.items, "nope", { + const matches = h.match(t.context.items, 'nope', { threshold: 0, }); @@ -84,10 +84,10 @@ test("no matches", (t) => { t.is(matches.length, 0); }); -test("no query should return all items", (t) => { +test('no query should return all items', (t) => { const h = hugo(); - const matches = h.match(t.context.items, ""); + const matches = h.match(t.context.items, ''); t.true(Array.isArray(matches)); t.is(matches.length, 5); diff --git a/test/meta/alfred.ts b/test/meta/alfred.ts index 3f69d96..c26bcd6 100644 --- a/test/meta/alfred.ts +++ b/test/meta/alfred.ts @@ -1,116 +1,116 @@ -import test from "ava"; -import fs from "fs-extra"; -import path from "path"; -import sinon from "sinon"; +import test from 'ava'; +import fs from 'fs-extra'; +import path from 'path'; +import sinon from 'sinon'; -import { hugo } from "../helpers/init"; +import { hugo } from '../helpers/init'; const backupConsoleError = console.error; -test.serial("valid version", (t) => { +test.serial('valid version', (t) => { const h = hugo(); - process.env.alfred_version = "3.0.0"; + process.env.alfred_version = '3.0.0'; // Check version number - t.is(typeof h.alfredMeta, "object"); - t.is(h.alfredMeta.version, "3.0.0"); + t.is(typeof h.alfredMeta, 'object'); + t.is(h.alfredMeta.version, '3.0.0'); }); -test.serial("single digit version", (t) => { +test.serial('single digit version', (t) => { const h = hugo(); - process.env.alfred_version = "3"; + process.env.alfred_version = '3'; // Check version number - t.is(typeof h.alfredMeta, "object"); - t.is(h.alfredMeta.version, "3.0.0"); + t.is(typeof h.alfredMeta, 'object'); + t.is(h.alfredMeta.version, '3.0.0'); }); -test.serial("two digit version", (t) => { +test.serial('two digit version', (t) => { const h = hugo(); - process.env.alfred_version = "3.0"; + process.env.alfred_version = '3.0'; // Check version number - t.is(typeof h.alfredMeta, "object"); - t.is(h.alfredMeta.version, "3.0.0"); + t.is(typeof h.alfredMeta, 'object'); + t.is(h.alfredMeta.version, '3.0.0'); }); -test.serial("no version", (t) => { - const consoleStub = sinon.stub(console, "error"); +test.serial('no version', (t) => { + const consoleStub = sinon.stub(console, 'error'); const h = hugo(); - process.env.alfred_debug = "0"; + process.env.alfred_debug = '0'; delete process.env.alfred_version; // Check version number - t.is(typeof h.alfredMeta, "object"); + t.is(typeof h.alfredMeta, 'object'); t.falsy(h.alfredMeta.version); t.false(consoleStub.called); // Check if debug message is output - process.env.alfred_debug = "1"; + process.env.alfred_debug = '1'; - t.is(typeof h.alfredMeta, "object"); + t.is(typeof h.alfredMeta, 'object'); t.falsy(h.alfredMeta.version); - t.true(consoleStub.calledWith("Invalid Alfred version: undefined")); + t.true(consoleStub.calledWith('Invalid Alfred version: undefined')); }); -test.serial("invalid version", (t) => { - const consoleStub = sinon.stub(console, "error"); +test.serial('invalid version', (t) => { + const consoleStub = sinon.stub(console, 'error'); const h = hugo(); - process.env.alfred_debug = "0"; - process.env.alfred_version = "foobar"; + process.env.alfred_debug = '0'; + process.env.alfred_version = 'foobar'; // Check version number - t.is(typeof h.alfredMeta, "object"); + t.is(typeof h.alfredMeta, 'object'); t.falsy(h.alfredMeta.version); t.false(consoleStub.called); // Check if debug message is output - process.env.alfred_debug = "1"; + process.env.alfred_debug = '1'; - t.is(typeof h.alfredMeta, "object"); + t.is(typeof h.alfredMeta, 'object'); t.falsy(h.alfredMeta.version); - t.true(consoleStub.calledWith("Invalid Alfred version: foobar")); + t.true(consoleStub.calledWith('Invalid Alfred version: foobar')); }); -test.serial("existing theme", (t) => { +test.serial('existing theme', (t) => { const h = hugo(); - process.env.alfred_theme = "foo"; + process.env.alfred_theme = 'foo'; - const themeFilePath = path.resolve(process.env.alfred_preferences, "themes", process.env.alfred_theme, "theme.json"); + const themeFilePath = path.resolve(process.env.alfred_preferences, 'themes', process.env.alfred_theme, 'theme.json'); fs.ensureFileSync(themeFilePath); fs.writeJsonSync(themeFilePath, { alfredtheme: { - foo: "bar", + foo: 'bar', }, }); - t.is(typeof h.alfredMeta, "object"); + t.is(typeof h.alfredMeta, 'object'); t.is(h.alfredMeta.themeFile, themeFilePath); }); -test.serial("non-existing theme", (t) => { - const consoleStub = sinon.stub(console, "error"); +test.serial('non-existing theme', (t) => { + const consoleStub = sinon.stub(console, 'error'); const h = hugo(); // Valid theme name but directory doesn't exist. - process.env.alfred_debug = "0"; - process.env.alfred_theme = "default"; + process.env.alfred_debug = '0'; + process.env.alfred_theme = 'default'; - t.is(typeof h.alfredMeta, "object"); + t.is(typeof h.alfredMeta, 'object'); t.falsy(h.alfredMeta.themeFile); t.false(consoleStub.called); // Check if debug message is output - process.env.alfred_debug = "1"; + process.env.alfred_debug = '1'; - t.is(typeof h.alfredMeta, "object"); + t.is(typeof h.alfredMeta, 'object'); t.falsy(h.alfredMeta.themeFile); t.true(consoleStub.called); t.regex(consoleStub.getCall(0).args[0], /^Could not find theme file /); diff --git a/test/meta/theme.ts b/test/meta/theme.ts index d97fd0d..18cf5e6 100644 --- a/test/meta/theme.ts +++ b/test/meta/theme.ts @@ -1,34 +1,34 @@ -import test from "ava"; -import fs from "fs-extra"; -import path from "path"; +import test from 'ava'; +import fs from 'fs-extra'; +import path from 'path'; -import { hugo } from "../helpers/init"; +import { hugo } from '../helpers/init'; -test.serial("existing theme", (t) => { +test.serial('existing theme', (t) => { const h = hugo(); - process.env.alfred_theme = "foo"; + process.env.alfred_theme = 'foo'; - const themeFilePath = path.resolve(process.env.alfred_preferences, "themes", process.env.alfred_theme, "theme.json"); + const themeFilePath = path.resolve(process.env.alfred_preferences, 'themes', process.env.alfred_theme, 'theme.json'); fs.ensureFileSync(themeFilePath); fs.writeJsonSync(themeFilePath, { alfredtheme: { - foo: "bar", + foo: 'bar', }, }); - t.is(typeof h.alfredTheme, "object"); + t.is(typeof h.alfredTheme, 'object'); t.deepEqual(h.alfredTheme, { - foo: "bar", + foo: 'bar', }); }); -test.serial("non-existing theme", (t) => { +test.serial('non-existing theme', (t) => { const h = hugo(); // Valid theme name but directory doesn't exist. - process.env.alfred_theme = "foo"; + process.env.alfred_theme = 'foo'; t.is(h.alfredTheme, null); }); diff --git a/test/meta/workflow.ts b/test/meta/workflow.ts index e561de0..e44a5b6 100644 --- a/test/meta/workflow.ts +++ b/test/meta/workflow.ts @@ -1,78 +1,78 @@ -import test from "ava"; -import sinon from "sinon"; +import test from 'ava'; +import sinon from 'sinon'; -import { hugo } from "../helpers/init"; +import { hugo } from '../helpers/init'; const backupConsoleError = console.error; -test.serial("valid version", (t) => { +test.serial('valid version', (t) => { const h = hugo(); - process.env.alfred_workflow_version = "3.0.0"; + process.env.alfred_workflow_version = '3.0.0'; // Check version number - t.is(typeof h.workflowMeta, "object"); - t.is(h.workflowMeta.version, "3.0.0"); + t.is(typeof h.workflowMeta, 'object'); + t.is(h.workflowMeta.version, '3.0.0'); }); -test.serial("single digit version", (t) => { +test.serial('single digit version', (t) => { const h = hugo(); - process.env.alfred_workflow_version = "3"; + process.env.alfred_workflow_version = '3'; // Check version number - t.is(typeof h.workflowMeta, "object"); - t.is(h.workflowMeta.version, "3.0.0"); + t.is(typeof h.workflowMeta, 'object'); + t.is(h.workflowMeta.version, '3.0.0'); }); -test.serial("two digit version", (t) => { +test.serial('two digit version', (t) => { const h = hugo(); - process.env.alfred_workflow_version = "3.0"; + process.env.alfred_workflow_version = '3.0'; // Check version number - t.is(typeof h.workflowMeta, "object"); - t.is(h.workflowMeta.version, "3.0.0"); + t.is(typeof h.workflowMeta, 'object'); + t.is(h.workflowMeta.version, '3.0.0'); }); -test.serial("no version", (t) => { - const consoleStub = sinon.stub(console, "error"); +test.serial('no version', (t) => { + const consoleStub = sinon.stub(console, 'error'); const h = hugo(); - process.env.alfred_debug = "0"; + process.env.alfred_debug = '0'; delete process.env.alfred_workflow_version; // Check version number - t.is(typeof h.workflowMeta, "object"); + t.is(typeof h.workflowMeta, 'object'); t.falsy(h.workflowMeta.version); t.false(consoleStub.called); // Check if debug message is output - process.env.alfred_debug = "1"; + process.env.alfred_debug = '1'; - t.is(typeof h.workflowMeta, "object"); + t.is(typeof h.workflowMeta, 'object'); t.falsy(h.workflowMeta.version); - t.true(consoleStub.calledWith(sinon.match("Invalid workflow version: undefined"))); + t.true(consoleStub.calledWith(sinon.match('Invalid workflow version: undefined'))); }); -test.serial("invalid version", (t) => { - const consoleStub = sinon.stub(console, "error"); +test.serial('invalid version', (t) => { + const consoleStub = sinon.stub(console, 'error'); const h = hugo(); - process.env.alfred_debug = "0"; - process.env.alfred_workflow_version = "foobar"; + process.env.alfred_debug = '0'; + process.env.alfred_workflow_version = 'foobar'; // Check version number - t.is(typeof h.workflowMeta, "object"); + t.is(typeof h.workflowMeta, 'object'); t.falsy(h.workflowMeta.version); t.false(consoleStub.called); // Check if debug message is output - process.env.alfred_debug = "1"; + process.env.alfred_debug = '1'; - t.is(typeof h.workflowMeta, "object"); + t.is(typeof h.workflowMeta, 'object'); t.falsy(h.workflowMeta.version); - t.true(consoleStub.calledWith(sinon.match("Invalid workflow version: foobar"))); + t.true(consoleStub.calledWith(sinon.match('Invalid workflow version: foobar'))); }); test.afterEach.always(() => { diff --git a/test/output.ts b/test/output.ts index 12476b5..f211303 100644 --- a/test/output.ts +++ b/test/output.ts @@ -1,98 +1,98 @@ -import test from "ava"; +import test from 'ava'; -import { hugo } from "./helpers/init"; +import { hugo } from './helpers/init'; -test("items only", (t) => { +test('items only', (t) => { const h = hugo(); h.items.push( { - title: "foo", + title: 'foo', }, { - title: "bar", - subtitle: "foo", + title: 'bar', + subtitle: 'foo', }, { - title: "boop", - subtitle: "bleep", + title: 'boop', + subtitle: 'bleep', }, ); t.snapshot(h.output); }); -test("variables only", (t) => { +test('variables only', (t) => { const h = hugo(); h.variables = { - bleep: "bloop", + bleep: 'bloop', boop: { - tap: "top", + tap: 'top', }, }; t.snapshot(h.output); }); -test("variables and items combined", (t) => { +test('variables and items combined', (t) => { const h = hugo(); - h.variables.foo = "bar"; + h.variables.foo = 'bar'; h.items.push({ - title: "foo", + title: 'foo', }); t.snapshot(h.output); }); -test("items with variables", (t) => { +test('items with variables', (t) => { const h = hugo(); h.items.push( { - title: "Test 1", + title: 'Test 1', variables: { - foo: "bar", + foo: 'bar', }, }, { - title: "Test 2", - arg: "foobar", + title: 'Test 2', + arg: 'foobar', variables: { - bar: "foo", + bar: 'foo', }, }, ); h.variables = { - bloop: "bleep", - flooble: "flab", - flabby: "flop", + bloop: 'bleep', + flooble: 'flab', + flabby: 'flop', }; t.snapshot(h.output); }); -test("rerun parameter", (t) => { +test('rerun parameter', (t) => { const h = hugo(); h.rerun = 1.4; - h.variables.foo = "bar"; + h.variables.foo = 'bar'; h.items.push({ - title: "foo", + title: 'foo', }); t.snapshot(h.output); }); -test("invalid rerun parameter", (t) => { +test('invalid rerun parameter', (t) => { const h = hugo(); h.rerun = 10.5; - h.variables.foo = "bar"; + h.variables.foo = 'bar'; h.items.push({ - title: "foo", + title: 'foo', }); try { diff --git a/test/updates/npm.ts b/test/updates/npm.ts index 5df1c9f..135addc 100644 --- a/test/updates/npm.ts +++ b/test/updates/npm.ts @@ -1,13 +1,13 @@ -import Test, { TestInterface } from "ava"; -import semver from "semver"; -import nock from "nock"; -import readPkg from "read-pkg-up"; +import Test, { TestInterface } from 'ava'; +import semver from 'semver'; +import nock from 'nock'; +import readPkg from 'read-pkg-up'; -import { UpdateSource } from "../../src"; +import { UpdateSource } from '../../src'; -import { updater, hugo } from "../helpers/init"; -import { TestContext } from "../helpers/types"; -import * as mock from "../helpers/mock"; +import { updater, hugo } from '../helpers/init'; +import { TestContext } from '../helpers/types'; +import * as mock from '../helpers/mock'; const test = Test as TestInterface; @@ -15,13 +15,13 @@ test.beforeEach(() => { mock.date(); }); -test.serial("check with valid update source NPM", async (t) => { +test.serial('check with valid update source NPM', async (t) => { // Mock requests mock.npm(5); await t.notThrowsAsync(async () => { const h = hugo({ - updateSource: "npm", + updateSource: 'npm', updateNotification: false, }); @@ -30,7 +30,7 @@ test.serial("check with valid update source NPM", async (t) => { await t.notThrowsAsync(async () => { const h = hugo({ - updateSource: "NPM", + updateSource: 'NPM', updateNotification: false, }); @@ -47,15 +47,15 @@ test.serial("check with valid update source NPM", async (t) => { }); await t.notThrowsAsync(async () => { - return updater().checkUpdates("npm"); + return updater().checkUpdates('npm'); }); await t.notThrowsAsync(async () => { - return updater().checkUpdates("NPM"); + return updater().checkUpdates('NPM'); }); }); -test.serial("check for updates uncached", async (t) => { +test.serial('check for updates uncached', async (t) => { const u = updater(); // Mock request @@ -64,43 +64,43 @@ test.serial("check for updates uncached", async (t) => { // Package const pkg = readPkg.sync().packageJson; - const update = await u.checkUpdates("npm"); + const update = await u.checkUpdates('npm'); if (!update) { - t.fail("Update is undefined or false."); + t.fail('Update is undefined or false.'); return; } - t.is(update.version, semver.parse(pkg.version).inc("major").toString()); + t.is(update.version, semver.parse(pkg.version).inc('major').toString()); t.is(update.url, `https://www.npmjs.com/package/${pkg.name}`); t.true(update.checkedOnline); }); -test.serial("check for updates uncached with custom package.json", async (t) => { +test.serial('check for updates uncached with custom package.json', async (t) => { const u = updater(); // Package const pkg = { - name: "alfred-my-workflow", - version: "1.0.0", + name: 'alfred-my-workflow', + version: '1.0.0', }; // Mock request mock.npm(1, pkg); - const update = await u.checkUpdates("npm", pkg); + const update = await u.checkUpdates('npm', pkg); if (!update) { - t.fail("Update is undefined or false."); + t.fail('Update is undefined or false.'); return; } - t.is(update.version, "2.0.0"); + t.is(update.version, '2.0.0'); t.is(update.url, `https://www.npmjs.com/package/${pkg.name}`); t.true(update.checkedOnline); }); -test.serial("check for updates cached", async (t) => { +test.serial('check for updates cached', async (t) => { const u = updater(); // Mock requests @@ -110,76 +110,76 @@ test.serial("check for updates cached", async (t) => { const pkg = readPkg.sync().packageJson; // Check for updates - let update = await u.checkUpdates("npm"); + let update = await u.checkUpdates('npm'); if (!update) { - t.fail("Update is undefined or false."); + t.fail('Update is undefined or false.'); return; } - t.is(update.version, semver.parse(pkg.version).inc("major").toString()); + t.is(update.version, semver.parse(pkg.version).inc('major').toString()); t.is(update.url, `https://www.npmjs.com/package/${pkg.name}`); t.true(update.checkedOnline); // Forward time - mock.forwardTime(30, "minutes"); + mock.forwardTime(30, 'minutes'); // Check for updates again, should be cached. - update = await u.checkUpdates("npm"); + update = await u.checkUpdates('npm'); if (!update) { - t.fail("Update is undefined or false."); + t.fail('Update is undefined or false.'); return; } t.false(update.checkedOnline); // Forward time - mock.forwardTime(30, "minutes"); + mock.forwardTime(30, 'minutes'); // Check for updates again, should be checked online - update = await u.checkUpdates("npm"); + update = await u.checkUpdates('npm'); if (!update) { - t.fail("Update is undefined or false."); + t.fail('Update is undefined or false.'); return; } t.true(update.checkedOnline); }); -test.serial("check for updates cached with custom package.json", async (t) => { +test.serial('check for updates cached with custom package.json', async (t) => { const u = updater(); const pkg = { - name: "alfred-my-workflow", - version: "1.0.0", + name: 'alfred-my-workflow', + version: '1.0.0', }; // Mock requests mock.npm(2, pkg); // Check for updates - let update = await u.checkUpdates("npm", pkg); + let update = await u.checkUpdates('npm', pkg); if (!update) { - t.fail("Update is undefined or false."); + t.fail('Update is undefined or false.'); return; } - t.is(update.version, "2.0.0"); + t.is(update.version, '2.0.0'); t.is(update.url, `https://www.npmjs.com/package/${pkg.name}`); t.true(update.checkedOnline); t.is(nock.pendingMocks().length, 1); // Forward time - mock.forwardTime(30, "minutes"); + mock.forwardTime(30, 'minutes'); // Check for updates again, should be cached. - update = await u.checkUpdates("npm", pkg); + update = await u.checkUpdates('npm', pkg); if (!update) { - t.fail("Update is undefined or false."); + t.fail('Update is undefined or false.'); return; } @@ -187,40 +187,40 @@ test.serial("check for updates cached with custom package.json", async (t) => { t.is(nock.pendingMocks().length, 1); // Forward time - mock.forwardTime(30, "minutes"); + mock.forwardTime(30, 'minutes'); // Check for updates again, should be checked online - update = await u.checkUpdates("npm", pkg); + update = await u.checkUpdates('npm', pkg); if (!update) { - t.fail("Update is undefined or false."); + t.fail('Update is undefined or false.'); return; } t.true(update.checkedOnline); }); -test("check for updates with no package name set", async (t) => { +test('check for updates with no package name set', async (t) => { const u = updater(); await t.throwsAsync(async () => { - return u.checkUpdates("npm", { - version: "1.0.0", + return u.checkUpdates('npm', { + version: '1.0.0', }); - }, {instanceOf: Error, message: "Invalid package.json."}); + }, {instanceOf: Error, message: 'Invalid package.json.'}); }); -test("check for updates with no package version set", async (t) => { +test('check for updates with no package version set', async (t) => { const u = updater(); await t.throwsAsync(async () => { - return u.checkUpdates("npm", { - name: "alfred-my-workflow", + return u.checkUpdates('npm', { + name: 'alfred-my-workflow', }); - }, {instanceOf: Error, message: "Invalid package.json."}); + }, {instanceOf: Error, message: 'Invalid package.json.'}); }); -test.serial("check for updates with unpublished package", async (t) => { +test.serial('check for updates with unpublished package', async (t) => { const u = updater(); const pkg = readPkg.sync().packageJson; @@ -228,87 +228,87 @@ test.serial("check for updates with unpublished package", async (t) => { // Mock request mock.npm(1, pkg, 404); - const update = await u.checkUpdates("npm"); + const update = await u.checkUpdates('npm'); - t.is(typeof update, "undefined"); + t.is(typeof update, 'undefined'); }); -test.serial("check for updates with unpublished package from custom package.json", async (t) => { +test.serial('check for updates with unpublished package from custom package.json', async (t) => { const u = updater(); const pkg = { - name: "alfred-my-workflow", - version: "1.0.0", + name: 'alfred-my-workflow', + version: '1.0.0', }; // Mock request mock.npm(1, pkg, 404); - const update = await u.checkUpdates("npm", pkg); + const update = await u.checkUpdates('npm', pkg); - t.is(typeof update, "undefined"); + t.is(typeof update, 'undefined'); }); -test.serial("check for updates with package without latest dist-tag", async (t) => { +test.serial('check for updates with package without latest dist-tag', async (t) => { const u = updater(); const pkg = readPkg.sync().packageJson; // Mock request - nock("https://registry.npmjs.org") - .get("/" + pkg.name) + nock('https://registry.npmjs.org') + .get('/' + pkg.name) .reply(200, JSON.stringify({ - "name": pkg.name, - "dist-tags": {}, - "versions": { - "1.0.0": { + 'name': pkg.name, + 'dist-tags': {}, + 'versions': { + '1.0.0': { name: pkg.name, - version: "1.0.0", + version: '1.0.0', }, - "2.0.0": { + '2.0.0': { name: pkg.name, - version: "2.0.0", + version: '2.0.0', }, }, })); await t.throwsAsync(async () => { - return u.checkUpdates("npm"); - }, {instanceOf: Error, message: "No latest version found in response."}); + return u.checkUpdates('npm'); + }, {instanceOf: Error, message: 'No latest version found in response.'}); }); -test.serial("check for updates with package without latest dist-tag from custom package.json", async (t) => { +test.serial('check for updates with package without latest dist-tag from custom package.json', async (t) => { const u = updater(); const pkg = { - name: "alfred-my-workflow", - version: "1.0.0", + name: 'alfred-my-workflow', + version: '1.0.0', }; // Mock request mock.npm(1, pkg, 200, null); await t.throwsAsync(async () => { - return u.checkUpdates("npm", pkg); - }, {instanceOf: Error, message: "No latest version found in response."}); + return u.checkUpdates('npm', pkg); + }, {instanceOf: Error, message: 'No latest version found in response.'}); }); -test.serial("check for updates when invalid version is returned", async (t) => { +test.serial('check for updates when invalid version is returned', async (t) => { const u = updater(); const pkg = readPkg.sync().packageJson; // Mock request - mock.npm(1, pkg, 200, "foobar"); + mock.npm(1, pkg, 200, 'foobar'); await t.throwsAsync(async () => { - return u.checkUpdates("npm"); - }, {instanceOf: Error, message: "Invalid version in response."}); + return u.checkUpdates('npm'); + }, {instanceOf: Error, message: 'Invalid version in response.'}); }); test.afterEach((t) => { if (!nock.isDone()) { - t.fail("Not all requests were performed."); + t.fail('Not all requests were performed.'); } }); diff --git a/test/updates/packal.ts b/test/updates/packal.ts index 9d32eca..1d75c2d 100644 --- a/test/updates/packal.ts +++ b/test/updates/packal.ts @@ -1,22 +1,22 @@ -import test from "ava"; -import nock from "nock"; +import test from 'ava'; +import nock from 'nock'; -import { UpdateSource } from "../../src"; +import { UpdateSource } from '../../src'; -import { updater, hugo } from "../helpers/init"; -import * as mock from "../helpers/mock"; +import { updater, hugo } from '../helpers/init'; +import * as mock from '../helpers/mock'; test.beforeEach(() => { mock.date(); }); -test.serial("check with valid update source Packal", async (t) => { +test.serial('check with valid update source Packal', async (t) => { // Mock requests mock.packal(5); await t.notThrowsAsync(async () => { const h = hugo({ - updateSource: "packal", + updateSource: 'packal', updateNotification: false, }); @@ -25,7 +25,7 @@ test.serial("check with valid update source Packal", async (t) => { await t.notThrowsAsync(async () => { const h = hugo({ - updateSource: "Packal", + updateSource: 'Packal', updateNotification: false, }); @@ -42,59 +42,59 @@ test.serial("check with valid update source Packal", async (t) => { }); await t.notThrowsAsync(async () => { - return updater().checkUpdates("packal"); + return updater().checkUpdates('packal'); }); await t.notThrowsAsync(async () => { - return updater().checkUpdates("Packal"); + return updater().checkUpdates('Packal'); }); }); -test.serial("check for updates uncached", async (t) => { +test.serial('check for updates uncached', async (t) => { const u = updater(); // Mock request mock.packal(1); - const update = await u.checkUpdates("packal"); + const update = await u.checkUpdates('packal'); if (!update) { - t.fail("Update is undefined or false."); + t.fail('Update is undefined or false.'); return; } - t.is(update.version, "2.0.0"); + t.is(update.version, '2.0.0'); t.regex(update.url, /^https:\/\/encrypted\.google\.com\//); t.regex(update.url, /my\.work\.flow/); t.true(update.checkedOnline); }); -test.serial("check for updates cached", async (t) => { +test.serial('check for updates cached', async (t) => { const u = updater(); mock.packal(2); - let update = await u.checkUpdates("packal"); + let update = await u.checkUpdates('packal'); if (!update) { - t.fail("Update is undefined or false."); + t.fail('Update is undefined or false.'); return; } - t.is(update.version, "2.0.0"); + t.is(update.version, '2.0.0'); t.regex(update.url, /^https:\/\/encrypted\.google\.com\//); t.regex(update.url, /my\.work\.flow/); t.true(update.checkedOnline); t.is(nock.pendingMocks().length, 1); // Forward time - mock.forwardTime(30, "minutes"); + mock.forwardTime(30, 'minutes'); // Check for updates again, should be cached. - update = await u.checkUpdates("packal"); + update = await u.checkUpdates('packal'); if (!update) { - t.fail("Update is undefined or false."); + t.fail('Update is undefined or false.'); return; } @@ -102,64 +102,64 @@ test.serial("check for updates cached", async (t) => { t.is(nock.pendingMocks().length, 1); // Forward time - mock.forwardTime(30, "minutes"); + mock.forwardTime(30, 'minutes'); // Check for updates again, should be checked online - update = await u.checkUpdates("packal"); + update = await u.checkUpdates('packal'); if (!update) { - t.fail("Update is undefined or false."); + t.fail('Update is undefined or false.'); return; } t.true(update.checkedOnline); }); -test.serial("check for updates with no bundle id set", async (t) => { +test.serial('check for updates with no bundle id set', async (t) => { const u = updater(); await t.throwsAsync(async () => { process.env.alfred_workflow_bundleid = undefined; delete process.env.alfred_workflow_bundleid; - return u.checkUpdates("packal"); - }, {instanceOf: Error, message: "No bundle ID, not checking Packal for updates."}); + return u.checkUpdates('packal'); + }, {instanceOf: Error, message: 'No bundle ID, not checking Packal for updates.'}); }); -test.serial("check for updates when no version is returned", async (t) => { +test.serial('check for updates when no version is returned', async (t) => { const u = updater(); - mock.packal(1, 200, "appcast-noversion.xml"); + mock.packal(1, 200, 'appcast-noversion.xml'); await t.throwsAsync(async () => { - return u.checkUpdates("packal"); - }, {instanceOf: Error, message: "No version found."}); + return u.checkUpdates('packal'); + }, {instanceOf: Error, message: 'No version found.'}); }); -test.serial("check for updates when invalid version is returned", async (t) => { +test.serial('check for updates when invalid version is returned', async (t) => { const u = updater(); - mock.packal(1, 200, "appcast-invalidversion.xml"); + mock.packal(1, 200, 'appcast-invalidversion.xml'); await t.throwsAsync(async () => { - return u.checkUpdates("packal"); - }, {instanceOf: Error, message: "Invalid version in response."}); + return u.checkUpdates('packal'); + }, {instanceOf: Error, message: 'Invalid version in response.'}); }); -test.serial("check for updates with unpublished workflow", async (t) => { +test.serial('check for updates with unpublished workflow', async (t) => { const u = updater(); // Mock request mock.packal(1, 404); - const update = await u.checkUpdates("packal"); + const update = await u.checkUpdates('packal'); - t.is(typeof update, "undefined"); + t.is(typeof update, 'undefined'); }); test.afterEach((t) => { if (!nock.isDone()) { - t.fail("Not all requests were performed."); + t.fail('Not all requests were performed.'); } }); diff --git a/test/updates/updater.ts b/test/updates/updater.ts index 4ee5eeb..6c09e4f 100644 --- a/test/updates/updater.ts +++ b/test/updates/updater.ts @@ -1,10 +1,10 @@ -import test from "ava"; -import sinon from "sinon"; -import moment from "moment"; -import nock from "nock"; +import test from 'ava'; +import sinon from 'sinon'; +import moment from 'moment'; +import nock from 'nock'; -import { hugo, updater } from "../helpers/init"; -import * as mock from "../helpers/mock"; +import { hugo, updater } from '../helpers/init'; +import * as mock from '../helpers/mock'; const backupConsoleError = console.error; @@ -12,25 +12,25 @@ test.beforeEach(() => { mock.date(); }); -test("check with invalid update source as string", async (t) => { +test('check with invalid update source as string', async (t) => { t.throws(() => { hugo({ - updateSource: "foobar", + updateSource: 'foobar', }); - }, {instanceOf: Error, message: "Invalid update source."}); + }, {instanceOf: Error, message: 'Invalid update source.'}); await t.throwsAsync(async () => { - return updater().checkUpdates("foobar"); - }, {instanceOf: Error, message: "Invalid update source."}); + return updater().checkUpdates('foobar'); + }, {instanceOf: Error, message: 'Invalid update source.'}); }); -test.serial("check update with no new updates", async (t) => { +test.serial('check update with no new updates', async (t) => { const h = hugo({ - updateSource: "packal", + updateSource: 'packal', }); // Ensure that no new version exists - process.env.alfred_workflow_version = "3.0.0"; + process.env.alfred_workflow_version = '3.0.0'; // Mock request mock.packal(1); @@ -43,13 +43,13 @@ test.serial("check update with no new updates", async (t) => { t.is(h.output.items.length, 0); }); -test.serial("update notification only when checked online", async (t) => { +test.serial('update notification only when checked online', async (t) => { const h = hugo({ - updateSource: "packal", + updateSource: 'packal', updateItem: false, }); - const notifyStub = sinon.stub(h, "notify"); + const notifyStub = sinon.stub(h, 'notify'); // Mock request mock.packal(1); @@ -68,13 +68,13 @@ test.serial("update notification only when checked online", async (t) => { t.is(h.items.length, 0); }); -test.serial("update item only", async (t) => { +test.serial('update item only', async (t) => { const h = hugo({ - updateSource: "packal", + updateSource: 'packal', updateNotification: false, }); - const notifyStub = sinon.stub(h, "notify"); + const notifyStub = sinon.stub(h, 'notify'); // Mock request mock.packal(1); @@ -98,9 +98,9 @@ test.serial("update item only", async (t) => { t.snapshot(item); }); -test.serial("check update item", async (t) => { +test.serial('check update item', async (t) => { const h = hugo({ - updateSource: "packal", + updateSource: 'packal', updateNotification: false, }); @@ -120,28 +120,28 @@ test.serial("check update item", async (t) => { t.snapshot(item); }); -test.serial("check for unpublished workflow twice within interval", async (t) => { +test.serial('check for unpublished workflow twice within interval', async (t) => { const u = updater(); // Mock request mock.packal(1, 404); // Check for update - let update = await u.checkUpdates("packal"); + let update = await u.checkUpdates('packal'); - t.is(typeof update, "undefined"); + t.is(typeof update, 'undefined'); t.true(nock.isDone()); // Check for update the second time shortly after. No request should be made. - update = await u.checkUpdates("packal"); + update = await u.checkUpdates('packal'); - t.is(typeof update, "undefined"); + t.is(typeof update, 'undefined'); }); -test.serial("check for updates with updates disabled", async (t) => { +test.serial('check for updates with updates disabled', async (t) => { const h = hugo({ checkUpdates: false, - updateSource: "npm", + updateSource: 'npm', }); // Mock request @@ -155,11 +155,11 @@ test.serial("check for updates with updates disabled", async (t) => { nock.cleanAll(); }); -test.serial("check for updates with update notification and item disabled", async (t) => { +test.serial('check for updates with update notification and item disabled', async (t) => { const h = hugo({ updateNotification: false, updateItem: false, - updateSource: "npm", + updateSource: 'npm', }); // Mock request @@ -173,10 +173,10 @@ test.serial("check for updates with update notification and item disabled", asyn nock.cleanAll(); }); -test.serial("check for updates with updateInterval undefined", async (t) => { +test.serial('check for updates with updateInterval undefined', async (t) => { const h = hugo({ updateInterval: undefined, - updateSource: "npm", + updateSource: 'npm', }); // Mock request @@ -190,10 +190,10 @@ test.serial("check for updates with updateInterval undefined", async (t) => { nock.cleanAll(); }); -test.serial("check for updates with updateInterval under one second", async (t) => { +test.serial('check for updates with updateInterval under one second', async (t) => { const h = hugo({ - updateInterval: moment.duration(1, "milliseconds"), - updateSource: "npm", + updateInterval: moment.duration(1, 'milliseconds'), + updateSource: 'npm', }); // Mock request @@ -207,12 +207,12 @@ test.serial("check for updates with updateInterval under one second", async (t) nock.cleanAll(); }); -test.serial("check for updates with invalid workflow version", async (t) => { +test.serial('check for updates with invalid workflow version', async (t) => { const h = hugo({ - updateSource: "packal", + updateSource: 'packal', }); - process.env.alfred_workflow_version = "foobar"; + process.env.alfred_workflow_version = 'foobar'; // Mock request mock.packal(1); @@ -223,9 +223,9 @@ test.serial("check for updates with invalid workflow version", async (t) => { t.true(nock.isDone()); }); -test.serial("check for updates with updates with unpublished package", async (t) => { +test.serial('check for updates with updates with unpublished package', async (t) => { const h = hugo({ - updateSource: "packal", + updateSource: 'packal', }); // Mock request @@ -237,11 +237,11 @@ test.serial("check for updates with updates with unpublished package", async (t) t.true(nock.isDone()); }); -test.serial("check for updates with updates when exception occurs", async (t) => { - const consoleStub = sinon.stub(console, "error"); +test.serial('check for updates with updates when exception occurs', async (t) => { + const consoleStub = sinon.stub(console, 'error'); const h = hugo({ - updateSource: "packal", + updateSource: 'packal', }); // Mock request @@ -257,18 +257,18 @@ test.serial("check for updates with updates when exception occurs", async (t) => h.cache.clear(); // Check if debug message is output - process.env.alfred_debug = "1"; + process.env.alfred_debug = '1'; update = await h.checkUpdates(); t.falsy(update); t.true(nock.isDone()); - t.true(consoleStub.calledWith("Request failed with status code 500")); + t.true(consoleStub.calledWith('Request failed with status code 500')); }); test.afterEach((t) => { if (!nock.isDone()) { - t.fail("Not all requests were performed."); + t.fail('Not all requests were performed.'); } }); diff --git a/test/utils.ts b/test/utils.ts index caeb055..cfde504 100644 --- a/test/utils.ts +++ b/test/utils.ts @@ -1,55 +1,55 @@ -import test from "ava"; -import os from "os"; -import path from "path"; -import fs from "fs-extra"; -import crypto from "crypto"; -import sinon from "sinon"; -import bplist from "bplist-creator"; -import semver from "semver"; +import test from 'ava'; +import os from 'os'; +import path from 'path'; +import fs from 'fs-extra'; +import crypto from 'crypto'; +import sinon from 'sinon'; +import bplist from 'bplist-creator'; +import semver from 'semver'; // Stub home directory -const homeDir = path.resolve("build", "cache", crypto.randomBytes(8).toString("hex")); -sinon.stub(os, "homedir").returns(homeDir); +const homeDir = path.resolve('build', 'cache', crypto.randomBytes(8).toString('hex')); +sinon.stub(os, 'homedir').returns(homeDir); -import utils from "../src/utils"; +import utils from '../src/utils'; -test.serial("resolve alfred 3 preferences", (t) => { +test.serial('resolve alfred 3 preferences', (t) => { // Write new binary plist const plist = bplist({}); // Write file to expected path - const plistPath = path.join(homeDir, "/Library/Preferences/com.runningwithcrayons.Alfred-Preferences-3.plist"); + const plistPath = path.join(homeDir, '/Library/Preferences/com.runningwithcrayons.Alfred-Preferences-3.plist'); fs.ensureFileSync(plistPath); fs.writeFileSync(plistPath, plist); // Resolve preferences file - const p = utils.resolveAlfredPrefs("3.0.0"); - const pSemver = utils.resolveAlfredPrefs(semver.parse("3.0.0")); + const p = utils.resolveAlfredPrefs('3.0.0'); + const pSemver = utils.resolveAlfredPrefs(semver.parse('3.0.0')); - t.is(p, path.join(homeDir, "Library/Application Support/Alfred 3/Alfred.alfredpreferences")); + t.is(p, path.join(homeDir, 'Library/Application Support/Alfred 3/Alfred.alfredpreferences')); t.is(pSemver, p); }); -test.serial("resolve alfred 4 preferences", (t) => { +test.serial('resolve alfred 4 preferences', (t) => { // Write new binary plist const plist = bplist({}); // Write file to expected path - const plistPath = path.join(homeDir, "/Library/Preferences/com.runningwithcrayons.Alfred-Preferences.plist"); + const plistPath = path.join(homeDir, '/Library/Preferences/com.runningwithcrayons.Alfred-Preferences.plist'); fs.ensureFileSync(plistPath); fs.writeFileSync(plistPath, plist); // Resolve preferences file - const p = utils.resolveAlfredPrefs("4.0.0"); - const pSemver = utils.resolveAlfredPrefs(semver.parse("4.0.0")); + const p = utils.resolveAlfredPrefs('4.0.0'); + const pSemver = utils.resolveAlfredPrefs(semver.parse('4.0.0')); - t.is(p, path.join(homeDir, "Library/Application Support/Alfred/Alfred.alfredpreferences")); + t.is(p, path.join(homeDir, 'Library/Application Support/Alfred/Alfred.alfredpreferences')); t.is(pSemver, p); }); -test.serial("resolve randomly versioned preferences", (t) => { +test.serial('resolve randomly versioned preferences', (t) => { // Write new binary plist const plist = bplist({}); @@ -72,13 +72,13 @@ test.serial("resolve randomly versioned preferences", (t) => { t.is(pSemver, p); }); -test.serial("prefer unversioned preferences over versioned preferences", (t) => { +test.serial('prefer unversioned preferences over versioned preferences', (t) => { // Write new binary plist const plist = bplist({}); // Write file to expected path - const plist3Path = path.join(homeDir, "/Library/Preferences/com.runningwithcrayons.Alfred-Preferences-3.plist"); - const plist4Path = path.join(homeDir, "/Library/Preferences/com.runningwithcrayons.Alfred-Preferences.plist"); + const plist3Path = path.join(homeDir, '/Library/Preferences/com.runningwithcrayons.Alfred-Preferences-3.plist'); + const plist4Path = path.join(homeDir, '/Library/Preferences/com.runningwithcrayons.Alfred-Preferences.plist'); fs.ensureFileSync(plist3Path); fs.writeFileSync(plist3Path, plist); @@ -87,57 +87,57 @@ test.serial("prefer unversioned preferences over versioned preferences", (t) => fs.writeFileSync(plist4Path, plist); // Resolve preferences file - const p = utils.resolveAlfredPrefs("4.0.0"); - const pSemver = utils.resolveAlfredPrefs(semver.parse("4.0.0")); + const p = utils.resolveAlfredPrefs('4.0.0'); + const pSemver = utils.resolveAlfredPrefs(semver.parse('4.0.0')); - t.is(p, path.join(homeDir, "Library/Application Support/Alfred/Alfred.alfredpreferences")); + t.is(p, path.join(homeDir, 'Library/Application Support/Alfred/Alfred.alfredpreferences')); t.is(pSemver, p); }); -test.serial("resolve synced alfred 3 preferences", (t) => { +test.serial('resolve synced alfred 3 preferences', (t) => { // Write new binary plist const plist = bplist({ - syncfolder: "~/Dropbox", + syncfolder: '~/Dropbox', }); // Write file to expected path - const plistPath = path.join(homeDir, "/Library/Preferences/com.runningwithcrayons.Alfred-Preferences-3.plist"); + const plistPath = path.join(homeDir, '/Library/Preferences/com.runningwithcrayons.Alfred-Preferences-3.plist'); fs.ensureFileSync(plistPath); fs.writeFileSync(plistPath, plist); // Resolve preferences file - const p = utils.resolveAlfredPrefs("3.0.0"); - const pSemver = utils.resolveAlfredPrefs(semver.parse("3.0.0")); + const p = utils.resolveAlfredPrefs('3.0.0'); + const pSemver = utils.resolveAlfredPrefs(semver.parse('3.0.0')); - t.is(p, path.join(homeDir, "Dropbox/Alfred.alfredpreferences")); + t.is(p, path.join(homeDir, 'Dropbox/Alfred.alfredpreferences')); t.is(pSemver, p); }); -test("resolve synced alfred 4 preferences", (t) => { +test('resolve synced alfred 4 preferences', (t) => { // Write new binary plist const plist = bplist({ - syncfolder: "~/Dropbox", + syncfolder: '~/Dropbox', }); // Write file to expected path - const plistPath = path.join(homeDir, "/Library/Preferences/com.runningwithcrayons.Alfred-Preferences.plist"); + const plistPath = path.join(homeDir, '/Library/Preferences/com.runningwithcrayons.Alfred-Preferences.plist'); fs.ensureFileSync(plistPath); fs.writeFileSync(plistPath, plist); // Resolve preferences file - const p = utils.resolveAlfredPrefs("4.0.0"); - const pSemver = utils.resolveAlfredPrefs(semver.parse("4.0.0")); + const p = utils.resolveAlfredPrefs('4.0.0'); + const pSemver = utils.resolveAlfredPrefs(semver.parse('4.0.0')); - t.is(p, path.join(homeDir, "Dropbox/Alfred.alfredpreferences")); + t.is(p, path.join(homeDir, 'Dropbox/Alfred.alfredpreferences')); t.is(pSemver, p); }); -test.serial("resolve randomly versioned synced preferences", (t) => { +test.serial('resolve randomly versioned synced preferences', (t) => { // Write new binary plist const plist = bplist({ - syncfolder: "~/Dropbox", + syncfolder: '~/Dropbox', }); const major = Math.floor(Math.random() * (15 - 5)) + 5; @@ -155,27 +155,27 @@ test.serial("resolve randomly versioned synced preferences", (t) => { const p = utils.resolveAlfredPrefs(version); const pSemver = utils.resolveAlfredPrefs(semver.parse(version)); - t.is(p, path.join(homeDir, "Dropbox/Alfred.alfredpreferences")); + t.is(p, path.join(homeDir, 'Dropbox/Alfred.alfredpreferences')); t.is(pSemver, p); }); -test.serial("resolve non-existing alfred 3 preferences", (t) => { +test.serial('resolve non-existing alfred 3 preferences', (t) => { // Write new binary plist const plist = bplist({}); // Write alfred 4 preferences file - const plistPath = path.join(homeDir, "/Library/Preferences/com.runningwithcrayons.Alfred-Preferences.plist"); + const plistPath = path.join(homeDir, '/Library/Preferences/com.runningwithcrayons.Alfred-Preferences.plist'); fs.ensureFileSync(plistPath); fs.writeFileSync(plistPath, plist); // Resolve preferences file for alfred 3 t.throws(() => { - utils.resolveAlfredPrefs("3.0.0"); + utils.resolveAlfredPrefs('3.0.0'); }); t.throws(() => { - utils.resolveAlfredPrefs(semver.parse("3.0.0")); + utils.resolveAlfredPrefs(semver.parse('3.0.0')); }); }); From 7a5bad357e1ca8b6789ca15a79c31b3b90a553d7 Mon Sep 17 00:00:00 2001 From: Maarten de Boer Date: Sat, 21 Mar 2020 20:20:29 +0100 Subject: [PATCH 04/13] =?UTF-8?q?=E2=AC=86=EF=B8=8F=20Update=20dependencie?= =?UTF-8?q?s?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- package.json | 10 +- yarn.lock | 682 +++++++++++++++++++++++++++++---------------------- 2 files changed, 393 insertions(+), 299 deletions(-) diff --git a/package.json b/package.json index e58719a..07cc14e 100644 --- a/package.json +++ b/package.json @@ -44,21 +44,21 @@ "eslint": "^6.8.0", "eslint-plugin-prefer-arrow": "^1.1.7", "mockdate": "^2.0.2", - "nock": "^11.7.2", + "nock": "^12.0.3", "npm-run-all": "^4.1.5", "nyc": "^15.0.0", - "sinon": "^8.1.1", + "sinon": "^9.0.1", "tslint": "^6.0.0", "typescript": "^3.7.5" }, "dependencies": { "@cloudstek/cache": "^1.0.5", - "@types/node-notifier": "^5.4.0", + "@types/node-notifier": "^6.0.0", "axios": "^0.19.2", "bplist-parser": "^0.2.0", "del": "^5.0.0", - "fs-extra": "^8.0.1", - "fuse.js": "^3.4.4", + "fs-extra": "^9.0.0", + "fuse.js": "^3.6.1", "glob": "^7.1.4", "moment": "^2.17.1", "node-notifier": "^6.0.0", diff --git a/yarn.lock b/yarn.lock index 50dec39..7cb042d 100644 --- a/yarn.lock +++ b/yarn.lock @@ -10,32 +10,33 @@ "@babel/highlight" "^7.8.3" "@babel/core@^7.7.5": - version "7.8.4" - resolved "https://registry.yarnpkg.com/@babel/core/-/core-7.8.4.tgz#d496799e5c12195b3602d0fddd77294e3e38e80e" - integrity sha512-0LiLrB2PwrVI+a2/IEskBopDYSd8BCb3rOvH7D5tzoWd696TBEduBvuLVm4Nx6rltrLZqvI3MCalB2K2aVzQjA== + version "7.9.0" + resolved "https://registry.yarnpkg.com/@babel/core/-/core-7.9.0.tgz#ac977b538b77e132ff706f3b8a4dbad09c03c56e" + integrity sha512-kWc7L0fw1xwvI0zi8OKVBuxRVefwGOrKSQMvrQ3dW+bIIavBY3/NpXmpjMy7bQnLgwgzWQZ8TlM57YHpHNHz4w== dependencies: "@babel/code-frame" "^7.8.3" - "@babel/generator" "^7.8.4" - "@babel/helpers" "^7.8.4" - "@babel/parser" "^7.8.4" - "@babel/template" "^7.8.3" - "@babel/traverse" "^7.8.4" - "@babel/types" "^7.8.3" + "@babel/generator" "^7.9.0" + "@babel/helper-module-transforms" "^7.9.0" + "@babel/helpers" "^7.9.0" + "@babel/parser" "^7.9.0" + "@babel/template" "^7.8.6" + "@babel/traverse" "^7.9.0" + "@babel/types" "^7.9.0" convert-source-map "^1.7.0" debug "^4.1.0" gensync "^1.0.0-beta.1" - json5 "^2.1.0" + json5 "^2.1.2" lodash "^4.17.13" resolve "^1.3.2" semver "^5.4.1" source-map "^0.5.0" -"@babel/generator@^7.8.4": - version "7.8.4" - resolved "https://registry.yarnpkg.com/@babel/generator/-/generator-7.8.4.tgz#35bbc74486956fe4251829f9f6c48330e8d0985e" - integrity sha512-PwhclGdRpNAf3IxZb0YVuITPZmmrXz9zf6fH8lT4XbrmfQKr6ryBzhv593P5C6poJRciFCL/eHGW2NuGrgEyxA== +"@babel/generator@^7.9.0": + version "7.9.0" + resolved "https://registry.yarnpkg.com/@babel/generator/-/generator-7.9.0.tgz#0f67adea4ec39dad6e63345f70eec33014d78c89" + integrity sha512-onl4Oy46oGCzymOXtKMQpI7VXtCbTSHK1kqBydZ6AmzuNcacEVqGk9tZtAS+48IA9IstZcDCgIg8hQKnb7suRw== dependencies: - "@babel/types" "^7.8.3" + "@babel/types" "^7.9.0" jsesc "^2.5.1" lodash "^4.17.13" source-map "^0.5.0" @@ -56,6 +57,58 @@ dependencies: "@babel/types" "^7.8.3" +"@babel/helper-member-expression-to-functions@^7.8.3": + version "7.8.3" + resolved "https://registry.yarnpkg.com/@babel/helper-member-expression-to-functions/-/helper-member-expression-to-functions-7.8.3.tgz#659b710498ea6c1d9907e0c73f206eee7dadc24c" + integrity sha512-fO4Egq88utkQFjbPrSHGmGLFqmrshs11d46WI+WZDESt7Wu7wN2G2Iu+NMMZJFDOVRHAMIkB5SNh30NtwCA7RA== + dependencies: + "@babel/types" "^7.8.3" + +"@babel/helper-module-imports@^7.8.3": + version "7.8.3" + resolved "https://registry.yarnpkg.com/@babel/helper-module-imports/-/helper-module-imports-7.8.3.tgz#7fe39589b39c016331b6b8c3f441e8f0b1419498" + integrity sha512-R0Bx3jippsbAEtzkpZ/6FIiuzOURPcMjHp+Z6xPe6DtApDJx+w7UYyOLanZqO8+wKR9G10s/FmHXvxaMd9s6Kg== + dependencies: + "@babel/types" "^7.8.3" + +"@babel/helper-module-transforms@^7.9.0": + version "7.9.0" + resolved "https://registry.yarnpkg.com/@babel/helper-module-transforms/-/helper-module-transforms-7.9.0.tgz#43b34dfe15961918707d247327431388e9fe96e5" + integrity sha512-0FvKyu0gpPfIQ8EkxlrAydOWROdHpBmiCiRwLkUiBGhCUPRRbVD2/tm3sFr/c/GWFrQ/ffutGUAnx7V0FzT2wA== + dependencies: + "@babel/helper-module-imports" "^7.8.3" + "@babel/helper-replace-supers" "^7.8.6" + "@babel/helper-simple-access" "^7.8.3" + "@babel/helper-split-export-declaration" "^7.8.3" + "@babel/template" "^7.8.6" + "@babel/types" "^7.9.0" + lodash "^4.17.13" + +"@babel/helper-optimise-call-expression@^7.8.3": + version "7.8.3" + resolved "https://registry.yarnpkg.com/@babel/helper-optimise-call-expression/-/helper-optimise-call-expression-7.8.3.tgz#7ed071813d09c75298ef4f208956006b6111ecb9" + integrity sha512-Kag20n86cbO2AvHca6EJsvqAd82gc6VMGule4HwebwMlwkpXuVqrNRj6CkCV2sKxgi9MyAUnZVnZ6lJ1/vKhHQ== + dependencies: + "@babel/types" "^7.8.3" + +"@babel/helper-replace-supers@^7.8.6": + version "7.8.6" + resolved "https://registry.yarnpkg.com/@babel/helper-replace-supers/-/helper-replace-supers-7.8.6.tgz#5ada744fd5ad73203bf1d67459a27dcba67effc8" + integrity sha512-PeMArdA4Sv/Wf4zXwBKPqVj7n9UF/xg6slNRtZW84FM7JpE1CbG8B612FyM4cxrf4fMAMGO0kR7voy1ForHHFA== + dependencies: + "@babel/helper-member-expression-to-functions" "^7.8.3" + "@babel/helper-optimise-call-expression" "^7.8.3" + "@babel/traverse" "^7.8.6" + "@babel/types" "^7.8.6" + +"@babel/helper-simple-access@^7.8.3": + version "7.8.3" + resolved "https://registry.yarnpkg.com/@babel/helper-simple-access/-/helper-simple-access-7.8.3.tgz#7f8109928b4dab4654076986af575231deb639ae" + integrity sha512-VNGUDjx5cCWg4vvCTR8qQ7YJYZ+HBjxOgXEl7ounz+4Sn7+LMD3CFrCTEU6/qXKbA2nKg21CwhhBzO0RpRbdCw== + dependencies: + "@babel/template" "^7.8.3" + "@babel/types" "^7.8.3" + "@babel/helper-split-export-declaration@^7.8.3": version "7.8.3" resolved "https://registry.yarnpkg.com/@babel/helper-split-export-declaration/-/helper-split-export-declaration-7.8.3.tgz#31a9f30070f91368a7182cf05f831781065fc7a9" @@ -63,59 +116,64 @@ dependencies: "@babel/types" "^7.8.3" -"@babel/helpers@^7.8.4": - version "7.8.4" - resolved "https://registry.yarnpkg.com/@babel/helpers/-/helpers-7.8.4.tgz#754eb3ee727c165e0a240d6c207de7c455f36f73" - integrity sha512-VPbe7wcQ4chu4TDQjimHv/5tj73qz88o12EPkO2ValS2QiQS/1F2SsjyIGNnAD0vF/nZS6Cf9i+vW6HIlnaR8w== +"@babel/helper-validator-identifier@^7.9.0": + version "7.9.0" + resolved "https://registry.yarnpkg.com/@babel/helper-validator-identifier/-/helper-validator-identifier-7.9.0.tgz#ad53562a7fc29b3b9a91bbf7d10397fd146346ed" + integrity sha512-6G8bQKjOh+of4PV/ThDm/rRqlU7+IGoJuofpagU5GlEl29Vv0RGqqt86ZGRV8ZuSOY3o+8yXl5y782SMcG7SHw== + +"@babel/helpers@^7.9.0": + version "7.9.2" + resolved "https://registry.yarnpkg.com/@babel/helpers/-/helpers-7.9.2.tgz#b42a81a811f1e7313b88cba8adc66b3d9ae6c09f" + integrity sha512-JwLvzlXVPjO8eU9c/wF9/zOIN7X6h8DYf7mG4CiFRZRvZNKEF5dQ3H3V+ASkHoIB3mWhatgl5ONhyqHRI6MppA== dependencies: "@babel/template" "^7.8.3" - "@babel/traverse" "^7.8.4" - "@babel/types" "^7.8.3" + "@babel/traverse" "^7.9.0" + "@babel/types" "^7.9.0" "@babel/highlight@^7.8.3": - version "7.8.3" - resolved "https://registry.yarnpkg.com/@babel/highlight/-/highlight-7.8.3.tgz#28f173d04223eaaa59bc1d439a3836e6d1265797" - integrity sha512-PX4y5xQUvy0fnEVHrYOarRPXVWafSjTW9T0Hab8gVIawpl2Sj0ORyrygANq+KjcNlSSTw0YCLSNA8OyZ1I4yEg== + version "7.9.0" + resolved "https://registry.yarnpkg.com/@babel/highlight/-/highlight-7.9.0.tgz#4e9b45ccb82b79607271b2979ad82c7b68163079" + integrity sha512-lJZPilxX7Op3Nv/2cvFdnlepPXDxi29wxteT57Q965oc5R9v86ztx0jfxVrTcBk8C2kcPkkDa2Z4T3ZsPPVWsQ== dependencies: + "@babel/helper-validator-identifier" "^7.9.0" chalk "^2.0.0" - esutils "^2.0.2" js-tokens "^4.0.0" -"@babel/parser@^7.7.5", "@babel/parser@^7.8.3", "@babel/parser@^7.8.4": - version "7.8.4" - resolved "https://registry.yarnpkg.com/@babel/parser/-/parser-7.8.4.tgz#d1dbe64691d60358a974295fa53da074dd2ce8e8" - integrity sha512-0fKu/QqildpXmPVaRBoXOlyBb3MC+J0A66x97qEfLOMkn3u6nfY5esWogQwi/K0BjASYy4DbnsEWnpNL6qT5Mw== +"@babel/parser@^7.7.5", "@babel/parser@^7.8.6", "@babel/parser@^7.9.0": + version "7.9.2" + resolved "https://registry.yarnpkg.com/@babel/parser/-/parser-7.9.2.tgz#4e767f424b479c514077544484d1f9bdba7f1158" + integrity sha512-2jyvKdoOS1aWAFL2rjJZmamyDDkPCx/AAz4/Wh1Dfxvw8qqnOvek/ZlHQ2noO/o8JpnXa/WiUUFOv48meBKkpA== -"@babel/template@^7.7.4", "@babel/template@^7.8.3": - version "7.8.3" - resolved "https://registry.yarnpkg.com/@babel/template/-/template-7.8.3.tgz#e02ad04fe262a657809327f578056ca15fd4d1b8" - integrity sha512-04m87AcQgAFdvuoyiQ2kgELr2tV8B4fP/xJAVUL3Yb3bkNdMedD3d0rlSQr3PegP0cms3eHjl1F7PWlvWbU8FQ== +"@babel/template@^7.7.4", "@babel/template@^7.8.3", "@babel/template@^7.8.6": + version "7.8.6" + resolved "https://registry.yarnpkg.com/@babel/template/-/template-7.8.6.tgz#86b22af15f828dfb086474f964dcc3e39c43ce2b" + integrity sha512-zbMsPMy/v0PWFZEhQJ66bqjhH+z0JgMoBWuikXybgG3Gkd/3t5oQ1Rw2WQhnSrsOmsKXnZOx15tkC4qON/+JPg== dependencies: "@babel/code-frame" "^7.8.3" - "@babel/parser" "^7.8.3" - "@babel/types" "^7.8.3" + "@babel/parser" "^7.8.6" + "@babel/types" "^7.8.6" -"@babel/traverse@^7.7.4", "@babel/traverse@^7.8.4": - version "7.8.4" - resolved "https://registry.yarnpkg.com/@babel/traverse/-/traverse-7.8.4.tgz#f0845822365f9d5b0e312ed3959d3f827f869e3c" - integrity sha512-NGLJPZwnVEyBPLI+bl9y9aSnxMhsKz42so7ApAv9D+b4vAFPpY013FTS9LdKxcABoIYFU52HcYga1pPlx454mg== +"@babel/traverse@^7.7.4", "@babel/traverse@^7.8.6", "@babel/traverse@^7.9.0": + version "7.9.0" + resolved "https://registry.yarnpkg.com/@babel/traverse/-/traverse-7.9.0.tgz#d3882c2830e513f4fe4cec9fe76ea1cc78747892" + integrity sha512-jAZQj0+kn4WTHO5dUZkZKhbFrqZE7K5LAQ5JysMnmvGij+wOdr+8lWqPeW0BcF4wFwrEXXtdGO7wcV6YPJcf3w== dependencies: "@babel/code-frame" "^7.8.3" - "@babel/generator" "^7.8.4" + "@babel/generator" "^7.9.0" "@babel/helper-function-name" "^7.8.3" "@babel/helper-split-export-declaration" "^7.8.3" - "@babel/parser" "^7.8.4" - "@babel/types" "^7.8.3" + "@babel/parser" "^7.9.0" + "@babel/types" "^7.9.0" debug "^4.1.0" globals "^11.1.0" lodash "^4.17.13" -"@babel/types@^7.8.3": - version "7.8.3" - resolved "https://registry.yarnpkg.com/@babel/types/-/types-7.8.3.tgz#5a383dffa5416db1b73dedffd311ffd0788fb31c" - integrity sha512-jBD+G8+LWpMBBWvVcdr4QysjUE4mU/syrhN17o1u3gx0/WzJB1kwiVZAXRtWbsIPOwW8pF/YJV5+nmetPzepXg== +"@babel/types@^7.8.3", "@babel/types@^7.8.6", "@babel/types@^7.9.0": + version "7.9.0" + resolved "https://registry.yarnpkg.com/@babel/types/-/types-7.9.0.tgz#00b064c3df83ad32b2dbf5ff07312b15c7f1efb5" + integrity sha512-BS9JKfXkzzJl8RluW4JGknzpiUV7ZrvTayM6yfqLTVBEnFtyowVIOu6rqxRd5cVO6yGoWf4T8u8dgK9oB+GCng== dependencies: - esutils "^2.0.2" + "@babel/helper-validator-identifier" "^7.9.0" lodash "^4.17.13" to-fast-properties "^2.0.0" @@ -176,24 +234,31 @@ integrity sha512-9NET910DNaIPngYnLLPeg+Ogzqsi9uM4mSboU5y6p8S5DzMTVEsJZrawi+BoDNUVBa2DhJqQYUFvMDfgU062LQ== "@sinonjs/commons@^1", "@sinonjs/commons@^1.6.0", "@sinonjs/commons@^1.7.0": - version "1.7.0" - resolved "https://registry.yarnpkg.com/@sinonjs/commons/-/commons-1.7.0.tgz#f90ffc52a2e519f018b13b6c4da03cbff36ebed6" - integrity sha512-qbk9AP+cZUsKdW1GJsBpxPKFmCJ0T8swwzVje3qFd+AkQb74Q/tiuzrdfFg8AD2g5HH/XbE/I8Uc1KYHVYWfhg== + version "1.7.1" + resolved "https://registry.yarnpkg.com/@sinonjs/commons/-/commons-1.7.1.tgz#da5fd19a5f71177a53778073978873964f49acf1" + integrity sha512-Debi3Baff1Qu1Unc3mjJ96MgpbwTn43S1+9yJ0llWygPwDNu2aaWBD6yc9y/Z8XDRNhx7U+u2UDg2OGQXkclUQ== dependencies: type-detect "4.0.8" -"@sinonjs/formatio@^4.0.1": - version "4.0.1" - resolved "https://registry.yarnpkg.com/@sinonjs/formatio/-/formatio-4.0.1.tgz#50ac1da0c3eaea117ca258b06f4f88a471668bdb" - integrity sha512-asIdlLFrla/WZybhm0C8eEzaDNNrzymiTqHMeJl6zPW2881l3uuVRpm0QlRQEjqYWv6CcKMGYME3LbrLJsORBw== +"@sinonjs/fake-timers@^6.0.0": + version "6.0.0" + resolved "https://registry.yarnpkg.com/@sinonjs/fake-timers/-/fake-timers-6.0.0.tgz#b64b0faadfdd01a6dcf0c4dcdb78438d86fa7dbf" + integrity sha512-atR1J/jRXvQAb47gfzSK8zavXy7BcpnYq21ALon0U99etu99vsir0trzIO3wpeLtW+LLVY6X7EkfVTbjGSH8Ww== + dependencies: + "@sinonjs/commons" "^1.7.0" + +"@sinonjs/formatio@^5.0.1": + version "5.0.1" + resolved "https://registry.yarnpkg.com/@sinonjs/formatio/-/formatio-5.0.1.tgz#f13e713cb3313b1ab965901b01b0828ea6b77089" + integrity sha512-KaiQ5pBf1MpS09MuA0kp6KBQt2JUOQycqVG1NZXvzeaXe5LGFqAKueIS0bw4w0P9r7KuBSVdUk5QjXsUdu2CxQ== dependencies: "@sinonjs/commons" "^1" - "@sinonjs/samsam" "^4.2.0" + "@sinonjs/samsam" "^5.0.2" -"@sinonjs/samsam@^4.2.0", "@sinonjs/samsam@^4.2.2": - version "4.2.2" - resolved "https://registry.yarnpkg.com/@sinonjs/samsam/-/samsam-4.2.2.tgz#0f6cb40e467865306d8a20a97543a94005204e23" - integrity sha512-z9o4LZUzSD9Hl22zV38aXNykgFeVj8acqfFabCY6FY83n/6s/XwNJyYYldz6/9lBJanpno9h+oL6HTISkviweA== +"@sinonjs/samsam@^5.0.2", "@sinonjs/samsam@^5.0.3": + version "5.0.3" + resolved "https://registry.yarnpkg.com/@sinonjs/samsam/-/samsam-5.0.3.tgz#86f21bdb3d52480faf0892a480c9906aa5a52938" + integrity sha512-QucHkc2uMJ0pFGjJUDP3F9dq5dx8QIaqISl9QgwLOh6P9yv877uONPGXh/OH/0zmM3tW1JjuJltAZV2l7zU+uQ== dependencies: "@sinonjs/commons" "^1.6.0" lodash.get "^4.4.2" @@ -227,9 +292,9 @@ integrity sha512-EaObqwIvayI5a8dCzhFrjKzVwKLxjoG9T6Ppd5CEo07LRKfQ8Yokw54r5+Wq7FaBQ+yXRvQAYPrHwya1/UFt9g== "@types/fs-extra@^8.0.0": - version "8.0.1" - resolved "https://registry.yarnpkg.com/@types/fs-extra/-/fs-extra-8.0.1.tgz#a2378d6e7e8afea1564e44aafa2e207dadf77686" - integrity sha512-J00cVDALmi/hJOYsunyT52Hva5TnJeKP5yd1r+mH/ZU0mbYZflR0Z5kw5kITtKTRYMhm1JMClOFYdHnQszEvqw== + version "8.1.0" + resolved "https://registry.yarnpkg.com/@types/fs-extra/-/fs-extra-8.1.0.tgz#1114834b53c3914806cd03b3304b37b3bd221a4d" + integrity sha512-UoOfVEzAUpeSPmjm7h1uk5MH6KZma2z2O7a75onTGjnNvAvMVrPzPL/vBbT65iIGHWj6rokwfmYcmxmlSf2uwg== dependencies: "@types/node" "*" @@ -257,17 +322,17 @@ resolved "https://registry.yarnpkg.com/@types/mockdate/-/mockdate-2.0.0.tgz#aaf388a1ead3b0f5ed6dc1611956ea7b40a57d3c" integrity sha1-qvOIoerTsPXtbcFhGVbqe0ClfTw= -"@types/node-notifier@^5.4.0": - version "5.4.0" - resolved "https://registry.yarnpkg.com/@types/node-notifier/-/node-notifier-5.4.0.tgz#4e66c85eb41cce8387b4cd9c6c67852be41a99db" - integrity sha512-M1XvCG6Rwej6+W0+kWultE46YS7erOy+W7suRmXtKwLGT3ytj6YEe9lqo47nRfL1xILzg9xJpKeNczIsWR8ymw== +"@types/node-notifier@^6.0.0": + version "6.0.0" + resolved "https://registry.yarnpkg.com/@types/node-notifier/-/node-notifier-6.0.0.tgz#f9bc38da95f7da0d7e8b853a9978867006d002d1" + integrity sha512-j1CtoHjI4gCmo7TofyQP7TdBxip+YKD0/+S89w1d6DGrhH28RL9PYn6Jp2qxojGCmdVqTtBmzSLfEAOBa+Q+hQ== dependencies: "@types/node" "*" "@types/node@*", "@types/node@^13.7.0": - version "13.7.0" - resolved "https://registry.yarnpkg.com/@types/node/-/node-13.7.0.tgz#b417deda18cf8400f278733499ad5547ed1abec4" - integrity sha512-GnZbirvmqZUzMgkFn70c74OQpTTUcCzlhQliTzYjQMqg+hVKcDnxdL19Ne3UdYzdMA/+W3eb646FWn/ZaT1NfQ== + version "13.9.2" + resolved "https://registry.yarnpkg.com/@types/node/-/node-13.9.2.tgz#ace1880c03594cc3e80206d96847157d8e7fa349" + integrity sha512-bnoqK579sAYrQbp73wwglccjJ4sfRdKU7WNEZ5FW4K2U6Kc0/eZ5kvXG0JKsEKFB50zrFmfFt52/cvBbZa7eXg== "@types/normalize-package-data@^2.4.0": version "2.4.0" @@ -282,44 +347,44 @@ "@types/node" "*" "@types/sinon@^7.0.12": - version "7.5.1" - resolved "https://registry.yarnpkg.com/@types/sinon/-/sinon-7.5.1.tgz#d27b81af0d1cfe1f9b24eebe7a24f74ae40f5b7c" - integrity sha512-EZQUP3hSZQyTQRfiLqelC9NMWd1kqLcmQE0dMiklxBkgi84T+cHOhnKpgk4NnOWpGX863yE6+IaGnOXUNFqDnQ== + version "7.5.2" + resolved "https://registry.yarnpkg.com/@types/sinon/-/sinon-7.5.2.tgz#5e2f1d120f07b9cda07e5dedd4f3bf8888fccdb9" + integrity sha512-T+m89VdXj/eidZyejvmoP9jivXgBDdkOSBVQjU9kF349NEx10QdPNGxHeZUaj1IlJ32/ewdyXJjnJxyxJroYwg== "@typescript-eslint/eslint-plugin@^2.19.0": - version "2.19.0" - resolved "https://registry.yarnpkg.com/@typescript-eslint/eslint-plugin/-/eslint-plugin-2.19.0.tgz#bf743448a4633e4b52bee0c40148ba072ab3adbd" - integrity sha512-u7IcQ9qwsB6U806LupZmINRnQjC+RJyv36sV/ugaFWMHTbFm/hlLTRx3gGYJgHisxcGSTnf+I/fPDieRMhPSQQ== + version "2.24.0" + resolved "https://registry.yarnpkg.com/@typescript-eslint/eslint-plugin/-/eslint-plugin-2.24.0.tgz#a86cf618c965a462cddf3601f594544b134d6d68" + integrity sha512-wJRBeaMeT7RLQ27UQkDFOu25MqFOBus8PtOa9KaT5ZuxC1kAsd7JEHqWt4YXuY9eancX0GK9C68i5OROnlIzBA== dependencies: - "@typescript-eslint/experimental-utils" "2.19.0" + "@typescript-eslint/experimental-utils" "2.24.0" eslint-utils "^1.4.3" functional-red-black-tree "^1.0.1" regexpp "^3.0.0" tsutils "^3.17.1" -"@typescript-eslint/experimental-utils@2.19.0": - version "2.19.0" - resolved "https://registry.yarnpkg.com/@typescript-eslint/experimental-utils/-/experimental-utils-2.19.0.tgz#d5ca732f22c009e515ba09fcceb5f2127d841568" - integrity sha512-zwpg6zEOPbhB3+GaQfufzlMUOO6GXCNZq6skk+b2ZkZAIoBhVoanWK255BS1g5x9bMwHpLhX0Rpn5Fc3NdCZdg== +"@typescript-eslint/experimental-utils@2.24.0": + version "2.24.0" + resolved "https://registry.yarnpkg.com/@typescript-eslint/experimental-utils/-/experimental-utils-2.24.0.tgz#a5cb2ed89fedf8b59638dc83484eb0c8c35e1143" + integrity sha512-DXrwuXTdVh3ycNCMYmWhUzn/gfqu9N0VzNnahjiDJvcyhfBy4gb59ncVZVxdp5XzBC77dCncu0daQgOkbvPwBw== dependencies: "@types/json-schema" "^7.0.3" - "@typescript-eslint/typescript-estree" "2.19.0" + "@typescript-eslint/typescript-estree" "2.24.0" eslint-scope "^5.0.0" "@typescript-eslint/parser@^2.19.0": - version "2.19.0" - resolved "https://registry.yarnpkg.com/@typescript-eslint/parser/-/parser-2.19.0.tgz#912160d9425395d09857dcd5382352bc98be11ae" - integrity sha512-s0jZoxAWjHnuidbbN7aA+BFVXn4TCcxEVGPV8lWMxZglSs3NRnFFAlL+aIENNmzB2/1jUJuySi6GiM6uACPmpg== + version "2.24.0" + resolved "https://registry.yarnpkg.com/@typescript-eslint/parser/-/parser-2.24.0.tgz#2cf0eae6e6dd44d162486ad949c126b887f11eb8" + integrity sha512-H2Y7uacwSSg8IbVxdYExSI3T7uM1DzmOn2COGtCahCC3g8YtM1xYAPi2MAHyfPs61VKxP/J/UiSctcRgw4G8aw== dependencies: "@types/eslint-visitor-keys" "^1.0.0" - "@typescript-eslint/experimental-utils" "2.19.0" - "@typescript-eslint/typescript-estree" "2.19.0" + "@typescript-eslint/experimental-utils" "2.24.0" + "@typescript-eslint/typescript-estree" "2.24.0" eslint-visitor-keys "^1.1.0" -"@typescript-eslint/typescript-estree@2.19.0": - version "2.19.0" - resolved "https://registry.yarnpkg.com/@typescript-eslint/typescript-estree/-/typescript-estree-2.19.0.tgz#6bd7310b9827e04756fe712909f26956aac4b196" - integrity sha512-n6/Xa37k0jQdwpUszffi19AlNbVCR0sdvCs3DmSKMD7wBttKY31lhD2fug5kMD91B2qW4mQldaTEc1PEzvGu8w== +"@typescript-eslint/typescript-estree@2.24.0": + version "2.24.0" + resolved "https://registry.yarnpkg.com/@typescript-eslint/typescript-estree/-/typescript-estree-2.24.0.tgz#38bbc8bb479790d2f324797ffbcdb346d897c62a" + integrity sha512-RJ0yMe5owMSix55qX7Mi9V6z2FDuuDpN6eR5fzRJrp+8in9UF41IGNQHbg5aMK4/PjVaEQksLvz0IA8n+Mr/FA== dependencies: debug "^4.1.1" eslint-visitor-keys "^1.1.0" @@ -329,15 +394,15 @@ semver "^6.3.0" tsutils "^3.17.1" -acorn-jsx@^5.1.0: - version "5.1.0" - resolved "https://registry.yarnpkg.com/acorn-jsx/-/acorn-jsx-5.1.0.tgz#294adb71b57398b0680015f0a38c563ee1db5384" - integrity sha512-tMUqwBWfLFbJbizRmEcWSLw6HnFzfdJs2sOJEOwwtVPMoH/0Ay+E703oZz78VSXZiiDcZrQ5XKjPIUQixhmgVw== +acorn-jsx@^5.2.0: + version "5.2.0" + resolved "https://registry.yarnpkg.com/acorn-jsx/-/acorn-jsx-5.2.0.tgz#4c66069173d6fdd68ed85239fc256226182b2ebe" + integrity sha512-HiUX/+K2YpkpJ+SzBffkM/AQ2YE03S0U1kjTLVpoJdhZMOWy8qvXVN9JdLqv2QsaQ6MPYQIuNmwD8zOiYUofLQ== -acorn@^7.1.0: - version "7.1.0" - resolved "https://registry.yarnpkg.com/acorn/-/acorn-7.1.0.tgz#949d36f2c292535da602283586c2477c57eb2d6c" - integrity sha512-kL5CuoXA/dgxlBbVrflsflzQ3PAas7RYZB52NOm/6839iVYJgKMJ3cQJD+t2i5+qFa8h3MDpEOJiS64E8JLnSQ== +acorn@^7.1.1: + version "7.1.1" + resolved "https://registry.yarnpkg.com/acorn/-/acorn-7.1.1.tgz#e35668de0b402f359de515c5482a1ab9f89a69bf" + integrity sha512-add7dgA5ppRPxCFJoAGfMDi7PIBXq1RtGo7BhbLaxwrXPOmw8gq48Y9ozT01hUKy9byMjlR20EJhu5zlkErEkg== aggregate-error@^3.0.0: version "3.0.1" @@ -348,9 +413,9 @@ aggregate-error@^3.0.0: indent-string "^4.0.0" ajv@^6.10.0, ajv@^6.10.2, ajv@^6.5.5: - version "6.11.0" - resolved "https://registry.yarnpkg.com/ajv/-/ajv-6.11.0.tgz#c3607cbc8ae392d8a5a536f25b21f8e5f3f87fe9" - integrity sha512-nCprB/0syFYy9fVYU1ox1l2KN8S9I+tziH8D4zdZuLT3N6RMlGSGt5FSTpAiHB/Whv8Qs1cWHma1aMKZyaHRKA== + version "6.12.0" + resolved "https://registry.yarnpkg.com/ajv/-/ajv-6.12.0.tgz#06d60b96d87b8454a5adaba86e7854da629db4b7" + integrity sha512-D6gFiFA0RRLyUbvijN74DWAjXSFxWKaWP7mldxkVhyhAV3+SWA9HEJPHQ2c9soIeTFJqcSdFDGFgdqs1iUU2Hw== dependencies: fast-deep-equal "^3.1.1" fast-json-stable-stringify "^2.0.0" @@ -365,11 +430,11 @@ ansi-align@^3.0.0: string-width "^3.0.0" ansi-escapes@^4.2.1: - version "4.3.0" - resolved "https://registry.yarnpkg.com/ansi-escapes/-/ansi-escapes-4.3.0.tgz#a4ce2b33d6b214b7950d8595c212f12ac9cc569d" - integrity sha512-EiYhwo0v255HUL6eDyuLrXEkTi7WwVCLAw+SeOQ7M7qdun1z1pum4DEm/nuqIVbPvi9RPPc9k9LbyBv6H0DwVg== + version "4.3.1" + resolved "https://registry.yarnpkg.com/ansi-escapes/-/ansi-escapes-4.3.1.tgz#a5c47cc43181f1f38ffd7076837700d395522a61" + integrity sha512-JWF7ocqNrp8u9oqpgV+wH5ftbt+cfvv+PTjOvKLT3AdYly/LmORARfEVT1iyjwN+4MqE5UmVKoAdIBqeoCHgLA== dependencies: - type-fest "^0.8.1" + type-fest "^0.11.0" ansi-regex@^3.0.0: version "3.0.0" @@ -480,10 +545,15 @@ asynckit@^0.4.0: resolved "https://registry.yarnpkg.com/asynckit/-/asynckit-0.4.0.tgz#c79ed97f7f34cb8f2ba1bc9790bcc366474b4b79" integrity sha1-x57Zf380y48robyXkLzDZkdLS3k= +at-least-node@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/at-least-node/-/at-least-node-1.0.0.tgz#602cd4b46e844ad4effc92a8011a3c46e0238dc2" + integrity sha512-+q/t7Ekv1EDY2l6Gda6LLiX14rU9TV20Wa3ofeQmwPFZbOMo9DXrLbOjFaaclkXKWidIaopwAObQDqwWtGUjqg== + ava@^3.2.0: - version "3.2.0" - resolved "https://registry.yarnpkg.com/ava/-/ava-3.2.0.tgz#ab019f211c24f5d732b26babb7c75635012d3b83" - integrity sha512-Jf2DlzrDp83f8OcyN0fNcT6QX1ORk3E/bCxBrwPxbh3Szg8eA03QjK/ZYjAa6OHIEWBxZuuT7x7kupgrUo7HVQ== + version "3.5.0" + resolved "https://registry.yarnpkg.com/ava/-/ava-3.5.0.tgz#589f0f35f51e6ab67eb230a9057fd2442807c62f" + integrity sha512-o+xq1RgAZrQ7GX5nddTNeYbUDogwlBoa/Hnt+b1ciCLLxSOj5U6ZFblLNBSKwHtP1X/8R06bmzvX47jmlVu9KQ== dependencies: "@concordance/react" "^2.0.0" ansi-styles "^4.2.1" @@ -523,8 +593,8 @@ ava@^3.2.0: p-map "^3.0.0" picomatch "^2.2.1" pkg-conf "^3.1.0" - plur "^3.1.1" - pretty-ms "^5.1.0" + plur "^4.0.0" + pretty-ms "^6.0.0" read-pkg "^5.2.0" resolve-cwd "^3.0.0" slash "^3.0.0" @@ -534,7 +604,7 @@ ava@^3.2.0: supertap "^1.0.0" temp-dir "^2.0.0" trim-off-newlines "^1.0.1" - update-notifier "^4.0.0" + update-notifier "^4.1.0" write-file-atomic "^3.0.1" yargs "^15.1.0" @@ -880,12 +950,12 @@ concordance@^4.0.0: semver "^5.5.1" well-known-symbols "^2.0.0" -configstore@^5.0.0: - version "5.0.0" - resolved "https://registry.yarnpkg.com/configstore/-/configstore-5.0.0.tgz#37de662c7a49b5fe8dbcf8f6f5818d2d81ed852b" - integrity sha512-eE/hvMs7qw7DlcB5JPRnthmrITuHMmACUJAp89v6PT6iOqzoLS7HRWhBtuHMlhNHo2AhUSA/3Dh1bKNJHcublQ== +configstore@^5.0.1: + version "5.0.1" + resolved "https://registry.yarnpkg.com/configstore/-/configstore-5.0.1.tgz#d365021b5df4b98cdd187d6a3b0e3f6a7cc5ed96" + integrity sha512-aMKprgk5YhBNyH25hj8wGt2+D52Sw1DRRIzqBwLp2Ya9mFmY8KPvvtvmna8SxVR9JMZ4kzMD68N22vlaRpkeFA== dependencies: - dot-prop "^5.1.0" + dot-prop "^5.2.0" graceful-fs "^4.1.2" make-dir "^3.0.0" unique-string "^2.0.0" @@ -910,14 +980,14 @@ core-util-is@1.0.2: integrity sha1-tf1UIgqivFq1eqtxQMlAdUUDwac= coveralls@^3.0.4: - version "3.0.9" - resolved "https://registry.yarnpkg.com/coveralls/-/coveralls-3.0.9.tgz#8cfc5a5525f84884e2948a0bf0f1c0e90aac0420" - integrity sha512-nNBg3B1+4iDox5A5zqHKzUTiwl2ey4k2o0NEcVZYvl+GOSJdKBj4AJGKLv6h3SvWch7tABHePAQOSZWM9E2hMg== + version "3.0.11" + resolved "https://registry.yarnpkg.com/coveralls/-/coveralls-3.0.11.tgz#e141da0922b632fcc66620f334460c3f0026a4ce" + integrity sha512-LZPWPR2NyGKyaABnc49dR0fpeP6UqhvGq4B5nUrTQ1UBy55z96+ga7r+/ChMdMJUwBgyJDXBi88UBgz2rs9IiQ== dependencies: js-yaml "^3.13.1" lcov-parse "^1.0.0" log-driver "^1.2.7" - minimist "^1.2.0" + minimist "^1.2.5" request "^2.88.0" cross-spawn@^6.0.5: @@ -1082,7 +1152,7 @@ doctrine@^3.0.0: dependencies: esutils "^2.0.2" -dot-prop@^5.1.0: +dot-prop@^5.2.0: version "5.2.0" resolved "https://registry.yarnpkg.com/dot-prop/-/dot-prop-5.2.0.tgz#c34ecc29556dc45f1f4c22697b6f4904e0cc4fcb" integrity sha512-uEUyaDKoSQ1M4Oq8l45hSE26SnTxL6snNnqvK/VWx5wJhmff5z0FUVJDKDanor/6w3kzE3i7XZOk+7wC0EXr1A== @@ -1167,6 +1237,11 @@ es6-error@^4.0.1: resolved "https://registry.yarnpkg.com/es6-error/-/es6-error-4.1.1.tgz#9e3af407459deed47e9a91f9b885a84eb05c561d" integrity sha512-Um/+FxMr9CISWh0bi5Zv0iOD+4cFh5qLeks1qhAopKVAJw3drgKbKySikp7wGhDL0HPeaja0P5ULZrxLkniUVg== +escape-goat@^2.0.0: + version "2.1.1" + resolved "https://registry.yarnpkg.com/escape-goat/-/escape-goat-2.1.1.tgz#1b2dc77003676c457ec760b2dc68edb648188675" + integrity sha512-8/uIhbG12Csjy2JEW7D9pHbreaVaS/OpN3ycnyvElTdwM5n6GY6W6e2IPemfvGZeUMqZ9A/3GqIZMgKnBhAw/Q== + escape-string-regexp@^1.0.5: version "1.0.5" resolved "https://registry.yarnpkg.com/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz#1b61c0562190a8dff6ae3bb2cf0200ca130b86d4" @@ -1246,12 +1321,12 @@ eslint@^6.8.0: v8-compile-cache "^2.0.3" espree@^6.1.2: - version "6.1.2" - resolved "https://registry.yarnpkg.com/espree/-/espree-6.1.2.tgz#6c272650932b4f91c3714e5e7b5f5e2ecf47262d" - integrity sha512-2iUPuuPP+yW1PZaMSDM9eyVf8D5P0Hi8h83YtZ5bPc/zHYjII5khoixIUTMO794NOY8F/ThF1Bo8ncZILarUTA== + version "6.2.1" + resolved "https://registry.yarnpkg.com/espree/-/espree-6.2.1.tgz#77fc72e1fd744a2052c20f38a5b575832e82734a" + integrity sha512-ysCxRQY3WaXJz9tdbWOwuWr5Y/XrPTGX9Kiz3yoUXwW0VZ4w30HTkQLaGx/+ttFjF8i+ACbArnB4ce68a9m5hw== dependencies: - acorn "^7.1.0" - acorn-jsx "^5.1.0" + acorn "^7.1.1" + acorn-jsx "^5.2.0" eslint-visitor-keys "^1.1.0" esprima@^4.0.0: @@ -1260,9 +1335,9 @@ esprima@^4.0.0: integrity sha512-eGuFFw7Upda+g4p+QHvnW0RyTX/SVeJBDM/gCtMARO0cLuT2HcEKnTPvhjV6aGeqrCB/sbNop0Kszm0jsaWU4A== esquery@^1.0.1: - version "1.0.1" - resolved "https://registry.yarnpkg.com/esquery/-/esquery-1.0.1.tgz#406c51658b1f5991a5f9b62b1dc25b00e3e5c708" - integrity sha512-SmiyZ5zIWH9VM+SRUReLS5Q8a7GxtRdxEBVZpm98rJM7Sb+A9DVCndXfkeFUd3byderg+EbDkfnevfCwynWaNA== + version "1.1.0" + resolved "https://registry.yarnpkg.com/esquery/-/esquery-1.1.0.tgz#c5c0b66f383e7656404f86b31334d72524eddb48" + integrity sha512-MxYW9xKmROWF672KqjO75sszsA8Mxhw06YFeS5VHlB98KDHbOSurm3ArsjO60Eaf3QmGMCP1yn+0JQkNLo/97Q== dependencies: estraverse "^4.0.0" @@ -1318,15 +1393,16 @@ fast-diff@^1.1.2: integrity sha512-xJuoT5+L99XlZ8twedaRf6Ax2TgQVxvgZOYoPKqZufmJib0tL2tegPBOZb1pVNgIhlqDlA0eO0c3wBvQcmzx4w== fast-glob@^3.0.3, fast-glob@^3.1.1: - version "3.1.1" - resolved "https://registry.yarnpkg.com/fast-glob/-/fast-glob-3.1.1.tgz#87ee30e9e9f3eb40d6f254a7997655da753d7c82" - integrity sha512-nTCREpBY8w8r+boyFYAx21iL6faSsQynliPHM4Uf56SbkyohCNxpVPEH9xrF5TXKy+IsjkPUHDKiUkzBVRXn9g== + version "3.2.2" + resolved "https://registry.yarnpkg.com/fast-glob/-/fast-glob-3.2.2.tgz#ade1a9d91148965d4bf7c51f72e1ca662d32e63d" + integrity sha512-UDV82o4uQyljznxwMxyVRJgZZt3O5wENYojjzbaGEGZgeOxkLFf+V4cnUD+krzb2F72E18RhamkMZ7AdeggF7A== dependencies: "@nodelib/fs.stat" "^2.0.2" "@nodelib/fs.walk" "^1.2.3" glob-parent "^5.1.0" merge2 "^1.3.0" micromatch "^4.0.2" + picomatch "^2.2.1" fast-json-stable-stringify@^2.0.0: version "2.1.0" @@ -1339,16 +1415,16 @@ fast-levenshtein@~2.0.6: integrity sha1-PYpcZog6FqMMqGQ+hR8Zuqd5eRc= fastq@^1.6.0: - version "1.6.0" - resolved "https://registry.yarnpkg.com/fastq/-/fastq-1.6.0.tgz#4ec8a38f4ac25f21492673adb7eae9cfef47d1c2" - integrity sha512-jmxqQ3Z/nXoeyDmWAzF9kH1aGZSis6e/SbfPmJpUnyZ0ogr6iscHQaml4wsEepEWSdtmpy+eVXmCRIMpxaXqOA== + version "1.6.1" + resolved "https://registry.yarnpkg.com/fastq/-/fastq-1.6.1.tgz#4570c74f2ded173e71cf0beb08ac70bb85826791" + integrity sha512-mpIH5sKYueh3YyeJwqtVo8sORi0CgtmkVbK6kZStpQlZBYQuTzG2CZ7idSiJuA7bY0SFCWUc5WIs+oYumGCQNw== dependencies: - reusify "^1.0.0" + reusify "^1.0.4" figures@^3.0.0, figures@^3.1.0: - version "3.1.0" - resolved "https://registry.yarnpkg.com/figures/-/figures-3.1.0.tgz#4b198dd07d8d71530642864af2d45dd9e459c4ec" - integrity sha512-ravh8VRXqHuMvZt/d8GblBeqDMkdJMBdv/2KntFH+ra5MXkO7nxNKpzQ3n6QD/2da1kH0aWmNISdvhM7gl2gVg== + version "3.2.0" + resolved "https://registry.yarnpkg.com/figures/-/figures-3.2.0.tgz#625c18bd293c604dc4a8ddb2febf0c88341746af" + integrity sha512-yaduQFRKLXYOGgEn6AZau90j3ggSOyiqXU0F9JZfeXYhNa+Jk4X+s45A2zg5jns87GAFa34BBm2kXw4XpNcbdg== dependencies: escape-string-regexp "^1.0.5" @@ -1367,12 +1443,12 @@ fill-range@^7.0.1: to-regex-range "^5.0.1" find-cache-dir@^3.2.0: - version "3.2.0" - resolved "https://registry.yarnpkg.com/find-cache-dir/-/find-cache-dir-3.2.0.tgz#e7fe44c1abc1299f516146e563108fd1006c1874" - integrity sha512-1JKclkYYsf1q9WIJKLZa9S9muC+08RIjzAlLrK4QcYLJMS6mk9yombQ9qf+zJ7H9LS800k0s44L4sDq9VYzqyg== + version "3.3.1" + resolved "https://registry.yarnpkg.com/find-cache-dir/-/find-cache-dir-3.3.1.tgz#89b33fad4a4670daa94f855f7fbe31d6d84fe880" + integrity sha512-t2GDMt3oGC/v+BMwzmllWDuJF/xcDtE5j/fCGbqDD7OLuJkj0cfh1YSA5VKPvwMeLFLNDBkwOKZ2X85jGLVftQ== dependencies: commondir "^1.0.1" - make-dir "^3.0.0" + make-dir "^3.0.2" pkg-dir "^4.1.0" find-up@^2.0.0: @@ -1454,6 +1530,16 @@ fs-extra@^8.0.1: jsonfile "^4.0.0" universalify "^0.1.0" +fs-extra@^9.0.0: + version "9.0.0" + resolved "https://registry.yarnpkg.com/fs-extra/-/fs-extra-9.0.0.tgz#b6afc31036e247b2466dc99c29ae797d5d4580a3" + integrity sha512-pmEYSk3vYsG/bF651KPUXZ+hvjpgWYw/Gc7W9NFUe3ZVLczKKWIij3IKpOrQcdw4TILtibFslZ0UmR8Vvzig4g== + dependencies: + at-least-node "^1.0.0" + graceful-fs "^4.2.0" + jsonfile "^6.0.1" + universalify "^1.0.0" + fs.realpath@^1.0.0: version "1.0.0" resolved "https://registry.yarnpkg.com/fs.realpath/-/fs.realpath-1.0.0.tgz#1504ad2523158caa40db4a2787cb01411994ea4f" @@ -1474,10 +1560,10 @@ functional-red-black-tree@^1.0.1: resolved "https://registry.yarnpkg.com/functional-red-black-tree/-/functional-red-black-tree-1.0.1.tgz#1b0ab3bd553b2a0d6399d29c0e3ea0b252078327" integrity sha1-GwqzvVU7Kg1jmdKcDj6gslIHgyc= -fuse.js@^3.4.4: - version "3.4.6" - resolved "https://registry.yarnpkg.com/fuse.js/-/fuse.js-3.4.6.tgz#545c3411fed88bf2e27c457cab6e73e7af697a45" - integrity sha512-H6aJY4UpLFwxj1+5nAvufom5b2BT2v45P1MkPvdGIK8fWjQx/7o6tTT1+ALV0yawQvbmvCF0ufl2et8eJ7v7Cg== +fuse.js@^3.6.1: + version "3.6.1" + resolved "https://registry.yarnpkg.com/fuse.js/-/fuse.js-3.6.1.tgz#7de85fdd6e1b3377c23ce010892656385fd9b10c" + integrity sha512-hT9yh/tiinkmirKrlv4KWOjztdoZo1mx9Qh4KvWqC7isoXwdUY3PNWUxceF4/qO9R6riA2C29jdTOeQOIROjgw== gensync@^1.0.0-beta.1: version "1.0.0-beta.1" @@ -1542,9 +1628,9 @@ globals@^11.1.0: integrity sha512-WOBp/EEGUiIsJSp7wcv/y6MO+lV9UoncWqxuFfm8eBwzWNgyfBd6Gz+IeKQ9jCmyhoH99g15M3T+QaVHFjizVA== globals@^12.1.0: - version "12.3.0" - resolved "https://registry.yarnpkg.com/globals/-/globals-12.3.0.tgz#1e564ee5c4dded2ab098b0f88f24702a3c56be13" - integrity sha512-wAfjdLgFsPZsklLJvOBUBmzYE8/CwhEqSBEMRXA3qxIiNtyqvjYurAtIfDh6chlEPUfmTY3MnZh5Hfh4q0UlIw== + version "12.4.0" + resolved "https://registry.yarnpkg.com/globals/-/globals-12.4.0.tgz#a18813576a41b00a24a97e7f815918c2e19925f8" + integrity sha512-BWICuzzDvDoH54NHKCseDanAhE3CeDorgDL5MT6LMXXj2WCnd9UC2szdk4AWLfjdgNBCXLUanXYcpBBKOSWGwg== dependencies: type-fest "^0.8.1" @@ -1606,7 +1692,7 @@ har-schema@^2.0.0: resolved "https://registry.yarnpkg.com/har-schema/-/har-schema-2.0.0.tgz#a94c2224ebcac04782a0d9035521f24735b7ec92" integrity sha1-qUwiJOvKwEeCoNkDVSHyRzW37JI= -har-validator@~5.1.0: +har-validator@~5.1.3: version "5.1.3" resolved "https://registry.yarnpkg.com/har-validator/-/har-validator-5.1.3.tgz#1ef89ebd3e4996557675eed9893110dc350fa080" integrity sha512-sNvOCzEQNr/qrvJgc3UG/kD4QtlHycrzwS+6mfTrrSq97BvaYcPZZI1ZSqGSPR73Cxn4LKTD4PttRwfU7jWq5g== @@ -1642,27 +1728,27 @@ has@^1.0.3: function-bind "^1.1.1" hasha@^5.0.0: - version "5.1.0" - resolved "https://registry.yarnpkg.com/hasha/-/hasha-5.1.0.tgz#dd05ccdfcfe7dab626247ce2a58efe461922f4ca" - integrity sha512-OFPDWmzPN1l7atOV1TgBVmNtBxaIysToK6Ve9DK+vT6pYuklw/nPNT+HJbZi0KDcI6vWB+9tgvZ5YD7fA3CXcA== + version "5.2.0" + resolved "https://registry.yarnpkg.com/hasha/-/hasha-5.2.0.tgz#33094d1f69c40a4a6ac7be53d5fe3ff95a269e0c" + integrity sha512-2W+jKdQbAdSIrggA8Q35Br8qKadTrqCTC8+XZvBWepKDK6m9XkX6Iz1a2yh2KP01kzAR/dpuMeUnocoLYDcskw== dependencies: is-stream "^2.0.0" type-fest "^0.8.0" hosted-git-info@^2.1.4: - version "2.8.5" - resolved "https://registry.yarnpkg.com/hosted-git-info/-/hosted-git-info-2.8.5.tgz#759cfcf2c4d156ade59b0b2dfabddc42a6b9c70c" - integrity sha512-kssjab8CvdXfcXMXVcvsXum4Hwdq9XGtRD3TteMEvEbq0LXyiNQr6AprqKqfeaDXze7SxWvRxdpwE6ku7ikLkg== + version "2.8.8" + resolved "https://registry.yarnpkg.com/hosted-git-info/-/hosted-git-info-2.8.8.tgz#7539bd4bc1e0e0a895815a2e0262420b12858488" + integrity sha512-f/wzC2QaWBs7t9IYqB4T3sR1xviIViXJRJTWBlx2Gf3g0Xi5vI7Yy4koXQ1c9OYDGHN9sBy1DQ2AB8fqZBWhUg== html-escaper@^2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/html-escaper/-/html-escaper-2.0.0.tgz#71e87f931de3fe09e56661ab9a29aadec707b491" - integrity sha512-a4u9BeERWGu/S8JiWEAQcdrg9v4QArtP9keViQjGMdff20fBdd8waotXaNmODqBe6uZ3Nafi7K/ho4gCQHV3Ig== + version "2.0.1" + resolved "https://registry.yarnpkg.com/html-escaper/-/html-escaper-2.0.1.tgz#beed86b5d2b921e92533aa11bce6d8e3b583dee7" + integrity sha512-hNX23TjWwD3q56HpWjUHOKj1+4KKlnjv9PcmBUYKVpga+2cnb9nDx/B1o0yO4n+RZXZdiNxzx6B24C9aNMTkkQ== http-cache-semantics@^4.0.0: - version "4.0.3" - resolved "https://registry.yarnpkg.com/http-cache-semantics/-/http-cache-semantics-4.0.3.tgz#495704773277eeef6e43f9ab2c2c7d259dda25c5" - integrity sha512-TcIMG3qeVLgDr1TEd2XvHaTnMPwYQUQMIBLy+5pLSDKYFc7UIqj39w8EGzZkaxoLv/l2K8HaI0t5AVA+YYgUew== + version "4.1.0" + resolved "https://registry.yarnpkg.com/http-cache-semantics/-/http-cache-semantics-4.1.0.tgz#49e91c5cbf36c9b94bcfcd71c23d5249ec74e390" + integrity sha512-carPklcUh7ROWRK7Cv27RPtdhYhUsela/ue5/jKzjegVvXDqM2ILE9Q2BGn9JZJh1g87cp56su/FgQSzcWS8cQ== http-signature@~1.2.0: version "1.2.0" @@ -1750,28 +1836,28 @@ ini@^1.3.5, ini@~1.3.0: integrity sha512-RZY5huIKCMRWDUqZlEi72f/lmXKMvuszcMBduliQ3nnWbx9X/ZBQO7DijMEYS9EhHBb2qacRUMtC7svLwe0lcw== inquirer@^7.0.0: - version "7.0.4" - resolved "https://registry.yarnpkg.com/inquirer/-/inquirer-7.0.4.tgz#99af5bde47153abca23f5c7fc30db247f39da703" - integrity sha512-Bu5Td5+j11sCkqfqmUTiwv+tWisMtP0L7Q8WrqA2C/BbBhy1YTdFrvjjlrKq8oagA/tLQBski2Gcx/Sqyi2qSQ== + version "7.1.0" + resolved "https://registry.yarnpkg.com/inquirer/-/inquirer-7.1.0.tgz#1298a01859883e17c7264b82870ae1034f92dd29" + integrity sha512-5fJMWEmikSYu0nv/flMc475MhGbB7TSPd/2IpFV4I4rMklboCH2rQjYY5kKiYGHqUF9gvaambupcJFFG9dvReg== dependencies: ansi-escapes "^4.2.1" - chalk "^2.4.2" + chalk "^3.0.0" cli-cursor "^3.1.0" cli-width "^2.0.0" external-editor "^3.0.3" figures "^3.0.0" lodash "^4.17.15" mute-stream "0.0.8" - run-async "^2.2.0" + run-async "^2.4.0" rxjs "^6.5.3" string-width "^4.1.0" - strip-ansi "^5.1.0" + strip-ansi "^6.0.0" through "^2.3.6" -irregular-plurals@^2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/irregular-plurals/-/irregular-plurals-2.0.0.tgz#39d40f05b00f656d0b7fa471230dd3b714af2872" - integrity sha512-Y75zBYLkh0lJ9qxeHlMjQ7bSbyiSqNW/UOPWDmzC7cXskL1hekSITh1Oc6JV0XCWWZ9DE8VYSB71xocLk3gmGw== +irregular-plurals@^3.2.0: + version "3.2.0" + resolved "https://registry.yarnpkg.com/irregular-plurals/-/irregular-plurals-3.2.0.tgz#b19c490a0723798db51b235d7e39add44dab0822" + integrity sha512-YqTdPLfwP7YFN0SsD3QUVCkm9ZG2VzOXv3DOrw5G5mkMbVwptTwVcFv7/C0vOpBmgTxAeTG19XpUs1E522LW9Q== is-arrayish@^0.2.1: version "0.2.1" @@ -2065,12 +2151,12 @@ json-stringify-safe@^5.0.1, json-stringify-safe@~5.0.1: resolved "https://registry.yarnpkg.com/json-stringify-safe/-/json-stringify-safe-5.0.1.tgz#1296a2d58fd45f19a0f6ce01d65701e2c735b6eb" integrity sha1-Epai1Y/UXxmg9s4B1lcB4sc1tus= -json5@^2.1.0: - version "2.1.1" - resolved "https://registry.yarnpkg.com/json5/-/json5-2.1.1.tgz#81b6cb04e9ba496f1c7005d07b4368a2638f90b6" - integrity sha512-l+3HXD0GEI3huGq1njuqtzYK8OYJyXMkOLtQ53pjWh89tvWS2h6l+1zMkYWqlb57+SiQodKZyvMEFb2X+KrFhQ== +json5@^2.1.2: + version "2.1.2" + resolved "https://registry.yarnpkg.com/json5/-/json5-2.1.2.tgz#43ef1f0af9835dd624751a6b7fa48874fb2d608e" + integrity sha512-MoUOQ4WdiN3yxhm7NEVJSJrieAo5hNSLQ5sj05OTRHPL9HOBy8u4Bu88jsC1jvqAdN+E1bJmsUcZH+1HQxliqQ== dependencies: - minimist "^1.2.0" + minimist "^1.2.5" jsonfile@^4.0.0: version "4.0.0" @@ -2079,6 +2165,15 @@ jsonfile@^4.0.0: optionalDependencies: graceful-fs "^4.1.6" +jsonfile@^6.0.1: + version "6.0.1" + resolved "https://registry.yarnpkg.com/jsonfile/-/jsonfile-6.0.1.tgz#98966cba214378c8c84b82e085907b40bf614179" + integrity sha512-jR2b5v7d2vIOust+w3wtFKZIfpC2pnRmFAhAC/BuweZFQR8qZzxH1OyrQ10HmdVYiXWkYUqPVsz91cG7EL2FBg== + dependencies: + universalify "^1.0.0" + optionalDependencies: + graceful-fs "^4.1.6" + jsprim@^1.2.2: version "1.4.1" resolved "https://registry.yarnpkg.com/jsprim/-/jsprim-1.4.1.tgz#313e66bc1e5cc06e438bc1b7499c2e5c56acb6a2" @@ -2090,9 +2185,9 @@ jsprim@^1.2.2: verror "1.10.0" just-extend@^4.0.2: - version "4.0.2" - resolved "https://registry.yarnpkg.com/just-extend/-/just-extend-4.0.2.tgz#f3f47f7dfca0f989c55410a7ebc8854b07108afc" - integrity sha512-FrLwOgm+iXrPV+5zDU6Jqu4gCRXbWEQg2O3SKONsWE4w7AXFRkryS53bpWdaL9cNol+AmR3AEYz6kn+o0fCPnw== + version "4.1.0" + resolved "https://registry.yarnpkg.com/just-extend/-/just-extend-4.1.0.tgz#7278a4027d889601640ee0ce0e5a00b992467da4" + integrity sha512-ApcjaOdVTJ7y4r08xI5wIqpvwS48Q0PBG4DJROcEkH1f8MdAiNFyFxz3xoL0LWAVwjrwPYZdVHHxhRHcx/uGLA== keyv@^3.0.0: version "3.1.0" @@ -2212,13 +2307,6 @@ log-symbols@^3.0.0: dependencies: chalk "^2.4.2" -lolex@^5.0.1, lolex@^5.1.2: - version "5.1.2" - resolved "https://registry.yarnpkg.com/lolex/-/lolex-5.1.2.tgz#953694d098ce7c07bc5ed6d0e42bc6c0c6d5a367" - integrity sha512-h4hmjAvHTmd+25JSwrtTIuwbKdwg5NzZVRMLn9saij4SZaepCrTCxPr35H/3bjwfMJtN+t3CX8672UIkglz28A== - dependencies: - "@sinonjs/commons" "^1.7.0" - loud-rejection@^1.0.0: version "1.6.0" resolved "https://registry.yarnpkg.com/loud-rejection/-/loud-rejection-1.6.0.tgz#5b46f80147edee578870f086d04821cf998e551f" @@ -2237,10 +2325,10 @@ lowercase-keys@^2.0.0: resolved "https://registry.yarnpkg.com/lowercase-keys/-/lowercase-keys-2.0.0.tgz#2603e78b7b4b0006cbca2fbcc8a3202558ac9479" integrity sha512-tqNXrS78oMOE73NMxK4EMLQsQowWf8jKooH9g7xPavRT706R6bkQJ6DY2Te7QukaZsulxa30wQ7bk0pm4XiHmA== -make-dir@^3.0.0: - version "3.0.0" - resolved "https://registry.yarnpkg.com/make-dir/-/make-dir-3.0.0.tgz#1b5f39f6b9270ed33f9f054c5c0f84304989f801" - integrity sha512-grNJDhb8b1Jm1qeqW5R/O63wUo4UXo2v2HMic6YT9i/HBlF93S8jkMgH7yugvY9ABDShH4VZMn8I+U8+fCNegw== +make-dir@^3.0.0, make-dir@^3.0.2: + version "3.0.2" + resolved "https://registry.yarnpkg.com/make-dir/-/make-dir-3.0.2.tgz#04a1acbf22221e1d6ef43559f43e05a90dbb4392" + integrity sha512-rYKABKutXa6vXTXhoV18cBE7PaewPXHe/Bdq4v+ZLMhxbWApkFFplT0LcbMW+6BbjnQXzZ/sAvSE/JdguApG5w== dependencies: semver "^6.0.0" @@ -2350,22 +2438,17 @@ minimist-options@^3.0.1: arrify "^1.0.1" is-plain-obj "^1.1.0" -minimist@0.0.8: - version "0.0.8" - resolved "https://registry.yarnpkg.com/minimist/-/minimist-0.0.8.tgz#857fcabfc3397d2625b8228262e86aa7a011b05d" - integrity sha1-hX/Kv8M5fSYluCKCYuhqp6ARsF0= +minimist@^1.2.0, minimist@^1.2.5: + version "1.2.5" + resolved "https://registry.yarnpkg.com/minimist/-/minimist-1.2.5.tgz#67d66014b66a6a8aaa0c083c5fd58df4e4e97602" + integrity sha512-FM9nNUYrRBAELZQT3xeZQ7fmMOBg6nWNmJKTcgsJeaLstP/UODVpGsr5OhXhhXg6f+qtJ8uiZ+PUxkDWcgIXLw== -minimist@^1.2.0: - version "1.2.0" - resolved "https://registry.yarnpkg.com/minimist/-/minimist-1.2.0.tgz#a35008b20f41383eec1fb914f4cd5df79a264284" - integrity sha1-o1AIsg9BOD7sH7kU9M1d95omQoQ= - -mkdirp@^0.5.0, mkdirp@^0.5.1: - version "0.5.1" - resolved "https://registry.yarnpkg.com/mkdirp/-/mkdirp-0.5.1.tgz#30057438eac6cf7f8c4767f38648d6697d75c903" - integrity sha1-MAV0OOrGz3+MR2fzhkjWaX11yQM= +mkdirp@^0.5.1: + version "0.5.3" + resolved "https://registry.yarnpkg.com/mkdirp/-/mkdirp-0.5.3.tgz#5a514b7179259287952881e94410ec5465659f8c" + integrity sha512-P+2gwrFqx8lhew375MQHHeTlY8AuOJSrGf0R5ddkEndUkmwpgUob/vQuBD1V22/Cw1/lJr4x+EjllSezBThzBg== dependencies: - minimist "0.0.8" + minimist "^1.2.5" mockdate@^2.0.2: version "2.0.5" @@ -2402,27 +2485,25 @@ nice-try@^1.0.4: resolved "https://registry.yarnpkg.com/nice-try/-/nice-try-1.0.5.tgz#a3378a7696ce7d223e88fc9b764bd7ef1089e366" integrity sha512-1nh45deeb5olNY7eX82BkPO7SSxR5SSYJiPTrTdFUVYwAl8CKMA5N9PjTYkHiRjisVcxcQ1HXdLhx2qxxJzLNQ== -nise@^3.0.1: - version "3.0.1" - resolved "https://registry.yarnpkg.com/nise/-/nise-3.0.1.tgz#0659982af515e5aac15592226246243e8da0013d" - integrity sha512-fYcH9y0drBGSoi88kvhpbZEsenX58Yr+wOJ4/Mi1K4cy+iGP/a73gNoyNhu5E9QxPdgTlVChfIaAlnyOy/gHUA== +nise@^4.0.1: + version "4.0.3" + resolved "https://registry.yarnpkg.com/nise/-/nise-4.0.3.tgz#9f79ff02fa002ed5ffbc538ad58518fa011dc913" + integrity sha512-EGlhjm7/4KvmmE6B/UFsKh7eHykRl9VH+au8dduHLCyWUO/hr7+N+WtTvDUwc9zHuM1IaIJs/0lQ6Ag1jDkQSg== dependencies: "@sinonjs/commons" "^1.7.0" - "@sinonjs/formatio" "^4.0.1" + "@sinonjs/fake-timers" "^6.0.0" "@sinonjs/text-encoding" "^0.7.1" just-extend "^4.0.2" - lolex "^5.0.1" path-to-regexp "^1.7.0" -nock@^11.7.2: - version "11.7.2" - resolved "https://registry.yarnpkg.com/nock/-/nock-11.7.2.tgz#4cee4fa838dc3635c074c5b3436bcdec7f7ee213" - integrity sha512-7swr5bL1xBZ5FctyubjxEVySXOSebyqcL7Vy1bx1nS9IUqQWj81cmKjVKJLr8fHhtzI1MV8nyCdENA/cGcY1+Q== +nock@^12.0.3: + version "12.0.3" + resolved "https://registry.yarnpkg.com/nock/-/nock-12.0.3.tgz#83f25076dbc4c9aa82b5cdf54c9604c7a778d1c9" + integrity sha512-QNb/j8kbFnKCiyqi9C5DD0jH/FubFGj5rt9NQFONXwQm3IPB0CULECg/eS3AU1KgZb/6SwUa4/DTRKhVxkGABw== dependencies: debug "^4.1.0" json-stringify-safe "^5.0.1" lodash "^4.17.13" - mkdirp "^0.5.0" propagate "^2.0.0" node-notifier@^6.0.0: @@ -2744,9 +2825,9 @@ performance-now@^2.1.0: integrity sha1-Ywn04OX6kT7BxpMHrjZLSzd8nns= picomatch@^2.0.4, picomatch@^2.0.5, picomatch@^2.0.7, picomatch@^2.2.1: - version "2.2.1" - resolved "https://registry.yarnpkg.com/picomatch/-/picomatch-2.2.1.tgz#21bac888b6ed8601f831ce7816e335bc779f0a4a" - integrity sha512-ISBaA8xQNmwELC7eOjqFKMESB2VIqt4PPDD0nsS95b/9dZXvVKOlz9keMSnoGGKcOHXfTvDD6WMaRoSc9UuhRA== + version "2.2.2" + resolved "https://registry.yarnpkg.com/picomatch/-/picomatch-2.2.2.tgz#21f333e9b6b8eaff02468f5146ea406d345f4dad" + integrity sha512-q0M/9eZHzmr0AulXyPwNfZjtwZ/RBZlbN3K3CErVrk50T2ASYI7Bye0EvekFY3IP1Nt2DHu0re+V2ZHIpMkuWg== pidtree@^0.3.0: version "0.3.0" @@ -2787,12 +2868,12 @@ plist@^3.0.1: xmlbuilder "^9.0.7" xmldom "0.1.x" -plur@^3.1.1: - version "3.1.1" - resolved "https://registry.yarnpkg.com/plur/-/plur-3.1.1.tgz#60267967866a8d811504fe58f2faaba237546a5b" - integrity sha512-t1Ax8KUvV3FFII8ltczPn2tJdjqbd1sIzu6t4JL7nQ3EyeL/lTrj5PWKb06ic5/6XYDr65rQ4uzQEGN70/6X5w== +plur@^4.0.0: + version "4.0.0" + resolved "https://registry.yarnpkg.com/plur/-/plur-4.0.0.tgz#729aedb08f452645fe8c58ef115bf16b0a73ef84" + integrity sha512-4UGewrYgqDFw9vV6zNV+ADmPAUAfJPKtGvb/VdpQAx25X5f3xXdGdyOEVFwkl8Hl/tl7+xbeHqSEM+D5/TirUg== dependencies: - irregular-plurals "^2.0.0" + irregular-plurals "^3.2.0" prelude-ls@~1.1.2: version "1.1.2" @@ -2804,10 +2885,10 @@ prepend-http@^2.0.0: resolved "https://registry.yarnpkg.com/prepend-http/-/prepend-http-2.0.0.tgz#e92434bfa5ea8c19f41cdfd401d741a3c819d897" integrity sha1-6SQ0v6XqjBn0HN/UAddBo8gZ2Jc= -pretty-ms@^5.1.0: - version "5.1.0" - resolved "https://registry.yarnpkg.com/pretty-ms/-/pretty-ms-5.1.0.tgz#b906bdd1ec9e9799995c372e2b1c34f073f95384" - integrity sha512-4gaK1skD2gwscCfkswYQRmddUb2GJZtzDGRjHWadVHtK/DIKFufa12MvES6/xu1tVbUYeia5bmLcwJtZJQUqnw== +pretty-ms@^6.0.0: + version "6.0.1" + resolved "https://registry.yarnpkg.com/pretty-ms/-/pretty-ms-6.0.1.tgz#03ec6cfee20329f142645e63efad96bb775d3da4" + integrity sha512-ke4njoVmlotekHlHyCZ3wI/c5AMT8peuHs8rKJqekj/oR5G8lND2dVpicFlUz5cbZgE290vvkMuDwfj/OcW1kw== dependencies: parse-ms "^2.1.0" @@ -2828,7 +2909,7 @@ propagate@^2.0.0: resolved "https://registry.yarnpkg.com/propagate/-/propagate-2.0.1.tgz#40cdedab18085c792334e64f0ac17256d38f9a45" integrity sha512-vGrhOavPSTz4QVNuBNdcNXePNdNMaO1xj9yBeH1ScQPjk/rhg9sSlCXPhMkFuaNNW/syTvYqsnbIJxMBfRbbag== -psl@^1.1.24: +psl@^1.1.28: version "1.7.0" resolved "https://registry.yarnpkg.com/psl/-/psl-1.7.0.tgz#f1c4c47a8ef97167dea5d6bbf4816d736e884a3c" integrity sha512-5NsSEDv8zY70ScRnOTn7bK7eanl2MvFrOrS/R6x+dBt5g1ghnj9Zv90kO8GwT8gxcu2ANyFprnFYB85IogIJOQ== @@ -2841,16 +2922,18 @@ pump@^3.0.0: end-of-stream "^1.1.0" once "^1.3.1" -punycode@^1.4.1: - version "1.4.1" - resolved "https://registry.yarnpkg.com/punycode/-/punycode-1.4.1.tgz#c0d5a63b2718800ad8e1eb0fa5269c84dd41845e" - integrity sha1-wNWmOycYgArY4esPpSachN1BhF4= - -punycode@^2.1.0: +punycode@^2.1.0, punycode@^2.1.1: version "2.1.1" resolved "https://registry.yarnpkg.com/punycode/-/punycode-2.1.1.tgz#b58b010ac40c22c5657616c8d2c2c02c7bf479ec" integrity sha512-XRsRjdf+j5ml+y/6GKHPZbrF/8p2Yga0JPtdqTIY2Xe5ohJPD9saDJJLPvp9+NSBprVvevdXZybnj2cv8OEd0A== +pupa@^2.0.1: + version "2.0.1" + resolved "https://registry.yarnpkg.com/pupa/-/pupa-2.0.1.tgz#dbdc9ff48ffbea4a26a069b6f9f7abb051008726" + integrity sha512-hEJH0s8PXLY/cdXh66tNEQGndDrIKNqNC5xmrysZy3i5C3oEoLna7YAOad+7u125+zH1HNXUmGEkrhb3c2VriA== + dependencies: + escape-goat "^2.0.0" + qs@~6.5.2: version "6.5.2" resolved "https://registry.yarnpkg.com/qs/-/qs-6.5.2.tgz#cb3ae806e8740444584ef154ce8ee98d403f3e36" @@ -2954,9 +3037,9 @@ release-zalgo@^1.0.0: es6-error "^4.0.1" request@^2.88.0: - version "2.88.0" - resolved "https://registry.yarnpkg.com/request/-/request-2.88.0.tgz#9c2fca4f7d35b592efe57c7f0a55e81052124fef" - integrity sha512-NAqBSrijGLZdM0WZNsInLJpkJokL72XYjUpnB0iwsRgxh7dB6COrHnTBNwN0E+lHDAJzu7kLAkDeY08z2/A0hg== + version "2.88.2" + resolved "https://registry.yarnpkg.com/request/-/request-2.88.2.tgz#d73c918731cb5a87da047e207234146f664d12b3" + integrity sha512-MsvtOrfG9ZcrOwAW+Qi+F6HbD0CWXEh9ou77uOb7FM2WPhwT7smM833PzanhJLsgXjN89Ir6V2PczXNnMpwKhw== dependencies: aws-sign2 "~0.7.0" aws4 "^1.8.0" @@ -2965,7 +3048,7 @@ request@^2.88.0: extend "~3.0.2" forever-agent "~0.6.1" form-data "~2.3.2" - har-validator "~5.1.0" + har-validator "~5.1.3" http-signature "~1.2.0" is-typedarray "~1.0.0" isstream "~0.1.2" @@ -2975,7 +3058,7 @@ request@^2.88.0: performance-now "^2.1.0" qs "~6.5.2" safe-buffer "^5.1.2" - tough-cookie "~2.4.3" + tough-cookie "~2.5.0" tunnel-agent "^0.6.0" uuid "^3.3.2" @@ -3007,9 +3090,9 @@ resolve-from@^5.0.0: integrity sha512-qYg9KP24dD5qka9J47d0aVky0N+b4fTU89LN9iDnjB5waksiC49rvMB0PrUJQGoTmH50XPiqOvAjDfaijGxYZw== resolve@^1.10.0, resolve@^1.3.2: - version "1.15.0" - resolved "https://registry.yarnpkg.com/resolve/-/resolve-1.15.0.tgz#1b7ca96073ebb52e741ffd799f6b39ea462c67f5" - integrity sha512-+hTmAldEGE80U2wJJDC1lebb5jWqvTYAfm3YZ1ckk1gBr0MnCqUKlwK1e+anaFljIl+F5tR5IoZcm4ZDA1zMQw== + version "1.15.1" + resolved "https://registry.yarnpkg.com/resolve/-/resolve-1.15.1.tgz#27bdcdeffeaf2d6244b95bb0f9f4b4653451f3e8" + integrity sha512-84oo6ZTtoTUpjgNEr5SJyzQhzL72gaRodsSfyxC/AXRvwu0Yse9H8eF9IpGo7b8YetZhlI6v7ZQ6bKBFV/6S7w== dependencies: path-parse "^1.0.6" @@ -3028,7 +3111,7 @@ restore-cursor@^3.1.0: onetime "^5.1.0" signal-exit "^3.0.2" -reusify@^1.0.0: +reusify@^1.0.4: version "1.0.4" resolved "https://registry.yarnpkg.com/reusify/-/reusify-1.0.4.tgz#90da382b1e126efc02146e90845a88db12925d76" integrity sha512-U9nH88a3fc/ekCF1l0/UP1IosiuIjyTh7hBvXVMHYgVcfGvt897Xguj2UOLDeI5BG2m7/uwyaLVT6fbtCwTyzw== @@ -3041,16 +3124,16 @@ rimraf@2.6.3: glob "^7.1.3" rimraf@^3.0.0: - version "3.0.1" - resolved "https://registry.yarnpkg.com/rimraf/-/rimraf-3.0.1.tgz#48d3d4cb46c80d388ab26cd61b1b466ae9ae225a" - integrity sha512-IQ4ikL8SjBiEDZfk+DFVwqRK8md24RWMEJkdSlgNLkyyAImcjf8SWvU1qFMDOb4igBClbTQ/ugPqXcRwdFTxZw== + version "3.0.2" + resolved "https://registry.yarnpkg.com/rimraf/-/rimraf-3.0.2.tgz#f1a5402ba6220ad52cc1282bac1ae3aa49fd061a" + integrity sha512-JZkJMZkAGFFPP2YqXZXPbMlMBgsxzE8ILs4lMIX/2o0L9UBw9O/Y3o6wFw/i9YLapcUJWwqbi3kdxIPdC62TIA== dependencies: glob "^7.1.3" -run-async@^2.2.0: - version "2.3.0" - resolved "https://registry.yarnpkg.com/run-async/-/run-async-2.3.0.tgz#0371ab4ae0bdd720d4166d7dfda64ff7a445a6c0" - integrity sha1-A3GrSuC91yDUFm19/aZP96RFpsA= +run-async@^2.4.0: + version "2.4.0" + resolved "https://registry.yarnpkg.com/run-async/-/run-async-2.4.0.tgz#e59054a5b86876cfae07f431d18cbaddc594f1e8" + integrity sha512-xJTbh/d7Lm7SBhc1tNvTpeCHaEzoyxPrqNlvSdMfBTYwaY++UJFyXUOxAtsRUXjlqOfj8luNaR9vjCh4KeV+pg== dependencies: is-promise "^2.1.0" @@ -3099,9 +3182,9 @@ semver@^6.0.0, semver@^6.1.2, semver@^6.2.0, semver@^6.3.0: integrity sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw== semver@^7.1.2: - version "7.1.2" - resolved "https://registry.yarnpkg.com/semver/-/semver-7.1.2.tgz#847bae5bce68c5d08889824f02667199b70e3d87" - integrity sha512-BJs9T/H8sEVHbeigqzIEo57Iu/3DG6c4QoqTfbQB3BPA4zgzAomh/Fk9E7QtjWQ8mx2dgA9YCfSF4y9k9bHNpQ== + version "7.1.3" + resolved "https://registry.yarnpkg.com/semver/-/semver-7.1.3.tgz#e4345ce73071c53f336445cfc19efb1c311df2a6" + integrity sha512-ekM0zfiA9SCBlsKa2X1hxyxiI4L3B6EbVJkkdgQXnSEEaHlGdvyodMruTiulSRWMMB4NeIuYNMC9rTKTz97GxA== serialize-error@^2.1.0: version "2.1.0" @@ -3152,17 +3235,17 @@ signal-exit@^3.0.0, signal-exit@^3.0.2: resolved "https://registry.yarnpkg.com/signal-exit/-/signal-exit-3.0.2.tgz#b5fdc08f1287ea1178628e415e25132b73646c6d" integrity sha1-tf3AjxKH6hF4Yo5BXiUTK3NkbG0= -sinon@^8.1.1: - version "8.1.1" - resolved "https://registry.yarnpkg.com/sinon/-/sinon-8.1.1.tgz#21fffd5ad0a2d072a8aa7f8a3cf7ed2ced497497" - integrity sha512-E+tWr3acRdoe1nXbHMu86SSqA1WGM7Yw3jZRLvlCMnXwTHP8lgFFVn5BnKnF26uc5SfZ3D7pA9sN7S3Y2jG4Ew== +sinon@^9.0.1: + version "9.0.1" + resolved "https://registry.yarnpkg.com/sinon/-/sinon-9.0.1.tgz#dbb18f7d8f5835bcf91578089c0a97b2fffdd73b" + integrity sha512-iTTyiQo5T94jrOx7X7QLBZyucUJ2WvL9J13+96HMfm2CGoJYbIPqRfl6wgNcqmzk0DI28jeGx5bUTXizkrqBmg== dependencies: "@sinonjs/commons" "^1.7.0" - "@sinonjs/formatio" "^4.0.1" - "@sinonjs/samsam" "^4.2.2" + "@sinonjs/fake-timers" "^6.0.0" + "@sinonjs/formatio" "^5.0.1" + "@sinonjs/samsam" "^5.0.3" diff "^4.0.2" - lolex "^5.1.2" - nise "^3.0.1" + nise "^4.0.1" supports-color "^7.1.0" slash@^3.0.0: @@ -3462,13 +3545,13 @@ to-regex-range@^5.0.1: dependencies: is-number "^7.0.0" -tough-cookie@~2.4.3: - version "2.4.3" - resolved "https://registry.yarnpkg.com/tough-cookie/-/tough-cookie-2.4.3.tgz#53f36da3f47783b0925afa06ff9f3b165280f781" - integrity sha512-Q5srk/4vDM54WJsJio3XNn6K2sCG+CQ8G5Wz6bZhRZoAe/+TxjWB/GlFAnYEbkYVlON9FMk/fE3h2RLpPXo4lQ== +tough-cookie@~2.5.0: + version "2.5.0" + resolved "https://registry.yarnpkg.com/tough-cookie/-/tough-cookie-2.5.0.tgz#cd9fb2a0aa1d5a12b473bd9fb96fa3dcff65ade2" + integrity sha512-nlLsUzgm1kfLXSXfRZMc1KLAugd4hqJHDTvc2hDIwS3mZAfMEuMbc03SujMF+GEcpaX/qboeycw6iO8JwVv2+g== dependencies: - psl "^1.1.24" - punycode "^1.4.1" + psl "^1.1.28" + punycode "^2.1.1" trim-newlines@^2.0.0: version "2.0.0" @@ -3481,14 +3564,14 @@ trim-off-newlines@^1.0.1: integrity sha1-n5up2e+odkw4dpi8v+sshI8RrbM= tslib@^1.10.0, tslib@^1.8.1, tslib@^1.9.0: - version "1.10.0" - resolved "https://registry.yarnpkg.com/tslib/-/tslib-1.10.0.tgz#c3c19f95973fb0a62973fb09d90d961ee43e5c8a" - integrity sha512-qOebF53frne81cf0S9B41ByenJ3/IuH8yJKngAX35CmiZySA0khhkovshKK+jGCaMnVomla7gVlIcc3EvKPbTQ== + version "1.11.1" + resolved "https://registry.yarnpkg.com/tslib/-/tslib-1.11.1.tgz#eb15d128827fbee2841549e171f45ed338ac7e35" + integrity sha512-aZW88SY8kQbU7gpV19lN24LtXh/yD4ZZg6qieAJDDg+YBsJcSmLGK9QpnUjAKVG/xefmvJGd1WUmfpT/g6AJGA== tslint@^6.0.0: - version "6.0.0" - resolved "https://registry.yarnpkg.com/tslint/-/tslint-6.0.0.tgz#1c0148beac4779924216302f192cdaa153618310" - integrity sha512-9nLya8GBtlFmmFMW7oXXwoXS1NkrccqTqAtwXzdPV9e2mqSEvCki6iHL/Fbzi5oqbugshzgGPk7KBb2qNP1DSA== + version "6.1.0" + resolved "https://registry.yarnpkg.com/tslint/-/tslint-6.1.0.tgz#c6c611b8ba0eed1549bf5a59ba05a7732133d851" + integrity sha512-fXjYd/61vU6da04E505OZQGb2VCN2Mq3doeWcOIryuG+eqdmFUXTYVwdhnbEu2k46LNLgUYt9bI5icQze/j0bQ== dependencies: "@babel/code-frame" "^7.0.0" builtin-modules "^1.1.1" @@ -3542,6 +3625,11 @@ type-detect@4.0.8, type-detect@^4.0.8: resolved "https://registry.yarnpkg.com/type-detect/-/type-detect-4.0.8.tgz#7646fb5f18871cfbb7749e69bd39a6388eb7450c" integrity sha512-0fr/mIH1dlO+x7TlcMy+bIDqKPsw/70tVyeHW787goQjhmqaZe10uwLujubK9q9Lg6Fiho1KUKDYz0Z7k7g5/g== +type-fest@^0.11.0: + version "0.11.0" + resolved "https://registry.yarnpkg.com/type-fest/-/type-fest-0.11.0.tgz#97abf0872310fed88a5c466b25681576145e33f1" + integrity sha512-OdjXJxnCN1AvyLSzeKIgXTXxV+99ZuXl3Hpo9XpJAv9MBcHrrJOQ5kV7ypXOuQie+AmWG25hLbiKdwYTifzcfQ== + type-fest@^0.3.0: version "0.3.1" resolved "https://registry.yarnpkg.com/type-fest/-/type-fest-0.3.1.tgz#63d00d204e059474fe5e1b7c011112bbd1dc29e1" @@ -3565,9 +3653,9 @@ typedarray-to-buffer@^3.1.5: is-typedarray "^1.0.0" typescript@^3.7.5: - version "3.7.5" - resolved "https://registry.yarnpkg.com/typescript/-/typescript-3.7.5.tgz#0692e21f65fd4108b9330238aac11dd2e177a1ae" - integrity sha512-/P5lkRXkWHNAbcJIiHPfRoKqyd7bsyCma1hZNUGfn20qm64T6ZBlrzprymeu918H+mB/0rIg2gGK/BXkhhYgBw== + version "3.8.3" + resolved "https://registry.yarnpkg.com/typescript/-/typescript-3.8.3.tgz#409eb8544ea0335711205869ec458ab109ee1061" + integrity sha512-MYlEfn5VrLNsgudQTVJeNaQFUAI7DkhnOjdpAp4T+ku1TfQClewlbSuTVHiA+8skNBgaf02TL/kLOvig4y3G8w== unique-string@^2.0.0: version "2.0.0" @@ -3581,19 +3669,24 @@ universalify@^0.1.0: resolved "https://registry.yarnpkg.com/universalify/-/universalify-0.1.2.tgz#b646f69be3942dabcecc9d6639c80dc105efaa66" integrity sha512-rBJeI5CXAlmy1pV+617WB9J63U6XcazHHF2f2dbJix4XzpUF0RS3Zbj0FGIOCAva5P/d/GBOYaACQ1w+0azUkg== +universalify@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/universalify/-/universalify-1.0.0.tgz#b61a1da173e8435b2fe3c67d29b9adf8594bd16d" + integrity sha512-rb6X1W158d7pRQBg5gkR8uPaSfiids68LTJQYOtEUhoJUWBdaQHsuT/EUduxXYxcrt4r5PJ4fuHW1MHT6p0qug== + untildify@^4.0.0: version "4.0.0" resolved "https://registry.yarnpkg.com/untildify/-/untildify-4.0.0.tgz#2bc947b953652487e4600949fb091e3ae8cd919b" integrity sha512-KK8xQ1mkzZeg9inewmFVDNkg3l5LUhoq9kN6iWYB/CC9YMG8HA+c1Q8HwDe6dEX7kErrEVNVBO3fWsVq5iDgtw== -update-notifier@^4.0.0: - version "4.0.0" - resolved "https://registry.yarnpkg.com/update-notifier/-/update-notifier-4.0.0.tgz#f344a6f8b03e00e31b323d632a0e632e9f0e0654" - integrity sha512-p9zf71hWt5GVXM4iEBujpUgx8mK9AWiCCapEJm/O1z5ntCim83Z1ATqzZFBHFYqx03laMqv8LiDgs/7ikXjf/g== +update-notifier@^4.1.0: + version "4.1.0" + resolved "https://registry.yarnpkg.com/update-notifier/-/update-notifier-4.1.0.tgz#4866b98c3bc5b5473c020b1250583628f9a328f3" + integrity sha512-w3doE1qtI0/ZmgeoDoARmI5fjDoT93IfKgEGqm26dGUOh8oNpaSTsGNdYRN/SjOuo10jcJGwkEL3mroKzktkew== dependencies: boxen "^4.2.0" chalk "^3.0.0" - configstore "^5.0.0" + configstore "^5.0.1" has-yarn "^2.1.0" import-lazy "^2.1.0" is-ci "^2.0.0" @@ -3601,6 +3694,7 @@ update-notifier@^4.0.0: is-npm "^4.0.0" is-yarn-global "^0.3.0" latest-version "^5.0.0" + pupa "^2.0.1" semver-diff "^3.1.1" xdg-basedir "^4.0.0" @@ -3703,9 +3797,9 @@ wrappy@1: integrity sha1-tSQ9jz7BqjXxNkYFvA0QNuMKtp8= write-file-atomic@^3.0.0, write-file-atomic@^3.0.1: - version "3.0.1" - resolved "https://registry.yarnpkg.com/write-file-atomic/-/write-file-atomic-3.0.1.tgz#558328352e673b5bb192cf86500d60b230667d4b" - integrity sha512-JPStrIyyVJ6oCSz/691fAjFtefZ6q+fP6tm+OS4Qw6o+TGQxNp1ziY2PgS+X/m0V8OWhZiO/m4xSj+Pr4RrZvw== + version "3.0.3" + resolved "https://registry.yarnpkg.com/write-file-atomic/-/write-file-atomic-3.0.3.tgz#56bd5c5a5c70481cd19c571bd39ab965a5de56e8" + integrity sha512-AvHcyZ5JnSfq3ioSyjrBkH9yW4m7Ayk8/9My/DD9onKeu/94fwrMocemO2QAJFAlnnDN+ZDS+ZjAR5ua1/PV/Q== dependencies: imurmurhash "^0.1.4" is-typedarray "^1.0.0" @@ -3746,18 +3840,18 @@ yargs-parser@^10.0.0: dependencies: camelcase "^4.1.0" -yargs-parser@^16.1.0: - version "16.1.0" - resolved "https://registry.yarnpkg.com/yargs-parser/-/yargs-parser-16.1.0.tgz#73747d53ae187e7b8dbe333f95714c76ea00ecf1" - integrity sha512-H/V41UNZQPkUMIT5h5hiwg4QKIY1RPvoBV4XcjUbRM8Bk2oKqqyZ0DIEbTFZB0XjbtSPG8SAa/0DxCQmiRgzKg== +yargs-parser@^18.1.1: + version "18.1.1" + resolved "https://registry.yarnpkg.com/yargs-parser/-/yargs-parser-18.1.1.tgz#bf7407b915427fc760fcbbccc6c82b4f0ffcbd37" + integrity sha512-KRHEsOM16IX7XuLnMOqImcPNbLVXMNHYAoFc3BKR8Ortl5gzDbtXvvEoGx9imk5E+X1VeNKNlcHr8B8vi+7ipA== dependencies: camelcase "^5.0.0" decamelize "^1.2.0" yargs@^15.0.2, yargs@^15.1.0: - version "15.1.0" - resolved "https://registry.yarnpkg.com/yargs/-/yargs-15.1.0.tgz#e111381f5830e863a89550bd4b136bb6a5f37219" - integrity sha512-T39FNN1b6hCW4SOIk1XyTOWxtXdcen0t+XYrysQmChzSipvhBO8Bj0nK1ozAasdk24dNWuMZvr4k24nz+8HHLg== + version "15.3.1" + resolved "https://registry.yarnpkg.com/yargs/-/yargs-15.3.1.tgz#9505b472763963e54afe60148ad27a330818e98b" + integrity sha512-92O1HWEjw27sBfgmXiixJWT5hRBp2eobqXicLtPBIDBhYB+1HpwZlXmbW2luivBJHBzki+7VyCLRtAkScbTBQA== dependencies: cliui "^6.0.0" decamelize "^1.2.0" @@ -3769,4 +3863,4 @@ yargs@^15.0.2, yargs@^15.1.0: string-width "^4.2.0" which-module "^2.0.0" y18n "^4.0.0" - yargs-parser "^16.1.0" + yargs-parser "^18.1.1" From 47e105fc70bbfe9b7c8055a1d5f82df3b6c0f72a Mon Sep 17 00:00:00 2001 From: Maarten de Boer Date: Sat, 21 Mar 2020 20:28:11 +0100 Subject: [PATCH 05/13] Typos en minor fixes --- src/bin/link.ts | 10 ++++------ src/bin/unlink.ts | 6 ++---- src/hugo.ts | 5 +++-- src/utils.ts | 2 +- 4 files changed, 10 insertions(+), 13 deletions(-) diff --git a/src/bin/link.ts b/src/bin/link.ts index 4e31b60..d613c5f 100644 --- a/src/bin/link.ts +++ b/src/bin/link.ts @@ -13,7 +13,7 @@ if (process.getuid && process.getuid() === 0) { process.exit(1); } -// Get alfred ersion +// Get alfred version const apps = glob.sync('/Applications/Alfred?( )+([0-9]).app'); for (const app of apps) { @@ -51,7 +51,7 @@ for (const app of apps) { // Skip if destination exists but is not a directory or symlink if (destStat.isSymbolicLink() === false) { - console.debug('Desination exists but is neither a directory or symlink, skipping.'); + console.debug('Destination exists but is neither a directory or symlink, skipping.'); return; } @@ -66,12 +66,10 @@ for (const app of apps) { } // Create symlink - fs.ensureSymlink(src, dest); + fs.ensureSymlinkSync(src, dest); }) .catch((err) => { console.error(err); }); - } catch (err) { - continue; - } + } catch (err) {} } diff --git a/src/bin/unlink.ts b/src/bin/unlink.ts index d764057..d6d78d5 100644 --- a/src/bin/unlink.ts +++ b/src/bin/unlink.ts @@ -13,7 +13,7 @@ if (process.getuid && process.getuid() === 0) { process.exit(1); } -// Get alfred ersion +// Get alfred version const apps = glob.sync('/Applications/Alfred?( )+([0-9]).app'); for (const app of apps) { @@ -54,7 +54,5 @@ for (const app of apps) { del.sync(dest, { force: true }); }); - } catch (err) { - continue; - } + } catch (err) {} } diff --git a/src/hugo.ts b/src/hugo.ts index d6a37c8..5a5f6a7 100644 --- a/src/hugo.ts +++ b/src/hugo.ts @@ -60,7 +60,7 @@ export class Hugo { // Initialize updater this.updater = new Updater(this.cache, this.options.updateInterval); - // Notofier + // Notifier this.notifier = new NotificationCenter({ withFallback: true, }); @@ -175,6 +175,7 @@ export class Hugo { // Check if version is valid if (version === null) { if (process.env.alfred_debug === '1') { + // eslint-disable-next-line max-len console.error(`Invalid workflow version: ${process.env.alfred_workflow_version}. Open your workflow in Alfred, click on the [x]-Symbol and set a semantic version number.`); } @@ -280,7 +281,7 @@ export class Hugo { * * This allows you to read and process the data once, then storing it in cache until the file has changed again. * - * @param filepath File path + * @param filePath File path * @param options Cache options * * @return FileCache diff --git a/src/utils.ts b/src/utils.ts index 7644bbf..3b9e539 100644 --- a/src/utils.ts +++ b/src/utils.ts @@ -17,7 +17,7 @@ class Utils{ } /** - * Resolve alfred prefrerences file path + * Resolve alfred preferences file path */ resolveAlfredPrefs(version: string | semver.SemVer): string | null { if (typeof version === 'string') { From 581c92b974190f8ffe54d22cd502d142e4b66b4e Mon Sep 17 00:00:00 2001 From: Maarten de Boer Date: Sat, 21 Mar 2020 20:28:48 +0100 Subject: [PATCH 06/13] Make some properties readonly --- src/action.ts | 6 +++--- src/file-cache.ts | 4 ++-- src/hugo.ts | 8 ++++---- src/updater.ts | 4 ++-- 4 files changed, 11 insertions(+), 11 deletions(-) diff --git a/src/action.ts b/src/action.ts index cedffa0..be2af14 100644 --- a/src/action.ts +++ b/src/action.ts @@ -1,7 +1,7 @@ export class Action { - private actions: Action[]; - private name: string; - private callback?: (query: string[]) => void; + private readonly actions: Action[]; + private readonly name: string; + private readonly callback?: (query: string[]) => void; public constructor(name: string, callback?: (query: string[]) => void) { this.name = name; diff --git a/src/file-cache.ts b/src/file-cache.ts index c4c6086..90b33df 100644 --- a/src/file-cache.ts +++ b/src/file-cache.ts @@ -13,8 +13,8 @@ import { FileCacheEventEmitter } from './types'; * This allows you to read and process the data once, then storing it in cache until the file has changed again. */ export class FileCache extends (EventEmitter as new() => FileCacheEventEmitter) { - private filePath: string; - private cache: Cache; + private readonly filePath: string; + private readonly cache: Cache; /** * FileCache constructor diff --git a/src/hugo.ts b/src/hugo.ts index 5a5f6a7..583e3fc 100644 --- a/src/hugo.ts +++ b/src/hugo.ts @@ -21,11 +21,11 @@ export class Hugo { public variables: { [key: string]: any } = {}; public items: Item[] = []; - private actions: Action[]; - private fuseDefaults: Fuse.FuseOptions; + private readonly actions: Action[]; + private readonly fuseDefaults: Fuse.FuseOptions; private options: HugoOptions; - private updater: Updater; - private notifier: NotificationCenter; + private readonly updater: Updater; + private readonly notifier: NotificationCenter; public constructor(options?: HugoOptions) { // Save options diff --git a/src/updater.ts b/src/updater.ts index 431eb64..447cc31 100644 --- a/src/updater.ts +++ b/src/updater.ts @@ -10,8 +10,8 @@ import { LatestVersion, UpdateSource } from './types'; * Hugo updater */ export class Updater { - private cache: Cache; - private interval: number | moment.Duration; + private readonly cache: Cache; + private readonly interval: number | moment.Duration; /** * Hugo updater From e12d1745a2cfc92d25d4a90c4c5ec95ea2d38caa Mon Sep 17 00:00:00 2001 From: Maarten de Boer Date: Sat, 21 Mar 2020 20:28:59 +0100 Subject: [PATCH 07/13] Update gitignore --- .gitignore | 1 + 1 file changed, 1 insertion(+) diff --git a/.gitignore b/.gitignore index ce40699..faed515 100644 --- a/.gitignore +++ b/.gitignore @@ -6,3 +6,4 @@ yarn-error.log /build /coverage /dist +.idea From a5a30bd58a76abf0dacf761f809ea60426c05ff8 Mon Sep 17 00:00:00 2001 From: Maarten de Boer Date: Sat, 21 Mar 2020 21:00:18 +0100 Subject: [PATCH 08/13] Clean code in docs --- docs/actions.md | 23 ++++++++++++----------- docs/cache.md | 18 +++++++++--------- docs/config.md | 10 +++++----- docs/fetch.md | 8 ++++---- docs/file-cache.md | 10 +++++----- docs/items.md | 42 ++++++++++++++++++++---------------------- docs/match.md | 26 +++++++++++++------------- docs/metadata.md | 4 ++-- docs/updates.md | 8 ++++---- 9 files changed, 74 insertions(+), 75 deletions(-) diff --git a/docs/actions.md b/docs/actions.md index de10403..137e6cc 100644 --- a/docs/actions.md +++ b/docs/actions.md @@ -9,18 +9,19 @@ Best way to understand is to look at the examples below! ##### Simple action ```js -import { Hugo } from "alfred-hugo"; +import { Hugo } from 'alfred-hugo'; const hugo = new Hugo(); // Hello action -hugo.action("hello", (query) => { +hugo.action('hello', (query) => { console.log(`Hello ${query}!`); }); // Run matching actions hugo.run(); ``` + ```sh node index.js hello world # Hello world! @@ -29,32 +30,32 @@ node index.js hello world ##### Action with nested sub-actions ```js -import { Hugo } from "alfred-hugo"; +import { Hugo } from 'alfred-hugo'; const hugo = new Hugo(); // List action -const listAction = hugo.action("list", (query) => { - console.log("Usage: list "); +const listAction = hugo.action('list', (query) => { + console.log('Usage: list '); }); // List bikes sub-action -listAction.action("bikes", (query) => { - const brand = query[0] || ""; +listAction.action('bikes', (query) => { + const brand = query[0] || ''; console.log(`Here be a list of ${brand} bikes.`); }); // List cars sub-action -const listCarsAction = listAction.action("cars", (query) => { - const brand = query[0] || ""; + const listCarsAction = listAction.action('cars', (query) => { + const brand = query[0] || ''; console.log(`Here be a list of ${brand} cars.`); }); // Sub-action of the list cars sub-action. -listCarsAction.action("Porsche", (query) => { - console.log("Porsche, ahh very fancy cars!"); +listCarsAction.action('Porsche', (query) => { + console.log('Porsche, ahh very fancy cars!'); }); // Run matching actions diff --git a/docs/cache.md b/docs/cache.md index 85d9cd7..bf020f6 100644 --- a/docs/cache.md +++ b/docs/cache.md @@ -13,23 +13,23 @@ For more details about [Cache](https://www.npmjs.com/package/@cloudstek/cache), ### Example ```js -import { Hugo } from "alfred-hugo"; +import { Hugo } from 'alfred-hugo'; const hugo = new Hugo(); -// Store "foo" with value "bar" for 1 hour -hugo.cache.set("foo", "bar"); +// Store 'foo' with value 'bar' for 1 hour +hugo.cache.set('foo', 'bar'); -// Store "pie" with value "apple" for 5 seconds -hugo.cache.set("pie", "apple", 5); +// Store 'pie' with value 'apple' for 5 seconds +hugo.cache.set('pie', 'apple', 5); -hugo.cache.has("pie"); // true -hugo.cache.get("pie"); // apple +hugo.cache.has('pie'); // true +hugo.cache.get('pie'); // apple // Wait 5 seconds. ZzzZzZzZZz // sleep(5000); -hugo.cache.has("pie"); // false -hugo.cache.get("pie"); // undefined +hugo.cache.has('pie'); // false +hugo.cache.get('pie'); // undefined ``` diff --git a/docs/config.md b/docs/config.md index b52877d..332bea8 100644 --- a/docs/config.md +++ b/docs/config.md @@ -9,16 +9,16 @@ You *can* let a configuration item expire but that is entirely optional and I'm ### Example ```js -import { Hugo } from "alfred-hugo"; +import { Hugo } from 'alfred-hugo'; const hugo = new Hugo(); // No need to load anything, just use it! -// Store "foo" with value "bar" -hugo.config.set("foo", "bar"); +// Store 'foo' with value 'bar' +hugo.config.set('foo', 'bar'); -// Get "foo" -console.log(hugo.config.get("foo")); // bar +// Get 'foo' +console.log(hugo.config.get('foo')); // bar ``` diff --git a/docs/fetch.md b/docs/fetch.md index 490bcfb..8c31bba 100644 --- a/docs/fetch.md +++ b/docs/fetch.md @@ -9,27 +9,27 @@ Behind the scenes [Axios](https://github.com/axios/axios) is used to make the re ### Example ```js -import { Hugo } from "alfred-hugo"; +import { Hugo } from 'alfred-hugo'; const hugo = new Hugo(); // Fetch single todo item without caching hugo - .fetch("https://jsonplaceholder.typicode.com/todos/1") + .fetch('https://jsonplaceholder.typicode.com/todos/1') .then((data) => { console.log(`#${data.id} ${data.title}`); }); // Fetch todo list and cache it for 1 hour hugo - .fetch("https://jsonplaceholder.typicode.com/todos", {/* Axios options */}, 3600) + .fetch('https://jsonplaceholder.typicode.com/todos', {/* Axios options */}, 3600) .then((data) => { console.log(`${data.length} todo items fetched.`); }); // Fetch the todo list again, this time it's cached! hugo - .fetch("https://jsonplaceholder.typicode.com/todos", {/* Axios options */}, 3600) + .fetch('https://jsonplaceholder.typicode.com/todos', {/* Axios options */}, 3600) .then((data) => { console.log(`${data.length} todo items loaded from cache.`); }); diff --git a/docs/file-cache.md b/docs/file-cache.md index 18cd4b2..59fd95d 100644 --- a/docs/file-cache.md +++ b/docs/file-cache.md @@ -9,7 +9,7 @@ By default the TTL (cache lifetime) is set to `false`, which means the results a ### Example ```js -import { Hugo } from "alfred-hugo"; +import { Hugo } from 'alfred-hugo'; const hugo = new Hugo(); @@ -17,14 +17,14 @@ const hugo = new Hugo(); const fc = hugo.cacheFile('/path/to/file.to.process'); // Define the change handler for processing your file -fc.on("change", (cache, fileContents) => { +fc.on('change', (cache, fileContents) => { // Process the file contents const foo = processFoo(fileContents); const bar = processBar(fileContents); // Set the results - cache.set("foo", foo); - cache.set("bar", bar); + cache.set('foo', foo); + cache.set('bar', bar); }); // Get the results @@ -37,7 +37,7 @@ console.log(results.bar); // Will output processed bar data #### With a 1-hour TTL ```js -import { Hugo } from "alfred-hugo"; +import { Hugo } from 'alfred-hugo'; const hugo = new Hugo(); diff --git a/docs/items.md b/docs/items.md index 8c722da..9ecb7be 100644 --- a/docs/items.md +++ b/docs/items.md @@ -9,35 +9,35 @@ To learn more about items, variables and the rerun parameter, please see the Alf #### Items ```js -import { Hugo } from "alfred-hugo"; +import { Hugo } from 'alfred-hugo'; const hugo = new Hugo(); // Add single item hugo.items.push({ - title: "Foo", - subtitle: "Bar", - arg: "foobar" + title: 'Foo', + subtitle: 'Bar', + arg: 'foobar' }); // Add multiple items const items = [ - { - title: "Foo", - subtitle: "Bar", - arg: "foobar" - }, - { - title: "Apple", - subtitle: "Pie", - arg: "omnomnom" - } + { + title: 'Foo', + subtitle: 'Bar', + arg: 'foobar' + }, + { + title: 'Apple', + subtitle: 'Pie', + arg: 'omnomnom' + } ]; hugo.items = hugo.items.concat(items); // Flush output buffer -hugo.feedack(); +hugo.feedback(); ``` #### Variables @@ -45,17 +45,17 @@ hugo.feedack(); Besides item variables you can also set global/session variables (please see the [documentation](https://www.alfredapp.com/help/workflows/inputs/script-filter/json/#variables)). Much like items, the variables are directly exposed as an object. ```js -import { Hugo } from "alfred-hugo"; +import { Hugo } from 'alfred-hugo'; const hugo = new Hugo(); // Set a variable -hugo.variables.foo = "bar"; +hugo.variables.foo = 'bar'; // Set (override) multiple hugo.variables = { - foo: "bar", - apple: "pie" + foo: 'bar', + apple: 'pie' }; ``` @@ -64,13 +64,11 @@ hugo.variables = { > Scripts can be set to re-run automatically after an interval using the 'rerun' key with a value of 0.1 to 5.0 seconds. The script will only be re-run if the script filter is still active and the user hasn't changed the state of the filter by typing and triggering a re-run. ```js -import { Hugo } from "alfred-hugo"; +import { Hugo } from 'alfred-hugo'; const hugo = new Hugo(); // Will re-run the script each 650ms after output hugo.rerun = 0.65; - -hugo. ``` diff --git a/docs/match.md b/docs/match.md index c0688ca..4281db6 100644 --- a/docs/match.md +++ b/docs/match.md @@ -5,27 +5,27 @@ Alfred has a [pretty good matching](https://www.alfredapp.com/help/workflows/inp ### Example ```js -import { Hugo } from "alfred-hugo"; +import { Hugo } from 'alfred-hugo'; const hugo = new Hugo(); // Add multiple items hugo.items.push( - { - title: "Foo", - subtitle: "Bar", - arg: "foobar" - }, - { - title: "Apple", - subtitle: "Pie", - arg: "omnomnom" - } + { + title: 'Foo', + subtitle: 'Bar', + arg: 'foobar' + }, + { + title: 'Apple', + subtitle: 'Pie', + arg: 'omnomnom' + } ); // Match items on arg -const results = hugo.match(hugo.items, "omnom", { - keys: ["arg"] +const results = hugo.match(hugo.items, 'omnom', { + keys: ['arg'] }); // Filter items, discarding non-matching items diff --git a/docs/metadata.md b/docs/metadata.md index 76fd685..64579df 100644 --- a/docs/metadata.md +++ b/docs/metadata.md @@ -45,7 +45,7 @@ Workflow metadata can be accessed through the `workflowMeta` property of Hugo. To save you some effort when you really want to blend in, Hugo has an easy way of loading the theme file for you (if it was found). You can access the active theme data using the `alfredTheme` property of Hugo. ```js -import { Hugo } from "alfred-hugo"; +import { Hugo } from 'alfred-hugo'; const hugo = new Hugo(); @@ -57,7 +57,7 @@ const themeData = hugo.alfredTheme; ## Example ```js -import { Hugo } from "alfred-hugo"; +import { Hugo } from 'alfred-hugo'; const hugo = new Hugo(); diff --git a/docs/updates.md b/docs/updates.md index 2840aff..8c45b4a 100644 --- a/docs/updates.md +++ b/docs/updates.md @@ -17,21 +17,21 @@ See [alfred-atom](https://github.com/Cloudstek/alfred-atom) for example which us #### Defaults ```js -import { Hugo } from "alfred-hugo"; +import { Hugo } from 'alfred-hugo'; const hugo = new Hugo({ checkUpdates: true, // Check for updates! - updateInterval: moment.duration(1, "day"), // Check for updates once a day + updateInterval: moment.duration(1, 'day'), // Check for updates once a day updateItem: true, // Show an item on the bottom of the list updateNotification: true, // Show a notification - updateSource: "npm" // Check NPM for updates + updateSource: 'npm' // Check NPM for updates }); ``` #### Disable updates ```js -import { Hugo } from "alfred-hugo"; +import { Hugo } from 'alfred-hugo'; const hugo = new Hugo({ checkUpdates: false From 2f9ba53c4ca5fe5a30bba3778daaf1d94c607bdb Mon Sep 17 00:00:00 2001 From: Maarten de Boer Date: Sat, 21 Mar 2020 23:10:56 +0100 Subject: [PATCH 09/13] Update documentation with extra script filter example --- docs/actions.md | 29 ++++++++++++++++++++++++++++- 1 file changed, 28 insertions(+), 1 deletion(-) diff --git a/docs/actions.md b/docs/actions.md index 137e6cc..e915c08 100644 --- a/docs/actions.md +++ b/docs/actions.md @@ -2,7 +2,7 @@ Actions are an easy way to structure your workflow in-code without having to drag all kinds of nodes in to launch different script for each action. Now you can run one script and have it handle all your actions. -Best way to understand is to look at the examples below! +You can use them to do anything like run programs, manipulate files, whatever. You can also use them in [script filter inputs](https://www.alfredapp.com/help/workflows/inputs/script-filter/) for example to list the latest tweets for a hashtag you enter. Also see [./items.md] for more info and examples. ### Examples @@ -76,3 +76,30 @@ node index.js list cars Porsche # Porsche, ahh very fancy cars! ``` +##### Simple script filter action + +```js + import { Hugo } from 'alfred-hugo'; + +const hugo = new Hugo(); + +// List action +const listAction = hugo.action('list', (query) => { + // Add items + hugo.items.push({ + title: 'Foo', + subtitle: 'Bar', + arg: 'foobar' + }, { + title: 'Hello', + subtitle: 'World', + arg: 'helloworld' + }); + + // Flush output buffer + hugo.feedback(); +}); + +// Run matching actions +hugo.run(); +``` From 647cbf9d5048dee13ab096c5898dda0eedfa2bda Mon Sep 17 00:00:00 2001 From: Maarten de Boer Date: Sat, 21 Mar 2020 23:12:46 +0100 Subject: [PATCH 10/13] Add support for action aliases As requested by tillsanders in issue #7 --- docs/actions.md | 24 +++ src/action.ts | 42 ++++- src/hugo.ts | 10 +- test/actions.ts | 324 +++++++++++++++++++++++++++++++- test/helpers/init.ts | 7 +- test/matching.ts | 30 +++ test/meta/alfred.ts | 1 + test/snapshots/matching.ts.md | 24 +++ test/snapshots/matching.ts.snap | Bin 472 -> 535 bytes test/utils.ts | 19 ++ 10 files changed, 459 insertions(+), 22 deletions(-) diff --git a/docs/actions.md b/docs/actions.md index e915c08..a1de740 100644 --- a/docs/actions.md +++ b/docs/actions.md @@ -27,6 +27,30 @@ node index.js hello world # Hello world! ``` +##### Simple action with aliases + +```js +import { Hugo } from 'alfred-hugo'; + +const hugo = new Hugo(); + +// Hello action +hugo.action(['hi', 'hello'], (query) => { + console.log(`Hello ${query}!`); +}); + +// Run matching actions +hugo.run(); +``` + +```sh +node index.js hello world +# Hello world! + +node index.js hi world +# Hello world! +``` + ##### Action with nested sub-actions ```js diff --git a/src/action.ts b/src/action.ts index be2af14..2dccb2a 100644 --- a/src/action.ts +++ b/src/action.ts @@ -1,15 +1,39 @@ export class Action { private readonly actions: Action[]; - private readonly name: string; - private readonly callback?: (query: string[]) => void; + private readonly names: string[]; + private readonly callback?: (args: string[]) => void; - public constructor(name: string, callback?: (query: string[]) => void) { - this.name = name; + public constructor(name: string|string[], callback?: (args: string[]) => void) { + if (typeof name === 'string') { + name = [name]; + } + + this.names = name; this.callback = callback; this.actions = []; + + if (this.names.length === 0) { + throw new Error('Action has no name or aliases.'); + } + + for (const n of this.names) { + if (n.trim().length === 0) { + throw new Error('Action name or alias cannot be empty an empty string.'); + } + } } - public action(name: string, callback: (query: string[]) => void): Action { + /** + * Run a callback when script argument matches keyword. Callback wil have remaining arguments as argument. + * + * @example node index.js firstaction secondaction "my query" + * + * @param name Action name and optionally aliases + * @param callback Callback to execute when query matches action name + * + * @return Action + */ + public action(name: string|string[], callback: (args: string[]) => void): Action { const action = new Action(name, callback); this.actions.push(action); @@ -22,19 +46,19 @@ export class Action { return false; } - if (args[0] === this.name) { - const subargs = args.slice(1); + if (this.names.includes(args[0])) { + const subArgs = args.slice(1); // Check sub actions first for (const action of this.actions) { - if (action.run(subargs) === true) { + if (action.run(subArgs) === true) { return true; } } // Run self if (this.callback) { - this.callback(args.slice(1)); + this.callback(subArgs); return true; } } diff --git a/src/hugo.ts b/src/hugo.ts index 583e3fc..f512346 100644 --- a/src/hugo.ts +++ b/src/hugo.ts @@ -235,20 +235,20 @@ export class Hugo { } /** - * Run a callback when first script argument matches keyword. Callback will have second argument as query parameter. + * Run a callback when first script argument matches keyword. Callback wil have remaining arguments as argument. * * @example node index.js myaction "my query" * - * @param keyword Action name + * @param name Action name and optionally aliases * @param callback Callback to execute when query matches action name * * @return Action */ public action( - keyword: string, - callback?: (query: string[]) => void, + name: string|string[], + callback?: (args: string[]) => void, ): Action { - const action = new Action(keyword, callback); + const action = new Action(name, callback); this.actions.push(action); diff --git a/test/actions.ts b/test/actions.ts index c21c3fd..91eb127 100644 --- a/test/actions.ts +++ b/test/actions.ts @@ -21,6 +21,47 @@ test.serial('no actions defined', (t) => { h.run(['foo']); }); +test.serial('actions defined with empty name', (t) => { + process.argv = [ + 'node', + 'index.js', + ]; + + const h = hugo(); + + t.is(h.input.length, 0); + + t.throws(() => { + h.action('', (query) => { + t.log(query); + t.fail(); + }); + }, { message: 'Action name or alias cannot be empty an empty string.' }); + + h.run(); +}); + +test.serial('actions defined with empty aliases', (t) => { + process.argv = [ + 'node', + 'index.js', + ]; + + const h = hugo(); + + t.is(h.input.length, 0); + + t.throws(() => { + t.log('foo'); + h.action([], (query) => { + t.log(query); + t.fail(); + }); + }, { message: 'Action has no name or aliases.' }); + + h.run(); +}); + test.serial('actions defined but no matching action', (t) => { process.argv = [ 'node', @@ -40,6 +81,11 @@ test.serial('actions defined but no matching action', (t) => { t.fail(); }); + h.action(['hello', 'world'], (query) => { + t.log(query); + t.fail(); + }); + t.is(h.input.length, 1); t.is(h.input[0], 'foo'); @@ -69,6 +115,11 @@ test.serial('actions defined but no action given', (t) => { t.fail(); }); + h.action(['hello', 'world'], (query) => { + t.log(query); + t.fail(); + }); + t.is(h.input.length, 0); h.run(); @@ -107,6 +158,68 @@ test.serial('actions defined and matching action with no query', (t) => { h.run(['foo']); }); +test.serial('actions defined with aliases and matching action with no query', (t) => { + t.plan(4); + + process.argv = [ + 'node', + 'index.js', + 'foo', + ]; + + const h = hugo(); + + h.action('bar', (query) => { + t.log(query); + t.fail(); + }); + + h.action(['foo', 'zap'], (query) => { + t.is(query.length, 0); + }); + + t.is(h.input.length, 1); + t.is(h.input[0], 'foo'); + + h.run(); + + // Now run with custom args + process.argv = []; + + h.run(['foo']); +}); + +test.serial('actions defined with aliases and matching alias with no query', (t) => { + t.plan(4); + + process.argv = [ + 'node', + 'index.js', + 'zap', + ]; + + const h = hugo(); + + h.action('bar', (query) => { + t.log(query); + t.fail(); + }); + + h.action(['foo', 'zap'], (query) => { + t.is(query.length, 0); + }); + + t.is(h.input.length, 1); + t.is(h.input[0], 'zap'); + + h.run(); + + // Now run with custom args + process.argv = []; + + h.run(['zap']); +}); + test.serial('actions defined and matching action with query', (t) => { t.plan(4); @@ -137,8 +250,16 @@ test.serial('actions defined and matching action with query', (t) => { h.run(['foo', 'bar']); }); -test('run actions with custom arguments instead of argv', (t) => { - t.plan(2); +test.serial('actions defined with aliases and matching action with query', (t) => { + t.plan(7); + + process.argv = [ + 'node', + 'index.js', + 'foo', + 'bar', + ]; + const h = hugo(); h.action('bar', (query) => { @@ -146,14 +267,57 @@ test('run actions with custom arguments instead of argv', (t) => { t.fail(); }); - h.action('foo', (query) => { + h.action(['foo', 'zap'], (query) => { t.is(query.length, 1); t.is(query[0], 'bar'); }); + t.is(h.input.length, 2); + t.is(h.input[0], 'foo'); + t.is(h.input[1], 'bar'); + + h.run(); + + // Now run with custom args + process.argv = []; + h.run(['foo', 'bar']); }); +test.serial('actions defined with aliases and matching alias with query', (t) => { + t.plan(7); + + process.argv = [ + 'node', + 'index.js', + 'zap', + 'bar', + ]; + + const h = hugo(); + + h.action('bar', (query) => { + t.log(query); + t.fail(); + }); + + h.action(['foo', 'zap'], (query) => { + t.is(query.length, 1); + t.is(query[0], 'bar'); + }); + + t.is(h.input.length, 2); + t.is(h.input[0], 'zap'); + t.is(h.input[1], 'bar'); + + h.run(); + + // Now run with custom args + process.argv = []; + + h.run(['zap', 'bar']); +}); + test.serial('main action without callback and no matching sub-action', (t) => { process.argv = [ 'node', @@ -187,7 +351,7 @@ test.serial('main action without callback and no matching sub-action', (t) => { }); test.serial('main action with matching sub-action', (t) => { - t.plan(6); + t.plan(11); process.argv = [ 'node', @@ -202,6 +366,7 @@ test.serial('main action with matching sub-action', (t) => { // Foo action with bar sub-action const fooAction = h.action('foo', (query) => { + // Fail if calling just foo without sub action t.fail(); }); @@ -216,6 +381,12 @@ test.serial('main action with matching sub-action', (t) => { t.fail(); }); + t.is(h.input.length, 4); + t.is(h.input[0], 'foo'); + t.is(h.input[1], 'bar'); + t.is(h.input[2], 'hello'); + t.is(h.input[3], 'world'); + h.run(); // Now run with custom args @@ -224,8 +395,98 @@ test.serial('main action with matching sub-action', (t) => { h.run(['foo', 'bar', 'hello', 'world']); }); +test.serial('main action with matching sub-action by alias', (t) => { + t.plan(11); + + process.argv = [ + 'node', + 'index.js', + 'foo', + 'zap', + 'hello', + 'world', + ]; + + const h = hugo(); + + // Foo action with bar sub-action + const fooAction = h.action('foo', (query) => { + // Fail if calling just foo without sub action + t.fail(); + }); + + // Bar sub-action with floop sub-action + const barAction = fooAction.action(['bar', 'zap'], (query) => { + t.is(query.length, 2); + t.is(query[0], 'hello'); + t.is(query[1], 'world'); + }); + + barAction.action('floop', (query) => { + t.fail(); + }); + + t.is(h.input.length, 4); + t.is(h.input[0], 'foo'); + t.is(h.input[1], 'zap'); + t.is(h.input[2], 'hello'); + t.is(h.input[3], 'world'); + + h.run(); + + // Now run with custom args + process.argv = []; + + h.run(['foo', 'zap', 'hello', 'world']); +}); + +test.serial('main action by alias with matching sub-action', (t) => { + t.plan(11); + + process.argv = [ + 'node', + 'index.js', + 'bleep', + 'bar', + 'hello', + 'world', + ]; + + const h = hugo(); + + // Foo action with bar sub-action + const fooAction = h.action(['foo', 'bleep'], (query) => { + // Fail if calling just foo without sub action + t.fail(); + }); + + // Bar sub-action with floop sub-action + const barAction = fooAction.action(['bar', 'zap'], (query) => { + t.is(query.length, 2); + t.is(query[0], 'hello'); + t.is(query[1], 'world'); + }); + + barAction.action('floop', (query) => { + t.fail(); + }); + + t.is(h.input.length, 4); + t.is(h.input[0], 'bleep'); + t.is(h.input[1], 'bar'); + t.is(h.input[2], 'hello'); + t.is(h.input[3], 'world'); + + h.run(); + + // Now run with custom args + process.argv = []; + + h.run(['bleep', 'bar', 'hello', 'world']); +}); + test.serial('main action with matching sub-sub-action', (t) => { - t.plan(6); + t.plan(12); process.argv = [ 'node', @@ -255,6 +516,13 @@ test.serial('main action with matching sub-sub-action', (t) => { t.is(query[1], 'world'); }); + t.is(h.input.length, 5); + t.is(h.input[0], 'foo'); + t.is(h.input[1], 'bar'); + t.is(h.input[2], 'floop'); + t.is(h.input[3], 'hello'); + t.is(h.input[4], 'world'); + h.run(); // Now run with custom args @@ -263,6 +531,52 @@ test.serial('main action with matching sub-sub-action', (t) => { h.run(['foo', 'bar', 'floop', 'hello', 'world']); }); +test.serial('main action with matching sub-sub-action by alias', (t) => { + t.plan(12); + + process.argv = [ + 'node', + 'index.js', + 'foo', + 'bar', + 'flap', + 'hello', + 'world', + ]; + + const h = hugo(); + + // Foo action with bar sub-action + const fooAction = h.action('foo', (query) => { + t.fail(); + }); + + // Bar sub-action with floop sub-action + const barAction = fooAction.action('bar', (query) => { + t.fail(); + }); + + barAction.action(['floop', 'flap'], (query) => { + t.is(query.length, 2); + t.is(query[0], 'hello'); + t.is(query[1], 'world'); + }); + + t.is(h.input.length, 5); + t.is(h.input[0], 'foo'); + t.is(h.input[1], 'bar'); + t.is(h.input[2], 'flap'); + t.is(h.input[3], 'hello'); + t.is(h.input[4], 'world'); + + h.run(); + + // Now run with custom args + process.argv = []; + + h.run(['foo', 'bar', 'flap', 'hello', 'world']); +}); + test.serial('main action with sub-actions defined, without query', (t) => { t.plan(2); diff --git a/test/helpers/init.ts b/test/helpers/init.ts index 63e2264..45e403b 100644 --- a/test/helpers/init.ts +++ b/test/helpers/init.ts @@ -1,3 +1,4 @@ +/* eslint-disable prefer-arrow/prefer-arrow-functions,@typescript-eslint/camelcase */ import { Cache } from '@cloudstek/cache'; import crypto from 'crypto'; import path from 'path'; @@ -8,7 +9,7 @@ import sinon from 'sinon'; import { Updater, Hugo, HugoOptions } from '../../src'; -export function setAlfredEnv() { +export function setAlfredEnv(): void { process.env.alfred_version = '4.0.0'; process.env.alfred_workflow_version = '1.0.0'; process.env.alfred_workflow_bundleid = 'my.work.flow'; @@ -25,7 +26,7 @@ export function setAlfredEnv() { process.env.HOME = path.join('build', 'cache', crypto.randomBytes(8).toString('hex')); } -export function hugo(options?: HugoOptions) { +export function hugo(options?: HugoOptions): Hugo { setAlfredEnv(); // Disable real HTTP requests with nock @@ -55,7 +56,7 @@ export function hugo(options?: HugoOptions) { return h; } -export function updater(cacheTtl?: number | moment.Duration) { +export function updater(cacheTtl?: number | moment.Duration): Updater { setAlfredEnv(); // Disable real HTTP requests with nock diff --git a/test/matching.ts b/test/matching.ts index f3caa5d..8228fe5 100644 --- a/test/matching.ts +++ b/test/matching.ts @@ -61,6 +61,21 @@ test('exact match by single key', (t) => { t.deepEqual(matches[0], t.context.items[1]); }); +test('exact match by single key using weighted syntax', (t) => { + const h = hugo(); + + const matches = h.match(t.context.items, 'foo bar bleep', { + keys: [ + { name: 'subtitle', weight: 0 } + ], + threshold: 0, + }); + + t.true(Array.isArray(matches)); + t.is(matches.length, 1); + t.deepEqual(matches[0], t.context.items[1]); +}); + test('exact match multiple keys', (t) => { const h = hugo(); @@ -73,6 +88,21 @@ test('exact match multiple keys', (t) => { t.snapshot(matches); }); +test('exact match multiple keys using weighted syntax', (t) => { + const h = hugo(); + + const matches = h.match(t.context.items, 'foo', { + keys: [ + { name: 'title', weight: 0 }, + { name: 'subtitle', weight: 1 } + ], + }); + + t.true(Array.isArray(matches)); + t.is(matches.length, 4); + t.snapshot(matches); +}); + test('no matches', (t) => { const h = hugo(); diff --git a/test/meta/alfred.ts b/test/meta/alfred.ts index c26bcd6..5d64d1b 100644 --- a/test/meta/alfred.ts +++ b/test/meta/alfred.ts @@ -1,3 +1,4 @@ +/* eslint-disable @typescript-eslint/camelcase */ import test from 'ava'; import fs from 'fs-extra'; import path from 'path'; diff --git a/test/snapshots/matching.ts.md b/test/snapshots/matching.ts.md index 476a0db..ea13cbd 100644 --- a/test/snapshots/matching.ts.md +++ b/test/snapshots/matching.ts.md @@ -55,3 +55,27 @@ Generated by [AVA](https://ava.li). title: 'Abra', }, ] + +## exact match multiple keys using weighted syntax + +> Snapshot 1 + + [ + { + subtitle: 'foo bar', + title: 'Foo', + }, + { + subtitle: 'foo bar bleep', + title: 'Bar', + }, + { + match: 'Abra', + subtitle: 'eep foo blep', + title: 'Eep', + }, + { + subtitle: 'ploop', + title: 'Foo bar', + }, + ] diff --git a/test/snapshots/matching.ts.snap b/test/snapshots/matching.ts.snap index 804aa002ce11f19801df75a68363a71dd8226449..0dd8df7099a6eaa20a2faa280a49b8960c5eb119 100644 GIT binary patch literal 535 zcmV+y0_gogRzVAS0_| zQBh(gBO{E(&(F`m$i=|O!obMQ$e0N+0LYpGq8Y)={U9b2nE49CWCq#5ED3b1JP^Ax zLQQ7#Ps&P7E@5PXGX(?$z)CZKO7ehs3c6Be45d4PO7;WsTXdx?=t^1mfB_-`#AZO8 z%!H<#6;(Me*aQ4PHB2HP_XDLlic6D9GD~t&VFK)F`S}V-iA8AYSWy%)yXEH-XB=xm zPJVs?Uc=bkU^WtCATQK?3Q0MssrU_Mc7htpjIJy>I%EZ>vkG`RT#QJE=Md@eFEkwjnHs>90!qEW z#1jl;Mgnmo;Uu{TsAL5YUn7_#S-u06`~@X;U>fs5PiGj(k~tTsq!@^25=fFjrTc(N zjsWo+bfs(qo_dEwVjG~0$ex^-l8EUUR3pLOr9+AQj-nEI4&mg#7pUYg5I+TCA;QVu Z7^uV&h~o!ei99mXGynnQg%xTD007ks;)ehL literal 472 zcmV;}0Vn=JRzVmQ2<00000000Bk zlfO#>VHn5X_kK!ccaaoL3N5uXMnnioX@lh85Df))cA;^0q8HQ{*w_*-t24%bFA|X7H8AStBT*4Yf){zXdgG^Fsf{L+HNjs*rRVj)> z=m?<#p`(=Me;c5xIxA&m%_%unzB?uFOyFm5q%e}CZf7a2?;Ba0a_v%8Rfgt(93WLM z%J-o6Kx#8?AuIEv?dPHFzB8yqML@%zcC+ooAO?)pxN16>rII1CCzW_7=}gI zXwz@%no<1YptOQDj--%HL`MpK9*WGfqqc`v9S>hR9yVPMQO>~>$6m;jLAiyT_$zq{ z { // Write new binary plist @@ -179,6 +181,23 @@ test.serial('resolve non-existing alfred 3 preferences', (t) => { }); }); +test.serial('resolve alfred 3 preferences using alfredMeta', (t) => { + const plist = bplist({}); + const h = hugo(); + + process.env.alfred_version = '3.0.0'; + delete process.env.alfred_preferences; + + // Write file to expected path + const plistPath = path.join(homeDir, '/Library/Preferences/com.runningwithcrayons.Alfred-Preferences-3.plist'); + + fs.ensureFileSync(plistPath); + fs.writeFileSync(plistPath, plist); + + t.is(typeof h.alfredMeta, 'object'); + t.is(h.alfredMeta.preferences, path.join(homeDir, 'Library/Application Support/Alfred 3/Alfred.alfredpreferences')); +}); + test.afterEach.always(() => { fs.removeSync(homeDir); }); From 328c2afab48f6a2db054da50036a5fd4564840a7 Mon Sep 17 00:00:00 2001 From: Maarten de Boer Date: Sat, 21 Mar 2020 23:17:56 +0100 Subject: [PATCH 11/13] Require NodeJS >= 10 --- .circleci/config.yml | 28 +++++++++++++++++++++------- README.md | 2 +- package.json | 2 +- 3 files changed, 23 insertions(+), 9 deletions(-) diff --git a/.circleci/config.yml b/.circleci/config.yml index 1ff3307..718f395 100644 --- a/.circleci/config.yml +++ b/.circleci/config.yml @@ -1,17 +1,31 @@ version: 2 +shared: &shared + steps: + - checkout + - run: yarn + - run: yarn test:ci + jobs: - test: + test-node-10: docker: - - image: node:8 - steps: - - checkout + - image: node:10 + <<: *shared - - run: yarn - - run: yarn test:ci + test-node-12: + docker: + - image: node:12 + <<: *shared + + test-node-13: + docker: + - image: node:13 + <<: *shared workflows: version: 2 test: jobs: - - test + - test-node-10 + - test-node-12 + - test-node-13 diff --git a/README.md b/README.md index 7e883b6..cb4bcec 100644 --- a/README.md +++ b/README.md @@ -17,7 +17,7 @@ Hugo is a [script filter](https://www.alfredapp.com/help/workflows/inputs/script ### Prerequisites -* NodeJS 8 or higher +* NodeJS 10 or higher * Alfred 4 with [paid powerpack addon](https://www.alfredapp.com/powerpack/buy/) ### Installing diff --git a/package.json b/package.json index 07cc14e..7ab3d3c 100644 --- a/package.json +++ b/package.json @@ -69,7 +69,7 @@ "untildify": "^4.0.0" }, "engines": { - "node": ">=8" + "node": ">=10" }, "scripts": { "clean": "npm-run-all -p clean:*", From fd22ca8dc64eedeb2273519c579fd9b4a75b0249 Mon Sep 17 00:00:00 2001 From: Maarten de Boer Date: Sat, 21 Mar 2020 23:19:09 +0100 Subject: [PATCH 12/13] Update docs with note that packal notifications are deprecated --- README.md | 2 +- docs/updates.md | 2 ++ 2 files changed, 3 insertions(+), 1 deletion(-) diff --git a/README.md b/README.md index cb4bcec..51320ab 100644 --- a/README.md +++ b/README.md @@ -11,7 +11,7 @@ Hugo is a [script filter](https://www.alfredapp.com/help/workflows/inputs/script * Built-in cache and configuration storage * Advanced filtering of items using [Fuse.js](http://fusejs.io) :mag: * Fetch (JSON) from REST API's using [Axios](https://github.com/axios/axios) :earth_americas: -* Update notifications (for both NPM and Packal workflows) :mailbox: +* Update notifications :mailbox: ## Getting started diff --git a/docs/updates.md b/docs/updates.md index 8c45b4a..61c6cfe 100644 --- a/docs/updates.md +++ b/docs/updates.md @@ -4,6 +4,8 @@ If your workflow has been published on NPM or Packal, Hugo can automatically not There are two ways to notify the user of an available update, with a notification and with an item on the bottom of the list. You're free to choose either one or both. If you disable both methods, you effectively disable checking for updates. +*Please note that support for Packal is deprecated and may be removed in future versions.* + ### Update item option When the item is activated, it will set a variable named `task` (`{var:task}` in Alfred) with the value `wfUpdate`. The argument is set to the URL where the update can be found, either on Packal or NPM depending on `updateSource`. You can link the output to an [Open URL](https://www.alfredapp.com/help/workflows/actions/open-url/) action so a browser opens when the user selects the update item. From 9c037ef83a76326ac024c3a3637e2b9e09640f51 Mon Sep 17 00:00:00 2001 From: Maarten de Boer Date: Sat, 21 Mar 2020 23:23:21 +0100 Subject: [PATCH 13/13] Bump version to 3.0.0 --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index 7ab3d3c..52a32d1 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "alfred-hugo", - "version": "2.0.5", + "version": "3.0.0", "description": "Alfred workflow bindings for NodeJS", "author": "Maarten de Boer (https://cloudstek.nl)", "contributors": [