From d3cd1dc2feb9f9d4a1e08e020665af331ac7d3df Mon Sep 17 00:00:00 2001 From: Scott Prue Date: Tue, 11 Feb 2020 17:03:25 -0800 Subject: [PATCH] v0.10.0 (#89) * feat(login): add support for passing UID - #14 * feat(types): update type of `login` function to include optional `uid` param - #14 * feat(tests): add tests for emulator support - #73 * chore(deps): update [firebase-tools-extra version](https://github.com/prescottprue/firebase-tools-extra/releases/tag/v0.5.0) for custom token generation used in new `login` functionality - #73 --- .../cypress/integration/Projects.spec.js | 7 +- examples/basic/cypress/plugins/index.js | 4 +- examples/basic/package.json | 10 +- examples/basic/src/initFirebase.js | 2 +- examples/basic/yarn.lock | 408 +++++++++--------- index.d.ts | 6 +- package.json | 4 +- src/attachCustomCommands.ts | 92 +++- src/extendWithFirebaseConfig.ts | 22 +- src/utils.ts | 8 +- test/unit/attachCustomCommands.spec.ts | 24 +- test/unit/buildFirestoreCommand.spec.ts | 126 ++++-- test/unit/buildRtdbCommand.spec.ts | 327 ++++++++++---- yarn.lock | 8 +- 14 files changed, 652 insertions(+), 396 deletions(-) diff --git a/examples/basic/cypress/integration/Projects.spec.js b/examples/basic/cypress/integration/Projects.spec.js index ba4fb5b8..2ed742c2 100644 --- a/examples/basic/cypress/integration/Projects.spec.js +++ b/examples/basic/cypress/integration/Projects.spec.js @@ -2,10 +2,11 @@ describe('Projects View', () => { describe('when authenticated', () => { before(() => { // Login using custom token - cy.login(); + cy.log('Calling login') + cy.login(Cypress.env('TEST_UID')); // TODO: Use cy.setRtdb() to set projects created by authed user - cy.callFirestore('add', 'projects', { name: 'project 1'}) - cy.callRtdb('set', 'projects/asdf123', { name: 'project 1'}) + // cy.callFirestore('add', 'projects', { name: 'project 1'}) + // cy.callRtdb('set', 'projects/asdf123', { name: 'project 1'}) // Go to home page cy.visit('/'); }); diff --git a/examples/basic/cypress/plugins/index.js b/examples/basic/cypress/plugins/index.js index 17fae316..3dffb8e2 100644 --- a/examples/basic/cypress/plugins/index.js +++ b/examples/basic/cypress/plugins/index.js @@ -7,7 +7,7 @@ // You can read more here: // https://on.cypress.io/plugins-guide // *********************************************************** -const cypressFirebasePlugin = require('cypress-firebase').plugin +const { extendWithFirebaseConfig } = require('cypress-firebase') // This function is called when a project is opened or re-opened (e.g. due to // the project's config changing) @@ -15,5 +15,5 @@ const cypressFirebasePlugin = require('cypress-firebase').plugin module.exports = (on, config) => { // `on` is used to hook into various events Cypress emits // `config` is the resolved Cypress config - return cypressFirebasePlugin(config) + return extendWithFirebaseConfig(config) } diff --git a/examples/basic/package.json b/examples/basic/package.json index b66b7634..3cce77ee 100644 --- a/examples/basic/package.json +++ b/examples/basic/package.json @@ -3,11 +3,13 @@ "version": "0.1.0", "scripts": { "start": "react-scripts start", + "emulate": "cross-env REACT_APP_USE_DB_EMULATORS=true yarn start", "build": "react-scripts build", "eject": "react-scripts eject", "build:testConfig": "cypress-firebase createTestEnvFile", "test": "npm run build:testConfig && cross-env CYPRESS_baseUrl=http://localhost:3000 cypress run", - "test:ui": "npm run build:testConfig && cross-env CYPRESS_baseUrl=http://localhost:3000 cypress open" + "test:ui": "npm run build:testConfig && cross-env CYPRESS_baseUrl=http://localhost:3000 cypress open", + "test:emulate": "npm run build:testConfig && cross-env CYPRESS_baseUrl=http://localhost:3000 cypress open" }, "dependencies": { "firebase": "^7.8.0", @@ -17,11 +19,11 @@ }, "devDependencies": { "cross-env": "^5.2.0", - "cypress": "^3.8.3", + "cypress": "^4.0.1", "cypress-firebase": "*", "eslint-plugin-cypress": "^2.0.1", - "react-scripts": "3.3.1", - "firebase-tools": "^7.12.1" + "firebase-tools": "^7.12.1", + "react-scripts": "3.3.1" }, "eslintConfig": { "extends": "react-app" diff --git a/examples/basic/src/initFirebase.js b/examples/basic/src/initFirebase.js index 7d78e7ed..600ace80 100644 --- a/examples/basic/src/initFirebase.js +++ b/examples/basic/src/initFirebase.js @@ -17,7 +17,7 @@ export default function getFirebaseInstance(initialState, history) { // Initialize firebase instance if it doesn't already exist if (!firebaseInstance) { - const shouldUseEmulator = window.Cypress || window.location.hostname === 'localhost' + const shouldUseEmulator = process.env.REACT_APP_USE_DB_EMULATORS if (shouldUseEmulator) { // or window.location.hostname === 'localhost' if you want console.log('Using RTDB emulator') diff --git a/examples/basic/yarn.lock b/examples/basic/yarn.lock index af6d61d6..b824097f 100644 --- a/examples/basic/yarn.lock +++ b/examples/basic/yarn.lock @@ -1806,6 +1806,13 @@ resolved "https://registry.yarnpkg.com/@protobufjs/utf8/-/utf8-1.1.0.tgz#a777360b5b39a1a2e5106f8e858f2fd2d060c570" integrity sha1-p3c2C1s5oaLlEG+OhY8v0tBgxXA= +"@samverschueren/stream-to-observable@^0.3.0": + version "0.3.0" + resolved "https://registry.yarnpkg.com/@samverschueren/stream-to-observable/-/stream-to-observable-0.3.0.tgz#ecdf48d532c58ea477acfcab80348424f8d0662f" + integrity sha512-MI4Xx6LHs4Webyvi6EbspgyAb4D2Q2VtnCQ1blOJcoLS6mVa8lNN2rkIy1CVxfTUpoyIbCTkXES1rLXztFD1lg== + dependencies: + any-observable "^0.3.0" + "@svgr/babel-plugin-add-jsx-attribute@^4.2.0": version "4.2.0" resolved "https://registry.yarnpkg.com/@svgr/babel-plugin-add-jsx-attribute/-/babel-plugin-add-jsx-attribute-4.2.0.tgz#dadcb6218503532d6884b210e7f3c502caaa44b1" @@ -2516,10 +2523,6 @@ ansi-colors@^3.0.0: version "3.1.0" resolved "https://registry.yarnpkg.com/ansi-colors/-/ansi-colors-3.1.0.tgz#dcfaacc90ef9187de413ec3ef8d5eb981a98808f" -ansi-escapes@^1.0.0: - version "1.4.0" - resolved "https://registry.yarnpkg.com/ansi-escapes/-/ansi-escapes-1.4.0.tgz#d3a8a83b319aa67793662b13e761c7911422306e" - ansi-escapes@^3.0.0: version "3.1.0" resolved "https://registry.yarnpkg.com/ansi-escapes/-/ansi-escapes-3.1.0.tgz#f73207bb81207d75fd6c83f125af26eea378ca30" @@ -2591,6 +2594,11 @@ ansistyles@~0.1.3: resolved "https://registry.yarnpkg.com/ansistyles/-/ansistyles-0.1.3.tgz#5de60415bda071bb37127854c864f41b23254539" integrity sha1-XeYEFb2gcbs3EnhUyGT0GyMlRTk= +any-observable@^0.3.0: + version "0.3.0" + resolved "https://registry.yarnpkg.com/any-observable/-/any-observable-0.3.0.tgz#af933475e5806a67d0d7df090dd5e8bef65d119b" + integrity sha512-/FQM1EDkTsf63Ub2C6O7GuYFDsSXUwsaZDurV0np41ocwq0jthUAYCmhBX9f+KwlaCgIuWyr/4WlUQUBfKfZog== + anymatch@^2.0.0: version "2.0.0" resolved "https://registry.yarnpkg.com/anymatch/-/anymatch-2.0.0.tgz#bcb24b4f37934d9aa7ac17b4adaf89e7c76ef2eb" @@ -2826,13 +2834,6 @@ async-limiter@~1.0.0: version "1.0.0" resolved "https://registry.yarnpkg.com/async-limiter/-/async-limiter-1.0.0.tgz#78faed8c3d074ab81f22b4e985d79e8738f720f8" -async@2.6.1: - version "2.6.1" - resolved "https://registry.yarnpkg.com/async/-/async-2.6.1.tgz#b245a23ca71930044ec53fa46aa00a3e87c6a610" - integrity sha512-fNEiL2+AZt6AlAw/29Cr0UDe4sRAHCpEHh54WMz+Bb7QfNcFw4h3loofyJpLeQs4Yx7yuqu/2dLgM5hKOs6HlQ== - dependencies: - lodash "^4.17.10" - async@^1.3.0, async@^1.5.2: version "1.5.2" resolved "https://registry.yarnpkg.com/async/-/async-1.5.2.tgz#ec6a61ae56480c0c3cb241c95618e20892f9672a" @@ -2851,6 +2852,11 @@ async@^2.6.2, async@^2.6.3: dependencies: lodash "^4.17.14" +async@^3.1.0: + version "3.1.1" + resolved "https://registry.yarnpkg.com/async/-/async-3.1.1.tgz#dd3542db03de837979c9ebbca64ca01b06dc98df" + integrity sha512-X5Dj8hK1pJNC2Wzo2Rcp9FBVdJMGRR/S7V+lH46s8GVFhtbo5O4Le5GECCF/8PISVdkUA6mMPvgz7qTTD1rf1g== + async@~1.0.0: version "1.0.0" resolved "https://registry.yarnpkg.com/async/-/async-1.0.0.tgz#f8fc04ca3a13784ade9e1641af98578cfbd647a9" @@ -3167,9 +3173,10 @@ block-stream@*: dependencies: inherits "~2.0.0" -bluebird@3.5.0: - version "3.5.0" - resolved "https://registry.yarnpkg.com/bluebird/-/bluebird-3.5.0.tgz#791420d7f551eea2897453a8a77653f96606d67c" +bluebird@3.7.2, bluebird@^3.5.5: + version "3.7.2" + resolved "https://registry.yarnpkg.com/bluebird/-/bluebird-3.7.2.tgz#9f229c15be272454ffa973ace0dbee79a1b0c36f" + integrity sha512-XpNj6GDQzdfW+r2Wnn7xiSAd7TM3jzkxGXBGTtWKuSXv1xUV+azxAm8jdWZN06QTQk+2N2XB9jRDkvbmQmcRtg== bluebird@^3.5.0, bluebird@~3.5.0: version "3.5.3" @@ -3180,11 +3187,6 @@ bluebird@^3.5.1: version "3.5.2" resolved "https://registry.yarnpkg.com/bluebird/-/bluebird-3.5.2.tgz#1be0908e054a751754549c270489c1505d4ab15a" -bluebird@^3.5.5: - version "3.7.2" - resolved "https://registry.yarnpkg.com/bluebird/-/bluebird-3.7.2.tgz#9f229c15be272454ffa973ace0dbee79a1b0c36f" - integrity sha512-XpNj6GDQzdfW+r2Wnn7xiSAd7TM3jzkxGXBGTtWKuSXv1xUV+azxAm8jdWZN06QTQk+2N2XB9jRDkvbmQmcRtg== - bluebird@~3.4.1: version "3.4.7" resolved "https://registry.yarnpkg.com/bluebird/-/bluebird-3.4.7.tgz#f72d760be09b7f76d08ed8fae98b289a8d05fab3" @@ -3580,11 +3582,10 @@ cache-base@^1.0.1: union-value "^1.0.0" unset-value "^1.0.0" -cachedir@1.3.0: - version "1.3.0" - resolved "https://registry.yarnpkg.com/cachedir/-/cachedir-1.3.0.tgz#5e01928bf2d95b5edd94b0942188246740e0dbc4" - dependencies: - os-homedir "^1.0.1" +cachedir@2.3.0: + version "2.3.0" + resolved "https://registry.yarnpkg.com/cachedir/-/cachedir-2.3.0.tgz#0c75892a052198f0b21c7c1804d8331edfcae0e8" + integrity sha512-A+Fezp4zxnit6FanDmv9EqXNAi3vt9DWp51/71UEhXukb7QUuvtv9344h91dyAxuTLoSYJFU299qzR3tzwPAhw== call-limit@~1.1.0: version "1.1.0" @@ -3698,15 +3699,6 @@ chainsaw@~0.1.0: dependencies: traverse ">=0.3.0 <0.4" -chalk@2.4.2, chalk@^2.4.2: - version "2.4.2" - resolved "https://registry.yarnpkg.com/chalk/-/chalk-2.4.2.tgz#cd42541677a54333cf541a49108c1432b44c9424" - integrity sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ== - dependencies: - ansi-styles "^3.2.1" - escape-string-regexp "^1.0.5" - supports-color "^5.3.0" - chalk@3.0.0: version "3.0.0" resolved "https://registry.yarnpkg.com/chalk/-/chalk-3.0.0.tgz#3f73c2bf526591f574cc492c51e2456349f844e4" @@ -3715,7 +3707,7 @@ chalk@3.0.0: ansi-styles "^4.1.0" supports-color "^7.1.0" -chalk@^1.0.0, chalk@^1.1.1, chalk@^1.1.3: +chalk@^1.0.0, chalk@^1.1.3: version "1.1.3" resolved "https://registry.yarnpkg.com/chalk/-/chalk-1.1.3.tgz#a8115c55e4a702fe4d150abd3872822a7e09fc98" dependencies: @@ -3733,6 +3725,15 @@ chalk@^2.0.0, chalk@^2.0.1, chalk@^2.1.0, chalk@^2.4.1: escape-string-regexp "^1.0.5" supports-color "^5.3.0" +chalk@^2.4.2: + version "2.4.2" + resolved "https://registry.yarnpkg.com/chalk/-/chalk-2.4.2.tgz#cd42541677a54333cf541a49108c1432b44c9424" + integrity sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ== + dependencies: + ansi-styles "^3.2.1" + escape-string-regexp "^1.0.5" + supports-color "^5.3.0" + char-spinner@^1.0.1: version "1.0.1" resolved "https://registry.yarnpkg.com/char-spinner/-/char-spinner-1.0.1.tgz#e6ea67bd247e107112983b7ab0479ed362800081" @@ -3887,7 +3888,7 @@ cli-cursor@^1.0.2: dependencies: restore-cursor "^1.0.1" -cli-cursor@^2.1.0: +cli-cursor@^2.0.0, cli-cursor@^2.1.0: version "2.1.0" resolved "https://registry.yarnpkg.com/cli-cursor/-/cli-cursor-2.1.0.tgz#b35dac376479facc3e94747d41d0d0f5238ffcb5" dependencies: @@ -3900,10 +3901,6 @@ cli-cursor@^3.1.0: dependencies: restore-cursor "^3.1.0" -cli-spinners@^0.1.2: - version "0.1.2" - resolved "https://registry.yarnpkg.com/cli-spinners/-/cli-spinners-0.1.2.tgz#bb764d88e185fb9e1e6a2a1f19772318f605e31c" - cli-spinners@^2.0.0: version "2.2.0" resolved "https://registry.yarnpkg.com/cli-spinners/-/cli-spinners-2.2.0.tgz#e8b988d9206c692302d8ee834e7a85c0144d8f77" @@ -4082,10 +4079,10 @@ combined-stream@^1.0.5, combined-stream@~1.0.5, combined-stream@~1.0.6: dependencies: delayed-stream "~1.0.0" -commander@2.15.1: - version "2.15.1" - resolved "https://registry.yarnpkg.com/commander/-/commander-2.15.1.tgz#df46e867d0fc2aec66a34662b406a9ccafff5b0f" - integrity sha512-VlfT9F3V0v+jr4yxPc5gg9s62/fIVWsd2Bk2iD435um1NlGMYdVCq+MjcXnhYq2icNOizHr1kK+5TI6H0Hy0ag== +commander@4.1.0: + version "4.1.0" + resolved "https://registry.yarnpkg.com/commander/-/commander-4.1.0.tgz#545983a0603fe425bc672d66c9e3c89c42121a83" + integrity sha512-NIQrwvv9V39FHgGFm36+U9SMQzbiHvU79k+iADraJTpmrFFfx7Ds0IvDoAdZsDrknlkRk14OYoWXb57uTh7/sw== commander@^2.11.0, commander@^2.19.0: version "2.19.0" @@ -4457,7 +4454,7 @@ cross-env@^5.1.3, cross-env@^5.2.0: cross-spawn "^6.0.5" is-windows "^1.0.0" -cross-spawn@7.0.1: +cross-spawn@7.0.1, cross-spawn@^7.0.0: version "7.0.1" resolved "https://registry.yarnpkg.com/cross-spawn/-/cross-spawn-7.0.1.tgz#0ab56286e0f7c24e153d04cc2aa027e43a9a5d14" integrity sha512-u7v4o84SwFpD32Z8IIcPZ6z1/ie24O6RU3RbtL5Y316l3KuHVPx9ItBgWQ6VlfAFnRnTtMUrsQ9MUUTuEZjogg== @@ -4788,42 +4785,42 @@ cypress-firebase@*: firebase-tools-extra "^0.0.7" lodash "^4.17.11" -cypress@^3.8.3: - version "3.8.3" - resolved "https://registry.yarnpkg.com/cypress/-/cypress-3.8.3.tgz#e921f5482f1cbe5814891c878f26e704bbffd8f4" - integrity sha512-I9L/d+ilTPPA4vq3NC1OPKmw7jJIpMKNdyfR8t1EXYzYCjyqbc59migOm1YSse/VRbISLJ+QGb5k4Y3bz2lkYw== +cypress@^4.0.1: + version "4.0.1" + resolved "https://registry.yarnpkg.com/cypress/-/cypress-4.0.1.tgz#815da77c8e2528501b9af2e8d12cfcaec8c9dde7" + integrity sha512-P+cSwc5yE+1hIkWwJzpsiSQthKmzkFeFz2ySejSrJJ6FiXoL8pp0vr1cyWp+75KT4nqL9IYt1GMrHp+mVmvocA== dependencies: "@cypress/listr-verbose-renderer" "0.4.1" "@cypress/xvfb" "1.2.4" "@types/sizzle" "2.3.2" arch "2.1.1" - bluebird "3.5.0" - cachedir "1.3.0" - chalk "2.4.2" + bluebird "3.7.2" + cachedir "2.3.0" + chalk "3.0.0" check-more-types "2.24.0" - commander "2.15.1" + commander "4.1.0" common-tags "1.8.0" - debug "3.2.6" + debug "4.1.1" eventemitter2 "4.1.2" - execa "0.10.0" + execa "3.3.0" executable "4.1.1" extract-zip "1.6.7" - fs-extra "5.0.0" - getos "3.1.1" - is-ci "1.2.1" + fs-extra "8.1.0" + getos "3.1.4" + is-ci "2.0.0" is-installed-globally "0.1.0" lazy-ass "1.6.0" - listr "0.12.0" + listr "0.14.3" lodash "4.17.15" - log-symbols "2.2.0" + log-symbols "3.0.0" minimist "1.2.0" moment "2.24.0" - ramda "0.24.1" + ramda "0.26.1" request "2.88.0" request-progress "3.0.0" - supports-color "5.5.0" + supports-color "7.1.0" tmp "0.1.0" - untildify "3.0.3" + untildify "4.0.0" url "0.11.0" yauzl "2.10.0" @@ -4881,13 +4878,7 @@ debug@3.1.0, debug@=3.1.0: dependencies: ms "2.0.0" -debug@3.2.6, debug@^3.0.0, debug@^3.1.0, debug@^3.1.1, debug@^3.2.5, debug@^3.2.6: - version "3.2.6" - resolved "https://registry.yarnpkg.com/debug/-/debug-3.2.6.tgz#e83d17de16d8a7efb7717edbe5fb10135eee629b" - dependencies: - ms "^2.1.1" - -debug@4, debug@^4.0.1, debug@^4.1.0, debug@^4.1.1: +debug@4, debug@4.1.1, debug@^4.0.1, debug@^4.1.0, debug@^4.1.1: version "4.1.1" resolved "https://registry.yarnpkg.com/debug/-/debug-4.1.1.tgz#3b72260255109c6b589cee050f1d516139664791" integrity sha512-pYAIzeRo8J6KPEaJ0VWOh5Pzkbw/RetuzehGM7QRRX5he4fPHx2rdKMB256ehJCkX+XRQm16eZLqLNS8RSZXZw== @@ -4901,6 +4892,12 @@ debug@4.1.0: dependencies: ms "^2.1.1" +debug@^3.0.0, debug@^3.1.0, debug@^3.1.1, debug@^3.2.5, debug@^3.2.6: + version "3.2.6" + resolved "https://registry.yarnpkg.com/debug/-/debug-3.2.6.tgz#e83d17de16d8a7efb7717edbe5fb10135eee629b" + dependencies: + ms "^2.1.1" + debuglog@^1.0.1: version "1.0.1" resolved "https://registry.yarnpkg.com/debuglog/-/debuglog-1.0.1.tgz#aa24ffb9ac3df9a2351837cfb2d279360cd78492" @@ -5740,7 +5737,23 @@ exec-sh@^0.3.2: resolved "https://registry.yarnpkg.com/exec-sh/-/exec-sh-0.3.4.tgz#3a018ceb526cc6f6df2bb504b2bfe8e3a4934ec5" integrity sha512-sEFIkc61v75sWeOe72qyrqg2Qg0OuLESziUDk/O/z2qgS15y2gWVFrI6f2Qn/qw/0/NCfCEsmNA4zOjkwEZT1A== -execa@0.10.0, execa@^0.10.0: +execa@3.3.0: + version "3.3.0" + resolved "https://registry.yarnpkg.com/execa/-/execa-3.3.0.tgz#7e348eef129a1937f21ecbbd53390942653522c1" + integrity sha512-j5Vit5WZR/cbHlqU97+qcnw9WHRCIL4V1SVe75VcHcD1JRBdt8fv0zw89b7CQHQdUHTt2VjuhcF5ibAgVOxqpg== + dependencies: + cross-spawn "^7.0.0" + get-stream "^5.0.0" + human-signals "^1.1.1" + is-stream "^2.0.0" + merge-stream "^2.0.0" + npm-run-path "^4.0.0" + onetime "^5.1.0" + p-finally "^2.0.0" + signal-exit "^3.0.2" + strip-final-newline "^2.0.0" + +execa@^0.10.0: version "0.10.0" resolved "https://registry.yarnpkg.com/execa/-/execa-0.10.0.tgz#ff456a8f53f90f8eccc71a96d11bdfc7f082cb50" dependencies: @@ -6380,12 +6393,12 @@ fs-constants@^1.0.0: resolved "https://registry.yarnpkg.com/fs-constants/-/fs-constants-1.0.0.tgz#6be0de9be998ce16af8afc24497b9ee9b7ccd9ad" integrity sha512-y6OAwoSIf7FyjMIv94u+b5rdheZEjzR63GTyZJm5qh4Bi+2YgwLCcI/fPFZkL5PSixOt6ZNKm+w+Hfp/Bciwow== -fs-extra@5.0.0: - version "5.0.0" - resolved "https://registry.yarnpkg.com/fs-extra/-/fs-extra-5.0.0.tgz#414d0110cdd06705734d055652c5411260c31abd" - integrity sha512-66Pm4RYbjzdyeuqudYqhFiNBbCIuI9kgRqLPSHIlXHidW8NIQtVdkM1yeZ4lXwuhbTETv3EUGMNHAAw6hiundQ== +fs-extra@8.1.0, fs-extra@^8.1.0: + version "8.1.0" + resolved "https://registry.yarnpkg.com/fs-extra/-/fs-extra-8.1.0.tgz#49d43c45a88cd9677668cb7be1b46efdb8d2e1c0" + integrity sha512-yhlQgA6mnOJUKOsRUFsgJdQCvkKhcz8tlZG5HBQfReYZy46OwLcY+Zia0mtdHsOo9y/hP+CxMN0TU9QxoOtG4g== dependencies: - graceful-fs "^4.1.2" + graceful-fs "^4.2.0" jsonfile "^4.0.0" universalify "^0.1.0" @@ -6426,15 +6439,6 @@ fs-extra@^7.0.0: jsonfile "^4.0.0" universalify "^0.1.0" -fs-extra@^8.1.0: - version "8.1.0" - resolved "https://registry.yarnpkg.com/fs-extra/-/fs-extra-8.1.0.tgz#49d43c45a88cd9677668cb7be1b46efdb8d2e1c0" - integrity sha512-yhlQgA6mnOJUKOsRUFsgJdQCvkKhcz8tlZG5HBQfReYZy46OwLcY+Zia0mtdHsOo9y/hP+CxMN0TU9QxoOtG4g== - dependencies: - graceful-fs "^4.2.0" - jsonfile "^4.0.0" - universalify "^0.1.0" - fs-minipass@^1.2.5: version "1.2.5" resolved "https://registry.yarnpkg.com/fs-minipass/-/fs-minipass-1.2.5.tgz#06c277218454ec288df77ada54a03b8702aacb9d" @@ -6649,16 +6653,23 @@ get-stream@^4.0.0: dependencies: pump "^3.0.0" +get-stream@^5.0.0: + version "5.1.0" + resolved "https://registry.yarnpkg.com/get-stream/-/get-stream-5.1.0.tgz#01203cdc92597f9b909067c3e656cc1f4d3c4dc9" + integrity sha512-EXr1FOzrzTfGeL0gQdeFEvOMm2mzMOglyiOXSTpPC+iAjAKftbr3jpCMWynogwYnM+eSj9sHGc6wjIcDvYiygw== + dependencies: + pump "^3.0.0" + get-value@^2.0.3, get-value@^2.0.6: version "2.0.6" resolved "https://registry.yarnpkg.com/get-value/-/get-value-2.0.6.tgz#dc15ca1c672387ca76bd37ac0a395ba2042a2c28" -getos@3.1.1: - version "3.1.1" - resolved "https://registry.yarnpkg.com/getos/-/getos-3.1.1.tgz#967a813cceafee0156b0483f7cffa5b3eff029c5" - integrity sha512-oUP1rnEhAr97rkitiszGP9EgDVYnmchgFzfqRzSkgtfv7ai6tEi7Ko8GgjNXts7VLWEqrTWyhsOKLe5C5b/Zkg== +getos@3.1.4: + version "3.1.4" + resolved "https://registry.yarnpkg.com/getos/-/getos-3.1.4.tgz#29cdf240ed10a70c049add7b6f8cb08c81876faf" + integrity sha512-UORPzguEB/7UG5hqiZai8f0vQ7hzynMQyJLxStoQ8dPGAcmgsfXOPA4iE/fGtweHYkK+z4zc9V0g+CIFRf5HYw== dependencies: - async "2.6.1" + async "^3.1.0" getpass@^0.1.1: version "0.1.7" @@ -7385,6 +7396,11 @@ https-proxy-agent@^4.0.0: agent-base "5" debug "4" +human-signals@^1.1.1: + version "1.1.1" + resolved "https://registry.yarnpkg.com/human-signals/-/human-signals-1.1.1.tgz#c5b1cd14f50aeae09ab6c59fe63ba3395fe4dfa3" + integrity sha512-SEQu7vl8KjNL2eoGBLF3+wAjpsNfA9XMlXAYj/3EdaNfAlxKthD1xjEQfGOUhllCGGJVNY34bRr6lPINhNjyZw== + humanize-ms@^1.2.1: version "1.2.1" resolved "https://registry.yarnpkg.com/humanize-ms/-/humanize-ms-1.2.1.tgz#c46e3159a293f6b896da29316d8b6fe8bb79bbed" @@ -7496,12 +7512,6 @@ imurmurhash@^0.1.4: version "0.1.4" resolved "https://registry.yarnpkg.com/imurmurhash/-/imurmurhash-0.1.4.tgz#9218b9b2b928a238b13dc4fb6b6d576f231453ea" -indent-string@^2.1.0: - version "2.1.0" - resolved "https://registry.yarnpkg.com/indent-string/-/indent-string-2.1.0.tgz#8e2d48348742121b4a8218b7a137e9a52049dc80" - dependencies: - repeating "^2.0.0" - indent-string@^3.0.0: version "3.2.0" resolved "https://registry.yarnpkg.com/indent-string/-/indent-string-3.2.0.tgz#4a5fd6d27cc332f37e5419a504dbb837105c9289" @@ -7698,20 +7708,20 @@ is-callable@^1.1.5: resolved "https://registry.yarnpkg.com/is-callable/-/is-callable-1.1.5.tgz#f7e46b596890456db74e7f6e976cb3273d06faab" integrity sha512-ESKv5sMCJB2jnHTWZ3O5itG+O128Hsus4K4Qh1h2/cgn2vbgnLSVqfV46AeJA9D5EeeLa9w81KUXMtn34zhX+Q== -is-ci@1.2.1, is-ci@^1.0.10: - version "1.2.1" - resolved "https://registry.yarnpkg.com/is-ci/-/is-ci-1.2.1.tgz#e3779c8ee17fccf428488f6e281187f2e632841c" - integrity sha512-s6tfsaQaQi3JNciBH6shVqEDvhGut0SUXr31ag8Pd8BBbVVlcGfWhpPmEOoM6RJ5TFhbypvf5yyRw/VXW1IiWg== - dependencies: - ci-info "^1.5.0" - -is-ci@^2.0.0: +is-ci@2.0.0, is-ci@^2.0.0: version "2.0.0" resolved "https://registry.yarnpkg.com/is-ci/-/is-ci-2.0.0.tgz#6bc6334181810e04b5c22b3d589fdca55026404c" integrity sha512-YfJT7rkpQB0updsdHLGWrvhBJfcfzNNawYDNIyQXJz0IViGf75O8EBPKSdvw2rF+LGCsX4FZ8tcr3b19LcZq4w== dependencies: ci-info "^2.0.0" +is-ci@^1.0.10: + version "1.2.1" + resolved "https://registry.yarnpkg.com/is-ci/-/is-ci-1.2.1.tgz#e3779c8ee17fccf428488f6e281187f2e632841c" + integrity sha512-s6tfsaQaQi3JNciBH6shVqEDvhGut0SUXr31ag8Pd8BBbVVlcGfWhpPmEOoM6RJ5TFhbypvf5yyRw/VXW1IiWg== + dependencies: + ci-info "^1.5.0" + is-color-stop@^1.0.0: version "1.1.0" resolved "https://registry.yarnpkg.com/is-color-stop/-/is-color-stop-1.1.0.tgz#cfff471aee4dd5c9e158598fbe12967b5cdad345" @@ -7773,12 +7783,6 @@ is-extglob@^2.1.0, is-extglob@^2.1.1: version "2.1.1" resolved "https://registry.yarnpkg.com/is-extglob/-/is-extglob-2.1.1.tgz#a88c02535791f02ed37c76a1b9ea9773c833f8c2" -is-finite@^1.0.0: - version "1.0.2" - resolved "https://registry.yarnpkg.com/is-finite/-/is-finite-1.0.2.tgz#cc6677695602be550ef11e8b4aa6305342b6d0aa" - dependencies: - number-is-nan "^1.0.0" - is-fullwidth-code-point@^1.0.0: version "1.0.0" resolved "https://registry.yarnpkg.com/is-fullwidth-code-point/-/is-fullwidth-code-point-1.0.0.tgz#ef9e31386f031a7f0d643af82fde50c457ef00cb" @@ -7845,6 +7849,13 @@ is-obj@^1.0.0, is-obj@^1.0.1: version "1.0.1" resolved "https://registry.yarnpkg.com/is-obj/-/is-obj-1.0.1.tgz#3e4729ac1f5fde025cd7d83a896dab9f4f67db0f" +is-observable@^1.1.0: + version "1.1.0" + resolved "https://registry.yarnpkg.com/is-observable/-/is-observable-1.1.0.tgz#b3e986c8f44de950867cab5403f5a3465005975e" + integrity sha512-NqCa4Sa2d+u7BWc6CukaObG3Fh+CU9bvixbpcXYhy2VvYS7vVGIdAgnIS5Ks3A/cqk4rebLJ9s8zBstT2aKnIA== + dependencies: + symbol-observable "^1.1.0" + is-path-cwd@^2.0.0: version "2.2.0" resolved "https://registry.yarnpkg.com/is-path-cwd/-/is-path-cwd-2.2.0.tgz#67d43b82664a7b5191fd9119127eb300048a9fdb" @@ -8881,9 +8892,10 @@ listr-silent-renderer@^1.1.1: version "1.1.1" resolved "https://registry.yarnpkg.com/listr-silent-renderer/-/listr-silent-renderer-1.1.1.tgz#924b5a3757153770bf1a8e3fbf74b8bbf3f9242e" -listr-update-renderer@^0.2.0: - version "0.2.0" - resolved "https://registry.yarnpkg.com/listr-update-renderer/-/listr-update-renderer-0.2.0.tgz#ca80e1779b4e70266807e8eed1ad6abe398550f9" +listr-update-renderer@^0.5.0: + version "0.5.0" + resolved "https://registry.yarnpkg.com/listr-update-renderer/-/listr-update-renderer-0.5.0.tgz#4ea8368548a7b8aecb7e06d8c95cb45ae2ede6a2" + integrity sha512-tKRsZpKz8GSGqoI/+caPmfrypiaq+OQCbd+CovEC24uk1h952lVj5sC7SqyFUm+OaJ5HN/a1YLt5cit2FMNsFA== dependencies: chalk "^1.1.3" cli-truncate "^0.2.1" @@ -8891,38 +8903,33 @@ listr-update-renderer@^0.2.0: figures "^1.7.0" indent-string "^3.0.0" log-symbols "^1.0.2" - log-update "^1.0.2" + log-update "^2.3.0" strip-ansi "^3.0.1" -listr-verbose-renderer@^0.4.0: - version "0.4.1" - resolved "https://registry.yarnpkg.com/listr-verbose-renderer/-/listr-verbose-renderer-0.4.1.tgz#8206f4cf6d52ddc5827e5fd14989e0e965933a35" +listr-verbose-renderer@^0.5.0: + version "0.5.0" + resolved "https://registry.yarnpkg.com/listr-verbose-renderer/-/listr-verbose-renderer-0.5.0.tgz#f1132167535ea4c1261102b9f28dac7cba1e03db" + integrity sha512-04PDPqSlsqIOaaaGZ+41vq5FejI9auqTInicFRndCBgE3bXG8D6W1I+mWhk+1nqbHmyhla/6BUrd5OSiHwKRXw== dependencies: - chalk "^1.1.3" - cli-cursor "^1.0.2" + chalk "^2.4.1" + cli-cursor "^2.1.0" date-fns "^1.27.2" - figures "^1.7.0" + figures "^2.0.0" -listr@0.12.0: - version "0.12.0" - resolved "https://registry.yarnpkg.com/listr/-/listr-0.12.0.tgz#6bce2c0f5603fa49580ea17cd6a00cc0e5fa451a" +listr@0.14.3: + version "0.14.3" + resolved "https://registry.yarnpkg.com/listr/-/listr-0.14.3.tgz#2fea909604e434be464c50bddba0d496928fa586" + integrity sha512-RmAl7su35BFd/xoMamRjpIE4j3v+L28o8CT5YhAXQJm1fD+1l9ngXY8JAQRJ+tFK2i5njvi0iRUKV09vPwA0iA== dependencies: - chalk "^1.1.3" - cli-truncate "^0.2.1" - figures "^1.7.0" - indent-string "^2.1.0" + "@samverschueren/stream-to-observable" "^0.3.0" + is-observable "^1.1.0" is-promise "^2.1.0" is-stream "^1.1.0" listr-silent-renderer "^1.1.1" - listr-update-renderer "^0.2.0" - listr-verbose-renderer "^0.4.0" - log-symbols "^1.0.2" - log-update "^1.0.2" - ora "^0.2.3" - p-map "^1.1.1" - rxjs "^5.0.0-beta.11" - stream-to-observable "^0.1.0" - strip-ansi "^3.0.1" + listr-update-renderer "^0.5.0" + listr-verbose-renderer "^0.5.0" + p-map "^2.0.0" + rxjs "^6.3.3" load-json-file@^2.0.0: version "2.0.0" @@ -9225,11 +9232,12 @@ log-driver@1.2.7: resolved "https://registry.yarnpkg.com/log-driver/-/log-driver-1.2.7.tgz#63b95021f0702fedfa2c9bb0a24e7797d71871d8" integrity sha512-U7KCmLdqsGHBLeWqYlFA0V0Sl6P08EE1ZrmA9cxjUE0WVqT9qnyVDPz1kzpFEP0jdJuFnasWIfSd7fsaNXkpbg== -log-symbols@2.2.0, log-symbols@^2.2.0: - version "2.2.0" - resolved "https://registry.yarnpkg.com/log-symbols/-/log-symbols-2.2.0.tgz#5740e1c5d6f0dfda4ad9323b5332107ef6b4c40a" +log-symbols@3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/log-symbols/-/log-symbols-3.0.0.tgz#f3a08516a5dea893336a7dee14d18a1cfdab77c4" + integrity sha512-dSkNGuI7iG3mfvDzUuYZyvk5dD9ocYCYzNU6CYDE6+Xqd+gwme6Z00NS3dUh8mq/73HaEtT7m6W+yUPtU6BZnQ== dependencies: - chalk "^2.0.1" + chalk "^2.4.2" log-symbols@^1.0.2: version "1.0.2" @@ -9237,12 +9245,20 @@ log-symbols@^1.0.2: dependencies: chalk "^1.0.0" -log-update@^1.0.2: - version "1.0.2" - resolved "https://registry.yarnpkg.com/log-update/-/log-update-1.0.2.tgz#19929f64c4093d2d2e7075a1dad8af59c296b8d1" +log-symbols@^2.2.0: + version "2.2.0" + resolved "https://registry.yarnpkg.com/log-symbols/-/log-symbols-2.2.0.tgz#5740e1c5d6f0dfda4ad9323b5332107ef6b4c40a" dependencies: - ansi-escapes "^1.0.0" - cli-cursor "^1.0.2" + chalk "^2.0.1" + +log-update@^2.3.0: + version "2.3.0" + resolved "https://registry.yarnpkg.com/log-update/-/log-update-2.3.0.tgz#88328fd7d1ce7938b29283746f0b1bc126b24708" + integrity sha1-iDKP19HOeTiykoN0bwsbwSayRwg= + dependencies: + ansi-escapes "^3.0.0" + cli-cursor "^2.0.0" + wrap-ansi "^3.0.1" loglevel@^1.6.6: version "1.6.6" @@ -10192,6 +10208,13 @@ npm-run-path@^2.0.0: dependencies: path-key "^2.0.0" +npm-run-path@^4.0.0: + version "4.0.1" + resolved "https://registry.yarnpkg.com/npm-run-path/-/npm-run-path-4.0.1.tgz#b7ecd1e5ed53da8e37a55e1c2269e0b97ed748ea" + integrity sha512-S48WzZW777zhNIrn7gxOlISNAqi9ZC/uQFnRdbeIHhZhCA6UqpkOT8T1G7BvfdgP4Er8gF4sUbaS0i7QvIfCWw== + dependencies: + path-key "^3.0.0" + npm-user-validate@~1.0.0: version "1.0.0" resolved "https://registry.yarnpkg.com/npm-user-validate/-/npm-user-validate-1.0.0.tgz#8ceca0f5cea04d4e93519ef72d0557a75122e951" @@ -10536,15 +10559,6 @@ optjs@~3.2.2: version "3.2.2" resolved "https://registry.yarnpkg.com/optjs/-/optjs-3.2.2.tgz#69a6ce89c442a44403141ad2f9b370bd5bb6f4ee" -ora@^0.2.3: - version "0.2.3" - resolved "https://registry.npmjs.org/ora/-/ora-0.2.3.tgz#37527d220adcd53c39b73571d754156d5db657a4" - dependencies: - chalk "^1.1.1" - cli-cursor "^1.0.2" - cli-spinners "^0.1.2" - object-assign "^4.0.1" - ora@^3.4.0: version "3.4.0" resolved "https://registry.yarnpkg.com/ora/-/ora-3.4.0.tgz#bf0752491059a3ef3ed4c85097531de9fdbcd318" @@ -10568,7 +10582,7 @@ os-browserify@^0.3.0: version "0.3.0" resolved "https://registry.yarnpkg.com/os-browserify/-/os-browserify-0.3.0.tgz#854373c7f5c2315914fc9bfc6bd8238fdda1ec27" -os-homedir@^1.0.0, os-homedir@^1.0.1: +os-homedir@^1.0.0: version "1.0.2" resolved "https://registry.yarnpkg.com/os-homedir/-/os-homedir-1.0.2.tgz#ffbc4988336e0e833de0c168c7ef152121aa7fb3" @@ -10625,6 +10639,11 @@ p-finally@^1.0.0: version "1.0.0" resolved "https://registry.yarnpkg.com/p-finally/-/p-finally-1.0.0.tgz#3fbcfb15b899a44123b34b6dcc18b724336a2cae" +p-finally@^2.0.0: + version "2.0.1" + resolved "https://registry.yarnpkg.com/p-finally/-/p-finally-2.0.1.tgz#bd6fcaa9c559a096b680806f4d657b3f0f240561" + integrity sha512-vpm09aKwq6H9phqRQzecoDpD8TmVyGw70qmWlyq5onxY7tqyTTFVvxMykxQSQKILBSFlbXpypIw2T1Ml7+DDtw== + p-is-promise@^1.1.0: version "1.1.0" resolved "https://registry.yarnpkg.com/p-is-promise/-/p-is-promise-1.1.0.tgz#9c9456989e9f6588017b0434d56097675c3da05e" @@ -10667,10 +10686,6 @@ p-locate@^4.1.0: dependencies: p-limit "^2.2.0" -p-map@^1.1.1: - version "1.2.0" - resolved "https://registry.yarnpkg.com/p-map/-/p-map-1.2.0.tgz#e4e94f311eabbc8633a1e79908165fca26241b6b" - p-map@^2.0.0: version "2.1.0" resolved "https://registry.yarnpkg.com/p-map/-/p-map-2.1.0.tgz#310928feef9c9ecc65b68b17693018a665cea175" @@ -10857,7 +10872,7 @@ path-key@^2.0.0, path-key@^2.0.1: version "2.0.1" resolved "https://registry.yarnpkg.com/path-key/-/path-key-2.0.1.tgz#411cadb574c5a140d3a4b1910d40d80cc9f40b40" -path-key@^3.1.0: +path-key@^3.0.0, path-key@^3.1.0: version "3.1.1" resolved "https://registry.yarnpkg.com/path-key/-/path-key-3.1.1.tgz#581f6ade658cbba65a0d3380de7753295054f375" integrity sha512-ojmeN0qd+y0jszEtoY48r0Peq5dwMEkIlCOu6Q5f41lfkswXuKtYrhgoTpLnyIcHm24Uhqx+5Tqm2InSwLhE6Q== @@ -11959,9 +11974,10 @@ raf@^3.4.1: dependencies: performance-now "^2.1.0" -ramda@0.24.1: - version "0.24.1" - resolved "https://registry.yarnpkg.com/ramda/-/ramda-0.24.1.tgz#c3b7755197f35b8dc3502228262c4c91ddb6b857" +ramda@0.26.1: + version "0.26.1" + resolved "https://registry.yarnpkg.com/ramda/-/ramda-0.26.1.tgz#8d41351eb8111c55353617fc3bbffad8e4d35d06" + integrity sha512-hLWjpy7EnsDBb0p+Z3B7rPi3GDeRG5ZtiI33kJhTt+ORCd38AbAIjB/9zRIUoeTbE/AVX5ZkU7m6bznsvrf8eQ== randombytes@^2.0.0, randombytes@^2.0.1, randombytes@^2.0.5: version "2.0.6" @@ -12436,12 +12452,6 @@ repeat-string@^1.6.1: version "1.6.1" resolved "https://registry.yarnpkg.com/repeat-string/-/repeat-string-1.6.1.tgz#8dcae470e1c88abc2d600fff4a776286da75e637" -repeating@^2.0.0: - version "2.0.1" - resolved "https://registry.yarnpkg.com/repeating/-/repeating-2.0.1.tgz#5214c53a926d3552707527fbab415dbc08d06dda" - dependencies: - is-finite "^1.0.0" - request-progress@3.0.0: version "3.0.0" resolved "https://registry.yarnpkg.com/request-progress/-/request-progress-3.0.0.tgz#4ca754081c7fec63f505e4faa825aa06cd669dbe" @@ -12735,13 +12745,7 @@ run-queue@^1.0.0, run-queue@^1.0.3: dependencies: aproba "^1.1.1" -rxjs@^5.0.0-beta.11: - version "5.5.12" - resolved "https://registry.yarnpkg.com/rxjs/-/rxjs-5.5.12.tgz#6fa61b8a77c3d793dbaf270bee2f43f652d741cc" - dependencies: - symbol-observable "1.0.1" - -rxjs@^6.4.0, rxjs@^6.5.3: +rxjs@^6.3.3, rxjs@^6.4.0, rxjs@^6.5.3: version "6.5.4" resolved "https://registry.yarnpkg.com/rxjs/-/rxjs-6.5.4.tgz#e0777fe0d184cec7872df147f303572d414e211c" integrity sha512-naMQXcgEo3csAEGvw/NydRA0fuS2nDZJiw1YUWFKU7aPPAPGZEsD4Iimit96qwCieH6y614MCLYwdkrWx7z/7Q== @@ -13396,10 +13400,6 @@ stream-shift@^1.0.0: version "1.0.0" resolved "https://registry.yarnpkg.com/stream-shift/-/stream-shift-1.0.0.tgz#d5c752825e5367e786f78e18e445ea223a155952" -stream-to-observable@^0.1.0: - version "0.1.0" - resolved "https://registry.yarnpkg.com/stream-to-observable/-/stream-to-observable-0.1.0.tgz#45bf1d9f2d7dc09bed81f1c307c430e68b84cffe" - strict-uri-encode@^1.0.0: version "1.1.0" resolved "https://registry.yarnpkg.com/strict-uri-encode/-/strict-uri-encode-1.1.0.tgz#279b225df1d582b1f54e65addd4352e18faa0713" @@ -13569,6 +13569,11 @@ strip-eof@^1.0.0: version "1.0.0" resolved "https://registry.yarnpkg.com/strip-eof/-/strip-eof-1.0.0.tgz#bb43ff5598a6eb05d89b59fcd129c983313606bf" +strip-final-newline@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/strip-final-newline/-/strip-final-newline-2.0.0.tgz#89b852fb2fcbe936f6f4b3187afb0a12c1ab58ad" + integrity sha512-BrpvfNAE3dcvq7ll3xVumzjKjZQ5tI1sEUIKr3Uoks0XUl45St3FlatVqef9prk4jRDzhW6WZg+3bk93y6pLjA== + strip-json-comments@^3.0.1: version "3.0.1" resolved "https://registry.yarnpkg.com/strip-json-comments/-/strip-json-comments-3.0.1.tgz#85713975a91fb87bf1b305cca77395e40d2a64a7" @@ -13635,16 +13640,23 @@ superstatic@^6.0.1: try-require "^1.0.0" update-notifier "^2.5.0" -supports-color@5.5.0, supports-color@^5.0.0, supports-color@^5.3.0, supports-color@^5.5.0: - version "5.5.0" - resolved "https://registry.yarnpkg.com/supports-color/-/supports-color-5.5.0.tgz#e2e69a44ac8772f78a1ec0b35b689df6530efc8f" +supports-color@7.1.0, supports-color@^7.0.0, supports-color@^7.1.0: + version "7.1.0" + resolved "https://registry.yarnpkg.com/supports-color/-/supports-color-7.1.0.tgz#68e32591df73e25ad1c4b49108a2ec507962bfd1" + integrity sha512-oRSIpR8pxT1Wr2FquTNnGet79b3BWljqOuoW/h4oBhxJ/HUbX5nX6JSruTkvXDCFMwDPvsaTTbvMLKZWSy0R5g== dependencies: - has-flag "^3.0.0" + has-flag "^4.0.0" supports-color@^2.0.0: version "2.0.0" resolved "https://registry.yarnpkg.com/supports-color/-/supports-color-2.0.0.tgz#535d045ce6b6363fa40117084629995e9df324c7" +supports-color@^5.0.0, supports-color@^5.3.0, supports-color@^5.5.0: + version "5.5.0" + resolved "https://registry.yarnpkg.com/supports-color/-/supports-color-5.5.0.tgz#e2e69a44ac8772f78a1ec0b35b689df6530efc8f" + dependencies: + has-flag "^3.0.0" + supports-color@^6.1.0: version "6.1.0" resolved "https://registry.yarnpkg.com/supports-color/-/supports-color-6.1.0.tgz#0764abc69c63d5ac842dd4867e8d025e880df8f3" @@ -13652,13 +13664,6 @@ supports-color@^6.1.0: dependencies: has-flag "^3.0.0" -supports-color@^7.0.0, supports-color@^7.1.0: - version "7.1.0" - resolved "https://registry.yarnpkg.com/supports-color/-/supports-color-7.1.0.tgz#68e32591df73e25ad1c4b49108a2ec507962bfd1" - integrity sha512-oRSIpR8pxT1Wr2FquTNnGet79b3BWljqOuoW/h4oBhxJ/HUbX5nX6JSruTkvXDCFMwDPvsaTTbvMLKZWSy0R5g== - dependencies: - has-flag "^4.0.0" - supports-hyperlinks@^1.0.1: version "1.0.1" resolved "https://registry.yarnpkg.com/supports-hyperlinks/-/supports-hyperlinks-1.0.1.tgz#71daedf36cc1060ac5100c351bb3da48c29c0ef7" @@ -13710,9 +13715,10 @@ svgo@^1.2.2: unquote "~1.1.1" util.promisify "~1.0.0" -symbol-observable@1.0.1: - version "1.0.1" - resolved "https://registry.yarnpkg.com/symbol-observable/-/symbol-observable-1.0.1.tgz#8340fc4702c3122df5d22288f88283f513d3fdd4" +symbol-observable@^1.1.0: + version "1.2.0" + resolved "https://registry.yarnpkg.com/symbol-observable/-/symbol-observable-1.2.0.tgz#c22688aed4eab3cdc2dfeacbb561660560a00804" + integrity sha512-e900nM8RRtGhlV36KGEU9k65K3mPb1WV70OdjfxlG2EAuM1noi/E/BaW/uMhL7bPEssK8QV57vN3esixjUvcXQ== symbol-tree@^3.2.2: version "3.2.2" @@ -14227,10 +14233,10 @@ unset-value@^1.0.0: has-value "^0.3.1" isobject "^3.0.0" -untildify@3.0.3: - version "3.0.3" - resolved "https://registry.yarnpkg.com/untildify/-/untildify-3.0.3.tgz#1e7b42b140bcfd922b22e70ca1265bfe3634c7c9" - integrity sha512-iSk/J8efr8uPT/Z4eSUywnqyrQU7DSdMfdqK4iWEaUVVmcP5JcnpRqmVMwcwcnmI1ATFNgC5V90u09tBynNFKA== +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== unzip-response@^2.0.1: version "2.0.1" @@ -14886,6 +14892,14 @@ wrap-ansi@^2.0.0: string-width "^1.0.1" strip-ansi "^3.0.1" +wrap-ansi@^3.0.1: + version "3.0.1" + resolved "https://registry.yarnpkg.com/wrap-ansi/-/wrap-ansi-3.0.1.tgz#288a04d87eda5c286e060dfe8f135ce8d007f8ba" + integrity sha1-KIoE2H7aXChuBg3+jxNc6NAH+Lo= + dependencies: + string-width "^2.1.1" + strip-ansi "^4.0.0" + wrap-ansi@^5.1.0: version "5.1.0" resolved "https://registry.yarnpkg.com/wrap-ansi/-/wrap-ansi-5.1.0.tgz#1fd1f67235d5b6d0fee781056001bfb694c03b09" diff --git a/index.d.ts b/index.d.ts index 6aa64983..3173d121 100644 --- a/index.d.ts +++ b/index.d.ts @@ -178,7 +178,7 @@ declare module "attachCustomCommands" { * @example * cy.login() */ - login: () => Chainable; + login: (uid?: string) => Chainable; /** * Log out of Firebase instance * @see https://github.com/prescottprue/cypress-firebase#cylogout @@ -189,7 +189,7 @@ declare module "attachCustomCommands" { /** * Call Real Time Database path with some specified action. Authentication is through * `FIREBASE_TOKEN` (CI token) since firebase-tools is used under the hood, allowing - * for adming privileges. + * for admin privileges. * @param action - The action type to call with (set, push, update, remove) * @param actionPath - Path within RTDB that action should be applied * @param opts - Options @@ -406,7 +406,7 @@ declare module "extendWithFirebaseConfig" { * @param config - Cypress config object * @returns Id of firbase project */ - export function getFirebaseProjectIdFromConfig(config: CypressConfig): string; + export function getFirebaseProjectIdFromConfig(config: CypressConfig): string | undefined; /** * Load config for Cypress from .firebaserc. * @param cypressConfig - Existing Cypress config diff --git a/package.json b/package.json index 43a99ed1..caf488c6 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "cypress-firebase", - "version": "0.9.0", + "version": "0.10.0", "description": "Utilities to help testing Firebase projects with Cypress.", "main": "lib/index.js", "module": "lib/index.js", @@ -33,7 +33,7 @@ "commander": "^4.1.0", "figures": "^3.1.0", "firebase-admin": "^8.9.2", - "firebase-tools-extra": "0.4.0", + "firebase-tools-extra": "0.5.0", "lodash": "^4.17.15" }, "devDependencies": { diff --git a/src/attachCustomCommands.ts b/src/attachCustomCommands.ts index 060b3a49..ad5eea8c 100644 --- a/src/attachCustomCommands.ts +++ b/src/attachCustomCommands.ts @@ -28,7 +28,7 @@ declare global { * @example * cy.login() */ - login: () => Chainable; + login: (uid?: string) => Chainable; /** * Log out of Firebase instance @@ -41,7 +41,7 @@ declare global { /** * Call Real Time Database path with some specified action. Authentication is through * `FIREBASE_TOKEN` (CI token) since firebase-tools is used under the hood, allowing - * for adming privileges. + * for admin privileges. * @param action - The action type to call with (set, push, update, remove) * @param actionPath - Path within RTDB that action should be applied * @param opts - Options @@ -109,6 +109,28 @@ declare global { } } +/** + * @param firebase - firebase instance + * @param customToken - Custom token to use for login + * @returns Promise which resolves with the user auth object + */ +function loginWithCustomToken( + firebase: any, + customToken: string, +): Promise { + return new Promise((resolve, reject): any => { + firebase.auth().onAuthStateChanged((auth: any) => { + if (auth) { + resolve(auth); + } + }); + firebase + .auth() + .signInWithCustomToken(customToken) + .catch(reject); + }); +} + /** * Attach custom commands including cy.login, cy.logout, cy.callRtdb, * @param commandParams - List of params to provide scope during @@ -120,32 +142,56 @@ export default function attachCustomCommands( const { Cypress, cy, firebase } = commandParams; /** - * Login to Firebase auth using FIREBASE_AUTH_JWT environment variable - * which is generated using firebase-admin authenticated with serviceAccount - * during test:buildConfig phase. + * Login to Firebase auth using either a passed uid or the FIREBASE_AUTH_JWT + * environment variable which is generated using firebase-admin authenticated + * with serviceAccount during call to createTestEnvFile. * @name cy.login */ - Cypress.Commands.add('login', (): any => { - /** Log in using token * */ - if (!Cypress.env('FIREBASE_AUTH_JWT')) { - cy.log( - 'FIREBASE_AUTH_JWT must be set to cypress environment in order to login', - ); - } else if (firebase.auth().currentUser) { - cy.log('Authed user already exists, login complete.'); - } else { - return new Promise((resolve, reject): any => { - firebase.auth().onAuthStateChanged((auth: any) => { - if (auth) { - resolve(auth); + Cypress.Commands.add('login', (uid?: string): any => { + // Handle UID which is passed in + if (uid) { + // Resolve with current user if they already exist + if ( + firebase.auth().currentUser && + uid === firebase.auth().currentUser.uid + ) { + cy.log('Authed user already exists, login complete.'); + return undefined; + } + // Generate a custom token then login if a UID is passed + return cy + .exec(`npx firebase-extra createCustomToken ${uid}`, { + timeout: 100000, + }) + .then((out: any) => { + const { stdout, stderr } = out; + // Reject with Error if error in firestoreCommand call + if (stderr) { + return Promise.reject(new Error(stderr)); } + return loginWithCustomToken(firebase, stdout); }); - firebase - .auth() - .signInWithCustomToken(Cypress.env('FIREBASE_AUTH_JWT')) - .catch(reject); - }); } + + // Throw if JWT not within environment (passed uid case handled above) + if (!Cypress.env('FIREBASE_AUTH_JWT')) { + /** Log in using token * */ + const errMsg = + 'uid must be passed to cy.login or FIREBASE_AUTH_JWT must be set to cypress environment in order to login'; + cy.log(errMsg); + throw new Error(errMsg); + } + + // Resolve with currentUser if they exist + if (firebase.auth().currentUser) { + cy.log('Authed user already exists, login complete.'); + // Undefined is returned to prevent Cypress error: + // "Cypress detected that you invoked one or more cy commands in a custom command but returned a different value." + return undefined; + } + + // Otherwise, login with Token from environment + return loginWithCustomToken(firebase, Cypress.env('FIREBASE_AUTH_JWT')); }); /** diff --git a/src/extendWithFirebaseConfig.ts b/src/extendWithFirebaseConfig.ts index fed052e9..473e4236 100644 --- a/src/extendWithFirebaseConfig.ts +++ b/src/extendWithFirebaseConfig.ts @@ -26,11 +26,19 @@ export interface ExtendWithFirebaseConfigSettings { localHostPort?: string | number; } +interface FirebaseRcProjects { + [name: string]: string; +} + +interface FirebaseRc { + projects?: FirebaseRcProjects; +} + /** * Load .firebaserc file * @returns Contents of .firebaserc file parsed as JSON */ -function loadFirebaseRc(): string { +function loadFirebaseRc(): FirebaseRc { const rcFilePath = `${process.cwd()}/${FIREBASE_CONFIG_FILE_NAME}`; if (!existsSync(rcFilePath)) { throw new Error(`${FIREBASE_CONFIG_FILE_NAME} file not found`); @@ -56,16 +64,20 @@ function getEnvNameFromConfig(cypressConfig: CypressConfig): string { * @param config - Cypress config object * @returns Id of firbase project */ -export function getFirebaseProjectIdFromConfig(config: CypressConfig): string { +export function getFirebaseProjectIdFromConfig( + config: CypressConfig, +): string | undefined { const projectIdFromConfig = get(config, 'env.firebaseProjectId'); if (projectIdFromConfig) { return projectIdFromConfig; } - const firbaseRcConfig = loadFirebaseRc(); + const firebaseRcConfig = loadFirebaseRc(); const envName = getEnvNameFromConfig(config); - const projectsConfig = get(firbaseRcConfig, 'projects'); + const projectsConfig = firebaseRcConfig && firebaseRcConfig.projects; const firebaseProjectId = - projectsConfig[envName] || projectsConfig.master || projectsConfig.default; + (projectsConfig && projectsConfig[envName]) || + projectsConfig?.master || + projectsConfig?.default; return firebaseProjectId; } diff --git a/src/utils.ts b/src/utils.ts index d0ac7750..8a40989a 100644 --- a/src/utils.ts +++ b/src/utils.ts @@ -46,7 +46,7 @@ export function addDefaultArgs( args: string[], opts?: any, ): string[] { - const { disableYes = false, token, withMeta } = opts || {}; + const { disableYes = false } = opts || {}; const newArgs = [...args]; // TODO: Load this in a way that understands environment. Currently this will // go to the first project id that is defined, not which one should be used @@ -62,15 +62,15 @@ export function addDefaultArgs( } const tokenFromEnv = Cypress.env('FIREBASE_TOKEN'); // Include token if it exists in environment - if (!newArgs.includes('--token') && (token || tokenFromEnv)) { + if (!newArgs.includes('--token') && (opts?.token || tokenFromEnv)) { newArgs.push('--token'); - newArgs.push(token || tokenFromEnv); + newArgs.push(opts?.token || tokenFromEnv); } // Add Firebase's automatic approval argument if it is not already in newArgs if (!disableYes && !newArgs.includes(FIREBASE_TOOLS_YES_ARGUMENT)) { newArgs.push(FIREBASE_TOOLS_YES_ARGUMENT); } - if (withMeta) { + if (opts?.withMeta) { // Add -m to argsWithDefaults string (meta) if withmeta option is true newArgs.push('-m'); } diff --git a/test/unit/attachCustomCommands.spec.ts b/test/unit/attachCustomCommands.spec.ts index db6a905e..a71e3fbe 100644 --- a/test/unit/attachCustomCommands.spec.ts +++ b/test/unit/attachCustomCommands.spec.ts @@ -1,30 +1,30 @@ -import { attachCustomCommands } from '../../src'; import { expect } from 'chai'; import sinon from 'sinon'; +import { attachCustomCommands } from '../../src'; -const cy: any = {} -const addSpy = sinon.spy() -const Cypress = { Commands: { add: addSpy } } -const firebase = {} +const cy: any = {}; +const addSpy = sinon.spy(); +const Cypress = { Commands: { add: addSpy } }; +const firebase = {}; describe('attachCustomCommands', () => { before(() => { - attachCustomCommands({ cy, Cypress, firebase }) - }) + attachCustomCommands({ cy, Cypress, firebase }); + }); it('Sets cy.login', () => { - expect(addSpy).to.have.been.calledWith("login") + expect(addSpy).to.have.been.calledWith('login'); }); it('Sets cy.logout', () => { - expect(addSpy).to.have.been.calledWith("logout") + expect(addSpy).to.have.been.calledWith('logout'); }); it('Sets cy.callFirestore', () => { - expect(addSpy).to.have.been.calledWith("callFirestore") + expect(addSpy).to.have.been.calledWith('callFirestore'); }); it('Sets cy.callRtdb', () => { - expect(addSpy).to.have.been.calledWith("callRtdb") + expect(addSpy).to.have.been.calledWith('callRtdb'); }); -}); \ No newline at end of file +}); diff --git a/test/unit/buildFirestoreCommand.spec.ts b/test/unit/buildFirestoreCommand.spec.ts index a36e963d..08206a37 100644 --- a/test/unit/buildFirestoreCommand.spec.ts +++ b/test/unit/buildFirestoreCommand.spec.ts @@ -1,68 +1,112 @@ -import buildFirestoreCommand from '../../src/buildFirestoreCommand'; import { expect } from 'chai'; import sinon from 'sinon'; +import buildFirestoreCommand from '../../src/buildFirestoreCommand'; -const addSpy = sinon.spy() -const envSpy = sinon.spy() -const Cypress = { Commands: { add: addSpy }, env: envSpy } +const addSpy = sinon.spy(); +const envSpy = sinon.spy(); +const Cypress = { Commands: { add: addSpy }, env: envSpy }; -const firebaseExtraPath = 'npx firebase-extra' -const firebaseToolsPath = 'npx firebase' +const firebaseExtraPath = 'npx firebase-extra'; +const firebaseToolsPath = 'npx firebase'; describe('buildFirestoreCommand', () => { describe('get', () => { it('calls get with a path', () => { - const actionPath = 'some/path' - expect(buildFirestoreCommand(Cypress, 'get', actionPath)) - .to.equal(`${firebaseExtraPath} firestore get ${actionPath}`) - }) + const actionPath = 'some/path'; + expect(buildFirestoreCommand(Cypress, 'get', actionPath)).to.equal( + `${firebaseExtraPath} firestore get ${actionPath}`, + ); + }); }); describe('set', () => { it('creates a set command with path and object data', () => { - const actionPath = 'some/path' - const data = { some: 'other' } - expect(buildFirestoreCommand(Cypress, 'set', actionPath, data)) - .to.equal(`${firebaseExtraPath} firestore set ${actionPath} '${JSON.stringify(data)}'`) - }) + const actionPath = 'some/path'; + const data = { some: 'other' }; + expect(buildFirestoreCommand(Cypress, 'set', actionPath, data)).to.equal( + `${firebaseExtraPath} firestore set ${actionPath} '${JSON.stringify( + data, + )}'`, + ); + }); it('creates a set command with path, object data, and withMeta flag', () => { - const actionPath = 'some/path' - const data = { some: 'other' } - expect(buildFirestoreCommand(Cypress, 'set', actionPath, data, { withMeta: true })) - .to.equal(`${firebaseExtraPath} firestore set ${actionPath} '${JSON.stringify(data)}' -m`) - }) + const actionPath = 'some/path'; + const data = { some: 'other' }; + expect( + buildFirestoreCommand(Cypress, 'set', actionPath, data, { + withMeta: true, + }), + ).to.equal( + `${firebaseExtraPath} firestore set ${actionPath} '${JSON.stringify( + data, + )}' -m`, + ); + }); it('creates a set command with path, fixture path, and withMeta flag', () => { - const actionPath = 'some/path' - const action = 'set' - const fixturePath = 'some/fixture' - expect(buildFirestoreCommand(Cypress, action, actionPath, fixturePath, { withMeta: true })) - .to.equal(`${firebaseExtraPath} firestore ${action} ${actionPath} ${fixturePath} -m`) - }) + const actionPath = 'some/path'; + const action = 'set'; + const fixturePath = 'some/fixture'; + expect( + buildFirestoreCommand(Cypress, action, actionPath, fixturePath, { + withMeta: true, + }), + ).to.equal( + `${firebaseExtraPath} firestore ${action} ${actionPath} ${fixturePath} -m`, + ); + }); }); describe('update', () => { it('calls update with a path', () => { - const actionPath = 'some/path' - const action = 'update' - const data = { some: 'other' } - expect(buildFirestoreCommand(Cypress, action, actionPath, data)) - .to.equal(`${firebaseExtraPath} firestore ${action} ${actionPath} '${JSON.stringify(data)}'`) - }) + const actionPath = 'some/path'; + const action = 'update'; + const data = { some: 'other' }; + expect(buildFirestoreCommand(Cypress, action, actionPath, data)).to.equal( + `${firebaseExtraPath} firestore ${action} ${actionPath} '${JSON.stringify( + data, + )}'`, + ); + }); }); describe('delete', () => { it('calls delete with a path and --shallow by default', () => { - const actionPath = 'some/path' - expect(buildFirestoreCommand(Cypress, 'delete', actionPath)) - .to.equal(`${firebaseToolsPath} firestore:delete ${actionPath} -y --shallow`) - }) + const actionPath = 'some/path'; + expect(buildFirestoreCommand(Cypress, 'delete', actionPath)).to.equal( + `${firebaseToolsPath} firestore:delete ${actionPath} -y --shallow`, + ); + }); it('supports recursive delete (by passing -r flag)', () => { - const actionPath = 'some/path' - expect(buildFirestoreCommand(Cypress, 'delete', actionPath, { recursive: true })) - .to.equal(`${firebaseToolsPath} firestore:delete ${actionPath} -y -r`) - }) + const actionPath = 'some/path'; + expect( + buildFirestoreCommand(Cypress, 'delete', actionPath, { + recursive: true, + }), + ).to.equal(`${firebaseToolsPath} firestore:delete ${actionPath} -y -r`); + }); + + it('creates command which calls firebase-extra if emulator is enabled', () => { + const actionPath = 'some/path'; + expect( + buildFirestoreCommand( + { + ...Cypress, + env: (envVarName?: string) => { + if (envVarName === 'FIRESTORE_EMULATOR_HOST') { + return true; + } + }, + }, + 'delete', + actionPath, + { + recursive: true, + }, + ), + ).to.equal(`npx firebase-extra firestore:delete ${actionPath} -y -r`); + }); }); -}); \ No newline at end of file +}); diff --git a/test/unit/buildRtdbCommand.spec.ts b/test/unit/buildRtdbCommand.spec.ts index 945af8b0..c47b35eb 100644 --- a/test/unit/buildRtdbCommand.spec.ts +++ b/test/unit/buildRtdbCommand.spec.ts @@ -1,136 +1,273 @@ -import buildRtdbCommand from '../../src/buildRtdbCommand'; import { expect } from 'chai'; import sinon from 'sinon'; +import buildRtdbCommand from '../../src/buildRtdbCommand'; -const addSpy = sinon.spy() -const envSpy = sinon.spy() -const Cypress = { Commands: { add: addSpy }, env: envSpy } +const addSpy = sinon.spy(); +const envSpy = sinon.spy(); +const Cypress = { Commands: { add: addSpy }, env: envSpy }; -const firebasePath = 'npx firebase' +const firebasePath = 'npx firebase'; describe('buildRtdbCommand', () => { describe('get', () => { it('calls get with a path', () => { - const actionPath = 'some/path' - const action = 'get' - expect(buildRtdbCommand(Cypress, action, actionPath)) - .to.equal(`${firebasePath} database:${action} /${actionPath}`) - }) - + const actionPath = 'some/path'; + const action = 'get'; + expect(buildRtdbCommand(Cypress, action, actionPath)).to.equal( + `${firebasePath} database:${action} /${actionPath}`, + ); + }); + it('supports orderByChild (--order-by flag for firebase-tools)', () => { - const actionPath = 'some/path' - const action = 'get' - const orderByChild = 'asdf' - expect(buildRtdbCommand(Cypress, action, actionPath, { orderByChild })) - .to.equal(`${firebasePath} database:${action} /${actionPath} --order-by ${orderByChild}`) - }) + const actionPath = 'some/path'; + const action = 'get'; + const orderByChild = 'asdf'; + expect( + buildRtdbCommand(Cypress, action, actionPath, { orderByChild }), + ).to.equal( + `${firebasePath} database:${action} /${actionPath} --order-by ${orderByChild}`, + ); + }); it('supports orderByKey (--order-by-key flag for firebase-tools)', () => { - const actionPath = 'some/path' - const action = 'get' - expect(buildRtdbCommand(Cypress, action, actionPath, { orderByKey: true })) - .to.equal(`${firebasePath} database:${action} /${actionPath} --order-by-key`) - }) + const actionPath = 'some/path'; + const action = 'get'; + expect( + buildRtdbCommand(Cypress, action, actionPath, { orderByKey: true }), + ).to.equal( + `${firebasePath} database:${action} /${actionPath} --order-by-key`, + ); + }); it('supports orderByValue (--order-by-value flag for firebase-tools)', () => { - const actionPath = 'some/path' - const action = 'get' - expect(buildRtdbCommand(Cypress, action, actionPath, { orderByValue: true })) - .to.equal(`${firebasePath} database:${action} /${actionPath} --order-by-value`) - }) + const actionPath = 'some/path'; + const action = 'get'; + expect( + buildRtdbCommand(Cypress, action, actionPath, { orderByValue: true }), + ).to.equal( + `${firebasePath} database:${action} /${actionPath} --order-by-value`, + ); + }); it('supports startAt (--start-at flag for firebase-tools)', () => { - const actionPath = 'some/path' - const action = 'get' - const startAt = 'asdf' - expect(buildRtdbCommand(Cypress, action, actionPath, { startAt })) - .to.equal(`${firebasePath} database:${action} /${actionPath} --start-at ${startAt}`) - }) + const actionPath = 'some/path'; + const action = 'get'; + const startAt = 'asdf'; + expect( + buildRtdbCommand(Cypress, action, actionPath, { startAt }), + ).to.equal( + `${firebasePath} database:${action} /${actionPath} --start-at ${startAt}`, + ); + }); it('supports endAt (--end-at flag for firebase-tools)', () => { - const actionPath = 'some/path' - const action = 'get' - const endAt = 'asdf' - expect(buildRtdbCommand(Cypress, action, actionPath, { endAt })) - .to.equal(`${firebasePath} database:${action} /${actionPath} --end-at ${endAt}`) - }) + const actionPath = 'some/path'; + const action = 'get'; + const endAt = 'asdf'; + expect(buildRtdbCommand(Cypress, action, actionPath, { endAt })).to.equal( + `${firebasePath} database:${action} /${actionPath} --end-at ${endAt}`, + ); + }); it('supports equalTo (--equal-to flag for firebase-tools)', () => { - const actionPath = 'some/path' - const action = 'get' - const equalTo = 'asdf' - expect(buildRtdbCommand(Cypress, action, actionPath, { equalTo })) - .to.equal(`${firebasePath} database:${action} /${actionPath} --equal-to ${equalTo}`) - }) + const actionPath = 'some/path'; + const action = 'get'; + const equalTo = 'asdf'; + expect( + buildRtdbCommand(Cypress, action, actionPath, { equalTo }), + ).to.equal( + `${firebasePath} database:${action} /${actionPath} --equal-to ${equalTo}`, + ); + }); it('supports instance (--instance flag for firebase-tools)', () => { - const actionPath = 'some/path' - const action = 'get' - const instance = 'asdf' - expect(buildRtdbCommand(Cypress, action, actionPath, { instance })) - .to.equal(`${firebasePath} database:${action} /${actionPath} --instance ${instance}`) - }) + const actionPath = 'some/path'; + const action = 'get'; + const instance = 'asdf'; + expect( + buildRtdbCommand(Cypress, action, actionPath, { instance }), + ).to.equal( + `${firebasePath} database:${action} /${actionPath} --instance ${instance}`, + ); + }); it('supports limitToLast (--limitToLast flag for firebase-tools)', () => { - const actionPath = 'some/path' - const action = 'get' - const limitToLast = 'asdf' - expect(buildRtdbCommand(Cypress, action, actionPath, { limitToLast })) - .to.equal(`${firebasePath} database:${action} /${actionPath} --order-by-key --limit-to-last ${limitToLast}`) - }) + const actionPath = 'some/path'; + const action = 'get'; + const limitToLast = 'asdf'; + expect( + buildRtdbCommand(Cypress, action, actionPath, { limitToLast }), + ).to.equal( + `${firebasePath} database:${action} /${actionPath} --order-by-key --limit-to-last ${limitToLast}`, + ); + }); describe('supports limitToFirst (--limitToFirst flag for firebase-tools)', () => { it('as a boolean (defaults to 1 with order by key)', () => { - const actionPath = 'some/path' - const action = 'get' - const limitToFirst = 1 - expect(buildRtdbCommand(Cypress, action, actionPath, { limitToFirst })) - .to.equal(`${firebasePath} database:${action} /${actionPath} --order-by-key --limit-to-first ${limitToFirst}`) - }) + const actionPath = 'some/path'; + const action = 'get'; + const limitToFirst = 1; + expect( + buildRtdbCommand(Cypress, action, actionPath, { limitToFirst }), + ).to.equal( + `${firebasePath} database:${action} /${actionPath} --order-by-key --limit-to-first ${limitToFirst}`, + ); + }); it('as a string', () => { - const actionPath = 'some/path' - const action = 'get' - const limitToFirst = 'asdf' - expect(buildRtdbCommand(Cypress, action, actionPath, { limitToFirst })) - .to.equal(`${firebasePath} database:${action} /${actionPath} --order-by-key --limit-to-first ${limitToFirst}`) - }) - }) + const actionPath = 'some/path'; + const action = 'get'; + const limitToFirst = 'asdf'; + expect( + buildRtdbCommand(Cypress, action, actionPath, { limitToFirst }), + ).to.equal( + `${firebasePath} database:${action} /${actionPath} --order-by-key --limit-to-first ${limitToFirst}`, + ); + }); + }); + + it('creates command which includes firebase-extra if emulator is enabled', () => { + const actionPath = 'some/path'; + const action = 'get'; + const limitToLast = 'asdf'; + expect( + buildRtdbCommand( + { + ...Cypress, + env: (envVarName?: string) => { + if (envVarName === 'FIREBASE_DATABASE_EMULATOR_HOST') { + return true; + } + }, + }, + action, + actionPath, + { limitToLast }, + ), + ).to.equal( + `npx firebase-extra database:${action} /${actionPath} --order-by-key --limit-to-last ${limitToLast}`, + ); + }); }); describe('set', () => { it('creates a set command with path and object data', () => { - const actionPath = 'some/path' - const action = 'set' - const data = { some: 'other' } - expect(buildRtdbCommand(Cypress, action, actionPath, data)) - .to.equal(`${firebasePath} database:${action} /${actionPath} -d '${JSON.stringify(data)}' -y`) - }) + const actionPath = 'some/path'; + const action = 'set'; + const data = { some: 'other' }; + expect(buildRtdbCommand(Cypress, action, actionPath, data)).to.equal( + `${firebasePath} database:${action} /${actionPath} -d '${JSON.stringify( + data, + )}' -y`, + ); + }); it('creates a set command with path and non-string value', () => { - const actionPath = 'some/path' - const action = 'set' - const data = 123 - expect(buildRtdbCommand(Cypress, action, actionPath, data)) - .to.equal(`${firebasePath} database:${action} /${actionPath} ${data} -y`) - }) + const actionPath = 'some/path'; + const action = 'set'; + const data = 123; + expect(buildRtdbCommand(Cypress, action, actionPath, data)).to.equal( + `${firebasePath} database:${action} /${actionPath} ${data} -y`, + ); + }); it('creates a set command with path and string value', () => { - const actionPath = 'some/path' - const action = 'set' - const data = '123ABC' - expect(buildRtdbCommand(Cypress, action, actionPath, data)) - .to.equal(`${firebasePath} database:${action} /${actionPath} ${data} -y`) - }) + const actionPath = 'some/path'; + const action = 'set'; + const data = '123ABC'; + expect(buildRtdbCommand(Cypress, action, actionPath, data)).to.equal( + `${firebasePath} database:${action} /${actionPath} ${data} -y`, + ); + }); + + it('creates command which includes firebase-extra if emulator is enabled', () => { + const actionPath = 'some/path'; + const action = 'set'; + const data = '123ABC'; + expect( + buildRtdbCommand( + { + ...Cypress, + env: (envVarName?: string) => { + if (envVarName === 'FIREBASE_DATABASE_EMULATOR_HOST') { + return true; + } + }, + }, + action, + actionPath, + data, + ), + ).to.equal( + `npx firebase-extra database:${action} /${actionPath} ${data} -y`, + ); + }); }); describe('update', () => { it('calls update with a path', () => { - const actionPath = 'some/path' - const action = 'update' - const data = { some: 'other' } - expect(buildRtdbCommand(Cypress, action, actionPath, data)) - .to.equal(`${firebasePath} database:${action} /${actionPath} -d '${JSON.stringify(data)}' -y`) - }) + const actionPath = 'some/path'; + const action = 'update'; + const data = { some: 'other' }; + expect(buildRtdbCommand(Cypress, action, actionPath, data)).to.equal( + `${firebasePath} database:${action} /${actionPath} -d '${JSON.stringify( + data, + )}' -y`, + ); + }); + + it('creates command which includes firebase-extra if emulator is enabled', () => { + const actionPath = 'some/path'; + const action = 'update'; + const data = { some: 'other' }; + expect( + buildRtdbCommand( + { + ...Cypress, + env: (envVarName?: string) => { + if (envVarName === 'FIREBASE_DATABASE_EMULATOR_HOST') { + return true; + } + }, + }, + action, + actionPath, + data, + ), + ).to.equal( + `npx firebase-extra database:${action} /${actionPath} -d '${JSON.stringify( + data, + )}' -y`, + ); + }); + }); + + describe('remove', () => { + it('calls remove with a path', () => { + const actionPath = 'some/path'; + const action = 'remove'; + expect(buildRtdbCommand(Cypress, action, actionPath)).to.equal( + `${firebasePath} database:${action} /${actionPath} -y`, + ); + }); + + it('creates command which includes firebase-extra if emulator is enabled', () => { + const actionPath = 'some/path'; + const action = 'remove'; + expect( + buildRtdbCommand( + { + ...Cypress, + env: (envVarName?: string) => { + if (envVarName === 'FIREBASE_DATABASE_EMULATOR_HOST') { + return true; + } + }, + }, + action, + actionPath, + ), + ).to.equal(`npx firebase-extra database:${action} /${actionPath} -y`); + }); }); -}); \ No newline at end of file +}); diff --git a/yarn.lock b/yarn.lock index 11d89c6c..ecd7d1a5 100644 --- a/yarn.lock +++ b/yarn.lock @@ -2489,10 +2489,10 @@ firebase-admin@^8.9.2: "@google-cloud/firestore" "^3.0.0" "@google-cloud/storage" "^4.1.2" -firebase-tools-extra@0.4.0: - version "0.4.0" - resolved "https://registry.yarnpkg.com/firebase-tools-extra/-/firebase-tools-extra-0.4.0.tgz#cab88857cead4f2b09122691c5e1c62eedc26d36" - integrity sha512-c5l5LPHvuWqEU0+44IW9ZJjuqQeFKTCWbG2rhb0/Mxk+T5fnNrwqEjiRpYkPAVXgJuUGQR/Gn2cUMSQkZ3cmlg== +firebase-tools-extra@0.5.0: + version "0.5.0" + resolved "https://registry.yarnpkg.com/firebase-tools-extra/-/firebase-tools-extra-0.5.0.tgz#160cbb59d30eec14c2b2bfd5d83990b8cf3023f2" + integrity sha512-DxIIkYRmRiADP1HT+ZrstDZ0MwOWg5jHnDpntyHuPoPxTukgG5ZzRA+ZWIlNO8X0MqXkoCNhBdr5Sle/9KGC4A== dependencies: firebase-admin "^8.9.2" lodash "^4.17.15"