diff --git a/.circleci/config.yml b/.circleci/config.yml index 0e871ae9ba..653f616ad9 100644 --- a/.circleci/config.yml +++ b/.circleci/config.yml @@ -2,11 +2,11 @@ version: 2.0 jobs: test: - parallelism: 4 + parallelism: 8 # executor type https://circleci.com/docs/2.0/executor-types/ docker: - - image: digdag/digdag-build:20180921T102000-413301ee05f9660e41af70cdcddf0c6e747f0cc1 + - image: digdag/digdag-build:20191203T225216-c5b7206657c98c728b183634079f0a919ee98f8c # environment Variables in a Job https://circleci.com/docs/2.0/env-vars/#setting-an-environment-variable-in-a-job environment: TERM: dumb @@ -54,7 +54,7 @@ jobs: docs_deployment: # executor type https://circleci.com/docs/2.0/executor-types/ docker: - - image: digdag/digdag-build:20180921T191208-befdec51e47abfa34143ee63a8c8929cbfc7c759 + - image: digdag/digdag-build:20191203T225216-c5b7206657c98c728b183634079f0a919ee98f8c # environment Variables in a Job https://circleci.com/docs/2.0/env-vars/#setting-an-environment-variable-in-a-job environment: TERM: dumb diff --git a/.gitignore b/.gitignore index 1d9b10ccce..b4f3f14c3e 100644 --- a/.gitignore +++ b/.gitignore @@ -6,11 +6,16 @@ */build/ */out/ *.pyc +venv* +.venv* /dist/*.tar.gz /config/test_postgresql.properties +/config/dummy.properties MANIFEST pom.xml .digdag +docker/bootstrap/constraints.txt +docker/bootstrap/requirements.txt # intellij idea *.iml @@ -20,4 +25,4 @@ pom.xml # generated self-signed cert littleproxy_cert -littleproxy_keystore.jks \ No newline at end of file +littleproxy_keystore.jks diff --git a/.travis.yml b/.travis.yml index b3e7837a66..ea0bf0ed45 100644 --- a/.travis.yml +++ b/.travis.yml @@ -2,6 +2,8 @@ sudo: required language: java +dist: trusty + jdk: - oraclejdk8 @@ -16,8 +18,8 @@ cache: env: global: - TERM=dumb - - CI_NODE_TOTAL=8 - - BUILD_IMAGE=digdag/digdag-build:20180921T191208-befdec51e47abfa34143ee63a8c8929cbfc7c759 + - CI_NODE_TOTAL=12 + - BUILD_IMAGE=digdag/digdag-build:20191203T225216-c5b7206657c98c728b183634079f0a919ee98f8c matrix: - CI_NODE_INDEX=0 - CI_NODE_INDEX=1 @@ -27,6 +29,10 @@ env: - CI_NODE_INDEX=5 - CI_NODE_INDEX=6 - CI_NODE_INDEX=7 + - CI_NODE_INDEX=8 + - CI_NODE_INDEX=9 + - CI_NODE_INDEX=10 + - CI_NODE_INDEX=11 before_install: - sudo service --status-all diff --git a/README.md b/README.md index 03a201c279..40beea84a8 100644 --- a/README.md +++ b/README.md @@ -8,12 +8,14 @@ Please check [digdag.io](https://digdag.io) and [docs.digdag.io](https://docs.digdag.io) for installation & user manual. +REST API document is available at [docs.digdag.io/api](http://docs.digdag.io/api/). + ## Development ### Prerequirements * JDK 8 -* Node.js 8.x +* Node.js 12.x Installing Node.js using nodebrew: @@ -21,8 +23,8 @@ Installing Node.js using nodebrew: $ curl -L git.io/nodebrew | perl - setup $ echo 'export PATH=$HOME/.nodebrew/current/bin:$PATH' >> ~/.bashrc $ source ~/.bashrc -$ nodebrew install-binary v8.x -$ nodebrew use v8.x +$ nodebrew install-binary v12.x +$ nodebrew use v12.x ``` Installing Node.js using Homebrew on Mac OS X: @@ -36,18 +38,6 @@ $ brew install node * sphinx_rtd_theme * recommonmark -### Check Digdag REST API - -Use `--enable-swagger` option to check the current Digdag REST API. - -``` -$ ./gradlew cli -$ ./pkg/digdag-.jar server --memory --enable-swagger # Run server with --enable-swagger option - -$ docker run -dp 8080:8080 swaggerapi/swagger-ui # Run Swagger-UI on different console -$ open http://localhost:8080/?url=http://localhost:65432/api/swagger.json # Open api/swagger.json on Swagger-UI -``` - ### Running tests ``` @@ -86,15 +76,32 @@ It makes an executable in `pkg/`, e.g. `pkg/digdag-$VERSION.jar`. ### Releasing a new version You need to set Bintray user name and API key in `BINTRAY_USER` and `BINTRAY_KEY` environment variables. - -1. run `git pull origin --tags`. -2. run `./gradlew setVersion -Pto=` command. -3. write release notes to `releases/release-.rst` file. It must include at least version (the first line) and release date (the last line). -4. run `./gradlew clean cli site check releaseCheck`. -5. if it succeeded, run `./gradlew release`. +In the following instructions, assumed that `upstream` is set to `treasure-data/digdag` and `origin` is set to your private repository. + +1. run `git pull upstream master --tags`. +1. run `./gradlew setVersion -Pto=` command. +1. write release notes to `releases/release-.rst` file. It must include at least version (the first line) and release date (the last line). +1. run `./gradlew clean cli site check releaseCheck`. +1. make a release branch. `git checkout -b release_v` and commit. +1. push the release branch to origin and create a PR. +1. after the PR is merged to master, checkout master and pull latest upstream/master. +1. run `./gradlew clean cli site check releaseCheck` again. +1. if it succeeded, run `./gradlew release`. +1. a few minutes later, run `digdag selfupdate` and confirm the version. If major version is incremented, also update `version =` and `release =` at [digdag-docs/src/conf.py](digdag-docs/src/conf.py). +If you are expert, skip 5. to 7. and directly update master branch. + +### Post-process of new release + +You also need following steps after new version has been released. + +1. create a tag `git tag -a v` and push `git push upstream v` +1. create a release in [GitHub releases](https://github.com/treasure-data/digdag/releases). +1. create next snapshot version, run `./gradlew setVersion -Pto=-SNAPSHOT`. +1. push to master. + ### Releasing a SNAPSHOT version @@ -102,7 +109,6 @@ If major version is incremented, also update `version =` and `release =` at [dig ./gradlew releaseSnapshot ``` - ### Develop digdag-ui Node.js development server is useful because it reloads changes of digdag-ui source code automatically. @@ -125,6 +131,23 @@ $ npm install $ npm run dev # starts dev server on http://localhost:9000/ ``` +### Updating REST API document + +Run this command to update REST API document file at digdag-docs/src/api/swagger.yaml. + +``` +./gradlew swaggerYaml # dump swagger.yaml file +``` + +Use `--enable-swagger` option to check the current Digdag REST API. + +``` +$ ./gradlew cli +$ ./pkg/digdag-.jar server --memory --enable-swagger # Run server with --enable-swagger option + +$ docker run -dp 8080:8080 swaggerapi/swagger-ui # Run Swagger-UI on different console +$ open http://localhost:8080/?url=http://localhost:65432/api/swagger.json # Open api/swagger.json on Swagger-UI +``` ### Updating documents @@ -132,10 +155,20 @@ Documents are in digdag-docs/src directory. They're built using Sphinx. Website is hosted on [www.digdag.io](http://www.digdag.io) using Github Pages. Pages are built using deployment step of circle.yml and automatically pushed to [gh-pages branch of digdag-docs repository](https://github.com/treasure-data/digdag-docs/tree/gh-pages). -To build the pages and check them locally, run following command: +To build the pages and check them locally, follow this instruction. + +Create a virtual environment of Python and install dependent Python libraries including Sphinx. + +``` +$ python3 -m venv .venv +$ source .venv/bin/activate +(.venv)$ pip install -r digdag-docs/requirements.txt -c digdag-docs/constraints.txt +``` + +After installation of Python libraries, You can build with running the following command: ``` -$ ./gradlew site +(.venv)$ ./gradlew site ``` This might not always update all necessary files (Sphinx doesn't manage update dependencies well). In this case, run `./gradlew clean` first. @@ -153,7 +186,7 @@ The list of release note is [here](https://github.com/treasure-data/digdag/tree/ Digdag is using a Java annotation processor `org.immutables:value.` The combination of Java annotation processing and Gradle on IntelliJ IDEA sometimes introduces some troubles. In Digdag's case, you may run into some compile errors like `cannot find symbol: class ImmutableRestWorkflowDefinitionCollection.` So we'd recommend the followings to avoid those compile errors if you want to develop Digdag one the IDE. -1. There's an important configuration option to be enabled to fully have IntelliJ be fully integrated with an existing gradle build configuration: `Delegate IDE build/run actions to gradle` needs to be enabled. +1. There's an important configuration option to be enabled to fully have IntelliJ be fully integrated with an existing gradle build configuration: `Delegate IDE build/run actions to gradle` needs to be enabled. ![](https://user-images.githubusercontent.com/17990895/48221255-9706be80-e35f-11e8-8283-1ca6d713e31c.png) diff --git a/appveyor.yml b/appveyor.yml index 6a32b197d5..c5830d3226 100644 --- a/appveyor.yml +++ b/appveyor.yml @@ -18,7 +18,7 @@ environment: - JAVA_HOME: C:\Program Files (x86)\Java\jdk1.8.0 install: - - ps: Install-Product node '8' + - ps: Install-Product node '12' - node --version - npm --version diff --git a/build.gradle b/build.gradle index 639bd1d902..eb0f01c0e0 100644 --- a/build.gradle +++ b/build.gradle @@ -1,8 +1,8 @@ plugins { - id 'com.github.johnrengelman.shadow' version '4.0.4' - id 'com.jfrog.bintray' version '1.8.4' + id 'com.github.johnrengelman.shadow' version '2.0.3' + id 'com.jfrog.bintray' version '1.8.1' id 'com.github.kt3k.coveralls' version '2.6.3' - id 'com.github.spotbugs' version '1.6.9' + id 'com.github.spotbugs' version '1.6.2' id 'net.ltgt.apt-idea' version '0.19' } @@ -12,7 +12,7 @@ apply plugin: 'maven' allprojects { group = 'io.digdag' - version = '0.9.33' + version = '0.9.41-SNAPSHOT' ext { isSnapshotRelease = version.endsWith('-SNAPSHOT') @@ -110,9 +110,10 @@ subprojects { } ext { - jacksonVersion = "2.8.11" + jacksonVersion = "2.9.9" + jacksonDatabindVersion = "2.9.9" awsJavaSdkVersion = "1.11.63" - guavaVersion = "19.0" + guavaVersion = "27.1-jre" } tasks.withType(JavaCompile) { @@ -120,7 +121,7 @@ subprojects { } spotbugs { - toolVersion = '3.1.11' + toolVersion = '3.1.5' effort = 'max' reportLevel = 'high' ignoreFailures = true @@ -137,7 +138,7 @@ subprojects { jacocoTestReport { // exclude classes generated by Immutables afterEvaluate { - classDirectories.from = files(classDirectories.files.collect { + classDirectories = files(classDirectories.files.collect { fileTree(dir: it, exclude: ['**/Immutable*']) }) } @@ -286,19 +287,19 @@ subprojects { jacocoTestReport { dependsOn = subprojects.test - sourceDirectories.from = files(subprojects.sourceSets.main.allSource.srcDirs) - classDirectories.from = files(subprojects.sourceSets.main.output) - executionData.from = files(subprojects.jacocoTestReport.executionData) + sourceDirectories = files(subprojects.sourceSets.main.allSource.srcDirs) + classDirectories = files(subprojects.sourceSets.main.output) + executionData = files(subprojects.jacocoTestReport.executionData) reports { xml.enabled = true html.enabled = true } onlyIf = { true } doFirst { - executionData.from = files(executionData.findAll { it.exists() }) + executionData = files(executionData.findAll { it.exists() }) } afterEvaluate { - classDirectories.from = files(classDirectories.files.collect { + classDirectories = files(classDirectories.files.collect { fileTree(dir: it, exclude: ['**/Immutable*']) }) } @@ -311,7 +312,7 @@ coveralls { wrapper { // Find the latest version at https://gradle.org/releases/ - gradleVersion = '5.2' + gradleVersion = '4.8' } project(':digdag-ui') { @@ -321,7 +322,8 @@ project(':digdag-ui') { doFirst { exec { - commandLine System.env.NPM ?: "npm", "install" + // npm ci requires npm version 5.7 or more. + commandLine System.env.NPM ?: "npm", "ci" } exec { commandLine System.env.NPM ?: "npm", "run", "build" @@ -394,7 +396,7 @@ task cli(dependsOn: ':digdag-cli:shadowJar') { file('pkg').mkdirs() cliBuildFile.write("") cliBuildFile.append(file("digdag-cli/src/main/sh/selfrun.sh").readBytes()) - cliBuildFile.append(file("digdag-cli/build/libs/digdag-cli-${project.version}.jar").readBytes()) + cliBuildFile.append(file("digdag-cli/build/libs/digdag-cli-${project.version}-all.jar").readBytes()) cliBuildFile.setExecutable(true) } } @@ -406,6 +408,17 @@ task classpath(dependsOn: [':digdag-cli:classpath']){ } } +task swaggerYaml(dependsOn: ':digdag-cli:shadowJar') { + doLast { + file("config/dummy.properties").write("") + Process server = ["java", "-jar", "digdag-cli/build/libs/digdag-cli-${project.version}-all.jar", "server", "-c", "config/dummy.properties", "--memory", "--enable-swagger"].execute() + sleep(5 * 1000) + ["curl", "http://127.0.0.1:65432/api/swagger.yaml", "-o", "digdag-docs/src/_extra/api/swagger.yaml"].execute().waitFor() + server.destroy() + server.waitForOrKill(1000) + } +} + clean { delete 'classpath' delete 'pkg' diff --git a/ci/run_td_tests.sh b/ci/run_td_tests.sh index 3e07de38bd..cf05a6aa52 100755 --- a/ci/run_td_tests.sh +++ b/ci/run_td_tests.sh @@ -11,6 +11,16 @@ idleTimeout = 10 minimumPoolSize = 0 " +echo "---TARGET test ---" +target_src=`circleci tests glob "digdag-tests/src/test/java/acceptance/td/**/*IT.java" | circleci tests split --split-by=timings` +echo $target_src | xargs -n 1 echo +echo "------------------" + + export CI_ACCEPTANCE_TEST=true -./gradlew clean cleanTest test --info --no-daemon -p digdag-tests --tests 'acceptance.td.*' +./gradlew clean cleanTest test --info --no-daemon -p digdag-tests --tests 'acceptance.td.*' \ + -PtestFilter="$target_src" +# -PtestFilter='`circleci tests glob "digdag-tests/src/test/java/acceptance/td/**/*.java" | circleci tests split --split-by=timings`' + + diff --git a/ci/run_test_docker.sh b/ci/run_test_docker.sh index 02cdc8bbee..f965d86980 100755 --- a/ci/run_test_docker.sh +++ b/ci/run_test_docker.sh @@ -1,6 +1,7 @@ #!/bin/bash -xe docker run \ +-v /var/run/docker.sock:/var/run/docker.sock \ -w /digdag \ -v `pwd`/:/digdag \ -v ~/.gradle:/root/.gradle \ diff --git a/digdag-cli/build.gradle b/digdag-cli/build.gradle index fa34a75cc0..8771afd880 100644 --- a/digdag-cli/build.gradle +++ b/digdag-cli/build.gradle @@ -14,4 +14,5 @@ dependencies { // This line is for including digdag-storage-s3 in CLI (shadow jar) used through // dynamic class loading. digdag-cli itself doesn't depend on digdag-storage-s3. compile project(':digdag-storage-s3') + compile project(':digdag-storage-gcs') } diff --git a/digdag-cli/src/main/java/io/digdag/cli/BasicAuthParameterValidator.java b/digdag-cli/src/main/java/io/digdag/cli/BasicAuthParameterValidator.java new file mode 100644 index 0000000000..5550f87692 --- /dev/null +++ b/digdag-cli/src/main/java/io/digdag/cli/BasicAuthParameterValidator.java @@ -0,0 +1,19 @@ +package io.digdag.cli; + +import com.beust.jcommander.IParameterValidator; +import com.beust.jcommander.ParameterException; + +import java.util.regex.Pattern; + +public class BasicAuthParameterValidator + implements IParameterValidator +{ + private final static Pattern pattern = Pattern.compile(".+:.+"); + + public void validate(String name, String value) throws ParameterException + { + if (!pattern.matcher(value).matches()) { + throw new ParameterException("Expected format: username:password"); + } + } +} \ No newline at end of file diff --git a/digdag-cli/src/main/java/io/digdag/cli/Main.java b/digdag-cli/src/main/java/io/digdag/cli/Main.java index f2e0733c05..c1435884bb 100644 --- a/digdag-cli/src/main/java/io/digdag/cli/Main.java +++ b/digdag-cli/src/main/java/io/digdag/cli/Main.java @@ -30,6 +30,7 @@ import io.digdag.cli.client.ShowSession; import io.digdag.cli.client.ShowTask; import io.digdag.cli.client.ShowWorkflow; +import io.digdag.cli.client.ShowProjects; import io.digdag.cli.client.Start; import io.digdag.cli.client.Upload; import io.digdag.cli.client.Version; @@ -133,6 +134,7 @@ protected void configure() jc.addCommand("upload", injector.getInstance(Upload.class)); jc.addCommand("download", injector.getInstance(Download.class)); + jc.addCommand("project", injector.getInstance(ShowProjects.class), "projects"); jc.addCommand("workflow", injector.getInstance(ShowWorkflow.class), "workflows"); jc.addCommand("start", injector.getInstance(Start.class)); jc.addCommand("retry", injector.getInstance(Retry.class)); @@ -150,6 +152,8 @@ protected void configure() jc.addCommand("delete", injector.getInstance(Delete.class)); jc.addCommand("secrets", injector.getInstance(Secrets.class), "secret"); jc.addCommand("version", injector.getInstance(Version.class), "version"); + jc.addCommand("migrate", injector.getInstance(Migrate.class)); + jc.addCommand("selfupdate", injector.getInstance(SelfUpdate.class)); @@ -297,6 +301,7 @@ private SystemExitException usage(String error) err.println(" r[un] run a workflow"); err.println(" c[heck] show workflow definitions"); err.println(" sched[uler] run a scheduler server"); + err.println(" migrate (run|check) migrate database"); err.println(" selfupdate update cli to the latest version"); err.println(""); err.println(" Server-mode commands:"); @@ -308,9 +313,12 @@ private SystemExitException usage(String error) err.println(" start start a new session attempt of a workflow"); err.println(" retry retry a session"); err.println(" kill kill a running session attempt"); + err.println(" backfill start sessions of a schedule for past times"); err.println(" backfill start sessions of a schedule for past times"); - err.println(" reschedule skip sessions of a schedule to a future time"); + err.println(" reschedule skip sessions of a schedule to a future time"); + err.println(" reschedule skip sessions of a schedule to a future time"); err.println(" log show logs of a session attempt"); + err.println(" projects [name] show projects"); err.println(" workflows [project-name] [name] show registered workflow definitions"); err.println(" schedules show registered schedules"); err.println(" disable disable a workflow schedule"); @@ -333,6 +341,8 @@ private SystemExitException usage(String error) err.println(""); err.println(" Options:"); showCommonOptions(env, err); + err.println(" Client options:"); + showClientCommonOptions(err); if (error == null) { err.println("Use ` --help` to see detailed usage of a command."); return systemExit(null); @@ -348,6 +358,18 @@ public static void showCommonOptions(Map env, PrintStream err) err.println(" -l, --log-level LEVEL log level (error, warn, info, debug or trace)"); err.println(" -X KEY=VALUE add a performance system config"); err.println(" -c, --config PATH.properties Configuration file (default: " + defaultConfigPath(env) + ")"); + err.println(" --version show client version"); + err.println(""); + } + + public static void showClientCommonOptions(PrintStream err) + { + err.println(" -e, --endpoint URL Server endpoint (default: http://127.0.0.1:65432)"); + err.println(" -H, --header KEY=VALUE Additional headers"); + err.println(" --disable-version-check Disable server version check"); + err.println(" --disable-cert-validation Disable certificate verification"); + err.println(" --basic-auth Add an Authorization header with the provided username and password"); err.println(""); } + } diff --git a/digdag-cli/src/main/java/io/digdag/cli/Migrate.java b/digdag-cli/src/main/java/io/digdag/cli/Migrate.java new file mode 100644 index 0000000000..df66b9f36a --- /dev/null +++ b/digdag-cli/src/main/java/io/digdag/cli/Migrate.java @@ -0,0 +1,144 @@ +package io.digdag.cli; + +import com.beust.jcommander.Parameter; +import io.digdag.client.DigdagClient; +import io.digdag.client.config.Config; +import io.digdag.client.config.ConfigFactory; +import io.digdag.core.config.PropertyUtils; +import io.digdag.core.database.DataSourceProvider; +import io.digdag.core.database.DatabaseConfig; +import io.digdag.core.database.DatabaseMigrator; +import io.digdag.core.database.migrate.Migration; +import org.skife.jdbi.v2.DBI; + +import java.nio.file.Paths; +import java.util.List; +import java.util.Properties; + +import static io.digdag.cli.SystemExitException.systemExit; + + +public class Migrate + extends Command +{ + @Parameter(names = {"-o", "--database"}) + String database = null; + + SubCommand subCommand = null; + + @Override + public void main() + throws Exception + { + checkArgs(); + DatabaseConfig dbConfig = DatabaseConfig.convertFrom(buildConfig()); + try (DataSourceProvider dsp = new DataSourceProvider(dbConfig)) { + DBI dbi = new DBI(dsp.get()); + DatabaseMigrator migrator = new DatabaseMigrator(dbi, dbConfig); + switch (subCommand) { + case RUN: + runMigrate(migrator); + break; + case CHECK: + checkMigrate(migrator); + break; + default: + throw new RuntimeException("No command"); + } + } + } + + // migrate run + private void runMigrate(DatabaseMigrator migrator) + throws Exception + { + int numApplied = migrator.migrate(); + if (numApplied == 0) { + out.println("No update"); + } + else { + out.println("Migrations successfully finished"); + } + } + + // migrate check + private void checkMigrate(DatabaseMigrator migrator) + throws Exception + { + if (!migrator.existsSchemaMigrationsTable()) { + out.println("No table exist"); + return; + } + + List migrations = migrator.getApplicableMigration(); + for (Migration m : migrations) { + out.println(m.getVersion()); + } + if (migrations.size() == 0) { + out.println("No update"); + } + } + + // check and validate arguments + private void checkArgs() + throws Exception + { + switch (args.size()) { + case 1: + switch (args.get(0)) { + case "run": + subCommand = SubCommand.RUN; + break; + case "check": + subCommand = SubCommand.CHECK; + break; + default: + throw usage("Invalid command"); + } + break; + default: + throw usage("Invalid parameters"); + } + + if (database == null && configPath == null) { + throw usage("--database, or --config option is required"); + } + } + + // build Config from arguments and properties + private Config buildConfig() + throws Exception + { + Properties props = loadSystemProperties(); + if (database != null) { + props.setProperty("database.type", "h2"); + props.setProperty("database.path", Paths.get(database).toAbsolutePath().toString()); + } + ConfigFactory cf = new ConfigFactory(DigdagClient.objectMapper()); + Config config = PropertyUtils.toConfigElement(props).toConfig(cf); + return config; + } + + @Override + public SystemExitException usage(String error) + { + err.println("Usage: " + programName + " migrate (run|check) run or check database migration"); + err.println(" Options:"); + err.println(" -c, --config PATH.properties configuration file (default: ~/.config/digdag/config)"); + err.println(" -o, --database DIR path to H2 database"); + return systemExit(error); + } + + private enum SubCommand + { + RUN("run"), + CHECK("check") + ; + private final String name; + + SubCommand(String name) + { + this.name = name; + } + } +} diff --git a/digdag-cli/src/main/java/io/digdag/cli/Sched.java b/digdag-cli/src/main/java/io/digdag/cli/Sched.java index 9acd6c6987..3a4391e1df 100644 --- a/digdag-cli/src/main/java/io/digdag/cli/Sched.java +++ b/digdag-cli/src/main/java/io/digdag/cli/Sched.java @@ -68,7 +68,6 @@ public SystemExitException usage(String error) err.println(" --max-task-threads N limit maximum number of task execution threads"); err.println(" -p, --param KEY=VALUE overwrites a parameter (use multiple times to set many parameters)"); err.println(" -P, --params-file PATH.yml reads parameters from a YAML file"); - err.println(" -c, --config PATH.properties server configuration property path"); Main.showCommonOptions(env, err); return systemExit(error); } diff --git a/digdag-cli/src/main/java/io/digdag/cli/SelfUpdate.java b/digdag-cli/src/main/java/io/digdag/cli/SelfUpdate.java index e4849c55d4..5d1af563ec 100644 --- a/digdag-cli/src/main/java/io/digdag/cli/SelfUpdate.java +++ b/digdag-cli/src/main/java/io/digdag/cli/SelfUpdate.java @@ -90,7 +90,7 @@ public SystemExitException usage(String error) err.println(""); err.println(" Examples:"); err.println(" $ " + programName + " selfupdate"); - err.println(" $ " + programName + " selfupdate 0.9.33"); + err.println(" $ " + programName + " selfupdate 0.9.41-SNAPSHOT"); err.println(""); return systemExit(error); } diff --git a/digdag-cli/src/main/java/io/digdag/cli/Server.java b/digdag-cli/src/main/java/io/digdag/cli/Server.java index 6a8aeb288a..560247e4e8 100644 --- a/digdag-cli/src/main/java/io/digdag/cli/Server.java +++ b/digdag-cli/src/main/java/io/digdag/cli/Server.java @@ -63,6 +63,9 @@ public class Server @Parameter(names = {"--disable-executor-loop"}) boolean disableExecutorLoop = false; + @Parameter(names = {"--disable-scheduler"}) + boolean disableScheduler = false; + @Parameter(names = {"--enable-swagger"}) boolean enableSwagger = false; @@ -112,12 +115,13 @@ public SystemExitException usage(String error) err.println(" -A, --access-log DIR store access logs files to this path"); err.println(" --max-task-threads N limit maximum number of task execution threads"); err.println(" --disable-executor-loop disable workflow executor loop"); + err.println(" --disable-scheduler disable scheduler"); err.println(" --disable-local-agent disable local task execution"); - err.println(" --enable-swagger enable swagger api"); + err.println(" --enable-swagger enable swagger api. Do not use in production because CORS"); + err.println(" is also enabled on from any domains with all HTTP methods"); err.println(" -p, --param KEY=VALUE overwrites a parameter (use multiple times to set many parameters)"); err.println(" -H, --header KEY=VALUE a header to include in api HTTP responses"); err.println(" -P, --params-file PATH.yml reads parameters from a YAML file"); - err.println(" -c, --config PATH.properties server configuration property path"); Main.showCommonOptions(env, err); return systemExit(error); } @@ -129,7 +133,7 @@ private void startServer() Properties props = buildServerProperties(); ConfigElement ce = PropertyUtils.toConfigElement(props); ServerConfig serverConfig = ServerConfig.convertFrom(ce); - ServerBootstrap.start(new ServerBootstrap(version, serverConfig)); + ServerBootstrap.start(new ServerBootstrap(version, serverConfig, loadSystemPlugins(props))); } protected Properties buildServerProperties() @@ -184,6 +188,10 @@ else if (memoryDatabase) { props.setProperty("server.executor.enabled", Boolean.toString(false)); } + if (disableScheduler) { + props.setProperty("schedule.enabled", Boolean.toString(false)); + } + if (enableSwagger) { props.setProperty("server.enable-swagger", Boolean.toString(true)); } diff --git a/digdag-cli/src/main/java/io/digdag/cli/client/Archive.java b/digdag-cli/src/main/java/io/digdag/cli/client/Archive.java index 2c4449b096..7ff5d3a2a9 100644 --- a/digdag-cli/src/main/java/io/digdag/cli/client/Archive.java +++ b/digdag-cli/src/main/java/io/digdag/cli/client/Archive.java @@ -11,6 +11,7 @@ import io.digdag.cli.SystemExitException; import io.digdag.cli.YamlMapper; import io.digdag.client.config.Config; +import io.digdag.client.config.ConfigElement; import io.digdag.client.config.ConfigFactory; import io.digdag.core.DigdagEmbed; import io.digdag.core.config.ConfigLoaderManager; @@ -58,10 +59,14 @@ public SystemExitException usage(String error) private void archive() throws Exception { + ConfigElement systemConfig = ConfigElement.fromJson("{ \"database.migrate\" : false } }"); + try (DigdagEmbed digdag = new DigdagEmbed.Bootstrap() + .setSystemConfig(systemConfig) .withWorkflowExecutor(false) .withScheduleExecutor(false) .withLocalAgent(false) + .withTaskQueueServer(false) .addModules(binder -> { binder.bind(YamlMapper.class).in(Scopes.SINGLETON); binder.bind(Archiver.class).in(Scopes.SINGLETON); diff --git a/digdag-cli/src/main/java/io/digdag/cli/client/Backfill.java b/digdag-cli/src/main/java/io/digdag/cli/client/Backfill.java index 7cfcb8a384..f2a8d99ccb 100644 --- a/digdag-cli/src/main/java/io/digdag/cli/client/Backfill.java +++ b/digdag-cli/src/main/java/io/digdag/cli/client/Backfill.java @@ -7,6 +7,7 @@ import io.digdag.cli.TimeUtil; import io.digdag.client.DigdagClient; import io.digdag.client.api.LocalTimeOrInstant; +import io.digdag.client.api.Id; import io.digdag.client.api.RestProject; import io.digdag.client.api.RestSchedule; import io.digdag.client.api.RestSessionAttempt; @@ -40,20 +41,38 @@ public class Backfill public void mainWithClientException() throws Exception { - if (args.size() != 2) { - throw usage(null); - } - if (fromTimeString == null) { throw new ParameterException("--from option is required"); } - backfill(args.get(0), args.get(1)); + if (args.size() == 1) { + // Schedule id? + Id scheduleId = parseScheduleId(args.get(0)); + backfillScheduleId(scheduleId); + } + else if (args.size() == 2) { + // Single workflow + backfillWorkflow(args.get(0), args.get(1)); + } + else { + throw usage(null); + } + } + + private Id parseScheduleId(String s) + throws SystemExitException + { + try { + return Id.of(Integer.toString(Integer.parseUnsignedInt(s))); + } + catch (NumberFormatException ignore) { + throw usage(null); + } } public SystemExitException usage(String error) { - err.println("Usage: " + programName + " backfill "); + err.println("Usage: " + programName + " backfill | "); err.println(" Options:"); err.println(" -f, --from 'yyyy-MM-dd[ HH:mm:ss]' timestamp to start backfill from (required)"); err.println(" --name NAME retry attempt name"); @@ -63,23 +82,29 @@ public SystemExitException usage(String error) return systemExit(error); } - private void backfill(String projName, String workflowName) + private void backfillScheduleId(Id scheduleId) throws Exception { - LocalTimeOrInstant fromTime = LocalTimeOrInstant.of( - TimeUtil.parseLocalTime(fromTimeString, - "--from must be hourly, daily, now, \"yyyy-MM-dd\", or \"yyyy-MM-dd HH:mm:SS\" format")); - DigdagClient client = buildClient(); + RestSchedule sched = client.getSchedule(scheduleId); + backfill(sched, client); + } - RestSchedule sched = findScheduleByWorkflowName(client, projName, workflowName); + private void backfillWorkflow(String projectName, String workflowName) + throws Exception + { + DigdagClient client = buildClient(); + RestProject project = client.getProject(projectName); + RestSchedule sched = client.getSchedule(project.getId(), workflowName); + backfill(sched, client); + } - if (sched == null) { - // confirm that project and workflow exist, otherwise throws an exception - RestProject proj = client.getProject(projName); - RestWorkflowDefinition def = client.getWorkflowDefinition(proj.getId(), workflowName); - throw systemExit("Schedule is not set to the workflow"); - } + private void backfill(RestSchedule sched, DigdagClient client) + throws Exception + { + LocalTimeOrInstant fromTime = LocalTimeOrInstant.of( + TimeUtil.parseLocalTime(fromTimeString, + "--from must be \"yyyy-MM-dd\", or \"yyyy-MM-dd HH:mm:SS\" format")); RestWorkflowSessionTime truncatedTime = client.getWorkflowTruncatedSessionTime(sched.getWorkflow().getId(), fromTime); @@ -116,16 +141,4 @@ private void backfill(String projName, String workflowName) err.println("Use `" + programName + " sessions` to show the session attempts."); } } - - private static RestSchedule findScheduleByWorkflowName(DigdagClient client, - String projName, String workflowName) - { - for (RestSchedule sched : client.getSchedules(Optional.absent()).getSchedules()) { // TODO use pagination (last_id) to get all schedules - if (projName.equals(sched.getProject().getName()) && - workflowName.equals(sched.getWorkflow().getName())) { - return sched; - } - } - return null; - } } diff --git a/digdag-cli/src/main/java/io/digdag/cli/client/ClientCommand.java b/digdag-cli/src/main/java/io/digdag/cli/client/ClientCommand.java index 6dcae67f60..814baddcc5 100644 --- a/digdag-cli/src/main/java/io/digdag/cli/client/ClientCommand.java +++ b/digdag-cli/src/main/java/io/digdag/cli/client/ClientCommand.java @@ -1,24 +1,18 @@ package io.digdag.cli.client; -import com.beust.jcommander.DynamicParameter; import com.beust.jcommander.Parameter; import com.google.common.annotations.VisibleForTesting; import com.google.common.base.Optional; import com.google.inject.Inject; import com.google.inject.Injector; import com.treasuredata.client.ProxyConfig; -import io.digdag.cli.Command; -import io.digdag.cli.Main; -import io.digdag.cli.ParameterValidator; -import io.digdag.cli.SystemExitException; -import io.digdag.cli.YamlMapper; +import io.digdag.cli.*; import io.digdag.client.DigdagClient; import io.digdag.client.api.Id; import io.digdag.client.api.RestVersionCheckResult; import io.digdag.core.plugin.PluginSet; import io.digdag.spi.DigdagClientConfigurator; import io.digdag.standards.Proxies; -import io.digdag.standards.td.TdDigdagClientConfigurationPlugin; import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -26,13 +20,10 @@ import javax.ws.rs.core.Response; import java.io.IOException; -import java.util.ArrayList; -import java.util.HashMap; -import java.util.List; -import java.util.Map; -import java.util.Properties; +import java.util.*; import static io.digdag.cli.SystemExitException.systemExit; +import static javax.ws.rs.core.HttpHeaders.AUTHORIZATION; public abstract class ClientCommand extends Command @@ -40,6 +31,7 @@ public abstract class ClientCommand private static final Logger logger = LoggerFactory.getLogger(ClientCommand.class); private static final String DEFAULT_ENDPOINT = "http://127.0.0.1:65432"; + private static final String DEFAULT_DISABLE_DIRECT_DOWNLOAD = "false"; @Inject Injector injector; @@ -50,6 +42,9 @@ public abstract class ClientCommand List httpHeadersList = new ArrayList<>(); Map httpHeaders = new HashMap<>(); + @Parameter(names = {"--basic-auth"}, validateWith = BasicAuthParameterValidator.class) + protected String basicAuthUserPass; + @Parameter(names = {"--disable-version-check"}) protected boolean disableVersionCheck; @@ -109,6 +104,14 @@ protected DigdagClient buildClient(boolean checkServerVersion) } httpHeaders = ParameterValidator.toMap(httpHeadersList); + + if (basicAuthUserPass != null) { + httpHeaders.put( + AUTHORIZATION, + "Basic " + Base64.getEncoder().encodeToString(basicAuthUserPass.getBytes()) + ); + } + DigdagClient client = buildClient(endpoint, env, props, disableCertValidation, httpHeaders, clientConfigurators); if (checkServerVersion && !disableVersionCheck) { @@ -168,10 +171,12 @@ private boolean isBatchModeForVersionCheck() } @VisibleForTesting - static DigdagClient buildClient(String endpoint, Map env, Properties props, boolean disableCertValidation, Map httpHeaders, Iterable clientConfigurators) + static DigdagClient buildClient(String endpoint, Map env, Properties props, boolean disableCertValidation, + Map httpHeaders, Iterable clientConfigurators) throws SystemExitException { String[] fragments = endpoint.split(":", 2); + boolean disableDirectDownload = Boolean.parseBoolean(props.getProperty("client.http.disable_direct_download", DEFAULT_DISABLE_DIRECT_DOWNLOAD)); boolean useSsl = false; if (fragments.length == 2 && fragments[1].startsWith("//")) { @@ -217,6 +222,7 @@ static DigdagClient buildClient(String endpoint, Map env, Proper .port(port) .ssl(useSsl) .disableCertValidation(disableCertValidation) + .disableDirectDownload(disableDirectDownload) .headers(headers); Optional proxyConfig = Proxies.proxyConfigFromEnv(scheme, env); diff --git a/digdag-cli/src/main/java/io/digdag/cli/client/DisableSchedule.java b/digdag-cli/src/main/java/io/digdag/cli/client/DisableSchedule.java index 18d9ef4a67..e855b17275 100644 --- a/digdag-cli/src/main/java/io/digdag/cli/client/DisableSchedule.java +++ b/digdag-cli/src/main/java/io/digdag/cli/client/DisableSchedule.java @@ -18,7 +18,7 @@ public class DisableSchedule @Override public SystemExitException usage(String error) { - err.println("Usage: " + programName + " disable | [name]"); + err.println("Usage: " + programName + " disable | [name]"); showCommonOptions(); err.println(""); err.println(" Examples:"); diff --git a/digdag-cli/src/main/java/io/digdag/cli/client/EnableSchedule.java b/digdag-cli/src/main/java/io/digdag/cli/client/EnableSchedule.java index 6593c1c048..b67af7e831 100644 --- a/digdag-cli/src/main/java/io/digdag/cli/client/EnableSchedule.java +++ b/digdag-cli/src/main/java/io/digdag/cli/client/EnableSchedule.java @@ -18,7 +18,7 @@ public class EnableSchedule @Override public SystemExitException usage(String error) { - err.println("Usage: " + programName + " enable | [name]"); + err.println("Usage: " + programName + " enable | [name]"); showCommonOptions(); err.println(""); err.println(" Examples:"); diff --git a/digdag-cli/src/main/java/io/digdag/cli/client/Push.java b/digdag-cli/src/main/java/io/digdag/cli/client/Push.java index f871050fb2..a41b590fed 100644 --- a/digdag-cli/src/main/java/io/digdag/cli/client/Push.java +++ b/digdag-cli/src/main/java/io/digdag/cli/client/Push.java @@ -14,6 +14,7 @@ import io.digdag.client.DigdagClient; import io.digdag.client.api.RestProject; import io.digdag.client.config.Config; +import io.digdag.client.config.ConfigElement; import io.digdag.client.config.ConfigFactory; import io.digdag.core.DigdagEmbed; import io.digdag.core.config.ConfigLoaderManager; @@ -76,10 +77,14 @@ private void push(String projName) Path archivePath = Files.createTempFile(dir, "archive-", ".tar.gz"); archivePath.toFile().deleteOnExit(); + ConfigElement systemConfig = ConfigElement.fromJson("{ \"database.migrate\" : false } }"); + Injector injector = new DigdagEmbed.Bootstrap() + .setSystemConfig(systemConfig) .withWorkflowExecutor(false) .withScheduleExecutor(false) .withLocalAgent(false) + .withTaskQueueServer(false) .addModules(binder -> { binder.bind(YamlMapper.class).in(Scopes.SINGLETON); binder.bind(Archiver.class).in(Scopes.SINGLETON); diff --git a/digdag-cli/src/main/java/io/digdag/cli/client/Reschedule.java b/digdag-cli/src/main/java/io/digdag/cli/client/Reschedule.java index e5047f7347..a5d1c12e12 100644 --- a/digdag-cli/src/main/java/io/digdag/cli/client/Reschedule.java +++ b/digdag-cli/src/main/java/io/digdag/cli/client/Reschedule.java @@ -6,6 +6,8 @@ import io.digdag.cli.TimeUtil; import io.digdag.client.DigdagClient; import io.digdag.client.api.Id; +import io.digdag.client.api.RestProject; +import io.digdag.client.api.RestSchedule; import io.digdag.client.api.RestScheduleSummary; import java.time.Instant; @@ -32,46 +34,84 @@ public class Reschedule public void mainWithClientException() throws Exception { - if (args.size() != 1) { - throw usage(null); - } - Id schedId = parseScheduleIdOrUsage(args.get(0)); - if (toTime != null && skipCount > 0) { throw systemExit("-s and -t can't be set together"); } else if (toTime == null && skipCount <= 0) { throw usage("-s or -t is required"); } - reschedule(schedId); + + // Schedule id? + if (args.size() == 1) { + Id schedId = parseScheduleId(args.get(0)); + rescheduleScheduleId(schedId); + } + else if (args.size() == 2) { + // Single workflow + rescheduleWorkflow(args.get(0), args.get(1)); + } + else { + throw usage(null); + } } public SystemExitException usage(String error) { - err.println("Usage: " + programName + " reschedule "); + err.println("Usage: " + programName + " reschedule | "); err.println(" Options:"); err.println(" -s, --skip N skips specified number of schedules from now"); - err.println(" -t, --skip-to 'yyyy-MM-dd HH:mm:ss Z' skips schedules until the specified time (exclusive)"); - err.println(" -a, --run-at 'yyyy-MM-dd HH:mm:ss Z' set next run time to this time"); + err.println(" -t, --skip-to 'yyyy-MM-dd HH:mm:ss Z' | 'now'"); + err.println(" skips schedules until the specified time (exclusive)"); + err.println(" -a, --run-at 'yyyy-MM-dd HH:mm:ss Z'"); + err.println(" set next run time to this time"); err.println(" -d, --dry-run tries to reschedule and validates the results but does nothing"); showCommonOptions(); return systemExit(error); } - private void reschedule(Id schedId) + private Id parseScheduleId(String s) + throws SystemExitException + { + try { + return Id.of(Integer.toString(Integer.parseUnsignedInt(s))); + } + catch (NumberFormatException ignore) { + throw usage(null); + } + } + + private void rescheduleWorkflow(String projectName, String workflowName) + throws Exception + { + DigdagClient client = buildClient(); + RestProject project = client.getProject(projectName); + RestSchedule schedule = client.getSchedule(project.getId(), workflowName); + Instant now = Instant.now(); + reschedule(schedule.getId(), client, now); + } + + private void rescheduleScheduleId(Id schedId) throws Exception { + DigdagClient client = buildClient(); Instant now = Instant.now(); + reschedule(schedId, client, now); + } + private void reschedule(Id schedId, DigdagClient client, Instant now) + throws Exception + { Optional runAt = runAtTime == null ? Optional.absent() : Optional.of( TimeUtil.parseTime(runAtTime, "-a, --run-at") ); - DigdagClient client = buildClient(); RestScheduleSummary updated; if (toTime != null) { + Instant time = "now".equals(toTime) ? + now : + TimeUtil.parseTime(toTime, "-t, --skip-to"); updated = client.skipSchedulesToTime(schedId, - TimeUtil.parseTime(toTime, "-t, --skip-to"), + time, runAt, dryRun); } diff --git a/digdag-cli/src/main/java/io/digdag/cli/client/ShowProjects.java b/digdag-cli/src/main/java/io/digdag/cli/client/ShowProjects.java new file mode 100644 index 0000000000..9c9e9edd47 --- /dev/null +++ b/digdag-cli/src/main/java/io/digdag/cli/client/ShowProjects.java @@ -0,0 +1,77 @@ +package io.digdag.cli.client; + +import io.digdag.cli.SystemExitException; +import io.digdag.cli.TimeUtil; +import io.digdag.client.DigdagClient; +import io.digdag.client.api.RestProject; +import io.digdag.client.api.RestProjectCollection; + +import javax.ws.rs.NotFoundException; + +import static io.digdag.cli.SystemExitException.systemExit; + +public class ShowProjects + extends ClientCommand +{ + @Override + public void mainWithClientException() + throws Exception + { + switch (args.size()) { + case 0: + showProjects(); + break; + case 1: + showSingleProject(args.get(0)); + break; + default: + throw usage(null); + } + } + + private void showProjects() + throws Exception + { + DigdagClient client = buildClient(); + + RestProjectCollection projects = client.getProjects(); + ln("Projects"); + for (RestProject project : projects.getProjects()) { + showProjectDetail(project); + } + err.println("Use `" + programName + " workflows ` to show details."); + } + + private void showSingleProject(String name) + throws Exception + { + DigdagClient client = buildClient(); + try { + RestProject project = client.getProject(name); + ln("Projects"); + showProjectDetail(project); + err.println("Use `" + programName + " workflows ` to show details."); + } + catch (NotFoundException ex) { + throw systemExit("Project '" + name + "' does not exist."); + } + } + + private void showProjectDetail(RestProject project) + { + ln(" name: %s", project.getName()); + ln(" id: %s", project.getId()); + ln(" revision: %s", project.getRevision()); + ln(" archive type: %s", project.getArchiveType()); + ln(" project created at: %s", TimeUtil.formatTime(project.getCreatedAt())); + ln(" revision updated at: %s", TimeUtil.formatTime(project.getUpdatedAt())); + ln(""); + } + + public SystemExitException usage(String error) + { + err.println("Usage: " + programName + " projects [name]"); + showCommonOptions(); + return systemExit(error); + } +} diff --git a/digdag-cli/src/main/java/io/digdag/cli/client/ShowSession.java b/digdag-cli/src/main/java/io/digdag/cli/client/ShowSession.java index 8702c45d6b..23643588fa 100644 --- a/digdag-cli/src/main/java/io/digdag/cli/client/ShowSession.java +++ b/digdag-cli/src/main/java/io/digdag/cli/client/ShowSession.java @@ -79,7 +79,7 @@ public SystemExitException usage(String error) err.println(" " + programName + " sessions show sessions for a workflow"); err.println(" " + programName + " session show a single session"); err.println(" Options:"); - err.println(" -i, --last-id ID shows more sessions from this id"); + err.println(" -i, --last-id ID shows more sessions older than this id"); err.println(" -s, --page-size Number shows more sessions of the number of this page size(in default up to 100)"); showCommonOptions(); return systemExit(error); diff --git a/digdag-cli/src/main/java/io/digdag/cli/client/Start.java b/digdag-cli/src/main/java/io/digdag/cli/client/Start.java index 0fc9992922..3c8e77082d 100644 --- a/digdag-cli/src/main/java/io/digdag/cli/client/Start.java +++ b/digdag-cli/src/main/java/io/digdag/cli/client/Start.java @@ -16,6 +16,7 @@ import io.digdag.client.api.RestWorkflowSessionTime; import io.digdag.client.api.SessionTimeTruncate; import io.digdag.client.config.Config; +import io.digdag.client.config.ConfigElement; import io.digdag.client.config.ConfigFactory; import io.digdag.core.DigdagEmbed; import io.digdag.core.config.ConfigLoaderManager; @@ -91,10 +92,14 @@ public SystemExitException usage(String error) private void start(String projName, String workflowName) throws Exception { + ConfigElement systemConfig = ConfigElement.fromJson("{ \"database.migrate\" : false } }"); + Injector injector = new DigdagEmbed.Bootstrap() + .setSystemConfig(systemConfig) .withWorkflowExecutor(false) .withScheduleExecutor(false) .withLocalAgent(false) + .withTaskQueueServer(false) .addModules(binder -> { binder.bind(ConfigLoaderManager.class).in(Scopes.SINGLETON); }) diff --git a/digdag-cli/src/test/java/io/digdag/cli/BasicAuthParameterValidatorTest.java b/digdag-cli/src/test/java/io/digdag/cli/BasicAuthParameterValidatorTest.java new file mode 100644 index 0000000000..92eb2e7540 --- /dev/null +++ b/digdag-cli/src/test/java/io/digdag/cli/BasicAuthParameterValidatorTest.java @@ -0,0 +1,31 @@ +package io.digdag.cli; + +import com.beust.jcommander.ParameterException; +import org.junit.Test; + +public class BasicAuthParameterValidatorTest +{ + @Test + public void validUserPassPasses() + { + new BasicAuthParameterValidator().validate(null, "user:pass"); + } + + @Test(expected = ParameterException.class) + public void missingUsernameFails() + { + new BasicAuthParameterValidator().validate(null, ":pass"); + } + + @Test(expected = ParameterException.class) + public void missingPasswordFails() + { + new BasicAuthParameterValidator().validate(null, "user:"); + } + + @Test(expected = ParameterException.class) + public void missingColonFails() + { + new BasicAuthParameterValidator().validate(null, "userpass"); + } +} \ No newline at end of file diff --git a/digdag-client/build.gradle b/digdag-client/build.gradle index 7be3bc6084..615824541e 100644 --- a/digdag-client/build.gradle +++ b/digdag-client/build.gradle @@ -4,7 +4,7 @@ dependencies { compile "com.fasterxml.jackson.jaxrs:jackson-jaxrs-json-provider:${project.ext.jacksonVersion}" compile "com.fasterxml.jackson.core:jackson-annotations:${project.ext.jacksonVersion}" compile "com.fasterxml.jackson.core:jackson-core:${project.ext.jacksonVersion}" - compile "com.fasterxml.jackson.core:jackson-databind:${project.ext.jacksonVersion}" + compile "com.fasterxml.jackson.core:jackson-databind:${project.ext.jacksonDatabindVersion}" compile "com.fasterxml.jackson.datatype:jackson-datatype-guava:${project.ext.jacksonVersion}" compile("com.github.rholder:guava-retrying:2.0.0") { @@ -12,8 +12,8 @@ dependencies { // available version of guava at the moment (e.g. 21.0). This is not good. exclude group: 'com.google.guava', module: 'guava' } - compile "com.google.guava:guava:19.0" - + compile "com.google.guava:guava:${project.ext.guavaVersion}" + compile "com.google.code.findbugs:jsr305:3.0.2" compile 'org.jboss.resteasy:resteasy-client:3.0.24.Final' compile 'org.apache.commons:commons-compress:1.10' compile 'io.jsonwebtoken:jjwt:0.6.0' @@ -22,6 +22,7 @@ dependencies { // which conflicts with undertow 1.4.0.Final -> jboss-logging 3.2.1.Final compile 'org.jboss.logging:jboss-logging:3.3.0.Final' - testCompile 'com.squareup.okhttp3:okhttp:3.4.1' - testCompile 'com.squareup.okhttp3:mockwebserver:3.4.1' + testCompile 'com.squareup.okhttp3:okhttp:3.12.0' + testCompile 'com.squareup.okhttp3:okhttp-tls:3.12.0' + testCompile 'com.squareup.okhttp3:mockwebserver:3.12.0' } diff --git a/digdag-client/src/main/java/io/digdag/client/DigdagClient.java b/digdag-client/src/main/java/io/digdag/client/DigdagClient.java index 7fff208ff3..14ce6a92fa 100644 --- a/digdag-client/src/main/java/io/digdag/client/DigdagClient.java +++ b/digdag-client/src/main/java/io/digdag/client/DigdagClient.java @@ -66,6 +66,8 @@ import java.io.File; import java.io.IOException; import java.io.InputStream; +import java.io.UnsupportedEncodingException; +import java.net.URLEncoder; import java.time.Instant; import java.time.LocalDateTime; import java.util.HashMap; @@ -102,6 +104,7 @@ public static class Builder private final Map baseHeaders = new HashMap<>(); private Function, Map> headerBuilder = null; private boolean disableCertValidation; + private boolean disableDirectDownload = false; public Builder host(String host) { @@ -163,6 +166,12 @@ public Builder disableCertValidation(boolean value) return this; } + public Builder disableDirectDownload(boolean value) + { + this.disableDirectDownload = value; + return this; + } + public DigdagClient build() { return new DigdagClient(this); @@ -195,6 +204,7 @@ public static Builder builder() private final Client client; private final ConfigFactory cf; + private final boolean disableDirectDownload; private DigdagClient(Builder builder) { @@ -259,6 +269,9 @@ private DigdagClient(Builder builder) this.client = clientBuilder.build(); this.cf = new ConfigFactory(mapper); + + this.disableDirectDownload = builder.disableDirectDownload; + } @Override @@ -471,7 +484,7 @@ public InputStream getProjectArchive(Id projId, String revision) WebTarget webTarget = target("/api/projects/{id}/archive") .resolveTemplate("id", projId) .queryParam("revision", revision); - + webTarget = addDisableDirectDownloadParam(webTarget); return withFollowingRedirect(webTarget, (wt, lastResponse) -> { Invocation.Builder request = wt.request(); @@ -626,17 +639,25 @@ public RestTaskCollection getTasks(Id attemptId) public RestLogFileHandleCollection getLogFileHandlesOfAttempt(Id attemptId) { - return doGet(RestLogFileHandleCollection.class, - target("/api/logs/{id}/files") - .resolveTemplate("id", attemptId)); + WebTarget webTarget = target("/api/logs/{id}/files") + .resolveTemplate("id", attemptId); + webTarget = addDisableDirectDownloadParam(webTarget); + + return doGet(RestLogFileHandleCollection.class, webTarget); } public RestLogFileHandleCollection getLogFileHandlesOfTask(Id attemptId, String taskName) { - return doGet(RestLogFileHandleCollection.class, - target("/api/logs/{id}/files") - .resolveTemplate("id", attemptId) - .queryParam("task", taskName)); + try { + WebTarget webTarget = target("/api/logs/{id}/files") + .resolveTemplate("id", attemptId) + .queryParam("task", URLEncoder.encode(taskName, "UTF-8")); + webTarget = addDisableDirectDownloadParam(webTarget); + + return doGet(RestLogFileHandleCollection.class, webTarget); + } catch (UnsupportedEncodingException ex) { + throw Throwables.propagate(ex); + } } public InputStream getLogFile(Id attemptId, RestLogFileHandle handle) @@ -665,6 +686,16 @@ public InputStream getLogFile(Id attemptId, String fileName) .readEntity(InputStream.class); } + private WebTarget addDisableDirectDownloadParam(WebTarget target) + { + // direct_download is default true + // So only set direct_download=false when disableDirectDownload == true + if (disableDirectDownload) { + target = target.queryParam("direct_download", false); + } + return target; + } + private Response invokeWithRetry(Invocation request) { Retryer retryer = RetryerBuilder.newBuilder() diff --git a/digdag-client/src/main/java/io/digdag/client/api/JacksonTimeModule.java b/digdag-client/src/main/java/io/digdag/client/api/JacksonTimeModule.java index 3491cb5eef..c0b877a3e1 100644 --- a/digdag-client/src/main/java/io/digdag/client/api/JacksonTimeModule.java +++ b/digdag-client/src/main/java/io/digdag/client/api/JacksonTimeModule.java @@ -68,7 +68,7 @@ protected Instant _deserialize(String value, DeserializationContext context) return Instant.from(DateTimeFormatter.ISO_DATE_TIME.parse(value)); } catch (DateTimeParseException ex) { - throw new JsonMappingException("Invalid ISO time format: %s" + value, ex); + throw new JsonMappingException("Invalid ISO time format: " + value, ex); } } } diff --git a/digdag-client/src/main/java/io/digdag/client/api/RestTask.java b/digdag-client/src/main/java/io/digdag/client/api/RestTask.java index 826d8ee873..c9a62e605b 100644 --- a/digdag-client/src/main/java/io/digdag/client/api/RestTask.java +++ b/digdag-client/src/main/java/io/digdag/client/api/RestTask.java @@ -46,6 +46,8 @@ default boolean getCancelRequested() Optional getStartedAt(); + Config getError(); + // TODO in out Report static ImmutableRestTask.Builder builder() diff --git a/digdag-client/src/main/resources/io/digdag/client/version.txt b/digdag-client/src/main/resources/io/digdag/client/version.txt index 2e665126a5..a088cde257 100644 --- a/digdag-client/src/main/resources/io/digdag/client/version.txt +++ b/digdag-client/src/main/resources/io/digdag/client/version.txt @@ -1 +1 @@ -0.9.33 +0.9.41-SNAPSHOT diff --git a/digdag-client/src/test/java/io/digdag/client/DigdagClientTest.java b/digdag-client/src/test/java/io/digdag/client/DigdagClientTest.java index dcf863103a..b999eb269d 100644 --- a/digdag-client/src/test/java/io/digdag/client/DigdagClientTest.java +++ b/digdag-client/src/test/java/io/digdag/client/DigdagClientTest.java @@ -6,16 +6,17 @@ import io.digdag.client.api.RestDirectDownloadHandle; import io.digdag.client.api.RestLogFileHandle; import io.digdag.client.api.RestLogFileHandleCollection; -import okhttp3.internal.tls.SslClient; import okhttp3.mockwebserver.MockResponse; import okhttp3.mockwebserver.MockWebServer; import okhttp3.mockwebserver.QueueDispatcher; import okhttp3.mockwebserver.RecordedRequest; +import okhttp3.tls.HandshakeCertificates; import org.bouncycastle.util.io.Streams; import org.junit.After; import org.junit.Before; import org.junit.Test; +import javax.net.ssl.SSLSocketFactory; import javax.ws.rs.InternalServerErrorException; import javax.ws.rs.WebApplicationException; @@ -32,6 +33,7 @@ import static javax.ws.rs.core.HttpHeaders.USER_AGENT; import static javax.ws.rs.core.MediaType.APPLICATION_JSON; import static javax.ws.rs.core.MediaType.TEXT_PLAIN; +import static okhttp3.tls.internal.TlsUtil.localhost; import static org.hamcrest.Matchers.is; import static org.junit.Assert.assertArrayEquals; import static org.junit.Assert.assertThat; @@ -49,7 +51,9 @@ public void setUp() throws Exception { mockWebServer = new MockWebServer(); - mockWebServer.useHttps(SslClient.localhost().socketFactory, false); + HandshakeCertificates handshakeCertificates = localhost(); + SSLSocketFactory socketFactory = handshakeCertificates.sslSocketFactory(); + mockWebServer.useHttps(socketFactory, false); mockWebServer.start(); client = DigdagClient.builder() @@ -145,6 +149,43 @@ public void getLogFileHandlesOfTask() assertThat(mockWebServer.takeRequest().getPath(), is("/api/logs/17/files?task=test-task")); } + @Test + public void getLogFileHandlesOfTaskURLEncodedTaskName() + throws Exception + { + RestLogFileHandleCollection expectedLogFileHandles = RestLogFileHandleCollection.builder() + .addFiles( + RestLogFileHandle.builder() + .agentId("test-agent") + .fileName("test-task-%{}-1.log") + .fileSize(4711) + .fileTime(Instant.now().truncatedTo(SECONDS)) + .taskName("test-task-%{}-1") + .build(), + RestLogFileHandle.builder() + .agentId("test-agent") + .fileName("test-task-%{}-2.log") + .fileSize(4712) + .fileTime(Instant.now().truncatedTo(SECONDS)) + .taskName("test-task-%{}-2") + .build() + ).build(); + + mockWebServer.enqueue(new MockResponse().setResponseCode(500)); + + mockWebServer.enqueue(new MockResponse() + .setBody(objectMapper.writeValueAsString(expectedLogFileHandles)) + .setHeader(CONTENT_TYPE, APPLICATION_JSON)); + + RestLogFileHandleCollection receivedLogFileHandles = client.getLogFileHandlesOfTask(Id.of("17"), "test-task-%{}"); + + assertThat(receivedLogFileHandles, is(expectedLogFileHandles)); + + assertThat(mockWebServer.getRequestCount(), is(2)); + assertThat(mockWebServer.takeRequest().getPath(), is("/api/logs/17/files?task=test-task-%25%7B%7D")); + assertThat(mockWebServer.takeRequest().getPath(), is("/api/logs/17/files?task=test-task-%25%7B%7D")); + } + @Test public void getLogFileDirect() throws Exception diff --git a/digdag-core/build.gradle b/digdag-core/build.gradle index 4caee2486b..5286285ea7 100644 --- a/digdag-core/build.gradle +++ b/digdag-core/build.gradle @@ -5,10 +5,8 @@ dependencies { compile project(':digdag-plugin-utils') compile project(':digdag-guice-rs-server') - // this dependency is here only to override dependency conflict of - // jackson-module-guice -> guice 3.0. - // https://github.com/FasterXML/jackson-modules-base/pull/22 - compile 'org.embulk:guice-bootstrap:0.2.1' + compile 'com.google.inject:guice:4.2.2' + compile 'org.embulk:guice-bootstrap:0.3.2' compile("com.fasterxml.jackson.module:jackson-module-guice:${project.ext.jacksonVersion}") { // Avoid upgrading com.google.guava:guava:19.0 -> 23.6-android @@ -19,7 +17,7 @@ dependencies { compile 'com.zaxxer:HikariCP:2.4.7' compile 'com.h2database:h2:1.4.192' compile 'org.postgresql:postgresql:9.4.1211' - compile 'org.yaml:snakeyaml:1.17' + compile 'org.yaml:snakeyaml:1.23' compile 'com.google.code.findbugs:annotations:3.0.1' compile 'org.weakref:jmxutils:1.19' @@ -42,7 +40,7 @@ dependencies { // Dependency conflict resolution compile 'javax.activation:activation:1.1.1' - compile 'org.apache.httpcomponents:httpclient:4.5.2' + compile 'org.apache.httpcomponents:httpclient:4.5.3' testCompile project(path: ':digdag-client', configuration: 'testArtifacts') } diff --git a/digdag-core/src/main/java/io/digdag/core/DigdagEmbed.java b/digdag-core/src/main/java/io/digdag/core/DigdagEmbed.java index 8877c9a018..1549df6422 100644 --- a/digdag-core/src/main/java/io/digdag/core/DigdagEmbed.java +++ b/digdag-core/src/main/java/io/digdag/core/DigdagEmbed.java @@ -57,6 +57,7 @@ public static class Bootstrap private boolean withScheduleExecutor = true; private boolean withLocalAgent = true; private boolean withExtensionLoader = true; + private boolean withTaskQueueServer = true; private Map environment = ImmutableMap.of(); public Bootstrap addModules(Module... additionalModules) @@ -128,6 +129,12 @@ public Bootstrap withExtensionLoader(boolean v) return this; } + public Bootstrap withTaskQueueServer(boolean v) + { + this.withTaskQueueServer = v; + return this; + } + public DigdagEmbed initialize() { return build(true); @@ -171,13 +178,12 @@ private List standardModules(ConfigElement systemConfig) .registerModule(new JacksonTimeModule()), new DynamicPluginModule(), new SystemPluginModule(systemPlugins), - new DatabaseModule(), + new DatabaseModule(withTaskQueueServer), new AgentModule(), new LogModule(), new ScheduleModule(), new ConfigModule(), new WorkflowModule(), - new QueueModule(), new NotificationModule(), new StorageModule(), new EnvironmentModule(environment), @@ -205,6 +211,10 @@ private List standardModules(ConfigElement systemConfig) if (withExtensionLoader) { builder.add(new ExtensionServiceLoaderModule()); } + if (withTaskQueueServer) { + builder.add(new QueueModule()); + + } return builder.build(); } } diff --git a/digdag-core/src/main/java/io/digdag/core/agent/AgentConfigProvider.java b/digdag-core/src/main/java/io/digdag/core/agent/AgentConfigProvider.java index 2b90652a12..e6bfacbbd9 100644 --- a/digdag-core/src/main/java/io/digdag/core/agent/AgentConfigProvider.java +++ b/digdag-core/src/main/java/io/digdag/core/agent/AgentConfigProvider.java @@ -1,6 +1,5 @@ package io.digdag.core.agent; -import java.lang.management.ManagementFactory; import com.google.inject.Inject; import com.google.inject.Provider; import io.digdag.client.config.Config; diff --git a/digdag-core/src/main/java/io/digdag/core/agent/OperatorManager.java b/digdag-core/src/main/java/io/digdag/core/agent/OperatorManager.java index f1eb6ddd8b..741ebd1661 100644 --- a/digdag-core/src/main/java/io/digdag/core/agent/OperatorManager.java +++ b/digdag-core/src/main/java/io/digdag/core/agent/OperatorManager.java @@ -158,7 +158,7 @@ private void runWithHeartbeat(TaskRequest request) ex.getError(cf).get()); // TODO is error set? } } - catch (RuntimeException ex) { + catch (RuntimeException | AssertionError ex) { // Avoid infinite task retry cause of AssertionError by Operators if (ex instanceof ConfigException) { logger.error("Configuration error at task {}: {}", request.getTaskName(), formatExceptionMessage(ex)); } @@ -203,6 +203,9 @@ private void runWithWorkspace(Path projectPath, TaskRequest request) catch (RuntimeException ex) { throw new RuntimeException("Failed to process variables", ex); } + catch (AssertionError ex) { // Avoid infinite task retry cause of AssertionError by ConfigEvalEngine(nashorn) + throw new RuntimeException("Unexpected error happened in ConfigEvalEngine: " + ex.getMessage(), ex); + } logger.debug("evaluated config: {}", config); Set shouldBeUsedKeys = new HashSet<>(request.getLocalConfig().getKeys()); diff --git a/digdag-core/src/main/java/io/digdag/core/database/DataSourceProvider.java b/digdag-core/src/main/java/io/digdag/core/database/DataSourceProvider.java index 38ebd769f9..965ccd0df5 100644 --- a/digdag-core/src/main/java/io/digdag/core/database/DataSourceProvider.java +++ b/digdag-core/src/main/java/io/digdag/core/database/DataSourceProvider.java @@ -86,6 +86,8 @@ private void createPooledDataSource() hikari.setValidationTimeout(config.getValidationTimeout() * 1000); hikari.setMaximumPoolSize(config.getMaximumPoolSize()); hikari.setMinimumIdle(config.getMinimumPoolSize()); + hikari.setRegisterMbeans(config.getEnableJMX()); + hikari.setLeakDetectionThreshold(config.getLeakDetectionThreshold()); // Here should not set connectionTestQuery (that overrides isValid) because // ThreadLocalTransactionManager.commit assumes that Connection.isValid returns diff --git a/digdag-core/src/main/java/io/digdag/core/database/DatabaseConfig.java b/digdag-core/src/main/java/io/digdag/core/database/DatabaseConfig.java index dd91af991e..9ddfb94ea7 100644 --- a/digdag-core/src/main/java/io/digdag/core/database/DatabaseConfig.java +++ b/digdag-core/src/main/java/io/digdag/core/database/DatabaseConfig.java @@ -45,6 +45,10 @@ public interface DatabaseConfig int getValidationTimeout(); // seconds + boolean getEnableJMX(); + + long getLeakDetectionThreshold(); // milliseconds + static ImmutableDatabaseConfig.Builder builder() { return ImmutableDatabaseConfig.builder(); @@ -104,6 +108,10 @@ static DatabaseConfig convertFrom(Config config, String keyPrefix) builder.minimumPoolSize( config.get(keyPrefix + "." + "minimumPoolSize", int.class, maximumPoolSize)); // HikariCP default: Same as maximumPoolSize + builder.enableJMX(isJMXEnable(config)); + builder.leakDetectionThreshold( + config.get(keyPrefix + "." + "leakDetectionThreshold", long.class, 0L)); // HikariCP default: 0 + // database.opts.* to options ImmutableMap.Builder options = ImmutableMap.builder(); for (String key : config.getKeys()) { @@ -123,6 +131,19 @@ static DatabaseConfig convertFrom(Config config, String keyPrefix) return builder.build(); } + /** + * If server.jmx.port exists, then JMX is enable + * TODO this method should move to proper class? + * @param config + * @return + */ + static boolean isJMXEnable(Config config) + { + return config.getOptional("server.jmx.port", Integer.class) + .transform((port) -> true) + .or(false); + } + static Config toConfig(DatabaseConfig databaseConfig, ConfigFactory cf) { return toConfig(databaseConfig, cf, "database"); } @@ -158,6 +179,7 @@ static Config toConfig(DatabaseConfig databaseConfig, ConfigFactory cf, String k config.set(keyPrefix + "." + "validationTimeout", databaseConfig.getValidationTimeout()); config.set(keyPrefix + "." + "maximumPoolSize", databaseConfig.getMaximumPoolSize()); config.set(keyPrefix + "." + "minimumPoolSize", databaseConfig.getMinimumPoolSize()); + config.set(keyPrefix + "." + "enableJMX", databaseConfig.getEnableJMX()); // database.opts.* Map options = databaseConfig.getOptions(); @@ -177,7 +199,7 @@ static String buildJdbcUrl(DatabaseConfig config) switch (config.getType()) { case "h2": if (config.getRemoteDatabaseConfig().isPresent()) { - throw new IllegalArgumentException("Database type is postgresql but remoteDatabaseConfig is not set unexpectedly"); + throw new IllegalArgumentException("Database type is h2 but remoteDatabaseConfig is not set unexpectedly"); } if (config.getPath().isPresent()) { Path dir = FileSystems.getDefault().getPath(config.getPath().get()); diff --git a/digdag-core/src/main/java/io/digdag/core/database/DatabaseMigrator.java b/digdag-core/src/main/java/io/digdag/core/database/DatabaseMigrator.java index be333ab0b7..54983124b0 100644 --- a/digdag-core/src/main/java/io/digdag/core/database/DatabaseMigrator.java +++ b/digdag-core/src/main/java/io/digdag/core/database/DatabaseMigrator.java @@ -1,21 +1,23 @@ package io.digdag.core.database; +import com.google.common.annotations.VisibleForTesting; import com.google.inject.Inject; import org.skife.jdbi.v2.DBI; import org.skife.jdbi.v2.Handle; import org.skife.jdbi.v2.exceptions.StatementException; -import java.util.Comparator; -import java.util.HashSet; -import java.util.List; -import java.util.Set; +import java.util.*; import java.util.stream.Collectors; import java.util.stream.Stream; import io.digdag.core.database.migrate.*; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; public class DatabaseMigrator { + private static final Logger logger = LoggerFactory.getLogger(DatabaseMigrator.class); + private final List migrations = Stream.of(new Migration[] { new Migration_20151204221156_CreateTables(), new Migration_20160602123456_SessionsOnProjectIdIndexToDesc(), @@ -36,6 +38,7 @@ public class DatabaseMigrator new Migration_20170116082921_AddAttemptIndexColumn1(), new Migration_20170116090744_AddAttemptIndexColumn2(), new Migration_20170223220127_AddLastSessionTimeAndFlagsToSessions(), + new Migration_20190318175338_AddIndexToSessionAttempts(), }) .sorted(Comparator.comparing(m -> m.getVersion())) .collect(Collectors.toList()); @@ -49,7 +52,7 @@ public DatabaseMigrator(DBI dbi, DatabaseConfig config) this(dbi, config.getType()); } - public DatabaseMigrator(DBI dbi, String databaseType) + DatabaseMigrator(DBI dbi, String databaseType) { this.dbi = dbi; this.databaseType = databaseType; @@ -76,78 +79,131 @@ public String getSchemaVersion() } } - private static enum NextStatus + public int migrate() { - RUN_ALL, - FINISHED, - MORE; + int numApplied = 0; + MigrationContext context = new MigrationContext(databaseType); + Set appliedSet; + try (Handle handle = dbi.open()) { + boolean isInitial = !existsSchemaMigrationsTable(handle); + if (isInitial) { + createSchemaMigrationsTable(handle, context); + } + appliedSet = getAppliedMigrationNames(handle); + } + for (Migration m : migrations) { + if (appliedSet.add(m.getVersion())) { + if (applyMigrationIfNotDone(context, m)) { + numApplied++; + } + } + } + if (numApplied > 0) { + if (context.isPostgres()) { + logger.info("{} migrations applied.", numApplied); + } + else { + logger.debug("{} migrations applied.", numApplied); + } + } + return numApplied; } - public void migrate() + // add "synchronized" so that multiple threads don't run the same migration on the same database + private synchronized boolean applyMigrationIfNotDone(MigrationContext context, Migration m) { - MigrationContext context = new MigrationContext(databaseType); - - while (true) { - NextStatus status; - - try (Handle handle = dbi.open()) { - status = handle.inTransaction((h, session) -> { - Set appliedSet; - - try { - if (context.isPostgres()) { - // lock tables not to run migration concurrently. - // h2 doesn't support table lock. - h.update("LOCK TABLE schema_migrations IN EXCLUSIVE MODE"); - } - - appliedSet = new HashSet<>( - handle.createQuery("select name from schema_migrations") - .mapTo(String.class) - .list()); - } - catch (StatementException ex) { - // schema_migrations table does not exist. this is the initial run - // including local mode. apply everything at once. - return NextStatus.RUN_ALL; + // recreate Handle for each time to be able to discard pg_advisory_lock. + try (Handle handle = dbi.open()) { + if (m.noTransaction(context)) { + // Advisory lock if available -> migrate + if (context.isPostgres()) { + handle.select("SELECT pg_advisory_lock(23299, 0)"); + // re-check migration status after lock + if (!checkIfMigrationApplied(handle, m.getVersion())) { + logger.info("Applying database migration:" + m.getVersion()); + applyMigration(m, handle, context); + return true; } + return false; + } + else { + // h2 doesn't support table lock and it's unnecessary because of synchronized + logger.debug("Applying database migration:" + m.getVersion()); + applyMigration(m, handle, context); + return true; + } - for (Migration m : migrations) { - if (appliedSet.add(m.getVersion())) { - System.out.println("applying " + m.getVersion() + " set: " + appliedSet); - applyMigration(m, h, context); - // use isolated transaction for each migration script to avoid long lock. - return NextStatus.MORE; + } + else { + // Start transaction -> Lock table -> Re-check migration status -> migrate + return handle.inTransaction((h, session) -> { + if (context.isPostgres()) { + // lock tables not to run migration concurrently. + h.update("LOCK TABLE schema_migrations IN EXCLUSIVE MODE"); + // re-check migration status after lock + if (!checkIfMigrationApplied(h, m.getVersion())) { + logger.info("Applying database migration:" + m.getVersion()); + applyMigration(m, handle, context); + return true; } + return false; + } + else { + // h2 doesn't support table lock and it's unnecessary because of synchronized + logger.debug("Applying database migration:" + m.getVersion()); + applyMigration(m, handle, context); + return true; } - - return NextStatus.FINISHED; }); } + } + } - switch (status) { - case FINISHED: - return; + // Called from cli migrate - case RUN_ALL: - try (Handle handle = dbi.open()) { - handle.inTransaction((h, session) -> { - createSchemaMigrationsTable(h, context); - for (Migration m : migrations) { - applyMigration(m, h, context); - } - return true; - }); - } - break; + /** + * Called from cli migrate + * @return no applicated migrations. + */ + public List getApplicableMigration() + { + List applicableMigrations = new ArrayList<>(); + MigrationContext context = new MigrationContext(databaseType); + try (Handle handle = dbi.open()) { + boolean isInitial = !existsSchemaMigrationsTable(handle); + if (isInitial) { + return applicableMigrations; + } - case MORE: - // pass-through + Set appliedSet = getAppliedMigrationNames(handle); + for (Migration m : migrations) { + if (!appliedSet.contains(m.getVersion())) { + applicableMigrations.add(m); + } } } + return applicableMigrations; + } + + private Set getAppliedMigrationNames(Handle handle) + { + return new HashSet<>( + handle.createQuery("select name from schema_migrations") + .mapTo(String.class) + .list()); + } + + private boolean checkIfMigrationApplied(Handle handle, String name) + { + return handle.createQuery("select name from schema_migrations where name = :name limit 1") + .bind("name", name) + .mapTo(String.class) + .list() + .size() > 0; } - private void createSchemaMigrationsTable(Handle handle, MigrationContext context) + @VisibleForTesting + public void createSchemaMigrationsTable(Handle handle, MigrationContext context) { handle.update( context.newCreateTableBuilder("schema_migrations") @@ -156,9 +212,37 @@ private void createSchemaMigrationsTable(Handle handle, MigrationContext context .build()); } - private void applyMigration(Migration m, Handle handle, MigrationContext context) + // Called from cli migrate + public boolean existsSchemaMigrationsTable() + { + try (Handle handle = dbi.open()) { + return existsSchemaMigrationsTable(handle); + } + } + + private boolean existsSchemaMigrationsTable(Handle handle) + { + try { + handle.createQuery("select name from schema_migrations limit 1") + .mapTo(String.class) + .list(); + return true; + } + catch( RuntimeException re) { + return false; + } + } + + @VisibleForTesting + public void applyMigration(Migration m, Handle handle, MigrationContext context) { m.migrate(handle, context); handle.insert("insert into schema_migrations (name, created_at) values (?, now())", m.getVersion()); } + + @VisibleForTesting + public String getDatabaseType() + { + return databaseType; + } } diff --git a/digdag-core/src/main/java/io/digdag/core/database/DatabaseModule.java b/digdag-core/src/main/java/io/digdag/core/database/DatabaseModule.java index 3fa059d973..138a7c80af 100644 --- a/digdag-core/src/main/java/io/digdag/core/database/DatabaseModule.java +++ b/digdag-core/src/main/java/io/digdag/core/database/DatabaseModule.java @@ -16,6 +16,13 @@ public class DatabaseModule implements Module { + private boolean withTaskQueueServer; + + public DatabaseModule(boolean withTaskQueueServer) + { + this.withTaskQueueServer = withTaskQueueServer; + } + @Override public void configure(Binder binder) { @@ -30,8 +37,10 @@ public void configure(Binder binder) binder.bind(QueueSettingStoreManager.class).to(DatabaseQueueSettingStoreManager.class).in(Scopes.SINGLETON); binder.bind(SessionStoreManager.class).to(DatabaseSessionStoreManager.class).in(Scopes.SINGLETON); binder.bind(ScheduleStoreManager.class).to(DatabaseScheduleStoreManager.class).in(Scopes.SINGLETON); - binder.bind(DatabaseTaskQueueConfig.class).in(Scopes.SINGLETON); - binder.bind(DatabaseTaskQueueServer.class).in(Scopes.SINGLETON); + if (withTaskQueueServer) { + binder.bind(DatabaseTaskQueueConfig.class).in(Scopes.SINGLETON); + binder.bind(DatabaseTaskQueueServer.class).in(Scopes.SINGLETON); + } } public static class AutoMigrator diff --git a/digdag-core/src/main/java/io/digdag/core/database/DatabaseProjectStoreManager.java b/digdag-core/src/main/java/io/digdag/core/database/DatabaseProjectStoreManager.java index 09fcfaefdc..d378629cca 100644 --- a/digdag-core/src/main/java/io/digdag/core/database/DatabaseProjectStoreManager.java +++ b/digdag-core/src/main/java/io/digdag/core/database/DatabaseProjectStoreManager.java @@ -6,6 +6,7 @@ import io.digdag.client.config.Config; import io.digdag.core.repository.ArchiveType; import io.digdag.core.repository.ImmutableStoredProject; +import io.digdag.core.repository.ImmutableStoredProjectWithRevision; import io.digdag.core.repository.ImmutableStoredRevision; import io.digdag.core.repository.ImmutableStoredWorkflowDefinition; import io.digdag.core.repository.ImmutableStoredWorkflowDefinitionWithProject; @@ -18,6 +19,7 @@ import io.digdag.core.repository.ResourceNotFoundException; import io.digdag.core.repository.Revision; import io.digdag.core.repository.StoredProject; +import io.digdag.core.repository.StoredProjectWithRevision; import io.digdag.core.repository.StoredRevision; import io.digdag.core.repository.StoredWorkflowDefinition; import io.digdag.core.repository.StoredWorkflowDefinitionWithProject; @@ -123,6 +125,12 @@ public DatabaseProjectStore(int siteId) // return dao.getProjects(siteId, Integer.MAX_VALUE, 0); //} + @Override + public List getProjectsWithLatestRevision(int pageSize, Optional lastId) + { + return autoCommit((handle, dao) -> dao.getProjectsWithLatestRevision(siteId, pageSize, lastId.or(0))); + } + @Override public List getProjects(int pageSize, Optional lastId) { @@ -508,6 +516,24 @@ public void deleteSchedules(int projId) public interface H2Dao extends Dao { + // h2 doesn't have max window function. + // this is not efficient but gave up optimization on h2. + @Override + @SqlQuery("select proj.*, rev.name as revision_name, rev.created_at as revision_created_at, rev.archive_type as revision_archive_type, rev.archive_md5 as revision_archive_md5" + + " from projects proj" + + " join revisions rev on proj.id = rev.project_id" + + " join (" + + "select project_id, max(id) AS id" + + " from revisions" + + " group by project_id" + + ") a on a.id = rev.id" + + " where proj.site_id = :siteId" + + " and proj.name is not null" + + " and proj.id > :lastId" + + " order by proj.id asc" + + " limit :limit") + List getProjectsWithLatestRevision(@Bind("siteId") int siteId, @Bind("limit") int limit, @Bind("lastId") int lastId); + // h2's MERGE doesn't return generated id when conflicting row already exists @SqlUpdate("merge into projects" + " (site_id, name, created_at)" + @@ -542,6 +568,21 @@ public interface H2Dao public interface PgDao extends Dao { + @Override + @SqlQuery("select id, site_id, name, created_at, deleted_at, deleted_name, revision_name, revision_created_at, revision_archive_type, revision_archive_md5" + + " from (" + + " select proj.*, rev.name as revision_name, rev.created_at as revision_created_at, rev.archive_type as revision_archive_type, rev.archive_md5 as revision_archive_md5, rev.id as revision_id, max(rev.id) OVER(partition by rev.project_id) as max_revision_id" + + " from projects proj" + + " join revisions rev on proj.id = rev.project_id" + + " where proj.site_id = :siteId" + + " and proj.name is not null" + + " and proj.id > :lastId" + + ") as projects_with_revision" + + " where projects_with_revision.revision_id = projects_with_revision.max_revision_id" + + " order by id asc" + + " limit :limit") + List getProjectsWithLatestRevision(@Bind("siteId") int siteId, @Bind("limit") int limit, @Bind("lastId") int lastId); + @SqlQuery("insert into projects" + " (site_id, name, created_at)" + " values (:siteId, :name, now())" + @@ -588,6 +629,8 @@ public interface Dao " limit :limit") List getProjects(@Bind("siteId") int siteId, @Bind("limit") int limit, @Bind("lastId") int lastId); + List getProjectsWithLatestRevision(@Bind("siteId") int siteId, @Bind("limit") int limit, @Bind("lastId") int lastId); + @SqlUpdate("update projects" + " set deleted_name = name, deleted_at = now(), name = NULL" + " where id = :projId "+ @@ -850,6 +893,40 @@ public StoredProject map(int index, ResultSet r, StatementContext ctx) } } + static class StoredProjectWithRevisionMapper + implements ResultSetMapper + { + private final ConfigMapper cfm; + + public StoredProjectWithRevisionMapper(ConfigMapper cfm) + { + this.cfm = cfm; + } + + @Override + public StoredProjectWithRevision map(int index, ResultSet r, StatementContext ctx) + throws SQLException + { + String name = r.getString("name"); + Optional deletedAt = Optional.absent(); + if (r.wasNull()) { + name = r.getString("deleted_name"); + deletedAt = Optional.of(getTimestampInstant(r, "deleted_at")); + } + return ImmutableStoredProjectWithRevision.builder() + .id(r.getInt("id")) + .name(name) + .siteId(r.getInt("site_id")) + .createdAt(getTimestampInstant(r, "created_at")) + .deletedAt(deletedAt) + .revisionName(r.getString("revision_name")) + .revisionCreatedAt(getTimestampInstant(r, "revision_created_at")) + .revisionArchiveType(ArchiveType.of(r.getString("revision_archive_type"))) + .revisionArchiveMd5(getOptionalBytes(r, "revision_archive_md5")) + .build(); + } + } + static class StoredRevisionMapper implements ResultSetMapper { diff --git a/digdag-core/src/main/java/io/digdag/core/database/ThreadLocalTransactionManager.java b/digdag-core/src/main/java/io/digdag/core/database/ThreadLocalTransactionManager.java index 1a872460eb..29e9772844 100644 --- a/digdag-core/src/main/java/io/digdag/core/database/ThreadLocalTransactionManager.java +++ b/digdag-core/src/main/java/io/digdag/core/database/ThreadLocalTransactionManager.java @@ -65,6 +65,7 @@ public Handle getHandle(ConfigMapper configMapper) DBI dbi = new DBI(ds); ConfigKeyListMapper cklm = new ConfigKeyListMapper(); dbi.registerMapper(new DatabaseProjectStoreManager.StoredProjectMapper(configMapper)); + dbi.registerMapper(new DatabaseProjectStoreManager.StoredProjectWithRevisionMapper(configMapper)); dbi.registerMapper(new DatabaseProjectStoreManager.StoredRevisionMapper(configMapper)); dbi.registerMapper(new DatabaseProjectStoreManager.StoredWorkflowDefinitionMapper(configMapper)); dbi.registerMapper(new DatabaseProjectStoreManager.StoredWorkflowDefinitionWithProjectMapper(configMapper)); diff --git a/digdag-core/src/main/java/io/digdag/core/database/migrate/Migration.java b/digdag-core/src/main/java/io/digdag/core/database/migrate/Migration.java index dac4850484..a55cd06cac 100644 --- a/digdag-core/src/main/java/io/digdag/core/database/migrate/Migration.java +++ b/digdag-core/src/main/java/io/digdag/core/database/migrate/Migration.java @@ -17,5 +17,21 @@ default String getVersion() return m.group(1); } + /** + * If true, this Migration apply without transaction. + * This is introduced specifically for PostgreSQL's CREATE INDEX CONCURRENTLY statement. + * + * If this method returns true, the migration MUST RUN ONLY ONE DDL STATEMENT. + * Otherwise, a failure in the middle of multiple statements causes inconsistency, and + * retrying the migration may never success because the first DDL statement is already + * applied and next migration attempt will also apply the same DDL statement. + * + * @return + */ + default boolean noTransaction(MigrationContext context) + { + return false; + } + void migrate(Handle handle, MigrationContext context); } diff --git a/digdag-core/src/main/java/io/digdag/core/database/migrate/Migration_20190318175338_AddIndexToSessionAttempts.java b/digdag-core/src/main/java/io/digdag/core/database/migrate/Migration_20190318175338_AddIndexToSessionAttempts.java new file mode 100644 index 0000000000..d047367889 --- /dev/null +++ b/digdag-core/src/main/java/io/digdag/core/database/migrate/Migration_20190318175338_AddIndexToSessionAttempts.java @@ -0,0 +1,26 @@ +package io.digdag.core.database.migrate; + +import org.skife.jdbi.v2.Handle; + +public class Migration_20190318175338_AddIndexToSessionAttempts + implements Migration +{ + @Override + public void migrate(Handle handle, MigrationContext context) + { + // DatabaseSessionStoreManager.getActiveAttemptCount uses this index. + if (context.isPostgres()) { + handle.update("create index concurrently session_attempts_on_site_id_and_state_flags_partial_2 on session_attempts" + + " using btree(site_id) where state_flags & 2 = 0"); + } + else { + // H2 does not support partial index + } + } + + @Override + public boolean noTransaction(MigrationContext context) + { + return context.isPostgres(); + } +} diff --git a/digdag-core/src/main/java/io/digdag/core/log/BufferedRemoteTaskLogger.java b/digdag-core/src/main/java/io/digdag/core/log/BufferedRemoteTaskLogger.java index 0671dc3376..4d770915e0 100644 --- a/digdag-core/src/main/java/io/digdag/core/log/BufferedRemoteTaskLogger.java +++ b/digdag-core/src/main/java/io/digdag/core/log/BufferedRemoteTaskLogger.java @@ -1,16 +1,14 @@ package io.digdag.core.log; import java.time.Instant; -import java.util.zip.GZIPOutputStream; import java.io.InputStream; -import java.io.OutputStream; import java.io.IOException; import java.nio.file.Files; import java.nio.file.Path; import java.util.concurrent.locks.ReentrantReadWriteLock; import java.util.concurrent.locks.ReentrantReadWriteLock.ReadLock; import java.util.concurrent.locks.ReentrantReadWriteLock.WriteLock; -import java.time.Instant; + import com.google.common.base.Throwables; import com.google.common.io.ByteStreams; import io.digdag.core.TempFileManager; @@ -135,49 +133,4 @@ public void close() } } - private static class CountingLogOutputStream - extends GZIPOutputStream - { - private final Path path; - private final Instant openTime; - private int count; - - public CountingLogOutputStream(Path path) - throws IOException - { - super(Files.newOutputStream(path), 8*1024); - this.def.setLevel(9); - this.path = path; - this.openTime = Instant.now(); - } - - @Override - public void write(int b) throws IOException - { - super.write(b); - count++; - } - - @Override - public void write(byte b[], int off, int len) throws IOException - { - super.write(b, off, len); - count += len; - } - - public Path getPath() - { - return path; - } - - public Instant getOpenTime() - { - return openTime; - } - - public int getUncompressedSize() - { - return count; - } - } } diff --git a/digdag-core/src/main/java/io/digdag/core/log/CountingLogOutputStream.java b/digdag-core/src/main/java/io/digdag/core/log/CountingLogOutputStream.java new file mode 100644 index 0000000000..645262c77e --- /dev/null +++ b/digdag-core/src/main/java/io/digdag/core/log/CountingLogOutputStream.java @@ -0,0 +1,53 @@ +package io.digdag.core.log; + +import java.io.IOException; +import java.nio.file.Files; +import java.nio.file.Path; +import java.time.Instant; +import java.util.zip.GZIPOutputStream; + +public class CountingLogOutputStream + extends GZIPOutputStream +{ + private final Path path; + private final Instant openTime; + private int count; + + public CountingLogOutputStream(Path path) + throws IOException + { + super(Files.newOutputStream(path), 8*1024); + this.def.setLevel(9); + this.path = path; + this.openTime = Instant.now(); + } + + @Override + public void write(int b) throws IOException + { + super.write(b); + count++; + } + + @Override + public void write(byte b[], int off, int len) throws IOException + { + super.write(b, off, len); + count += len; + } + + public Path getPath() + { + return path; + } + + public Instant getOpenTime() + { + return openTime; + } + + public int getUncompressedSize() + { + return count; + } +} diff --git a/digdag-core/src/main/java/io/digdag/core/log/LocalFileLogServerFactory.java b/digdag-core/src/main/java/io/digdag/core/log/LocalFileLogServerFactory.java index 08389c02a5..d7d4a3647e 100644 --- a/digdag-core/src/main/java/io/digdag/core/log/LocalFileLogServerFactory.java +++ b/digdag-core/src/main/java/io/digdag/core/log/LocalFileLogServerFactory.java @@ -1,14 +1,12 @@ package io.digdag.core.log; -import java.util.List; -import java.util.ArrayList; -import java.util.zip.GZIPOutputStream; +import java.nio.file.FileAlreadyExistsException; +import java.util.concurrent.locks.ReentrantReadWriteLock; import java.io.InputStream; import java.io.OutputStream; import java.io.IOException; import java.io.FileNotFoundException; import java.time.Instant; -import java.time.ZoneId; import java.nio.file.FileSystems; import java.nio.file.Path; import java.nio.file.Files; @@ -21,16 +19,11 @@ import io.digdag.spi.LogServer; import io.digdag.spi.LogServerFactory; import io.digdag.spi.LogFilePrefix; -import io.digdag.spi.LogFileHandle; -import io.digdag.spi.DirectDownloadHandle; import io.digdag.spi.DirectUploadHandle; import io.digdag.spi.StorageFileNotFoundException; import io.digdag.client.config.Config; -import java.time.format.DateTimeFormatter; -import static java.util.Locale.ENGLISH; + import static java.nio.charset.StandardCharsets.UTF_8; -import static java.nio.file.StandardOpenOption.CREATE; -import static java.nio.file.StandardOpenOption.APPEND; public class LocalFileLogServerFactory implements LogServerFactory @@ -38,6 +31,7 @@ public class LocalFileLogServerFactory private static final String LOG_GZ_FILE_SUFFIX = ".log.gz"; private final Path logPath; + private final long logSplitSize; private final AgentId agentId; @Inject @@ -47,6 +41,7 @@ public LocalFileLogServerFactory(Config systemConfig, AgentId agentId) .toAbsolutePath() .normalize(); this.agentId = agentId; + this.logSplitSize = systemConfig.get("log-server.local.split_size", Long.class, 0L); } @Override @@ -70,11 +65,15 @@ class LocalFileLogServer extends AbstractFileLogServer { private final Path logPath; + private final ReentrantReadWriteLock lock; + private final ReentrantReadWriteLock.ReadLock logAppendLock; public LocalFileLogServer(Path logPath) throws IOException { this.logPath = logPath; + this.lock = new ReentrantReadWriteLock(); + this.logAppendLock = lock.readLock(); } @Override @@ -144,7 +143,7 @@ private Path getPrefixDir(String dateDir, String attemptDir) public LocalFileDirectTaskLogger newDirectTaskLogger(LogFilePrefix prefix, String taskName) { try { - return new LocalFileDirectTaskLogger(prefix, taskName); + return new LocalFileDirectTaskLogger(prefix, taskName, logSplitSize); } catch (IOException ex) { throw Throwables.propagate(ex); @@ -154,20 +153,40 @@ public LocalFileDirectTaskLogger newDirectTaskLogger(LogFilePrefix prefix, Strin class LocalFileDirectTaskLogger implements TaskLogger { - private final OutputStream output; + private CountingLogOutputStream output; + private final long splitSize;; + + private final LogFilePrefix prefix; + private final String taskName; - public LocalFileDirectTaskLogger(LogFilePrefix prefix, String taskName) + public LocalFileDirectTaskLogger(LogFilePrefix prefix, String taskName, Long splitSize) throws IOException + { + this.prefix = prefix; + this.taskName = taskName; + this.splitSize = splitSize; + + this.output = createOutput(prefix, taskName, agentId); + } + + protected CountingLogOutputStream createOutput(LogFilePrefix prefix, String taskName, AgentId agentId) + throws IOException { String dateDir = LogFiles.formatDataDir(prefix); String attemptDir = LogFiles.formatSessionAttemptDir(prefix); String fileName = LogFiles.formatFileName(taskName, Instant.now(), agentId.toString()); Path dir = getPrefixDir(dateDir, attemptDir); - Files.createDirectories(dir); + if (!Files.exists(dir)) { + try { + Files.createDirectories(dir); + } + catch (FileAlreadyExistsException e) { + // do nothing + } + } Path path = dir.resolve(fileName); - - this.output = new GZIPOutputStream(Files.newOutputStream(path, CREATE, APPEND), 16*1024); + return new CountingLogOutputStream(path); } @Override @@ -179,24 +198,51 @@ public void log(LogLevel level, long timestamp, String message) @Override public void log(byte[] data, int off, int len) + { + write(data, off, len); + } + + protected void write(byte[] data, int off, int len) { try { - output.write(data, off, len); + logAppendLock.lock(); + try { + output.write(data, off, len); + if (splitSize > 0 && output.getUncompressedSize() > splitSize) { + switchLogFile(); + } + } + finally { + logAppendLock.unlock(); + } } catch (IOException ex) { + // here can do almost nothing. adding logs to logger causes infinite loop throw Throwables.propagate(ex); } } + private void switchLogFile() + throws IOException + { + output.close(); + output = createOutput(prefix, taskName, agentId); + } + + @Override public void close() { + logAppendLock.lock(); try { output.close(); } catch (IOException ex) { throw Throwables.propagate(ex); } + finally { + logAppendLock.unlock(); + } } } } diff --git a/digdag-core/src/main/java/io/digdag/core/repository/ProjectStore.java b/digdag-core/src/main/java/io/digdag/core/repository/ProjectStore.java index 2417104440..0e4d6eaeaa 100644 --- a/digdag-core/src/main/java/io/digdag/core/repository/ProjectStore.java +++ b/digdag-core/src/main/java/io/digdag/core/repository/ProjectStore.java @@ -9,6 +9,8 @@ public interface ProjectStore { List getProjects(int pageSize, Optional lastId); + List getProjectsWithLatestRevision(int pageSize, Optional lastId); + ProjectMap getProjectsByIdList(List projIdList); StoredProject getProjectById(int projId) diff --git a/digdag-core/src/main/java/io/digdag/core/repository/StoredProjectWithRevision.java b/digdag-core/src/main/java/io/digdag/core/repository/StoredProjectWithRevision.java new file mode 100644 index 0000000000..8e40aec170 --- /dev/null +++ b/digdag-core/src/main/java/io/digdag/core/repository/StoredProjectWithRevision.java @@ -0,0 +1,46 @@ +package io.digdag.core.repository; + +import java.time.Instant; +import com.google.common.base.*; +import com.google.common.collect.*; +import com.fasterxml.jackson.databind.annotation.JsonSerialize; +import com.fasterxml.jackson.databind.annotation.JsonDeserialize; +import org.immutables.value.Value; + +@Value.Immutable +@JsonSerialize(as = ImmutableStoredProjectWithRevision.class) +@JsonDeserialize(as = ImmutableStoredProjectWithRevision.class) +public abstract class StoredProjectWithRevision + extends Project +{ + public abstract int getId(); + + public abstract int getSiteId(); + + public abstract Instant getCreatedAt(); + + public abstract Optional getDeletedAt(); + + public abstract String getRevisionName(); + + public abstract Instant getRevisionCreatedAt(); + + public abstract ArchiveType getRevisionArchiveType(); + + public abstract Optional getRevisionArchiveMd5(); + + public static StoredProjectWithRevision of(StoredProject proj, StoredRevision rev) + { + return ImmutableStoredProjectWithRevision.builder() + .from((Project)proj) + .id(proj.getId()) + .siteId(proj.getSiteId()) + .createdAt(proj.getCreatedAt()) + .deletedAt(proj.getDeletedAt()) + .revisionName(rev.getName()) + .revisionCreatedAt(rev.getCreatedAt()) + .revisionArchiveType(rev.getArchiveType()) + .revisionArchiveMd5(rev.getArchiveMd5()) + .build(); + } +} diff --git a/digdag-core/src/main/java/io/digdag/core/schedule/ScheduleConfig.java b/digdag-core/src/main/java/io/digdag/core/schedule/ScheduleConfig.java new file mode 100644 index 0000000000..3564d4db42 --- /dev/null +++ b/digdag-core/src/main/java/io/digdag/core/schedule/ScheduleConfig.java @@ -0,0 +1,27 @@ +package io.digdag.core.schedule; + +import io.digdag.client.config.Config; +import com.fasterxml.jackson.databind.annotation.JsonSerialize; +import com.fasterxml.jackson.databind.annotation.JsonDeserialize; +import org.immutables.value.Value; + +@Value.Immutable +@JsonSerialize(as = ImmutableScheduleConfig.class) +@JsonDeserialize(as = ImmutableScheduleConfig.class) +public interface ScheduleConfig +{ + boolean getEnabled(); + + static ImmutableScheduleConfig.Builder defaultBuilder() + { + return ImmutableScheduleConfig.builder() + .enabled(true); + } + + static ScheduleConfig convertFrom(Config config) + { + return defaultBuilder() + .enabled(config.get("schedule.enabled", boolean.class, true)) + .build(); + } +} diff --git a/digdag-core/src/main/java/io/digdag/core/schedule/ScheduleConfigProvider.java b/digdag-core/src/main/java/io/digdag/core/schedule/ScheduleConfigProvider.java new file mode 100644 index 0000000000..68d31ac7d9 --- /dev/null +++ b/digdag-core/src/main/java/io/digdag/core/schedule/ScheduleConfigProvider.java @@ -0,0 +1,23 @@ +package io.digdag.core.schedule; + +import com.google.inject.Inject; +import com.google.inject.Provider; +import io.digdag.client.config.Config; + +public class ScheduleConfigProvider + implements Provider +{ + private final ScheduleConfig config; + + @Inject + public ScheduleConfigProvider(Config systemConfig) + { + this.config = ScheduleConfig.convertFrom(systemConfig); + } + + @Override + public ScheduleConfig get() + { + return config; + } +} diff --git a/digdag-core/src/main/java/io/digdag/core/schedule/ScheduleExecutor.java b/digdag-core/src/main/java/io/digdag/core/schedule/ScheduleExecutor.java index ab9b39ba2f..fb56158caa 100644 --- a/digdag-core/src/main/java/io/digdag/core/schedule/ScheduleExecutor.java +++ b/digdag-core/src/main/java/io/digdag/core/schedule/ScheduleExecutor.java @@ -66,6 +66,7 @@ public class ScheduleExecutor private final AttemptBuilder attemptBuilder; private final WorkflowExecutor workflowExecutor; private final ConfigFactory cf; + private final ScheduleConfig scheduleConfig; private ScheduledExecutorService executor; @Inject(optional = true) @@ -80,7 +81,8 @@ public ScheduleExecutor( SessionStoreManager sessionStoreManager, AttemptBuilder attemptBuilder, WorkflowExecutor workflowExecutor, - ConfigFactory cf) + ConfigFactory cf, + ScheduleConfig scheduleConfig) { this.rm = rm; this.sm = sm; @@ -90,25 +92,36 @@ public ScheduleExecutor( this.attemptBuilder = attemptBuilder; this.workflowExecutor = workflowExecutor; this.cf = cf; + this.scheduleConfig = scheduleConfig; + } + + @VisibleForTesting + boolean isStarted() + { + return executor != null; } @PostConstruct public synchronized void start() { - if (executor == null) { - executor = Executors.newScheduledThreadPool(1, - new ThreadFactoryBuilder() - .setDaemon(true) - .setNameFormat("scheduler-%d") - .build() - ); + if (scheduleConfig.getEnabled()) { + if (executor == null) { + executor = Executors.newScheduledThreadPool(1, + new ThreadFactoryBuilder() + .setDaemon(true) + .setNameFormat("scheduler-%d") + .build() + ); + } + // TODO make interval configurable? + executor.scheduleWithFixedDelay(() -> runSchedules(), + 1, 1, TimeUnit.SECONDS); + // TODO make interval configurable? + executor.scheduleWithFixedDelay(() -> runDelayedAttempts(), + 1, 1, TimeUnit.SECONDS); + } else { + logger.debug("Scheduler is disabled."); } - // TODO make interval configurable? - executor.scheduleWithFixedDelay(() -> runSchedules(), - 1, 1, TimeUnit.SECONDS); - // TODO make interval configurable? - executor.scheduleWithFixedDelay(() -> runDelayedAttempts(), - 1, 1, TimeUnit.SECONDS); } @PreDestroy diff --git a/digdag-core/src/main/java/io/digdag/core/schedule/ScheduleExecutorModule.java b/digdag-core/src/main/java/io/digdag/core/schedule/ScheduleExecutorModule.java index 70fd8c9764..7a8ad599f3 100644 --- a/digdag-core/src/main/java/io/digdag/core/schedule/ScheduleExecutorModule.java +++ b/digdag-core/src/main/java/io/digdag/core/schedule/ScheduleExecutorModule.java @@ -10,6 +10,7 @@ public class ScheduleExecutorModule @Override public void configure(Binder binder) { + binder.bind(ScheduleConfig.class).toProvider(ScheduleConfigProvider.class).in(Scopes.SINGLETON); binder.bind(ScheduleExecutor.class).asEagerSingleton(); } } diff --git a/digdag-core/src/test/java/io/digdag/core/database/DatabaseProjectStoreManagerTest.java b/digdag-core/src/test/java/io/digdag/core/database/DatabaseProjectStoreManagerTest.java index f9af7c16ab..5d5484eecb 100644 --- a/digdag-core/src/test/java/io/digdag/core/database/DatabaseProjectStoreManagerTest.java +++ b/digdag-core/src/test/java/io/digdag/core/database/DatabaseProjectStoreManagerTest.java @@ -162,6 +162,9 @@ public void testGetAndNotFounds() StoredWorkflowDefinitionWithProject wfDetails3 = StoredWorkflowDefinitionWithProject.of(wf3, proj2, srcRev3); StoredWorkflowDefinitionWithProject wfDetails4 = StoredWorkflowDefinitionWithProject.of(wf4, proj2, srcRev3); + StoredProjectWithRevision proj1Rev1 = StoredProjectWithRevision.of(proj1, rev1); + StoredProjectWithRevision proj2Rev3 = StoredProjectWithRevision.of(proj2, rev3); + ProjectStore anotherSite = manager.getProjectStore(1); //// @@ -199,6 +202,11 @@ public void testGetAndNotFounds() assertEquals(ImmutableList.of(proj2), store.getProjects(100, Optional.of(proj1.getId()))); assertEmpty(anotherSite.getProjects(100, Optional.absent())); + assertEquals(ImmutableList.of(proj1Rev1, proj2Rev3), store.getProjectsWithLatestRevision(100, Optional.absent())); + assertEquals(ImmutableList.of(proj1Rev1), store.getProjectsWithLatestRevision(1, Optional.absent())); + assertEquals(ImmutableList.of(proj2Rev3), store.getProjectsWithLatestRevision(100, Optional.of(proj1.getId()))); + assertEmpty(anotherSite.getProjectsWithLatestRevision(100, Optional.absent())); + assertEquals(ImmutableList.of(rev3, rev2), store.getRevisions(proj2.getId(), 100, Optional.absent())); // revision is returned in reverse order assertEquals(ImmutableList.of(rev3), store.getRevisions(proj2.getId(), 1, Optional.absent())); assertEquals(ImmutableList.of(rev2), store.getRevisions(proj2.getId(), 100, Optional.of(rev3.getId()))); @@ -328,6 +336,7 @@ public void testDeleteProject() // listing doesn't include deleted projects assertEquals(ImmutableList.of(), store.getProjects(100, Optional.absent())); + assertEquals(ImmutableList.of(), store.getProjectsWithLatestRevision(100, Optional.absent())); assertEquals(ImmutableList.of(), store.getLatestActiveWorkflowDefinitions(100, Optional.absent())); // lookup by project/revision id succeeds and deletedAt is set diff --git a/digdag-core/src/test/java/io/digdag/core/database/DatabaseTestingUtils.java b/digdag-core/src/test/java/io/digdag/core/database/DatabaseTestingUtils.java index a185ccaac1..bca6cc4b02 100644 --- a/digdag-core/src/test/java/io/digdag/core/database/DatabaseTestingUtils.java +++ b/digdag-core/src/test/java/io/digdag/core/database/DatabaseTestingUtils.java @@ -59,6 +59,8 @@ public static DatabaseConfig getEnvironmentDatabaseConfig() .validationTimeout(5) .minimumPoolSize(0) .maximumPoolSize(10) + .enableJMX(false) + .leakDetectionThreshold(0) .build(); } } diff --git a/digdag-core/src/test/java/io/digdag/core/log/LocalFileLogServerFactoryTest.java b/digdag-core/src/test/java/io/digdag/core/log/LocalFileLogServerFactoryTest.java new file mode 100644 index 0000000000..9826d2fbf0 --- /dev/null +++ b/digdag-core/src/test/java/io/digdag/core/log/LocalFileLogServerFactoryTest.java @@ -0,0 +1,145 @@ +package io.digdag.core.log; + +import io.digdag.client.DigdagClient; +import io.digdag.client.config.Config; +import io.digdag.client.config.ConfigFactory; +import io.digdag.core.agent.AgentId; +import io.digdag.core.config.PropertyUtils; +import io.digdag.spi.LogFilePrefix; +import org.junit.Before; +import org.junit.Rule; +import org.junit.Test; +import org.junit.rules.TemporaryFolder; +import static org.hamcrest.Matchers.is; +import static org.junit.Assert.assertThat; + + +import java.io.File; +import java.io.IOException; +import java.nio.file.Path; +import java.time.Instant; +import java.time.ZoneId; +import com.google.common.base.Optional; +import java.util.Properties; + +import static java.nio.charset.StandardCharsets.UTF_8; + +import io.digdag.core.log.LocalFileLogServerFactory.LocalFileLogServer.LocalFileDirectTaskLogger; + +public class LocalFileLogServerFactoryTest +{ + private static final ConfigFactory CONFIG_FACTORY = new ConfigFactory(DigdagClient.objectMapper()); + + @Rule + public TemporaryFolder tempFolder = new TemporaryFolder(); + + Path taskLogPath; + Properties props; + Config systemConfig; + LocalFileLogServerFactory logServerFactory; + LocalFileLogServerFactory.LocalFileLogServer localServer; + + LogFilePrefix prefix = LogFilePrefix.builder() + .createdAt(Instant.now()) + .retryAttemptName(Optional.absent()) + .projectId(1) + .sessionTime(Instant.now()) + .siteId(1) + .timeZone(ZoneId.systemDefault()) + .workflowName("test1") + .build(); + LocalFileDirectTaskLogger taskLogger; + + @Before + public void setUp() throws IOException + { + taskLogPath = tempFolder.newFolder("task_logs").toPath(); + } + + private void setUpTaskLogger(Optional size) + { + props = new Properties(); + props.setProperty("log-server.local.path", taskLogPath.toString()); + if (size.isPresent()) { + props.setProperty("log-server.local.split_size", size.get()); + } + else { + } + systemConfig = PropertyUtils.toConfigElement(props).toConfig(CONFIG_FACTORY); + System.out.println(systemConfig); + logServerFactory = new LocalFileLogServerFactory(systemConfig, AgentId.of("agentA")); + localServer = (LocalFileLogServerFactory.LocalFileLogServer) logServerFactory.getLogServer(); + taskLogger = localServer.newDirectTaskLogger(prefix, "+task1"); + } + + @Test + public void checkSplitSize() + { + setUpTaskLogger(Optional.of("100")); + String msg = repeatedString("a", 51); + for (int i = 0; i < 100; i++) { + taskLogger.log(msg.getBytes(UTF_8), 0, msg.length()); + } + taskLogger.close(); + for (File f : taskLogPath.toFile().listFiles()) { + for (File f2: f.listFiles()) { + File[] taskLogs = f2.listFiles(); + for (File f3: taskLogs) { + System.out.println(f3); + } + assertThat("log file should be splitted", f2.listFiles().length > 1, is(true)); + } + } + } + + @Test + public void checkSplitSizeIsZero() + { + setUpTaskLogger(Optional.of("0")); + + String msg = repeatedString("a", 51); + for (int i = 0; i < 100; i++) { + taskLogger.log(msg.getBytes(UTF_8), 0, msg.length()); + } + taskLogger.close(); + for (File f : taskLogPath.toFile().listFiles()) { + for (File f2: f.listFiles()) { + File[] taskLogs = f2.listFiles(); + for (File f3: taskLogs) { + System.out.println(f3); + } + assertThat("log file should be a file", f2.listFiles().length, is(1)); + } + } + } + + @Test + public void checkNoSplitSize() + { + setUpTaskLogger(Optional.absent()); + + String msg = repeatedString("a", 51); + for (int i = 0; i < 100; i++) { + taskLogger.log(msg.getBytes(UTF_8), 0, msg.length()); + } + taskLogger.close(); + for (File f : taskLogPath.toFile().listFiles()) { + for (File f2: f.listFiles()) { + File[] taskLogs = f2.listFiles(); + for (File f3: taskLogs) { + System.out.println(f3); + } + assertThat("log file should be a file", f2.listFiles().length, is(1)); + } + } + } + + private String repeatedString(String v, int num) + { + StringBuilder b = new StringBuilder(); + for (int i = 0; i < num; i++) { + b.append(v); + } + return b.toString(); + } +} diff --git a/digdag-core/src/test/java/io/digdag/core/schedule/ScheduleExecutorTest.java b/digdag-core/src/test/java/io/digdag/core/schedule/ScheduleExecutorTest.java index be9924d29b..600916d50c 100644 --- a/digdag-core/src/test/java/io/digdag/core/schedule/ScheduleExecutorTest.java +++ b/digdag-core/src/test/java/io/digdag/core/schedule/ScheduleExecutorTest.java @@ -29,6 +29,7 @@ import java.time.Instant; import static java.time.ZoneOffset.UTC; +import static org.junit.Assert.assertFalse; import static org.mockito.Matchers.any; import static org.mockito.Matchers.anyInt; import static org.mockito.Matchers.eq; @@ -65,6 +66,7 @@ public class ScheduleExecutorTest @Mock AttemptBuilder attemptBuilder; @Mock WorkflowExecutor workflowExecutor; @Mock DataSource dataSource; + @Mock ScheduleConfig scheduleConfig; private ScheduleExecutor scheduleExecutor; @@ -85,7 +87,8 @@ public void setUp() sessionStoreManager, attemptBuilder, workflowExecutor, - CONFIG_FACTORY + CONFIG_FACTORY, + scheduleConfig )); now = Instant.now(); @@ -232,4 +235,17 @@ public void testNoSkipDelayedBy() verify(scs).updateNextScheduleTimeAndLastSessionTime(SCHEDULE_ID, nextScheduleTime, now); } + @Test + public void testDisabled() + throws Exception + { + // Disable scheduler + when(scheduleConfig.getEnabled()).thenReturn(false); + + // Trying to start the schedule executor. + scheduleExecutor.start(); + + // Executor is not started. + assertFalse(scheduleExecutor.isStarted()); + } } diff --git a/digdag-core/src/test/java/io/digdag/core/workflow/WorkflowExecutorTest.java b/digdag-core/src/test/java/io/digdag/core/workflow/WorkflowExecutorTest.java index 6d2897d816..b38d97862b 100644 --- a/digdag-core/src/test/java/io/digdag/core/workflow/WorkflowExecutorTest.java +++ b/digdag-core/src/test/java/io/digdag/core/workflow/WorkflowExecutorTest.java @@ -6,7 +6,8 @@ import java.util.ArrayList; import java.util.Arrays; import java.util.List; - +import java.time.Duration; +import java.time.Instant; import com.google.common.io.Resources; import io.digdag.core.config.YamlConfigLoader; import io.digdag.core.database.TransactionManager; @@ -28,6 +29,7 @@ import static io.digdag.core.workflow.WorkflowTestingUtils.setupEmbed; import static io.digdag.core.workflow.WorkflowTestingUtils.loadYamlResource; import static org.hamcrest.Matchers.greaterThanOrEqualTo; +import static org.hamcrest.Matchers.lessThanOrEqualTo; import static org.junit.Assert.*; import static org.hamcrest.Matchers.is; @@ -127,6 +129,20 @@ public TestSet(String retryStatement, int minWaitSecs) } } + @Test + public void retryExponential() + throws Exception + { + Instant start = Instant.now(); + runWorkflow("retry_exponential", loadYamlResource("/io/digdag/core/workflow/retry_exponential.dig")); + Instant end = Instant.now(); + Duration duration = Duration.between(start, end); + // Duration should be longer than 11 sec and shorter than 63 sec: + // with max_interval: 2: [1, 2, 2, 2, 2, 2].sum => 11 + // without max_interval: [1, 2, 4, 8, 16, 32].sum => 63 + assertThat(duration.getSeconds(), greaterThanOrEqualTo(11L)); + assertThat(duration.getSeconds(), lessThanOrEqualTo(63L)); + } @Test public void retryInCall() diff --git a/digdag-core/src/test/resources/io/digdag/core/workflow/retry_exponential.dig b/digdag-core/src/test/resources/io/digdag/core/workflow/retry_exponential.dig new file mode 100644 index 0000000000..c98b896b95 --- /dev/null +++ b/digdag-core/src/test/resources/io/digdag/core/workflow/retry_exponential.dig @@ -0,0 +1,8 @@ ++retrying: + _retry: + interval_type: exponential + limit: 6 + interval: 1 + max_interval: 2 + +fail: + fail>: task failed expectedly at ${moment().valueOf() / 1000} diff --git a/digdag-docs/Makefile b/digdag-docs/Makefile index 61159aaae6..ee230164de 100644 --- a/digdag-docs/Makefile +++ b/digdag-docs/Makefile @@ -1,193 +1,20 @@ -# Makefile for Sphinx documentation +# Minimal makefile for Sphinx documentation # -# You can set these variables from the command line. -SPHINXOPTS = -SPHINXENV = LC_ALL=en_US.UTF-8 -SPHINXBUILD = sphinx-build -PAPER = +# You can set these variables from the command line, and also +# from the environment for the first two. +SPHINXOPTS ?= +SPHINXBUILD ?= sphinx-build +SOURCEDIR = src BUILDDIR = build -# User-friendly check for sphinx-build -ifeq ($(shell which $(SPHINXBUILD) >/dev/null 2>&1; echo $$?), 1) -$(error The '$(SPHINXBUILD)' command was not found. Make sure you have Sphinx installed, then set the SPHINXBUILD environment variable to point to the full path of the '$(SPHINXBUILD)' executable. Alternatively you can add the directory with the executable to your PATH. If you don't have Sphinx installed, grab it from http://sphinx-doc.org/) -endif - -# Internal variables. -PAPEROPT_a4 = -D latex_paper_size=a4 -PAPEROPT_letter = -D latex_paper_size=letter -ALLSPHINXOPTS = -d $(BUILDDIR)/doctrees $(PAPEROPT_$(PAPER)) $(SPHINXOPTS) src -# the i18n builder cannot share the environment and doctrees with the others -I18NSPHINXOPTS = $(PAPEROPT_$(PAPER)) $(SPHINXOPTS) src - -.PHONY: help clean html dirhtml singlehtml pickle json htmlhelp qthelp devhelp epub latex latexpdf text man changes linkcheck doctest coverage gettext - +# Put it first so that "make" without argument is like "make help". help: - @echo "Please use \`make ' where is one of" - @echo " html to make standalone HTML files" - @echo " dirhtml to make HTML files named index.html in directories" - @echo " singlehtml to make a single large HTML file" - @echo " pickle to make pickle files" - @echo " json to make JSON files" - @echo " htmlhelp to make HTML files and a HTML help project" - @echo " qthelp to make HTML files and a qthelp project" - @echo " applehelp to make an Apple Help Book" - @echo " devhelp to make HTML files and a Devhelp project" - @echo " epub to make an epub" - @echo " latex to make LaTeX files, you can set PAPER=a4 or PAPER=letter" - @echo " latexpdf to make LaTeX files and run them through pdflatex" - @echo " latexpdfja to make LaTeX files and run them through platex/dvipdfmx" - @echo " text to make text files" - @echo " man to make manual pages" - @echo " texinfo to make Texinfo files" - @echo " info to make Texinfo files and run them through makeinfo" - @echo " gettext to make PO message catalogs" - @echo " changes to make an overview of all changed/added/deprecated items" - @echo " xml to make Docutils-native XML files" - @echo " pseudoxml to make pseudoxml-XML files for display purposes" - @echo " linkcheck to check all external links for integrity" - @echo " doctest to run all doctests embedded in the documentation (if enabled)" - @echo " coverage to run coverage check of the documentation (if enabled)" - -clean: - rm -rf $(BUILDDIR)/* - -html: - $(SPHINXENV) $(SPHINXBUILD) -b html $(ALLSPHINXOPTS) $(BUILDDIR)/html - @echo - @echo "Build finished. The HTML pages are in $(BUILDDIR)/html." - -dirhtml: - $(SPHINXENV) $(SPHINXBUILD) -b dirhtml $(ALLSPHINXOPTS) $(BUILDDIR)/dirhtml - @echo - @echo "Build finished. The HTML pages are in $(BUILDDIR)/dirhtml." - -singlehtml: - $(SPHINXENV) $(SPHINXBUILD) -b singlehtml $(ALLSPHINXOPTS) $(BUILDDIR)/singlehtml - @echo - @echo "Build finished. The HTML page is in $(BUILDDIR)/singlehtml." - -pickle: - $(SPHINXENV) $(SPHINXBUILD) -b pickle $(ALLSPHINXOPTS) $(BUILDDIR)/pickle - @echo - @echo "Build finished; now you can process the pickle files." - -json: - $(SPHINXENV) $(SPHINXBUILD) -b json $(ALLSPHINXOPTS) $(BUILDDIR)/json - @echo - @echo "Build finished; now you can process the JSON files." - -htmlhelp: - $(SPHINXENV) $(SPHINXBUILD) -b htmlhelp $(ALLSPHINXOPTS) $(BUILDDIR)/htmlhelp - @echo - @echo "Build finished; now you can run HTML Help Workshop with the" \ - ".hhp project file in $(BUILDDIR)/htmlhelp." - -qthelp: - $(SPHINXENV) $(SPHINXBUILD) -b qthelp $(ALLSPHINXOPTS) $(BUILDDIR)/qthelp - @echo - @echo "Build finished; now you can run "qcollectiongenerator" with the" \ - ".qhcp project file in $(BUILDDIR)/qthelp, like this:" - @echo "# qcollectiongenerator $(BUILDDIR)/qthelp/Digdag.qhcp" - @echo "To view the help file:" - @echo "# assistant -collectionFile $(BUILDDIR)/qthelp/Digdag.qhc" - -applehelp: - $(SPHINXENV) $(SPHINXBUILD) -b applehelp $(ALLSPHINXOPTS) $(BUILDDIR)/applehelp - @echo - @echo "Build finished. The help book is in $(BUILDDIR)/applehelp." - @echo "N.B. You won't be able to view it unless you put it in" \ - "~/Library/Documentation/Help or install it in your application" \ - "bundle." - -devhelp: - $(SPHINXENV) $(SPHINXBUILD) -b devhelp $(ALLSPHINXOPTS) $(BUILDDIR)/devhelp - @echo - @echo "Build finished." - @echo "To view the help file:" - @echo "# mkdir -p $$HOME/.local/share/devhelp/Digdag" - @echo "# ln -s $(BUILDDIR)/devhelp $$HOME/.local/share/devhelp/Digdag" - @echo "# devhelp" - -epub: - $(SPHINXENV) $(SPHINXBUILD) -b epub $(ALLSPHINXOPTS) $(BUILDDIR)/epub - @echo - @echo "Build finished. The epub file is in $(BUILDDIR)/epub." - -latex: - $(SPHINXENV) $(SPHINXBUILD) -b latex $(ALLSPHINXOPTS) $(BUILDDIR)/latex - @echo - @echo "Build finished; the LaTeX files are in $(BUILDDIR)/latex." - @echo "Run \`make' in that directory to run these through (pdf)latex" \ - "(use \`make latexpdf' here to do that automatically)." - -latexpdf: - $(SPHINXENV) $(SPHINXBUILD) -b latex $(ALLSPHINXOPTS) $(BUILDDIR)/latex - @echo "Running LaTeX files through pdflatex..." - $(MAKE) -C $(BUILDDIR)/latex all-pdf - @echo "pdflatex finished; the PDF files are in $(BUILDDIR)/latex." - -latexpdfja: - $(SPHINXENV) $(SPHINXBUILD) -b latex $(ALLSPHINXOPTS) $(BUILDDIR)/latex - @echo "Running LaTeX files through platex and dvipdfmx..." - $(MAKE) -C $(BUILDDIR)/latex all-pdf-ja - @echo "pdflatex finished; the PDF files are in $(BUILDDIR)/latex." - -text: - $(SPHINXENV) $(SPHINXBUILD) -b text $(ALLSPHINXOPTS) $(BUILDDIR)/text - @echo - @echo "Build finished. The text files are in $(BUILDDIR)/text." - -man: - $(SPHINXENV) $(SPHINXBUILD) -b man $(ALLSPHINXOPTS) $(BUILDDIR)/man - @echo - @echo "Build finished. The manual pages are in $(BUILDDIR)/man." - -texinfo: - $(SPHINXENV) $(SPHINXBUILD) -b texinfo $(ALLSPHINXOPTS) $(BUILDDIR)/texinfo - @echo - @echo "Build finished. The Texinfo files are in $(BUILDDIR)/texinfo." - @echo "Run \`make' in that directory to run these through makeinfo" \ - "(use \`make info' here to do that automatically)." - -info: - $(SPHINXENV) $(SPHINXBUILD) -b texinfo $(ALLSPHINXOPTS) $(BUILDDIR)/texinfo - @echo "Running Texinfo files through makeinfo..." - make -C $(BUILDDIR)/texinfo info - @echo "makeinfo finished; the Info files are in $(BUILDDIR)/texinfo." - -gettext: - $(SPHINXENV) $(SPHINXBUILD) -b gettext $(I18NSPHINXOPTS) $(BUILDDIR)/locale - @echo - @echo "Build finished. The message catalogs are in $(BUILDDIR)/locale." - -changes: - $(SPHINXENV) $(SPHINXBUILD) -b changes $(ALLSPHINXOPTS) $(BUILDDIR)/changes - @echo - @echo "The overview file is in $(BUILDDIR)/changes." - -linkcheck: - $(SPHINXENV) $(SPHINXBUILD) -b linkcheck $(ALLSPHINXOPTS) $(BUILDDIR)/linkcheck - @echo - @echo "Link check complete; look for any errors in the above output " \ - "or in $(BUILDDIR)/linkcheck/output.txt." - -doctest: - $(SPHINXENV) $(SPHINXBUILD) -b doctest $(ALLSPHINXOPTS) $(BUILDDIR)/doctest - @echo "Testing of doctests in the sources finished, look at the " \ - "results in $(BUILDDIR)/doctest/output.txt." - -coverage: - $(SPHINXENV) $(SPHINXBUILD) -b coverage $(ALLSPHINXOPTS) $(BUILDDIR)/coverage - @echo "Testing of coverage in the sources finished, look at the " \ - "results in $(BUILDDIR)/coverage/python.txt." + @$(SPHINXBUILD) -M help "$(SOURCEDIR)" "$(BUILDDIR)" $(SPHINXOPTS) $(O) -xml: - $(SPHINXENV) $(SPHINXBUILD) -b xml $(ALLSPHINXOPTS) $(BUILDDIR)/xml - @echo - @echo "Build finished. The XML files are in $(BUILDDIR)/xml." +.PHONY: help Makefile -pseudoxml: - $(SPHINXENV) $(SPHINXBUILD) -b pseudoxml $(ALLSPHINXOPTS) $(BUILDDIR)/pseudoxml - @echo - @echo "Build finished. The pseudo-XML files are in $(BUILDDIR)/pseudoxml." +# Catch-all target: route all unknown targets to Sphinx using the new +# "make mode" option. $(O) is meant as a shortcut for $(SPHINXOPTS). +%: Makefile + @$(SPHINXBUILD) -M $@ "$(SOURCEDIR)" "$(BUILDDIR)" $(SPHINXOPTS) $(O) diff --git a/digdag-docs/constraints.txt b/digdag-docs/constraints.txt new file mode 100644 index 0000000000..835cd69e48 --- /dev/null +++ b/digdag-docs/constraints.txt @@ -0,0 +1,28 @@ +alabaster==0.7.12 +Babel==2.7.0 +certifi==2019.3.9 +chardet==3.0.4 +commonmark==0.9.0 +docutils==0.14 +future==0.17.1 +idna==2.8 +imagesize==1.1.0 +Jinja2==2.10.1 +MarkupSafe==1.1.1 +packaging==19.0 +Pygments==2.4.2 +pyparsing==2.4.0 +pytz==2019.1 +recommonmark==0.5.0 +requests==2.22.0 +six==1.12.0 +snowballstemmer==1.2.1 +Sphinx==2.1.1 +sphinx-rtd-theme==0.4.3 +sphinxcontrib-applehelp==1.0.1 +sphinxcontrib-devhelp==1.0.1 +sphinxcontrib-htmlhelp==1.0.2 +sphinxcontrib-jsmath==1.0.1 +sphinxcontrib-qthelp==1.0.2 +sphinxcontrib-serializinghtml==1.1.3 +urllib3==1.25.3 diff --git a/digdag-docs/make.bat b/digdag-docs/make.bat index cd89c194ef..6247f7e231 100644 --- a/digdag-docs/make.bat +++ b/digdag-docs/make.bat @@ -1,62 +1,18 @@ @ECHO OFF +pushd %~dp0 + REM Command file for Sphinx documentation if "%SPHINXBUILD%" == "" ( set SPHINXBUILD=sphinx-build ) +set SOURCEDIR=source set BUILDDIR=build -set ALLSPHINXOPTS=-d %BUILDDIR%/doctrees %SPHINXOPTS% source -set I18NSPHINXOPTS=%SPHINXOPTS% source -if NOT "%PAPER%" == "" ( - set ALLSPHINXOPTS=-D latex_paper_size=%PAPER% %ALLSPHINXOPTS% - set I18NSPHINXOPTS=-D latex_paper_size=%PAPER% %I18NSPHINXOPTS% -) if "%1" == "" goto help -if "%1" == "help" ( - :help - echo.Please use `make ^` where ^ is one of - echo. html to make standalone HTML files - echo. dirhtml to make HTML files named index.html in directories - echo. singlehtml to make a single large HTML file - echo. pickle to make pickle files - echo. json to make JSON files - echo. htmlhelp to make HTML files and a HTML help project - echo. qthelp to make HTML files and a qthelp project - echo. devhelp to make HTML files and a Devhelp project - echo. epub to make an epub - echo. latex to make LaTeX files, you can set PAPER=a4 or PAPER=letter - echo. text to make text files - echo. man to make manual pages - echo. texinfo to make Texinfo files - echo. gettext to make PO message catalogs - echo. changes to make an overview over all changed/added/deprecated items - echo. xml to make Docutils-native XML files - echo. pseudoxml to make pseudoxml-XML files for display purposes - echo. linkcheck to check all external links for integrity - echo. doctest to run all doctests embedded in the documentation if enabled - echo. coverage to run coverage check of the documentation if enabled - goto end -) - -if "%1" == "clean" ( - for /d %%i in (%BUILDDIR%\*) do rmdir /q /s %%i - del /q /s %BUILDDIR%\* - goto end -) - - -REM Check if sphinx-build is available and fallback to Python version if any -%SPHINXBUILD% 2> nul -if errorlevel 9009 goto sphinx_python -goto sphinx_ok - -:sphinx_python - -set SPHINXBUILD=python -m sphinx.__init__ -%SPHINXBUILD% 2> nul +%SPHINXBUILD% >NUL 2>NUL if errorlevel 9009 ( echo. echo.The 'sphinx-build' command was not found. Make sure you have Sphinx @@ -69,195 +25,11 @@ if errorlevel 9009 ( exit /b 1 ) -:sphinx_ok - - -if "%1" == "html" ( - %SPHINXBUILD% -b html %ALLSPHINXOPTS% %BUILDDIR%/html - if errorlevel 1 exit /b 1 - echo. - echo.Build finished. The HTML pages are in %BUILDDIR%/html. - goto end -) - -if "%1" == "dirhtml" ( - %SPHINXBUILD% -b dirhtml %ALLSPHINXOPTS% %BUILDDIR%/dirhtml - if errorlevel 1 exit /b 1 - echo. - echo.Build finished. The HTML pages are in %BUILDDIR%/dirhtml. - goto end -) - -if "%1" == "singlehtml" ( - %SPHINXBUILD% -b singlehtml %ALLSPHINXOPTS% %BUILDDIR%/singlehtml - if errorlevel 1 exit /b 1 - echo. - echo.Build finished. The HTML pages are in %BUILDDIR%/singlehtml. - goto end -) - -if "%1" == "pickle" ( - %SPHINXBUILD% -b pickle %ALLSPHINXOPTS% %BUILDDIR%/pickle - if errorlevel 1 exit /b 1 - echo. - echo.Build finished; now you can process the pickle files. - goto end -) - -if "%1" == "json" ( - %SPHINXBUILD% -b json %ALLSPHINXOPTS% %BUILDDIR%/json - if errorlevel 1 exit /b 1 - echo. - echo.Build finished; now you can process the JSON files. - goto end -) - -if "%1" == "htmlhelp" ( - %SPHINXBUILD% -b htmlhelp %ALLSPHINXOPTS% %BUILDDIR%/htmlhelp - if errorlevel 1 exit /b 1 - echo. - echo.Build finished; now you can run HTML Help Workshop with the ^ -.hhp project file in %BUILDDIR%/htmlhelp. - goto end -) +%SPHINXBUILD% -M %1 %SOURCEDIR% %BUILDDIR% %SPHINXOPTS% %O% +goto end -if "%1" == "qthelp" ( - %SPHINXBUILD% -b qthelp %ALLSPHINXOPTS% %BUILDDIR%/qthelp - if errorlevel 1 exit /b 1 - echo. - echo.Build finished; now you can run "qcollectiongenerator" with the ^ -.qhcp project file in %BUILDDIR%/qthelp, like this: - echo.^> qcollectiongenerator %BUILDDIR%\qthelp\Digdag.qhcp - echo.To view the help file: - echo.^> assistant -collectionFile %BUILDDIR%\qthelp\Digdag.ghc - goto end -) - -if "%1" == "devhelp" ( - %SPHINXBUILD% -b devhelp %ALLSPHINXOPTS% %BUILDDIR%/devhelp - if errorlevel 1 exit /b 1 - echo. - echo.Build finished. - goto end -) - -if "%1" == "epub" ( - %SPHINXBUILD% -b epub %ALLSPHINXOPTS% %BUILDDIR%/epub - if errorlevel 1 exit /b 1 - echo. - echo.Build finished. The epub file is in %BUILDDIR%/epub. - goto end -) - -if "%1" == "latex" ( - %SPHINXBUILD% -b latex %ALLSPHINXOPTS% %BUILDDIR%/latex - if errorlevel 1 exit /b 1 - echo. - echo.Build finished; the LaTeX files are in %BUILDDIR%/latex. - goto end -) - -if "%1" == "latexpdf" ( - %SPHINXBUILD% -b latex %ALLSPHINXOPTS% %BUILDDIR%/latex - cd %BUILDDIR%/latex - make all-pdf - cd %~dp0 - echo. - echo.Build finished; the PDF files are in %BUILDDIR%/latex. - goto end -) - -if "%1" == "latexpdfja" ( - %SPHINXBUILD% -b latex %ALLSPHINXOPTS% %BUILDDIR%/latex - cd %BUILDDIR%/latex - make all-pdf-ja - cd %~dp0 - echo. - echo.Build finished; the PDF files are in %BUILDDIR%/latex. - goto end -) - -if "%1" == "text" ( - %SPHINXBUILD% -b text %ALLSPHINXOPTS% %BUILDDIR%/text - if errorlevel 1 exit /b 1 - echo. - echo.Build finished. The text files are in %BUILDDIR%/text. - goto end -) - -if "%1" == "man" ( - %SPHINXBUILD% -b man %ALLSPHINXOPTS% %BUILDDIR%/man - if errorlevel 1 exit /b 1 - echo. - echo.Build finished. The manual pages are in %BUILDDIR%/man. - goto end -) - -if "%1" == "texinfo" ( - %SPHINXBUILD% -b texinfo %ALLSPHINXOPTS% %BUILDDIR%/texinfo - if errorlevel 1 exit /b 1 - echo. - echo.Build finished. The Texinfo files are in %BUILDDIR%/texinfo. - goto end -) - -if "%1" == "gettext" ( - %SPHINXBUILD% -b gettext %I18NSPHINXOPTS% %BUILDDIR%/locale - if errorlevel 1 exit /b 1 - echo. - echo.Build finished. The message catalogs are in %BUILDDIR%/locale. - goto end -) - -if "%1" == "changes" ( - %SPHINXBUILD% -b changes %ALLSPHINXOPTS% %BUILDDIR%/changes - if errorlevel 1 exit /b 1 - echo. - echo.The overview file is in %BUILDDIR%/changes. - goto end -) - -if "%1" == "linkcheck" ( - %SPHINXBUILD% -b linkcheck %ALLSPHINXOPTS% %BUILDDIR%/linkcheck - if errorlevel 1 exit /b 1 - echo. - echo.Link check complete; look for any errors in the above output ^ -or in %BUILDDIR%/linkcheck/output.txt. - goto end -) - -if "%1" == "doctest" ( - %SPHINXBUILD% -b doctest %ALLSPHINXOPTS% %BUILDDIR%/doctest - if errorlevel 1 exit /b 1 - echo. - echo.Testing of doctests in the sources finished, look at the ^ -results in %BUILDDIR%/doctest/output.txt. - goto end -) - -if "%1" == "coverage" ( - %SPHINXBUILD% -b coverage %ALLSPHINXOPTS% %BUILDDIR%/coverage - if errorlevel 1 exit /b 1 - echo. - echo.Testing of coverage in the sources finished, look at the ^ -results in %BUILDDIR%/coverage/python.txt. - goto end -) - -if "%1" == "xml" ( - %SPHINXBUILD% -b xml %ALLSPHINXOPTS% %BUILDDIR%/xml - if errorlevel 1 exit /b 1 - echo. - echo.Build finished. The XML files are in %BUILDDIR%/xml. - goto end -) - -if "%1" == "pseudoxml" ( - %SPHINXBUILD% -b pseudoxml %ALLSPHINXOPTS% %BUILDDIR%/pseudoxml - if errorlevel 1 exit /b 1 - echo. - echo.Build finished. The pseudo-XML files are in %BUILDDIR%/pseudoxml. - goto end -) +:help +%SPHINXBUILD% -M help %SOURCEDIR% %BUILDDIR% %SPHINXOPTS% %O% :end +popd diff --git a/digdag-docs/requirements.txt b/digdag-docs/requirements.txt new file mode 100644 index 0000000000..2866521234 --- /dev/null +++ b/digdag-docs/requirements.txt @@ -0,0 +1,3 @@ +sphinx +recommonmark +sphinx_rtd_theme diff --git a/digdag-docs/src/_extra/api/index.html b/digdag-docs/src/_extra/api/index.html new file mode 100644 index 0000000000..6075dbdbf3 --- /dev/null +++ b/digdag-docs/src/_extra/api/index.html @@ -0,0 +1,48 @@ + + + + + + + + +
+ Digdag logo +
+
+ + + + diff --git a/digdag-docs/src/_extra/api/swagger.yaml b/digdag-docs/src/_extra/api/swagger.yaml new file mode 100644 index 0000000000..b2506cc95a --- /dev/null +++ b/digdag-docs/src/_extra/api/swagger.yaml @@ -0,0 +1,1711 @@ +--- +swagger: "2.0" +info: + description: "Digdag server API" + version: "0.9.41-SNAPSHOT" + title: "Digdag" +tags: +- name: "Schedule" +- name: "Project" +- name: "Attempt" +- name: "Admin" +- name: "Workflow" +- name: "Log" +- name: "Session" +- name: "Version" +paths: + /api/admin/attempts/{id}/userinfo: + get: + tags: + - "Admin" + operationId: "getUserInfo" + produces: + - "application/json" + parameters: + - name: "id" + in: "path" + required: true + type: "integer" + format: "int64" + responses: + 200: + description: "successful operation" + schema: + $ref: "#/definitions/Config" + headers: {} + /api/attempts: + get: + tags: + - "Attempt" + summary: "List attempts with filters" + description: "" + operationId: "getAttempts" + produces: + - "application/json" + parameters: + - name: "project" + in: "query" + description: "exact matching filter on project name" + required: false + type: "string" + - name: "workflow" + in: "query" + description: "exact matching filter on workflow name" + required: false + type: "string" + - name: "include_retried" + in: "query" + description: "list more than 1 attempts per session" + required: false + type: "boolean" + - name: "last_id" + in: "query" + description: "list attempts whose id is grater than this id for pagination" + required: false + type: "integer" + format: "int64" + - name: "page_size" + in: "query" + description: "number of attempts to return" + required: false + type: "integer" + format: "int32" + responses: + 200: + description: "successful operation" + schema: + $ref: "#/definitions/RestSessionAttemptCollection" + put: + tags: + - "Attempt" + summary: "Start a workflow execution as a new session or a new attempt of an\ + \ existing session" + description: "" + operationId: "startAttempt" + consumes: + - "application/json" + produces: + - "application/json" + parameters: + - in: "body" + name: "body" + required: false + schema: + $ref: "#/definitions/RestSessionAttemptRequest" + responses: + default: + description: "successful operation" + /api/attempts/{id}: + get: + tags: + - "Attempt" + summary: "Get an attempt" + description: "" + operationId: "getAttempt" + produces: + - "application/json" + parameters: + - name: "id" + in: "path" + description: "attempt id" + required: true + type: "integer" + format: "int64" + responses: + 200: + description: "successful operation" + schema: + $ref: "#/definitions/RestSessionAttempt" + /api/attempts/{id}/kill: + post: + tags: + - "Attempt" + summary: "Set a cancel-requested flag on a running attempt" + description: "" + operationId: "killAttempt" + consumes: + - "application/json" + produces: + - "application/json" + parameters: + - name: "id" + in: "path" + description: "attempt id" + required: true + type: "integer" + format: "int64" + responses: + default: + description: "successful operation" + /api/attempts/{id}/retries: + get: + tags: + - "Attempt" + summary: "List attempts of a session of a given attempt" + description: "" + operationId: "getAttemptRetries" + produces: + - "application/json" + parameters: + - name: "id" + in: "path" + description: "attempt id" + required: true + type: "integer" + format: "int64" + responses: + 200: + description: "successful operation" + schema: + $ref: "#/definitions/RestSessionAttemptCollection" + /api/attempts/{id}/tasks: + get: + tags: + - "Attempt" + summary: "List tasks of an attempt" + description: "" + operationId: "getTasks" + produces: + - "application/json" + parameters: + - name: "id" + in: "path" + description: "attempt id" + required: true + type: "integer" + format: "int64" + responses: + 200: + description: "successful operation" + schema: + $ref: "#/definitions/RestTaskCollection" + /api/logs/{attempt_id}/files: + get: + tags: + - "Log" + summary: "List log files of an attempt with filters" + description: "" + operationId: "getFileHandles" + produces: + - "application/json" + parameters: + - name: "attempt_id" + in: "path" + description: "attempt id" + required: true + type: "integer" + format: "int64" + - name: "task" + in: "query" + description: "partial prefix match filter on task name" + required: false + type: "string" + responses: + 200: + description: "successful operation" + schema: + $ref: "#/definitions/RestLogFileHandleCollection" + put: + tags: + - "Log" + operationId: "putFile" + consumes: + - "application/gzip" + produces: + - "application/json" + parameters: + - name: "attempt_id" + in: "path" + required: true + type: "integer" + format: "int64" + - name: "task" + in: "query" + required: false + type: "string" + - name: "file_time" + in: "query" + required: false + type: "integer" + format: "int64" + - name: "node_id" + in: "query" + required: false + type: "string" + - in: "body" + name: "body" + required: false + schema: + $ref: "#/definitions/InputStream" + responses: + 200: + description: "successful operation" + schema: + $ref: "#/definitions/RestLogFilePutResult" + headers: {} + /api/logs/{attempt_id}/files/{file_name}: + get: + tags: + - "Log" + summary: "Download a log file" + description: "" + operationId: "getFile" + produces: + - "application/gzip" + parameters: + - name: "attempt_id" + in: "path" + description: "attempt id" + required: true + type: "integer" + format: "int64" + - name: "file_name" + in: "path" + description: "log file name" + required: true + type: "string" + responses: + 200: + description: "successful operation" + schema: + type: "array" + items: + type: "string" + format: "byte" + /api/logs/{attempt_id}/upload_handle: + get: + tags: + - "Log" + operationId: "getFileHandles" + produces: + - "application/json" + parameters: + - name: "attempt_id" + in: "path" + required: true + type: "integer" + format: "int64" + - name: "task" + in: "query" + required: false + type: "string" + - name: "file_time" + in: "query" + required: false + type: "integer" + format: "int64" + - name: "node_id" + in: "query" + required: false + type: "string" + responses: + 200: + description: "successful operation" + schema: + $ref: "#/definitions/DirectUploadHandle" + headers: {} + /api/project: + get: + tags: + - "Project" + operationId: "getProject" + produces: + - "application/json" + parameters: + - name: "name" + in: "query" + required: false + type: "string" + responses: + 200: + description: "successful operation" + schema: + $ref: "#/definitions/RestProject" + headers: {} + /api/projects: + get: + tags: + - "Project" + summary: "List projects with filters" + description: "" + operationId: "getProjects" + produces: + - "application/json" + parameters: + - name: "name" + in: "query" + description: "exact matching filter on project name" + required: false + type: "string" + responses: + 200: + description: "successful operation" + schema: + $ref: "#/definitions/RestProjectCollection" + put: + tags: + - "Project" + summary: "Upload a project archive as a new project or a new revision of an\ + \ existing project" + description: "" + operationId: "putProject" + consumes: + - "application/gzip" + produces: + - "application/json" + parameters: + - name: "project" + in: "query" + description: "project name" + required: true + type: "string" + - name: "revision" + in: "query" + description: "revision" + required: true + type: "string" + - in: "body" + name: "body" + required: false + schema: + $ref: "#/definitions/InputStream" + - name: "Content-Length" + in: "header" + required: false + type: "integer" + format: "int64" + - name: "schedule_from" + in: "query" + description: "start scheduling of new workflows from the given time instead\ + \ of current time" + required: false + type: "string" + responses: + 200: + description: "successful operation" + schema: + $ref: "#/definitions/RestProject" + /api/projects/{id}: + get: + tags: + - "Project" + summary: "Get a project" + description: "" + operationId: "getProject" + produces: + - "application/json" + parameters: + - name: "id" + in: "path" + description: "project id" + required: true + type: "integer" + format: "int32" + responses: + 200: + description: "successful operation" + schema: + $ref: "#/definitions/RestProject" + delete: + tags: + - "Project" + summary: "Delete a project" + description: "" + operationId: "deleteProject" + produces: + - "application/json" + parameters: + - name: "id" + in: "path" + required: true + type: "integer" + format: "int32" + responses: + 200: + description: "successful operation" + schema: + $ref: "#/definitions/RestProject" + /api/projects/{id}/archive: + get: + tags: + - "Project" + summary: "Download a project archive file" + description: "" + operationId: "getArchive" + produces: + - "application/gzip" + parameters: + - name: "id" + in: "path" + description: "project id" + required: true + type: "integer" + format: "int32" + - name: "revision" + in: "query" + description: "use a given revision of a project instead of the latest revision" + required: true + type: "string" + responses: + default: + description: "successful operation" + /api/projects/{id}/revisions: + get: + tags: + - "Project" + summary: "List revisions of a project" + description: "" + operationId: "getRevisions" + produces: + - "application/json" + parameters: + - name: "id" + in: "path" + required: true + type: "integer" + format: "int32" + - name: "last_id" + in: "query" + description: "deprecated - do not use" + required: false + type: "integer" + format: "int32" + responses: + 200: + description: "successful operation" + schema: + $ref: "#/definitions/RestRevisionCollection" + /api/projects/{id}/schedules: + get: + tags: + - "Project" + summary: "List schedules of a project with filters" + description: "" + operationId: "getSchedules" + produces: + - "application/json" + parameters: + - name: "id" + in: "path" + description: "project id" + required: true + type: "integer" + format: "int32" + - name: "workflow" + in: "query" + description: "exact matching filter on workflow name" + required: false + type: "string" + - name: "last_id" + in: "query" + description: "list schedules whose id is grater than this id for pagination" + required: false + type: "integer" + format: "int32" + responses: + 200: + description: "successful operation" + schema: + $ref: "#/definitions/RestScheduleCollection" + /api/projects/{id}/secrets: + get: + tags: + - "Project" + summary: "List secret keys of a project" + description: "" + operationId: "getProjectSecrets" + produces: + - "application/json" + parameters: + - name: "id" + in: "path" + description: "project id" + required: true + type: "integer" + format: "int32" + responses: + 200: + description: "successful operation" + schema: + $ref: "#/definitions/RestSecretList" + /api/projects/{id}/secrets/{key}: + put: + tags: + - "Project" + summary: "Set a secret to a project" + description: "" + operationId: "putProjectSecret" + consumes: + - "application/json" + produces: + - "application/json" + parameters: + - name: "id" + in: "path" + description: "project id" + required: true + type: "integer" + format: "int32" + - name: "key" + in: "path" + description: "secret key" + required: true + type: "string" + - in: "body" + name: "body" + required: false + schema: + $ref: "#/definitions/RestSetSecretRequest" + responses: + default: + description: "successful operation" + delete: + tags: + - "Project" + summary: "Delete a secret from a project" + description: "" + operationId: "deleteProjectSecret" + produces: + - "application/json" + parameters: + - name: "id" + in: "path" + description: "project id" + required: true + type: "integer" + format: "int32" + - name: "key" + in: "path" + description: "secret key" + required: true + type: "string" + responses: + default: + description: "successful operation" + /api/projects/{id}/sessions: + get: + tags: + - "Project" + summary: "List sessions of a project with filters" + description: "" + operationId: "getSessions" + produces: + - "application/json" + parameters: + - name: "id" + in: "path" + description: "project id" + required: true + type: "integer" + format: "int32" + - name: "workflow" + in: "query" + description: "exact matching filter on workflow name" + required: false + type: "string" + - name: "last_id" + in: "query" + description: "list sessions whose id is grater than this id for pagination" + required: false + type: "integer" + format: "int64" + - name: "page_size" + in: "query" + description: "number of sessions to return" + required: false + type: "integer" + format: "int32" + responses: + 200: + description: "successful operation" + schema: + $ref: "#/definitions/RestSessionCollection" + /api/projects/{id}/workflow: + get: + tags: + - "Project" + operationId: "getWorkflow" + produces: + - "application/json" + parameters: + - name: "id" + in: "path" + required: true + type: "integer" + format: "int32" + - name: "name" + in: "query" + required: false + type: "string" + - name: "revision" + in: "query" + required: false + type: "string" + responses: + 200: + description: "successful operation" + schema: + $ref: "#/definitions/RestWorkflowDefinition" + headers: {} + /api/projects/{id}/workflows: + get: + tags: + - "Project" + summary: "List workflows of a project with filters" + description: "" + operationId: "getWorkflows" + produces: + - "application/json" + parameters: + - name: "id" + in: "path" + description: "project id" + required: true + type: "integer" + format: "int32" + - name: "revision" + in: "query" + description: "use a given revision of the project instead of the latest revision" + required: true + type: "string" + - name: "name" + in: "query" + description: "exact matching filter on workflow name" + required: false + type: "string" + responses: + 200: + description: "successful operation" + schema: + $ref: "#/definitions/RestWorkflowDefinitionCollection" + /api/projects/{id}/workflows/{name}: + get: + tags: + - "Project" + operationId: "getWorkflowByName" + produces: + - "application/json" + parameters: + - name: "id" + in: "path" + required: true + type: "integer" + format: "int32" + - name: "name" + in: "path" + required: true + type: "string" + - name: "revision" + in: "query" + required: false + type: "string" + responses: + 200: + description: "successful operation" + schema: + $ref: "#/definitions/RestWorkflowDefinition" + headers: {} + /api/schedules: + get: + tags: + - "Schedule" + summary: "List schedules" + description: "" + operationId: "getSchedules" + produces: + - "application/json" + parameters: + - name: "last_id" + in: "query" + description: "list schedules whose id is grater than this id for pagination" + required: false + type: "integer" + format: "int32" + responses: + 200: + description: "successful operation" + schema: + $ref: "#/definitions/RestScheduleCollection" + /api/schedules/{id}: + get: + tags: + - "Schedule" + summary: "Get a schedule" + description: "" + operationId: "getSchedules" + produces: + - "application/json" + parameters: + - name: "id" + in: "path" + description: "schedule id" + required: true + type: "integer" + format: "int32" + responses: + 200: + description: "successful operation" + schema: + $ref: "#/definitions/RestSchedule" + /api/schedules/{id}/backfill: + post: + tags: + - "Schedule" + summary: "Re-schedule past sessions by count or duration" + description: "" + operationId: "backfillSchedule" + consumes: + - "application/json" + produces: + - "application/json" + parameters: + - name: "id" + in: "path" + description: "session id" + required: true + type: "integer" + format: "int32" + - in: "body" + name: "body" + required: false + schema: + $ref: "#/definitions/RestScheduleBackfillRequest" + responses: + 200: + description: "successful operation" + schema: + $ref: "#/definitions/RestSessionAttemptCollection" + /api/schedules/{id}/disable: + post: + tags: + - "Schedule" + summary: "Disable scheduling of new sessions" + description: "" + operationId: "disableSchedule" + produces: + - "application/json" + parameters: + - name: "id" + in: "path" + description: "session id" + required: true + type: "integer" + format: "int32" + responses: + 200: + description: "successful operation" + schema: + $ref: "#/definitions/RestScheduleSummary" + /api/schedules/{id}/enable: + post: + tags: + - "Schedule" + summary: "Re-enable disabled scheduling" + description: "" + operationId: "enableSchedule" + produces: + - "application/json" + parameters: + - name: "id" + in: "path" + description: "session id" + required: true + type: "integer" + format: "int32" + responses: + 200: + description: "successful operation" + schema: + $ref: "#/definitions/RestScheduleSummary" + /api/schedules/{id}/skip: + post: + tags: + - "Schedule" + summary: "Skip future sessions by count or time" + description: "" + operationId: "skipSchedule" + consumes: + - "application/json" + produces: + - "application/json" + parameters: + - name: "id" + in: "path" + description: "session id" + required: true + type: "integer" + format: "int32" + - in: "body" + name: "body" + required: false + schema: + $ref: "#/definitions/RestScheduleSkipRequest" + responses: + 200: + description: "successful operation" + schema: + $ref: "#/definitions/RestScheduleSummary" + /api/sessions: + get: + tags: + - "Session" + summary: "List sessions" + description: "" + operationId: "getSessions" + produces: + - "application/json" + parameters: + - name: "last_id" + in: "query" + description: "list sessions whose id is grater than this id for pagination" + required: false + type: "integer" + format: "int64" + - name: "page_size" + in: "query" + description: "number of sessions to return" + required: false + type: "integer" + format: "int32" + responses: + 200: + description: "successful operation" + schema: + $ref: "#/definitions/RestSessionCollection" + /api/sessions/{id}: + get: + tags: + - "Session" + summary: "Get a session" + description: "" + operationId: "getSession" + produces: + - "application/json" + parameters: + - name: "id" + in: "path" + description: "session id" + required: true + type: "integer" + format: "int64" + responses: + 200: + description: "successful operation" + schema: + $ref: "#/definitions/RestSession" + /api/sessions/{id}/attempts: + get: + tags: + - "Session" + summary: "List attempts of a session" + description: "" + operationId: "getSessionAttempts" + produces: + - "application/json" + parameters: + - name: "id" + in: "path" + description: "session id" + required: true + type: "integer" + format: "int64" + - name: "last_id" + in: "query" + description: "list attempts whose id is grater than this id for pagination" + required: false + type: "integer" + format: "int64" + - name: "page_size" + in: "query" + description: "number of attempts to return" + required: false + type: "integer" + format: "int32" + responses: + 200: + description: "successful operation" + schema: + $ref: "#/definitions/RestSessionAttemptCollection" + /api/version: + get: + tags: + - "Version" + summary: "Get server version" + description: "" + operationId: "getVersion" + produces: + - "application/json" + parameters: [] + responses: + 200: + description: "successful operation" + schema: + type: "object" + additionalProperties: + type: "object" + /api/version/check: + get: + tags: + - "Version" + summary: "Check client version compatibility" + description: "" + operationId: "checkClientVersion" + produces: + - "application/json" + parameters: + - name: "client" + in: "query" + description: "client version" + required: true + type: "string" + responses: + 200: + description: "successful operation" + schema: + $ref: "#/definitions/RestVersionCheckResult" + /api/workflow: + get: + tags: + - "Workflow" + operationId: "getWorkflowDefinition" + produces: + - "application/json" + parameters: + - name: "project" + in: "query" + required: false + type: "string" + - name: "revision" + in: "query" + required: false + type: "string" + - name: "name" + in: "query" + required: false + type: "string" + responses: + 200: + description: "successful operation" + schema: + $ref: "#/definitions/RestWorkflowDefinition" + headers: {} + /api/workflows: + get: + tags: + - "Workflow" + summary: "List workflows" + description: "" + operationId: "getWorkflowDefinitions" + produces: + - "application/json" + parameters: + - name: "last_id" + in: "query" + description: "list workflows whose id is grater than this id for pagination" + required: false + type: "integer" + format: "int64" + - name: "count" + in: "query" + description: "number of workflows to return" + required: false + type: "integer" + format: "int32" + responses: + 200: + description: "successful operation" + schema: + $ref: "#/definitions/RestWorkflowDefinitionCollection" + /api/workflows/{id}: + get: + tags: + - "Workflow" + summary: "Get a workflow" + description: "" + operationId: "getWorkflowDefinition" + produces: + - "application/json" + parameters: + - name: "id" + in: "path" + description: "workflow id" + required: true + type: "integer" + format: "int64" + responses: + 200: + description: "successful operation" + schema: + $ref: "#/definitions/RestWorkflowDefinition" + /api/workflows/{id}/truncated_session_time: + get: + tags: + - "Workflow" + summary: "Get truncated local time based on the time zone of a workflow" + description: "" + operationId: "getWorkflowDefinition" + produces: + - "application/json" + parameters: + - name: "id" + in: "path" + description: "workflow id" + required: true + type: "integer" + format: "int64" + - name: "session_time" + in: "query" + description: "session time to be truncated" + required: true + type: "string" + - name: "mode" + in: "query" + description: "truncation mode - second, minute, hour, day, schedule, or next_schedule" + required: false + type: "string" + enum: + - "SECOND" + - "MINUTE" + - "HOUR" + - "DAY" + - "SCHEDULE" + - "NEXT_SCHEDULE" + responses: + 200: + description: "successful operation" + schema: + $ref: "#/definitions/RestWorkflowSessionTime" +definitions: + ResumeFrom: + allOf: + - $ref: "#/definitions/Resume" + - type: "object" + properties: + from: + type: "string" + readOnly: true + DirectUploadHandle: + type: "object" + Config: + type: "object" + properties: + empty: + type: "boolean" + default: false + factory: + $ref: "#/definitions/ConfigFactory" + keys: + type: "array" + items: + type: "string" + RestSession: + type: "object" + properties: + project: + $ref: "#/definitions/IdAndName" + id: + $ref: "#/definitions/Id" + sessionUuid: + type: "string" + format: "uuid" + sessionTime: + $ref: "#/definitions/OffsetDateTime" + workflow: + $ref: "#/definitions/NameOptionalId" + lastAttempt: + $ref: "#/definitions/Attempt" + RestSchedule: + type: "object" + properties: + project: + $ref: "#/definitions/IdAndName" + id: + $ref: "#/definitions/Id" + disabledAt: + type: "integer" + format: "int64" + nextScheduleTime: + $ref: "#/definitions/OffsetDateTime" + nextRunTime: + type: "integer" + format: "int64" + workflow: + $ref: "#/definitions/IdAndName" + RestProject: + type: "object" + properties: + name: + type: "string" + id: + $ref: "#/definitions/Id" + revision: + type: "string" + archiveType: + type: "string" + archiveMd5: + type: "array" + items: + type: "string" + format: "byte" + createdAt: + type: "integer" + format: "int64" + deletedAt: + type: "integer" + format: "int64" + updatedAt: + type: "integer" + format: "int64" + RestLogFileHandle: + type: "object" + properties: + fileSize: + type: "integer" + format: "int64" + agentId: + type: "string" + direct: + $ref: "#/definitions/RestDirectDownloadHandle" + fileName: + type: "string" + taskName: + type: "string" + fileTime: + type: "integer" + format: "int64" + IdAndName: + type: "object" + properties: + name: + type: "string" + id: + $ref: "#/definitions/Id" + ZoneOffset: + type: "object" + properties: + totalSeconds: + type: "integer" + format: "int32" + id: + type: "string" + rules: + $ref: "#/definitions/ZoneRules" + RestProjectCollection: + type: "object" + properties: + projects: + type: "array" + items: + $ref: "#/definitions/RestProject" + RestVersionCheckResult: + type: "object" + properties: + apiCompatible: + type: "boolean" + default: false + serverVersion: + type: "string" + upgradeRecommended: + type: "boolean" + default: false + RestWorkflowDefinitionCollection: + type: "object" + properties: + workflows: + type: "array" + items: + $ref: "#/definitions/RestWorkflowDefinition" + Attempt: + type: "object" + properties: + id: + $ref: "#/definitions/Id" + createdAt: + type: "integer" + format: "int64" + retryAttemptName: + type: "string" + params: + $ref: "#/definitions/Config" + finishedAt: + type: "integer" + format: "int64" + success: + type: "boolean" + default: false + done: + type: "boolean" + default: false + cancelRequested: + type: "boolean" + default: false + RestLogFilePutResult: + type: "object" + properties: + fileName: + type: "string" + RestWorkflowDefinition: + type: "object" + properties: + project: + $ref: "#/definitions/IdAndName" + name: + type: "string" + id: + $ref: "#/definitions/Id" + config: + $ref: "#/definitions/Config" + revision: + type: "string" + timezone: + readOnly: true + $ref: "#/definitions/ZoneId" + RestWorkflowSessionTime: + type: "object" + properties: + project: + $ref: "#/definitions/IdAndName" + revision: + type: "string" + sessionTime: + $ref: "#/definitions/OffsetDateTime" + timezone: + readOnly: true + $ref: "#/definitions/ZoneId" + RestScheduleBackfillRequest: + type: "object" + properties: + fromTime: + type: "integer" + format: "int64" + attemptName: + type: "string" + dryRun: + type: "boolean" + default: false + count: + type: "integer" + format: "int32" + ZoneOffsetTransition: + type: "object" + properties: + offsetBefore: + $ref: "#/definitions/ZoneOffset" + offsetAfter: + $ref: "#/definitions/ZoneOffset" + overlap: + type: "boolean" + default: false + instant: + type: "integer" + format: "int64" + duration: + $ref: "#/definitions/Duration" + gap: + type: "boolean" + default: false + dateTimeBefore: + type: "string" + format: "date-time" + dateTimeAfter: + type: "string" + format: "date-time" + RestRevision: + type: "object" + properties: + userInfo: + $ref: "#/definitions/Config" + revision: + type: "string" + archiveType: + type: "string" + archiveMd5: + type: "array" + items: + type: "string" + format: "byte" + createdAt: + type: "integer" + format: "int64" + RestSessionCollection: + type: "object" + properties: + sessions: + type: "array" + items: + $ref: "#/definitions/RestSession" + RestTaskCollection: + type: "object" + properties: + tasks: + type: "array" + items: + $ref: "#/definitions/RestTask" + ZoneOffsetTransitionRule: + type: "object" + properties: + month: + type: "string" + enum: + - "JANUARY" + - "FEBRUARY" + - "MARCH" + - "APRIL" + - "MAY" + - "JUNE" + - "JULY" + - "AUGUST" + - "SEPTEMBER" + - "OCTOBER" + - "NOVEMBER" + - "DECEMBER" + timeDefinition: + type: "string" + enum: + - "UTC" + - "WALL" + - "STANDARD" + standardOffset: + $ref: "#/definitions/ZoneOffset" + offsetBefore: + $ref: "#/definitions/ZoneOffset" + offsetAfter: + $ref: "#/definitions/ZoneOffset" + dayOfMonthIndicator: + type: "integer" + format: "int32" + localTime: + $ref: "#/definitions/LocalTime" + midnightEndOfDay: + type: "boolean" + default: false + dayOfWeek: + type: "string" + enum: + - "MONDAY" + - "TUESDAY" + - "WEDNESDAY" + - "THURSDAY" + - "FRIDAY" + - "SATURDAY" + - "SUNDAY" + RestSetSecretRequest: + type: "object" + LocalTime: + type: "object" + properties: + hour: + type: "integer" + format: "int32" + minute: + type: "integer" + format: "int32" + second: + type: "integer" + format: "int32" + nano: + type: "integer" + format: "int32" + ZoneId: + type: "object" + properties: + rules: + $ref: "#/definitions/ZoneRules" + id: + type: "string" + RestTask: + type: "object" + properties: + group: + type: "boolean" + default: false + id: + $ref: "#/definitions/Id" + state: + type: "string" + startedAt: + type: "integer" + format: "int64" + fullName: + type: "string" + parentId: + $ref: "#/definitions/Id" + upstreams: + type: "array" + items: + $ref: "#/definitions/Id" + retryAt: + type: "integer" + format: "int64" + config: + $ref: "#/definitions/Config" + exportParams: + $ref: "#/definitions/Config" + storeParams: + $ref: "#/definitions/Config" + stateParams: + $ref: "#/definitions/Config" + error: + $ref: "#/definitions/Config" + updatedAt: + type: "integer" + format: "int64" + cancelRequested: + type: "boolean" + default: false + TemporalUnit: + type: "object" + properties: + duration: + $ref: "#/definitions/Duration" + durationEstimated: + type: "boolean" + default: false + dateBased: + type: "boolean" + default: false + timeBased: + type: "boolean" + default: false + RestScheduleSummary: + type: "object" + properties: + id: + $ref: "#/definitions/Id" + disabledAt: + type: "integer" + format: "int64" + nextScheduleTime: + $ref: "#/definitions/OffsetDateTime" + nextRunTime: + type: "integer" + format: "int64" + createdAt: + type: "integer" + format: "int64" + updatedAt: + type: "integer" + format: "int64" + workflow: + $ref: "#/definitions/IdAndName" + InputStream: + type: "object" + RestScheduleSkipRequest: + type: "object" + properties: + nextRunTime: + type: "integer" + format: "int64" + fromTime: + type: "integer" + format: "int64" + dryRun: + type: "boolean" + default: false + nextTime: + $ref: "#/definitions/LocalTimeOrInstant" + count: + type: "integer" + format: "int32" + RestDirectDownloadHandle: + type: "object" + Duration: + type: "object" + properties: + seconds: + type: "integer" + format: "int64" + nano: + type: "integer" + format: "int32" + zero: + type: "boolean" + default: false + negative: + type: "boolean" + default: false + units: + type: "array" + items: + $ref: "#/definitions/TemporalUnit" + NameOptionalId: + type: "object" + properties: + name: + type: "string" + id: + $ref: "#/definitions/Id" + ConfigFactory: + type: "object" + RestRevisionCollection: + type: "object" + properties: + revisions: + type: "array" + items: + $ref: "#/definitions/RestRevision" + RestSessionAttempt: + type: "object" + properties: + project: + $ref: "#/definitions/IdAndName" + id: + $ref: "#/definitions/Id" + createdAt: + type: "integer" + format: "int64" + sessionUuid: + type: "string" + format: "uuid" + retryAttemptName: + type: "string" + params: + $ref: "#/definitions/Config" + sessionId: + $ref: "#/definitions/Id" + finishedAt: + type: "integer" + format: "int64" + sessionTime: + $ref: "#/definitions/OffsetDateTime" + workflow: + $ref: "#/definitions/NameOptionalId" + success: + type: "boolean" + default: false + done: + type: "boolean" + default: false + cancelRequested: + type: "boolean" + default: false + index: + type: "integer" + format: "int32" + OffsetDateTime: + type: "object" + properties: + offset: + $ref: "#/definitions/ZoneOffset" + nano: + type: "integer" + format: "int32" + hour: + type: "integer" + format: "int32" + minute: + type: "integer" + format: "int32" + dayOfYear: + type: "integer" + format: "int32" + dayOfWeek: + type: "string" + enum: + - "MONDAY" + - "TUESDAY" + - "WEDNESDAY" + - "THURSDAY" + - "FRIDAY" + - "SATURDAY" + - "SUNDAY" + month: + type: "string" + enum: + - "JANUARY" + - "FEBRUARY" + - "MARCH" + - "APRIL" + - "MAY" + - "JUNE" + - "JULY" + - "AUGUST" + - "SEPTEMBER" + - "OCTOBER" + - "NOVEMBER" + - "DECEMBER" + dayOfMonth: + type: "integer" + format: "int32" + year: + type: "integer" + format: "int32" + second: + type: "integer" + format: "int32" + monthValue: + type: "integer" + format: "int32" + LocalTimeOrInstant: + type: "object" + RestScheduleCollection: + type: "object" + properties: + schedules: + type: "array" + items: + $ref: "#/definitions/RestSchedule" + RestSecretList: + type: "object" + ZoneRules: + type: "object" + properties: + fixedOffset: + type: "boolean" + default: false + transitions: + type: "array" + items: + $ref: "#/definitions/ZoneOffsetTransition" + transitionRules: + type: "array" + items: + $ref: "#/definitions/ZoneOffsetTransitionRule" + RestSessionAttemptCollection: + type: "object" + properties: + attempts: + type: "array" + items: + $ref: "#/definitions/RestSessionAttempt" + RestLogFileHandleCollection: + type: "object" + properties: + files: + type: "array" + items: + $ref: "#/definitions/RestLogFileHandle" + Id: + type: "object" + ResumeFailed: + allOf: + - $ref: "#/definitions/Resume" + - type: "object" + properties: {} + RestSessionAttemptRequest: + type: "object" + properties: + retryAttemptName: + type: "string" + params: + $ref: "#/definitions/Config" + sessionTime: + type: "integer" + format: "int64" + workflowId: + $ref: "#/definitions/Id" + resume: + $ref: "#/definitions/Resume" + Resume: + type: "object" + discriminator: "mode" + properties: + attemptId: + readOnly: true + $ref: "#/definitions/Id" + mode: + type: "string" + readOnly: true + enum: + - "FROM" + - "FAILED" diff --git a/digdag-docs/src/command_reference.rst b/digdag-docs/src/command_reference.rst index 23535826e0..a2dc729d43 100644 --- a/digdag-docs/src/command_reference.rst +++ b/digdag-docs/src/command_reference.rst @@ -115,9 +115,11 @@ Options: Add a session parameter (use multiple times to set many parameters) in KEY=VALUE syntax. This parameter is available using ``${...}`` syntax in the YAML file, or using language API. Example: ``-p environment=staging`` + + Note: Variable defined in _export is not overwritable by --param option. :command:`-P, --params-file PATH` - Read parameters from a YAML file. Nested parameter (like {mysql: {user: me}}) are accessible using "." syntax (like \${mysql.user}). + Read parameters from a YAML/JSON file. Nested parameter (like {mysql: {user: me}}) are accessible using "." syntax (like \${mysql.user}). Example: ``-P params.yml`` @@ -156,6 +158,8 @@ Shows workflow definitions and schedules. "c" is alias of check command. Example Overwrite a parameter (use multiple times to set many parameters) in KEY=VALUE syntax. This parameter is available using ``${...}`` syntax in the YAML file, or using language API. Example: ``-p environment=staging`` + + Note: Variable defined in _export is not overwritable by --param option. :command:`-P, --params-file PATH` Read parameters from a YAML file. Nested parameter (like {mysql: {user: me}}) are accessible using "." syntax (like \${mysql.user}). @@ -212,6 +216,8 @@ Runs a workflow scheduler that runs schedules periodically. This picks up all wo Add a session parameter (use multiple times to set many parameters) in KEY=VALUE syntax. This parameter is available using ``${...}`` syntax in the YAML file, or using language API. Example: ``-p environment=staging`` + + Note: Variable defined in _export is not overwritable by --param option. :command:`-P, --params-file PATH` Read parameters from a YAML file. Nested parameter (like {mysql: {user: me}}) are accessible using "." syntax (like \${mysql.user}). @@ -235,7 +241,7 @@ Updates the executable binary file to the latest version or specified version. E .. code-block:: console $ digdag selfupdate - $ digdag selfupdate 0.9.33 + $ digdag selfupdate 0.9.40 Server-mode commands ---------------------------------- @@ -271,7 +277,7 @@ Runs a digdag server. --memory or --database option is required. Examples: Example: ``--database digdag`` :command:`-m, --memory` - Store status in memory. Data will be removed when the server exists. + Store status in memory. Data will be removed when the server exits. Example: ``--memory`` @@ -304,10 +310,19 @@ Runs a digdag server. --memory or --database option is required. Examples: Example: ``--disable-executor-loop`` +:command:`--disable-scheduler` + Disable a schedule executor on this server. + + This option is useful when you want to disable all schedules without modifying workflow files. See also ``--disable-executor-loop`` option. + + Example: ``--disable-scheduler`` + :command:`-p, --param KEY=VALUE` Add a session parameter (use multiple times to set many parameters) in KEY=VALUE syntax. This parameter is available using ``${...}`` syntax in the YAML file, or using language API. Example: ``-p environment=staging`` + + Note: Variable defined in _export is not overwritable by --param option. :command:`-P, --params-file PATH` Read parameters from a YAML file. Nested parameter (like {mysql: {user: me}}) are accessible using "." syntax (like \${mysql.user}). @@ -315,9 +330,9 @@ Runs a digdag server. --memory or --database option is required. Examples: Example: ``-P params.yml`` :command:`-c, --config PATH` - Server configuration property path. See the followings for details. + Configuration file to load. (default: ~/.config/digdag/config) See the followings for details. - Example: ``-c digdag.properties`` + Example: ``-c digdag-server/server.properties`` In the config file, following parameters are available @@ -336,6 +351,7 @@ In the config file, following parameters are available * server.http.enable-http2 (enable HTTP/2. default: false) * server.http.headers.KEY = VALUE (HTTP header to set on API responses) * server.jmx.port (port to listen JMX in integer. default: JMX is disabled) +* server.authenticator-class (string) The FQCN of the ``io.digdag.spi.Authenticator`` implementation to use. The implementation is to be provided by a system plugin. The auth plugin configuration is implementation specific. Default: ``io.digdag.standards.auth.jwt.JwtAuthenticator`` * database.type (enum, "h2" or "postgresql") * database.user (string) * database.password (string) @@ -349,14 +365,19 @@ In the config file, following parameters are available * database.idleTimeout (seconds in integer, default: 600) * database.validationTimeout (seconds in integer, default: 5) * database.maximumPoolSize (integer, default: available CPU cores * 32) -* archive.type (type of project archiving, "db" or "s3". default: "db") +* database.leakDetectionThreshold (HikariCP leakDetectionThreshold milliseconds in integer. default: 0. To enable, set to >= 2000.) +* database.migrate (enable DB migration. default: true) +* archive.type (type of project archiving, "db", "s3" or "gcs". default: "db") * archive.s3.endpoint (string. default: "s3.amazonaws.com") * archive.s3.bucket (string) * archive.s3.path (string) * archive.s3.credentials.access-key-id (string. default: instance profile) * archive.s3.credentials.secret-access-key (string. default: instance profile) * archive.s3.path-style-access (boolean. default: false) -* log-server.type (type of log storage, "local" , "null", or "s3". default: "null". This parameter will be overwritten with "local" if ``-O, --task-log DIR`` is set.) +* archive.gcs.bucket (string) +* archive.gcs.credentials.json.path (string. if not set, auth with local authentication information. Also if path and content are set, path has priority.) +* archive.gcs.credentials.json.content (string. if not set, auth with local authentication information. Also if path and content are set, path has priority.) +* log-server.type (type of log storage, "local" , "null", "s3" or "gcs". default: "null". This parameter will be overwritten with "local" if ``-O, --task-log DIR`` is set.) * log-server.s3.endpoint (string, default: "s3.amazonaws.com") * log-server.s3.bucket (string) * log-server.s3.path (string) @@ -364,11 +385,35 @@ In the config file, following parameters are available * log-server.s3.credentials.access-key-id (string. default: instance profile) * log-server.s3.credentials.secret-access-key (string. default: instance profile) * log-server.s3.path-style-access (boolean. default: false) +* log-server.gcs.bucket (string) +* log-server.gcs.credentials.json.path (string. if not set, auth with local authentication information. Also if path and content are set, path has priority.) +* log-server.gcs.credentials.json.content (string. if not set, auth with local authentication information. Also if path and content are set, path has priority.) +* log-server.local.path (string. default: digdag.log) +* log-server.local.split_size (long. max log file size in bytes(uncompressed). default: 0 (not splitted)) * digdag.secret-encryption-key = (base64 encoded 128-bit AES encryption key) * executor.task_ttl (string. default: 1d. A task is killed if it is running longer than this period.) * executor.attempt_ttl (string. default: 7d. An attempt is killed if it is running longer than this period.) * api.max_attempts_page_size (integer. The max number of rows of attempts in api response) * api.max_sessions_page_size (integer. The max number of rows of sessions in api response) +* api.max_archive_total_size_limit (integer. The maximum size of an archived project. i.e. ``digdag push`` size. default: 2MB(2\*1024\*1024)) + +Authenticator Plugins +********************* + +**Basic Auth** + +Enabled by setting the config parameter ``server.authenticator-class`` to ``io.digdag.standards.auth.basic.BasicAuthenticator``. + +Configuration: + +* basicauth.username (string) *required* +* basicauth.password (string) *required* +* basicauth.admin (boolean) optional, default ``false`` + + +**Jwt** + +Undocumented. Secret Encryption Key @@ -381,7 +426,9 @@ Example: .. code-block:: none digdag.secret-encryption-key = MDEyMzQ1Njc4OTAxMjM0NQ== - + # example + echo -n '16_bytes_phrase!' | openssl base64 + MTZfYnl0ZXNfcGhyYXNlIQ== Client-mode commands ---------------------------------- @@ -396,15 +443,21 @@ Client-mode common options: :command:`-H, --header KEY=VALUE` Add a custom HTTP header. Use multiple times to set multiple headers. +:command:`--basic-auth ` + Add an Authorization header with the provided username and password. + :command:`-c, --config PATH` Configuration file to load. (default: ~/.config/digdag/config) Example: ``-c digdag-server/client.properties`` + + You can include following parameters in ~/.config/digdag/config file: * client.http.endpoint = http://HOST:PORT or https://HOST:PORT * client.http.headers.KEY = VALUE (set custom HTTP header) +* client.http.disable_direct_download=true (disable direct download in `log` and `download`. effect to server v0.10.0(not yet released) or later.) start @@ -444,6 +497,8 @@ Starts a new session. This command requires project name, workflow name, and ses Add a session parameter (use multiple times to set many parameters) in KEY=VALUE syntax. This parameter is available using ``${...}`` syntax in the YAML file, or using language API. Example: ``-p environment=staging`` + + Note: Variable defined in _export is not overwritable by --param option. :command:`-P, --params-file PATH` Read parameters from a YAML file. Nested parameter (like {mysql: {user: me}}) are accessible using "." syntax (like \${mysql.user}). @@ -531,6 +586,20 @@ Kills a session attempt. Examples: $ digdag kill 32 +projects +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +.. code-block:: console + + $ digdag projects [name] + +Shows list of projects or details of a project. Examples: + +.. code-block:: console + + $ digdag projects + $ digdag projects myproj + workflows ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ @@ -557,11 +626,58 @@ schedules Shows list of schedules. +disable +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +.. code-block:: console + + $ digdag disable [project-name] + +Disable all workflow schedules in a project. + +.. code-block:: console + + $ digdag disable [schedule-id] + $ digdag disable [project-name] [name] + +Disable a workflow schedule. + +.. code-block:: console + + $ digdag disable + $ digdag disable myproj + $ digdag disable myproj main + + +enable +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +.. code-block:: console + + $ digdag enable [project-name] + +Enable all workflow schedules in a project. + +.. code-block:: console + + $ digdag enable [schedule-id] + $ digdag enable [project-name] [name] + +Enable a workflow schedule. + +.. code-block:: console + + $ digdag enable + $ digdag enable myproj + $ digdag enable myproj main + + backfill ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ .. code-block:: console + $ digdag backfill $ digdag backfill Starts sessions of a schedule for past session times. @@ -591,8 +707,9 @@ reschedule .. code-block:: console $ digdag reschedule + $ digdag reschedule -Skips schedule forward to a future time. To run past schedules, use backfill instead. +Skips a workflow schedule forward to a future time. To run past schedules, use backfill instead. :command:`-s, --skip N` Skips specified number of schedules from now. This number "N" doesn't mean number of sessions to be skipped. "N" is the number of sessions to be skipped. @@ -628,20 +745,32 @@ Shows list of sessions. This command shows only the latest attempts of sessions :command:`-s, --page-size N` Shows more sessions of the number of N (in default up to 100). +session +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +.. code-block:: console + + $ digdag session [session-id] + +Show a single session. Examples: + +.. code-block:: console + + $ digdag session + attempts ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ .. code-block:: console - $ digdag attempts [project-name] [+name] + $ digdag attempts [session-id] Shows list of attempts. This command shows all attempts including attempts retried by another attempt. Examples: .. code-block:: console $ digdag attempts - $ digdag attempts myproj - $ digdag attempts myproj +main + $ digdag attempts :command:`-i, --last-id ID` Shows more attempts older than this id. @@ -649,6 +778,19 @@ Shows list of attempts. This command shows all attempts including attempts retri :command:`-s, --page-size N` Shows more attempts of the number of N (in default up to 100). +attempt +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +.. code-block:: console + + $ digdag attempt [attempt-id] + +Shows a single attempt. Examples: + +.. code-block:: console + + $ digdag attempt + tasks ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ @@ -732,6 +874,9 @@ Deletes a project. Sessions of the deleted project are kept retained so that we $ digdag delete myproj +:command:`--force` + Skip y/N prompt + secrets ~~~~~~~ @@ -817,6 +962,15 @@ The above command sets the local secret `foo`. The above command deletes the local secrets `foo` and `bar`. +version +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +.. code-block:: console + + $ digdag version + +Show client and server version. + Common options ---------------------------------- diff --git a/digdag-docs/src/concepts.md b/digdag-docs/src/concepts.md index 97f2b4def7..ffbf5db612 100644 --- a/digdag-docs/src/concepts.md +++ b/digdag-docs/src/concepts.md @@ -79,6 +79,18 @@ But loops and branches are useful. To solve this issue, Digdag dynamically appen `_error` task is generated after failure of a task. This is useful to notify failure of a task to external systems. +The following example output `success` on succeeding the tasks. And also, It output the message `fail` on failing the tasks. + +```yaml ++example: + sh>: your_script.sh + _check: + +succeed: + echo>: success + _error: + +failed: + echo>: fail +``` ## Task naming and resuming diff --git a/digdag-docs/src/conf.py b/digdag-docs/src/conf.py index 303467ef82..4d0bc45542 100644 --- a/digdag-docs/src/conf.py +++ b/digdag-docs/src/conf.py @@ -1,54 +1,44 @@ -# -*- coding: utf-8 -*- +# Configuration file for the Sphinx documentation builder. # -# Digdag documentation build configuration file, created by -# sphinx-quickstart on Mon Feb 8 12:20:49 2016. -# -# This file is execfile()d with the current directory set to its -# containing dir. -# -# Note that not all possible configuration values are present in this -# autogenerated file. +# This file only contains a selection of the most common options. For a full +# list see the documentation: +# http://www.sphinx-doc.org/en/master/config + +# -- Path setup -------------------------------------------------------------- + +# If extensions (or modules to document with autodoc) are in another directory, +# add these directories to sys.path here. If the directory is relative to the +# documentation root, use os.path.abspath to make it absolute, like shown here. # -# All configuration values have a default; values that are commented out -# serve to show the default. +# import os +# import sys +# sys.path.insert(0, os.path.abspath('.')) -import sys -import os -import shlex import subprocess +from datetime import datetime from recommonmark.parser import CommonMarkParser from recommonmark.transform import AutoStructify -from datetime import datetime -# If extensions (or modules to document with autodoc) are in another directory, -# add these directories to sys.path here. If the directory is relative to the -# documentation root, use os.path.abspath to make it absolute, like shown here. -#sys.path.insert(0, os.path.abspath('.')) -# -- General configuration ------------------------------------------------ +# -- Project information ----------------------------------------------------- + +project = 'Digdag' +copyright = '2016-' + datetime.now().strftime("%Y") + ', Digdag Project' +author = '2016, Digdag Project' +version = '0.9' +release = subprocess.check_output(['git', 'describe', '--abbrev=0', '--tags'])[1:].strip().decode("utf-8") + -# If your documentation needs a minimal Sphinx version, state it here. -#needs_sphinx = '1.0' +# -- General configuration --------------------------------------------------- # Add any Sphinx extension module names here, as strings. They can be # extensions coming with Sphinx (named 'sphinx.ext.*') or your custom # ones. -extensions = [ - 'sphinx.ext.autodoc', -] +extensions = ['recommonmark'] # Add any paths that contain templates here, relative to this directory. templates_path = ['_templates'] -# The suffix(es) of source filenames. -# You can specify multiple suffix as a list of string: -# source_suffix = ['.rst', '.md'] -source_suffix = ['.rst', '.md'] - -source_parsers = { - '.md': CommonMarkParser, -} - # http://recommonmark.readthedocs.io/en/latest/auto_structify.html def setup(app): app.add_config_value('recommonmark_config', { @@ -58,251 +48,24 @@ def setup(app): }, True) app.add_transform(AutoStructify) -# The encoding of source files. -#source_encoding = 'utf-8-sig' - -# The master toctree document. -master_doc = 'index' - -# General information about the project. -project = u'Digdag' -copyright = u'2016-' + datetime.now().strftime("%Y") + ', Digdag Project' -author = u'2016, Digdag Project' - -# The version info for the project you're documenting, acts as replacement for -# |version| and |release|, also used in various other places throughout the -# built documents. -# -# The short X.Y version. -version = '0.9' -# The full version, including alpha/beta/rc tags. -release = subprocess.check_output(['git', 'describe', '--abbrev=0', '--tags'])[1:].strip() - -# The language for content autogenerated by Sphinx. Refer to documentation -# for a list of supported languages. -# -# This is also used if you do content translation via gettext catalogs. -# Usually you set "language" from the command line for these cases. -language = None - -# There are two options for replacing |today|: either, you set today to some -# non-false value, then it is used: -#today = '' -# Else, today_fmt is used as the format for a strftime call. -#today_fmt = '%B %d, %Y' - # List of patterns, relative to source directory, that match files and # directories to ignore when looking for source files. +# This pattern also affects html_static_path and html_extra_path. exclude_patterns = [] -# The reST default role (used for this markup: `text`) to use for all -# documents. -#default_role = None - -# If true, '()' will be appended to :func: etc. cross-reference text. -#add_function_parentheses = True - -# If true, the current module name will be prepended to all description -# unit titles (such as .. function::). -#add_module_names = True - -# If true, sectionauthor and moduleauthor directives will be shown in the -# output. They are ignored by default. -#show_authors = False - -# The name of the Pygments (syntax highlighting) style to use. -pygments_style = 'sphinx' - -# A list of ignored prefixes for module index sorting. -#modindex_common_prefix = [] - -# If true, keep warnings as "system message" paragraphs in the built documents. -#keep_warnings = False - -# If true, `todo` and `todoList` produce output, else they produce nothing. -todo_include_todos = False - - -# -- Options for HTML output ---------------------------------------------- -import sphinx_rtd_theme +# -- Options for HTML output ------------------------------------------------- # The theme to use for HTML and HTML Help pages. See the documentation for # a list of builtin themes. +# html_theme = 'sphinx_rtd_theme' -# Theme options are theme-specific and customize the look and feel of a theme -# further. For a list of options available for each theme, see the -# documentation. -#html_theme_options = {} - -html_context = { - 'extra_css_files': ['_static/custom.css'] -} - -# Add any paths that contain custom themes here, relative to this directory. -html_theme_path = [sphinx_rtd_theme.get_html_theme_path()] - -# The name for this set of Sphinx documents. If None, it defaults to -# " v documentation". -#html_title = None - -# A shorter title for the navigation bar. Default is the same as html_title. -#html_short_title = None - -# The name of an image file (relative to this directory) to place at the top -# of the sidebar. -#html_logo = None - -# The name of an image file (within the static path) to use as favicon of the -# docs. This file should be a Windows icon file (.ico) being 16x16 or 32x32 -# pixels large. -#html_favicon = None - # Add any paths that contain custom static files (such as style sheets) here, # relative to this directory. They are copied after the builtin static files, # so a file named "default.css" will overwrite the builtin "default.css". html_static_path = ['_static'] +html_extra_path = ['_extra'] -# Add any extra paths that contain custom files (such as robots.txt or -# .htaccess) here, relative to this directory. These files are copied -# directly to the root of the documentation. -#html_extra_path = [] - -# If not '', a 'Last updated on:' timestamp is inserted at every page bottom, -# using the given strftime format. -#html_last_updated_fmt = '%b %d, %Y' - -# If true, SmartyPants will be used to convert quotes and dashes to -# typographically correct entities. -#html_use_smartypants = True - -# Custom sidebar templates, maps document names to template names. -#html_sidebars = {} - -# Additional templates that should be rendered to pages, maps page names to -# template names. -#html_additional_pages = {} - -# If false, no module index is generated. -#html_domain_indices = True - -# If false, no index is generated. -#html_use_index = True - -# If true, the index is split into individual pages for each letter. -#html_split_index = False - -# If true, links to the reST sources are added to the pages. -#html_show_sourcelink = True - -# If true, "Created using Sphinx" is shown in the HTML footer. Default is True. -#html_show_sphinx = True - -# If true, "(C) Copyright ..." is shown in the HTML footer. Default is True. -#html_show_copyright = True - -# If true, an OpenSearch description file will be output, and all pages will -# contain a tag referring to it. The value of this option must be the -# base URL from which the finished HTML is served. -#html_use_opensearch = '' - -# This is the file name suffix for HTML files (e.g. ".xhtml"). -#html_file_suffix = None - -# Language to be used for generating the HTML full-text search index. -# Sphinx supports the following languages: -# 'da', 'de', 'en', 'es', 'fi', 'fr', 'hu', 'it', 'ja' -# 'nl', 'no', 'pt', 'ro', 'ru', 'sv', 'tr' -#html_search_language = 'en' - -# A dictionary with options for the search language support, empty by default. -# Now only 'ja' uses this config value -#html_search_options = {'type': 'default'} - -# The name of a javascript file (relative to the configuration directory) that -# implements a search results scorer. If empty, the default will be used. -#html_search_scorer = 'scorer.js' - -# Output file base name for HTML help builder. -htmlhelp_basename = 'Digdagdoc' - -# -- Options for LaTeX output --------------------------------------------- - -latex_elements = { -# The paper size ('letterpaper' or 'a4paper'). -#'papersize': 'letterpaper', - -# The font size ('10pt', '11pt' or '12pt'). -#'pointsize': '10pt', - -# Additional stuff for the LaTeX preamble. -#'preamble': '', - -# Latex figure (float) alignment -#'figure_align': 'htbp', +html_context = { + 'extra_css_files': ['_static/custom.css'] } - -# Grouping the document tree into LaTeX files. List of tuples -# (source start file, target name, title, -# author, documentclass [howto, manual, or own class]). -latex_documents = [ - (master_doc, 'Digdag.tex', u'Digdag Documentation', - u'2016, Digdag Project', 'manual'), -] - -# The name of an image file (relative to this directory) to place at the top of -# the title page. -#latex_logo = None - -# For "manual" documents, if this is true, then toplevel headings are parts, -# not chapters. -#latex_use_parts = False - -# If true, show page references after internal links. -#latex_show_pagerefs = False - -# If true, show URL addresses after external links. -#latex_show_urls = False - -# Documents to append as an appendix to all manuals. -#latex_appendices = [] - -# If false, no module index is generated. -#latex_domain_indices = True - - -# -- Options for manual page output --------------------------------------- - -# One entry per manual page. List of tuples -# (source start file, name, description, authors, manual section). -man_pages = [ - (master_doc, 'digdag', u'Digdag Documentation', - [author], 1) -] - -# If true, show URL addresses after external links. -#man_show_urls = False - - -# -- Options for Texinfo output ------------------------------------------- - -# Grouping the document tree into Texinfo files. List of tuples -# (source start file, target name, title, author, -# dir menu entry, description, category) -texinfo_documents = [ - (master_doc, 'Digdag', u'Digdag Documentation', - author, 'Digdag', 'One line description of project.', - 'Miscellaneous'), -] - -# Documents to append as an appendix to all manuals. -#texinfo_appendices = [] - -# If false, no module index is generated. -#texinfo_domain_indices = True - -# How to display URL addresses: 'footnote', 'no', or 'inline'. -#texinfo_show_urls = 'footnote' - -# If true, do not generate a @detailmenu in the "Top" node's menu. -#texinfo_no_detailmenu = False diff --git a/digdag-docs/src/db_migration.md b/digdag-docs/src/db_migration.md new file mode 100644 index 0000000000..3d6c756094 --- /dev/null +++ b/digdag-docs/src/db_migration.md @@ -0,0 +1,34 @@ +# Upgrade with database migration + +## 1. Automatic migration + +Digdag supports automatic migration when newer version requires database schema modification. +When a digdag server start, it check `schema_migrations` table and execute each migration sequentially and automatically. +This is default enable, but you can enable/disable with system parameter `database.migrate`. +This parameter is documented from 0.9.36 + +## 2. Change of migration behavior from 0.9.36 +Each migration is executed with transaction. So if migrations fail, you can fix the cause and then retry it. +From 0.9.36, we added non-transactional migration. This is because some DDL cannot run in transaction. +In such migration, if the migration fail, there is a possibility to be required fix by hand before you retry. +So we explain how to recover when a non-transactional migration fails in section 4. + +## 3. How to upgrade Digdag safely +If you are running a Digdag cluster in production, we recommend the following way to avoid trouble. + +1. Disable auto migration: `database.migrate: false` +1. Stop all Digdag servers. +1. Upgrade Digdag binary. +1. Check migrations by `digdag migrate check` and confirm which migrations will be applied. +1. Run cli `digdag migrate run` in a server. +1. Start Digdag servers. + +## 4. List of non-transactional migrations +### ver. 0.9.36 +#### 20190318175338 +This migration add an index to session_attempts to avoid performance degrade with large session_attempts. +If you want to retry this migration because of unexpected errors, please run following sql. + + drop index session_attempts_on_site_id_and_state_flags_partial_2; + delete from schema_migrations where name like '20190318175338'; + diff --git a/digdag-docs/src/getting_started.md b/digdag-docs/src/getting_started.md index 025f1bfe76..386d338ce5 100644 --- a/digdag-docs/src/getting_started.md +++ b/digdag-docs/src/getting_started.md @@ -34,6 +34,11 @@ setx PATH "%PATH%;%USERPROFILE%\bin" Please reopen your command window. If `digdag --help` command shows usage message, Digdag is installed successfully. +### Using packages? + +Digdag has already been packaged for multiple platforms. + +[![Packaging status](https://repology.org/badge/vertical-allrepos/digdag.svg)](https://repology.org/project/digdag/versions) ### curl did not work? diff --git a/digdag-docs/src/index.md b/digdag-docs/src/index.md index 61d6bd2f49..bd1b41b37e 100644 --- a/digdag-docs/src/index.md +++ b/digdag-docs/src/index.md @@ -28,6 +28,7 @@ Digdag fits simple replacement of cron, IT operations automation, data analytics command_reference.rst python_api.rst ruby_api.rst + rest_api.rst internal.rst releases.rst logo.md diff --git a/digdag-docs/src/internal.md b/digdag-docs/src/internal.md index 0105270248..4fc2716cf5 100644 --- a/digdag-docs/src/internal.md +++ b/digdag-docs/src/internal.md @@ -58,6 +58,7 @@ When Digdag runs as a server, it has 3 major thread pools: By default, `digdag server` runs all of them. There're some options to disable the components: * ``--disable-executor-loop`` disables workflow executor and schedule executor. +* ``--disable-scheduler`` disables schedule executor. * ``--disable-local-agent`` disables agent. API server, workflow executor, and schedule executor use database (H2 or PostgreSQL) to communicate each other. @@ -84,7 +85,7 @@ Storage (`io.digdag.spi.Storage`) is a plugin interface that is used to store ta S3Storage is a storage implementation that stores files on Amazon S3. -Storage is injected using Extension mechanism (see bellow). +Storage is injected using Extension mechanism (see below). ## Command executor @@ -113,7 +114,7 @@ Extension needs least code to make some extension possible. But it's the hardest A typical use case is for system integrators to customize digdag for their internal use. -Many of customization points in digdag are assuming Extension to override (e.g. `io.digdag.server.Authenticator`) because it needs less code. But for ease of use, they should also accept system plugins, eventually. +Many of customization points in digdag are assuming Extension to override (i.e. most of what's bound using guice) because it needs less code. But for ease of use, they should also accept system plugins, eventually. ### System plugins diff --git a/digdag-docs/src/operators/bq.md b/digdag-docs/src/operators/bq.md index abf79ee574..62a82376b5 100644 --- a/digdag-docs/src/operators/bq.md +++ b/digdag-docs/src/operators/bq.md @@ -20,6 +20,8 @@ Note: The **bq>** operator uses [standard SQL](https://cloud.google.com/bigquery ## Secrets +When you set those parameters, use [digdag secrets command](https://docs.digdag.io/command_reference.html#secrets). + * **gcp.credential**: CREDENTIAL The [Google Cloud Platform account](https://cloud.google.com/docs/authentication#user_accounts_and_service_accounts) credential private key to use, in JSON format. @@ -155,7 +157,6 @@ Note: The **bq>** operator uses [standard SQL](https://cloud.google.com/bigquery ## Output parameters -* **bq.last_job_id** - - The id of the BigQuery job that executed this query. +* **bq.last_job_id** or **bq.last_jobid** + The id of the BigQuery job that executed this query. `bq.last_jobid` will be kept for compatibility and remove in near future release. diff --git a/digdag-docs/src/operators/bq_ddl.md b/digdag-docs/src/operators/bq_ddl.md index cdd68ddfbd..984d9110e3 100644 --- a/digdag-docs/src/operators/bq_ddl.md +++ b/digdag-docs/src/operators/bq_ddl.md @@ -24,9 +24,11 @@ ## Secrets +When you set those parameters, use [digdag secrets command](https://docs.digdag.io/command_reference.html#secrets). + * **gcp.credential**: CREDENTIAL - See [gcp.credential](../bq.html#secrets). + See [gcp.credential](bq.html#secrets). ## Options diff --git a/digdag-docs/src/operators/bq_extract.md b/digdag-docs/src/operators/bq_extract.md index 66ac2465f5..8dd088ed32 100644 --- a/digdag-docs/src/operators/bq_extract.md +++ b/digdag-docs/src/operators/bq_extract.md @@ -17,9 +17,11 @@ ## Secrets +When you set those parameters, use [digdag secrets command](https://docs.digdag.io/command_reference.html#secrets). + * **gcp.credential**: CREDENTIAL - See [gcp.credential](../bq.html#secrets). + See [gcp.credential](bq.html#secrets). ## Options @@ -99,7 +101,6 @@ ## Output parameters -* **bq.last_job_id** - - The id of the BigQuery job that performed this export. +* **bq.last_job_id** or **bq.last_jobid** + The id of the BigQuery job that performed this export. `bq.last_jobid` will be kept for compatibility and remove in near future release. diff --git a/digdag-docs/src/operators/bq_load.md b/digdag-docs/src/operators/bq_load.md index a6371cdaa7..795655da2d 100644 --- a/digdag-docs/src/operators/bq_load.md +++ b/digdag-docs/src/operators/bq_load.md @@ -16,9 +16,11 @@ ## Secrets +When you set those parameters, use [digdag secrets command](https://docs.digdag.io/command_reference.html#secrets). + * **gcp.credential**: CREDENTIAL - See [gcp.credential](../bq.html#secrets). + See [gcp.credential](bq.html#secrets). ## Options @@ -273,6 +275,6 @@ ## Output parameters -* **bq.last_job_id** +* **bq.last_job_id** or **bq.last_jobid** - The id of the BigQuery job that performed this import. + The id of the BigQuery job that performed this import. `bq.last_jobid` will be kept for compatibility and remove in near future release. diff --git a/digdag-docs/src/operators/emr.md b/digdag-docs/src/operators/emr.md index f718b4f889..04cca99ffc 100644 --- a/digdag-docs/src/operators/emr.md +++ b/digdag-docs/src/operators/emr.md @@ -29,6 +29,8 @@ For detailed information about EMR, see the [Amazon Elastic MapReduce Documentat ## Secrets +When you set those parameters, use [digdag secrets command](https://docs.digdag.io/command_reference.html#secrets). + * **aws.emr.access_key_id, aws.access_key_id** The AWS Access Key ID to use when submitting EMR jobs. diff --git a/digdag-docs/src/operators/fail.md b/digdag-docs/src/operators/fail.md index 261988cfae..1ac3727de2 100644 --- a/digdag-docs/src/operators/fail.md +++ b/digdag-docs/src/operators/fail.md @@ -2,7 +2,7 @@ **fail>** always fails and makes the workflow failed. -This operator is useful used with [if> operator](../if.html) to validate results of a previous task with `_check` directive so that a workflow fails when the validation doesn't pass. +This operator is useful used with [if> operator](if.html) to validate results of a previous task with `_check` directive so that a workflow fails when the validation doesn't pass. +fail_if_too_few: if>: ${count < 10} diff --git a/digdag-docs/src/operators/gcs_wait.md b/digdag-docs/src/operators/gcs_wait.md index 53c222c144..d02f4df37c 100644 --- a/digdag-docs/src/operators/gcs_wait.md +++ b/digdag-docs/src/operators/gcs_wait.md @@ -10,9 +10,11 @@ ## Secrets +When you set those parameters, use [digdag secrets command](https://docs.digdag.io/command_reference.html#secrets). + * **gcp.credential**: CREDENTIAL - See [gcp.credential](../bq.html#secrets). + See [gcp.credential](bq.html#secrets). ## Options diff --git a/digdag-docs/src/operators/http.md b/digdag-docs/src/operators/http.md index 3be417358f..d9a586d95d 100644 --- a/digdag-docs/src/operators/http.md +++ b/digdag-docs/src/operators/http.md @@ -16,7 +16,7 @@ ``` +notify: - http>: https://api.example.com/data/sessions/{$session_uuid} + http>: https://api.example.com/data/sessions/${session_uuid} method: POST content: status: RUNNING @@ -25,6 +25,8 @@ ## Secrets +When you set those parameters, use [digdag secrets command](https://docs.digdag.io/command_reference.html#secrets). + * **http.authorization**: STRING A string that should be included in the HTTP request as the value of the `Authorization` header. This can be used to authenticate using e.g. Oauth bearer tokens. @@ -54,7 +56,7 @@ ``` ``` - http>: https://api.example.com/data/sessions/{$session_uuid} + http>: https://api.example.com/data/sessions/${session_uuid} ``` * **method**: STRING @@ -157,3 +159,6 @@ *Note:* Enabling retries might cause the target endpoint to receive multiple duplicate HTTP requests. Thus retries should only be enabled if duplicated requests are tolerable. E.g. when the outcome of the HTTP request is *idempotent*. +* **timeout**: INTEGER + + The timeout value used for http operations. *Default*: `30`(30 seconds). diff --git a/digdag-docs/src/operators/http_call.md b/digdag-docs/src/operators/http_call.md new file mode 100644 index 0000000000..6c300a3c90 --- /dev/null +++ b/digdag-docs/src/operators/http_call.md @@ -0,0 +1,40 @@ +# http_call>: Call workflow fetched by HTTP + +**http_call>** operator makes a HTTP request, parse response body as workflow, and embeds it as a subtask. The operator is similar to [call> operator](call.html). The difference is that another workflow is fetched from HTTP. + +This operator parses response body based on returned Content-Type header. Content-Type must be set and following values are supported: + +* **application/json**: Parse the response as JSON. +* **application/x-yaml**: Use the returned body as-is. + +If appropriate Content-Type header is not returned, use content_type_override option. + +## Options + +* **http_call>**: URI + + The URI of the HTTP request. + + Examples: + + ``` + http_call>: https://api.example.com/foobar + ``` + +* **content_type_override**: application/x-yaml or application/json + + Overrides Content-Type response header returned from the server. This option is useful when the server doesn't return an appropriate Content-Type but returns a generic value such as text/plain or application/octet-stream. + + Examples: + + ``` + http_call>: https://api.example.com/foobar + content_type_override: application/x-yaml + ``` + +## Other options + +Same parameters with **http>** operator are also supported except the parameters listed below. The name of the operator is similar to [http> operator](http.html). But the role is different. See also [http> operator document](http.html). + +* store_content + diff --git a/digdag-docs/src/operators/mail.md b/digdag-docs/src/operators/mail.md index 191ec8be15..568ddf63fe 100644 --- a/digdag-docs/src/operators/mail.md +++ b/digdag-docs/src/operators/mail.md @@ -34,6 +34,8 @@ To use Gmail SMTP server, you need to do either of: ## Secrets +When you set those parameters, use [digdag secrets command](https://docs.digdag.io/command_reference.html#secrets). + * **mail.host**: HOST SMTP host name. diff --git a/digdag-docs/src/operators/param_get.md b/digdag-docs/src/operators/param_get.md index ad81f23151..034f28d4df 100644 --- a/digdag-docs/src/operators/param_get.md +++ b/digdag-docs/src/operators/param_get.md @@ -1,6 +1,6 @@ # param_get>: Get persistent data from ParamServer and set it as a value of store parameters -**param_get>** operator gets a value from a ParamServer and sets it as a value of [store parameters](../../concepts.html#export-and-store-parameters) +**param_get>** operator gets a value from a ParamServer and sets it as a value of [store parameters](../concepts.html#export-and-store-parameters) +get_single_value: param_get>: diff --git a/digdag-docs/src/operators/param_set.md b/digdag-docs/src/operators/param_set.md index 798805b5b9..a042b27250 100644 --- a/digdag-docs/src/operators/param_set.md +++ b/digdag-docs/src/operators/param_set.md @@ -11,6 +11,10 @@ key2: value2 key3: value3 + +(Note: Each parameter has expired time (TTL). +The value is 7,776,000 seconds (90days: 60sec * 60min * 24hours * 90days)). + ## System configurations ### Common diff --git a/digdag-docs/src/operators/pg.md b/digdag-docs/src/operators/pg.md index 887db4d439..2168c40236 100644 --- a/digdag-docs/src/operators/pg.md +++ b/digdag-docs/src/operators/pg.md @@ -39,6 +39,8 @@ _export: ## Secrets +When you set those parameters, use [digdag secrets command](https://docs.digdag.io/command_reference.html#secrets). + * **pg.password**: NAME Optional user password to use when connecting to the Postgres database. If you want to use multiple credentials, use `password_override` option. diff --git a/digdag-docs/src/operators/py.md b/digdag-docs/src/operators/py.md index ac89ba4a31..be466f6bf3 100644 --- a/digdag-docs/src/operators/py.md +++ b/digdag-docs/src/operators/py.md @@ -2,7 +2,7 @@ **py>** operator runs a Python script using `python` command. -See [Python API documents](../../python_api.html) for details including variable mappings to keyword arguments. +See [Python API documents](../python_api.html) for details including variable mappings to keyword arguments. +step1: py>: my_step1_method @@ -17,15 +17,85 @@ See [Python API documents](../../python_api.html) for details including variable Examples: - ``` + ```yaml + # sample.dig py>: tasks.MyWorkflow.my_task ``` -The python defaults to `python`. If an alternate python such as `/opt/conda/bin/python` is desired, use the `python` option in the `_export` section. + This example assume the following directory structure: - _export: - py: - python: /opt/conda/bin/python + ``` + . + ├── sample.dig + └── tasks + └── __init__.py + ``` - +step1: - py>: tasks.MyWorkflow.my_task2 + You can write `__init__.py` like: + + ```python + # __init__.py + class MyWorkflow(object): + def my_task(self): + print("awesome execution") + ``` + + Or, you can create put a Python script named `tasks.py` in a same directory as dig file. + + ``` + . + ├── sample.dig + └── tasks.py + ``` + + Here is the example of `tasks.py`: + + ```python + # tasks.py + class MyWorkflow(object): + def my_task(self): + print("awesome execution") + ``` + + You can write a function without creating a class as the following: + + ```yaml + # simple_sample.dig + py>: simple_tasks.my_func + ``` + + ``` + . + ├── simple_sample.dig + └── simple_tasks.py + ``` + + ```python + # simple_tasks.py + def my_func(): + print("simple execution") + ``` + +* **python**: PATH STRING or COMMAND ARGUMENTS LIST + + The python defaults to `python`. If an alternate python and options are desired, use the `python` option. + + Examples: + + ```yaml + python: /opt/conda/bin/python + ``` + + ```yaml + python: ["python", "-v"] + ``` + + It is also possible to configure in `_export` section. + + Examples: + + ```yaml + _export: + py: + python: /opt/conda/bin/python + ``` diff --git a/digdag-docs/src/operators/rb.md b/digdag-docs/src/operators/rb.md index 94870b0dd3..2334ded9b5 100644 --- a/digdag-docs/src/operators/rb.md +++ b/digdag-docs/src/operators/rb.md @@ -2,7 +2,7 @@ **rb>** operator runs a Ruby script using `ruby` command. -See [Ruby API documents](../../ruby_api.html) for details including best practices how to configure the workflow using `_export: require:`. +See [Ruby API documents](../ruby_api.html) for details including best practices how to configure the workflow using `_export: require:`. _export: rb: @@ -34,3 +34,43 @@ See [Ruby API documents](../../ruby_api.html) for details including best practic ``` require: task/my_workflow ``` + +* **ruby**: PATH STRING or COMMAND ARGUMENTS LIST + + The ruby defaults to `ruby`. If an alternate ruby and options are desired, use the `ruby` option. + + Examples: + + ``` + ruby: /usr/local/bin/ruby + ``` + + ``` + ruby: ["ruby", "-rbundler/setup"] + ``` + + It is also possible to configure in `_export` section. + + Examples: + + ``` + _export: + rb: + ruby: /usr/local/bin/ruby + ``` + +## TIPS: Run ruby with bundler + +It is possible to run ruby scripts with [bundler](https://bundler.io/) using `BUNDLE_GEMFILE` environment variable and `-rbundler/setup` option as: + + _export: + BUNDLE_GEMFILE: /path/to/Gemfile + rb: + require: tasks/my_workflow + ruby: ["ruby", "-rbundler/setup"] + + +step1: + rb>: my_step1_method + +step2: + rb>: Task::MyWorkflow.step2 + diff --git a/digdag-docs/src/operators/redshift.md b/digdag-docs/src/operators/redshift.md index a78d380311..d8c1a19c75 100644 --- a/digdag-docs/src/operators/redshift.md +++ b/digdag-docs/src/operators/redshift.md @@ -39,6 +39,8 @@ _export: ## Secrets +When you set those parameters, use [digdag secrets command](https://docs.digdag.io/command_reference.html#secrets). + * **aws.redshift.password**: NAME Optional user password to use when connecting to the Redshift database. If you want to use multiple credentials, use `password_override` option. @@ -171,6 +173,7 @@ _export: Whether this operator uses a strict transaction to prevent generating unexpected duplicated records just in case. *Default*: `true`. This operator creates and uses a status table in the database to make an operation idempotent. But if creating a table isn't allowed, this option should be false. + If the query that created the status table completed 24 hours ago, this operator drop the table in the cleanup step. Examples: diff --git a/digdag-docs/src/operators/redshift_load.md b/digdag-docs/src/operators/redshift_load.md index f66dc0a5ec..5eefdd9f8c 100644 --- a/digdag-docs/src/operators/redshift_load.md +++ b/digdag-docs/src/operators/redshift_load.md @@ -64,6 +64,8 @@ ## Secrets +When you set those parameters, use [digdag secrets command](https://docs.digdag.io/command_reference.html#secrets). + * **aws.redshift.password**: NAME Optional user password to use when connecting to the Redshift database. diff --git a/digdag-docs/src/operators/redshift_unload.md b/digdag-docs/src/operators/redshift_unload.md index 6a16b4914e..089952f08e 100644 --- a/digdag-docs/src/operators/redshift_unload.md +++ b/digdag-docs/src/operators/redshift_unload.md @@ -29,6 +29,8 @@ ## Secrets +When you set those parameters, use [digdag secrets command](https://docs.digdag.io/command_reference.html#secrets). + * **aws.redshift.password**: NAME Optional user password to use when connecting to the Redshift database. diff --git a/digdag-docs/src/operators/require.md b/digdag-docs/src/operators/require.md index f3aaf56a9d..63ee59155c 100644 --- a/digdag-docs/src/operators/require.md +++ b/digdag-docs/src/operators/require.md @@ -1,6 +1,6 @@ # require>: Depends on another workflow -**require>** operator requires completion of another workflow. This operator is similar to [call> operator](../call.html), but this operator doesn't start the other workflow if it's already running or has done for the same session time of this workflow. If the workflow is running or newly started, this operator waits until it completes. +**require>** operator requires completion of another workflow. This operator is similar to [call> operator](call.html), but this operator doesn't start the other workflow if it's already running or has done for the same session time of this workflow. If the workflow is running or newly started, this operator waits until it completes. In addition, require operator can kick the another project's workflow. ``` # workflow1.dig @@ -49,6 +49,17 @@ session_time: ${moment(last_session_time).add(i, 'day')} ``` +* **project_id**: project_id + + Id of another project. You can kick another project's workflow by setting this parameter. + + Examples: + + ``` + require>: another_project_wf + project_id: 12345 + ``` + * **ignore_failure**: BOOLEAN This operator fails when the dependent workflow finished with errors by default. @@ -60,3 +71,16 @@ ignore_failure: true ``` +* **params**: MAP + + This operator doesn't pass a parameter to another workflow. `params` options set parameters. + + Examples: + + ```yaml + +example: + require>: child + params: + param_name1: ${parent_param_name} + ``` + diff --git a/digdag-docs/src/operators/s3_wait.md b/digdag-docs/src/operators/s3_wait.md index 834283cba6..d68df49fc8 100644 --- a/digdag-docs/src/operators/s3_wait.md +++ b/digdag-docs/src/operators/s3_wait.md @@ -7,6 +7,8 @@ ## Secrets +When you set those parameters, use [digdag secrets command](https://docs.digdag.io/command_reference.html#secrets). + * **aws.s3.access_key_id, aws.access_key_id** The AWS Access Key ID to use when accessing S3. diff --git a/digdag-docs/src/operators/sh.md b/digdag-docs/src/operators/sh.md index 5b8ba8fa69..5c37a4b24b 100644 --- a/digdag-docs/src/operators/sh.md +++ b/digdag-docs/src/operators/sh.md @@ -2,7 +2,7 @@ **sh>** operator runs a shell script. -Running a shell command (Note: you can use [echo> operator](../echo.html) to show a message): +Running a shell command (Note: you can use [echo> operator](echo.html) to show a message): +step1: sh>: echo "hello world" diff --git a/digdag-docs/src/operators/td.md b/digdag-docs/src/operators/td.md index 31351142cf..0ea2eae9f4 100644 --- a/digdag-docs/src/operators/td.md +++ b/digdag-docs/src/operators/td.md @@ -9,6 +9,14 @@ +simple_query: td>: queries/simple_query.sql + +simple_query_expanded: + td>: + data: "SELECT '${session_id}' FROM nasdaq" + + +simple_query_nonexpanded: + td>: + query: "SELECT * FROM nasdaq" + +create_new_table_using_result_of_select: td>: queries/select_sql.sql create_table: mytable_${session_date_compact} @@ -34,6 +42,8 @@ ## Secrets +When you set those parameters, use [digdag secrets command](https://docs.digdag.io/command_reference.html#secrets). + * **td.apikey**: API_KEY The Treasure Data API key to use when running Treasure Data queries. @@ -50,6 +60,50 @@ td>: queries/step1.sql ``` +* **data**: query + + A query can be passed as a string. + (Note that this is actually not an option; this needs indent) + + Examples: + + ``` + td>: + data: "SELECT * FROM nasdaq" + ``` + +* **query**: query template + + A query template. This string can contain `${...}` syntax to embed variables. + + Examples: + + ``` + # Activate some customers to mail + _export: + database: project_a + + # This API returns following JSON, which has comments to track Presto Jobs and Workflows. + # It contains a query whose condition is unfortunately dynamically decided... + # ("dynamicaly" means it's not decided when they pushes this workflow) + # {"query":"-- https://console.treasuredata.com/app/workflows/sessions/${session_id}\n-- ${task_name}\nSELECT * FROM customers WHERE ..."} + +get_queries + http>: http://example.com/get_queries + store_content: true + + # doesn't expand given string + +td_data: + td>: + data: ${JSON.parse(http.last_content)["query"]} + result_connection: mail_something + + # it expands given string + +td_query: + td>: + query: ${JSON.parse(http.last_content)["query"]} + result_connection: mail_something + ``` + * **create_table**: NAME Name of a table to create from the results. This option deletes the table if it already exists. @@ -150,6 +204,12 @@ Set Priority (From `-2` (VERY LOW) to `2` (VERY HIGH) , default: 0 (NORMAL)). +* **job_retry**: 0 + + Set automatic job retry count (default: 0). + + We recommend that you not set retry count over 10. If the job is not succeessful less than 10 times retry, it needs some fix a cause of failure. + * **result_connection**: NAME Use a connection to write the query results to an external system. @@ -206,10 +266,20 @@ hive_pool_name: poc ``` +* **engine_version**: NAME + + Specify engine version for Hive and Presto. + + Examples: + + ``` + engine: hive + engine_version: stable + ``` + ## Output parameters -* **td.last_job_id** -* **td.last_job.id** +* **td.last_job_id** or **td.last_job.id** The job id this task executed. diff --git a/digdag-docs/src/operators/td_ddl.md b/digdag-docs/src/operators/td_ddl.md index 21ae5e2f16..f9fe6a5ac4 100644 --- a/digdag-docs/src/operators/td_ddl.md +++ b/digdag-docs/src/operators/td_ddl.md @@ -19,8 +19,25 @@ td_ddl>: rename_tables: [{from: "my_table_${session_date_compact}", to: "my_table"}] + +If you would like to specify a different database which is not declared with _export, you can specify the database name under the options as below. + + + _export: + td: + database: test_db1 + + +task1: + td_ddl>: + create_tables: [test_ddl1, test_ddl2] + database: test_db2 + + + ## Secrets +When you set those parameters, use [digdag secrets command](https://docs.digdag.io/command_reference.html#secrets). + * **td.apikey:** API_KEY The Treasure Data API key to use when performing Treasure Data operations. diff --git a/digdag-docs/src/operators/td_for_each.md b/digdag-docs/src/operators/td_for_each.md index b3994c8438..71e30fe247 100644 --- a/digdag-docs/src/operators/td_for_each.md +++ b/digdag-docs/src/operators/td_for_each.md @@ -18,13 +18,15 @@ For example, if you run a query `select email, name from users` and the query re ## Secrets +When you set those parameters, use [digdag secrets command](https://docs.digdag.io/command_reference.html#secrets). + * **td.apikey**: API_KEY The Treasure Data API key to use when running Treasure Data queries. ## Options -* **td>**: FILE.sql +* **td_for_each>**: FILE.sql Path to a query template file. This file can contain `${...}` syntax to embed variables. @@ -70,6 +72,12 @@ For example, if you run a query `select email, name from users` and the query re Set Priority (From `-2` (VERY LOW) to `2` (VERY HIGH) , default: 0 (NORMAL)). +* **job_retry**: 0 + + Set automatic job retry count (default: 0). + + We recommend that you not set retry count over 10. If the job is not succeessful less than 10 times retry, it needs some fix a cause of failure. + * **presto_pool_name**: NAME Name of a resource pool to run the query in. @@ -93,10 +101,20 @@ For example, if you run a query `select email, name from users` and the query re pool_name: poc ``` +* **engine_version**: NAME + + Specify engine version for Hive and Presto. + + Examples: + + ``` + engine: hive + engine_version: stable + ``` + ## Output parameters -* **td.last_job_id** -* **td.last_job.id** +* **td.last_job_id** or **td.last_job.id** The job id this task executed. diff --git a/digdag-docs/src/operators/td_load.md b/digdag-docs/src/operators/td_load.md index 76354410c2..459152aba0 100644 --- a/digdag-docs/src/operators/td_load.md +++ b/digdag-docs/src/operators/td_load.md @@ -13,6 +13,8 @@ ## Secrets +When you set those parameters, use [digdag secrets command](https://docs.digdag.io/command_reference.html#secrets). + * **td.apikey**: API_KEY The Treasure Data API key to use when submitting Treasure Data bulk load jobs. @@ -21,7 +23,7 @@ * **td_load>**: FILE.yml - Path to a YAML template file. This configuration needs to be guessed using td command. If you saved DataConnector job on Treasure Data, you can use job name instead of YAML path. + Path to a YAML template file. This configuration needs to be guessed using td command. If you saved DataConnector job on Treasure Data, you can use [Unique ID](https://support.treasuredata.com/hc/en-us/articles/360001474328-Reference-an-Input-Data-Transfer#Configuring%20your%20Unique%20ID%20Incremental%20Data%20Transfer) instead of YAML path. Examples: @@ -29,6 +31,10 @@ td_load>: imports/load.yml ``` + ``` + td_load>: unique_id + ``` + * **database**: NAME Name of the database load data to. @@ -60,8 +66,7 @@ ## Output parameters -* **td.last_job_id** -* **td.last_job.id** +* **td.last_job_id** or **td.last_job.id** The job id this task executed. diff --git a/digdag-docs/src/operators/td_partial_delete.md b/digdag-docs/src/operators/td_partial_delete.md index 65611ba0da..f0188302f5 100644 --- a/digdag-docs/src/operators/td_partial_delete.md +++ b/digdag-docs/src/operators/td_partial_delete.md @@ -14,6 +14,8 @@ Time range needs to be hourly. Setting non-zero values to minutes or seconds wil ## Secrets +When you set those parameters, use [digdag secrets command](https://docs.digdag.io/command_reference.html#secrets). + * **td.apikey**: API_KEY The Treasure Data API key to use when running Treasure Data queries. diff --git a/digdag-docs/src/operators/td_run.md b/digdag-docs/src/operators/td_run.md index 516616a954..3ec5272bf1 100644 --- a/digdag-docs/src/operators/td_run.md +++ b/digdag-docs/src/operators/td_run.md @@ -10,7 +10,7 @@ td_run>: 12345 +step2: td_run>: myquery2 - session_time: 2016-01-01T01:01:01+0000 + session_time: 2016-01-01T01:01:01+00:00 ## Examples @@ -18,6 +18,8 @@ ## Secrets +When you set those parameters, use [digdag secrets command](https://docs.digdag.io/command_reference.html#secrets). + * **td.apikey**: API_KEY The Treasure Data API key to use when running Treasure Data queries. @@ -81,8 +83,7 @@ ## Output parameters -* **td.last_job_id** -* **td.last_job.id** +* **td.last_job_id** or **td.last_job.id** The job id this task executed. diff --git a/digdag-docs/src/operators/td_table_export.md b/digdag-docs/src/operators/td_table_export.md index 86ef35923c..9705daa17a 100644 --- a/digdag-docs/src/operators/td_table_export.md +++ b/digdag-docs/src/operators/td_table_export.md @@ -16,6 +16,8 @@ NOTE: We're limiting export capability to only us-east region S3 bucket. In gene ## Secrets +When you set those parameters, use [digdag secrets command](https://docs.digdag.io/command_reference.html#secrets). + * **td.apikey**: API_KEY The Treasure Data API key to use when running Treasure Data table exports. @@ -125,8 +127,7 @@ NOTE: We're limiting export capability to only us-east region S3 bucket. In gene ## Output parameters -* **td.last_job_id** -* **td.last_job.id** +* **td.last_job_id** or **td.last_job.id** The job id this task executed. diff --git a/digdag-docs/src/operators/td_wait.md b/digdag-docs/src/operators/td_wait.md index 128fc92f13..9252d50e43 100644 --- a/digdag-docs/src/operators/td_wait.md +++ b/digdag-docs/src/operators/td_wait.md @@ -1,6 +1,6 @@ # td_wait>: Waits for data arriving at Treasure Data table -**td_wait>** operator runs a query periodically until it returns true. This operator can use more complex query compared to [td_wait_table> operator](../td_wait_table.html). +**td_wait>** operator runs a query periodically until it returns true. This operator can use more complex query compared to [td_wait_table> operator](td_wait_table.html). _export: td: @@ -20,6 +20,8 @@ Example queries: ## Secrets +When you set those parameters, use [digdag secrets command](https://docs.digdag.io/command_reference.html#secrets). + * **td.apikey**: API_KEY The Treasure Data API key to use when running Treasure Data queries. @@ -68,10 +70,20 @@ Example queries: engine: presto ``` +* **interval**: 30s + + Set Interval (default: 30s (30 second)). + * **priority**: 0 Set Priority (From `-2` (VERY LOW) to `2` (VERY HIGH) , default: 0 (NORMAL)). +* **job_retry**: 0 + + Set automatic job retry count (default: 0). + + We recommend that you not set retry count over 10. If the job is not succeessful less than 10 times retry, it needs some fix a cause of failure. + * **presto_pool_name**: NAME Name of a resource pool to run the queries in. @@ -95,10 +107,20 @@ Example queries: hive_pool_name: poc ``` +* **engine_version**: NAME + + Specify engine version for Hive and Presto. + + Examples: + + ``` + engine: hive + engine_version: stable + ``` + ## Output parameters -* **td.last_job_id** -* **td.last_job.id** +* **td.last_job_id** or **td.last_job.id** The job id this task executed. diff --git a/digdag-docs/src/operators/td_wait_table.md b/digdag-docs/src/operators/td_wait_table.md index 7bbe48a43b..80dc6f1233 100644 --- a/digdag-docs/src/operators/td_wait_table.md +++ b/digdag-docs/src/operators/td_wait_table.md @@ -14,13 +14,15 @@ ## Secrets +When you set those parameters, use [digdag secrets command](https://docs.digdag.io/command_reference.html#secrets). + * **td.apikey**: API_KEY The Treasure Data API key to use when running Treasure Data queries. ## Options -* **td_wait_table>**: FILE.sql +* **td_wait_table>**: NAME Name of a table. @@ -72,10 +74,20 @@ engine: presto ``` +* **interval**: 30s + + Set Interval (default: 30s (30 second)). + * **priority**: 0 Set Priority (From `-2` (VERY LOW) to `2` (VERY HIGH) , default: 0 (NORMAL)). +* **job_retry**: 0 + + Set automatic job retry count (default: 0). + + We recommend that you not set retry count over 10. If the job is not succeessful less than 10 times retry, it needs some fix a cause of failure. + * **presto_pool_name**: NAME Name of a resource pool to run the queries in. @@ -98,3 +110,15 @@ engine: hive hive_pool_name: poc ``` + +* **engine_version**: NAME + + Specify engine version for Hive and Presto. + + Examples: + + ``` + engine: hive + engine_version: stable + ``` + diff --git a/digdag-docs/src/operators/workflow_control.rst b/digdag-docs/src/operators/workflow_control.rst index f48ce75c24..c22d95e5c1 100644 --- a/digdag-docs/src/operators/workflow_control.rst +++ b/digdag-docs/src/operators/workflow_control.rst @@ -5,6 +5,7 @@ Workflow control operators :maxdepth: 1 call.md + http_call.md require.md loop.md for_each.md diff --git a/digdag-docs/src/releases.rst b/digdag-docs/src/releases.rst index 2e950d5d4b..a73508fc84 100644 --- a/digdag-docs/src/releases.rst +++ b/digdag-docs/src/releases.rst @@ -5,6 +5,13 @@ Release Notes :maxdepth: 1 # add new version here + releases/release-0.9.40 + releases/release-0.9.39 + releases/release-0.9.38 + releases/release-0.9.37 + releases/release-0.9.36 + releases/release-0.9.35 + releases/release-0.9.34 releases/release-0.9.33 releases/release-0.9.32 releases/release-0.9.31 diff --git a/digdag-docs/src/releases/release-0.9.34.rst b/digdag-docs/src/releases/release-0.9.34.rst new file mode 100644 index 0000000000..4c903bfd24 --- /dev/null +++ b/digdag-docs/src/releases/release-0.9.34.rst @@ -0,0 +1,34 @@ +Release 0.9.34 +============== + +General Changes +--------------- + +* Many documents, help improvements. + +* Support ``api.max_archive_total_size_limit`` system parameter. [#994] + +* Support backfill command with [#1021] + +* UI improvement [#989] + +Fixed Issues +------------ + +* Downgrade Gradle 5.2 to 4.8 to avoid CI fail. + +Release Date +------------ +2019-02-28 + +Contributors +------------ +* Emanuel Haupt +* Hideaki Hosokawa +* Hiroyuki Sato +* sonots +* kiyoto +* Muga Nishizawa +* Satoru Kamikaseda +* Shota Suzuki +* You Yamagata diff --git a/digdag-docs/src/releases/release-0.9.35.rst b/digdag-docs/src/releases/release-0.9.35.rst new file mode 100644 index 0000000000..acd74669d9 --- /dev/null +++ b/digdag-docs/src/releases/release-0.9.35.rst @@ -0,0 +1,25 @@ +Release 0.9.35 +============== + +General Changes +--------------- + +* Enhance ruby option in rb>: operator [#1022] +* Enhance python option in py>: operator [#1023] +* Support reschedule command with in CLI [#1023] +* Support engine_version parameter in TD operators. [#1045] + +Fixed Issues +------------ + +* Minor document issues. + +Release Date +------------ +2019-03-12 + +Contributors +------------ +* sonots +* Muga Nishizawa +* You Yamagata diff --git a/digdag-docs/src/releases/release-0.9.36.rst b/digdag-docs/src/releases/release-0.9.36.rst new file mode 100644 index 0000000000..af07ef01d3 --- /dev/null +++ b/digdag-docs/src/releases/release-0.9.36.rst @@ -0,0 +1,35 @@ +Release 0.9.36 +============== + + +General Changes +--------------- + +* Enhance validation on push command. [#1026] +* Support digdag server --disable-scheduler option. [#1048] +* Support `digdag projects` cmd. [#1060] +* UI Show attempt params to attempt/session views. [#1068] +* Support HikariCP JMX metrics. [#1072] + +Fixed Issues +------------ + +* Fix ParamServer DEFAULT_TTL value. [#1054] +* Cli help improvements [#1070]. +* Fix infinite task retry caused by AssertionError. [#1073] +* Document improvements. +* Build/CI improvements. + +Release Date +------------ +2019-04-16 + +Contributors +------------ +* Hiroyuki Sato +* Ryohei UEDA +* sonots +* Kazuki Ito +* Shota Suzuki +* Muga Nishizawa +* You Yamagata diff --git a/digdag-docs/src/releases/release-0.9.37.rst b/digdag-docs/src/releases/release-0.9.37.rst new file mode 100644 index 0000000000..2b6a28e813 --- /dev/null +++ b/digdag-docs/src/releases/release-0.9.37.rst @@ -0,0 +1,35 @@ +Release 0.9.37 +============== + +General Changes +--------------- +* Improve error message on `rb>' operator. [#1024] +* Support `run_options` and `build_options` in docker. [#1025] +* Introduce `http_call>` operator. [#1082] +* Introduce `max_interval` option in retry. [#1104] +* Introduce `migrate` command for database migration. [#1061] + +Fixed Issues +------------ +* Fix status filter in UI. [#1118] +* Fix url encoded character issue in log [#1090] +* Document improvements. +* Build/CI improvements. +* Performance improvements. +* Update some UI packages for security vulnerabilities. + +Release Date +------------ +2019-05-31 + +Contributors +------------ +* Emanuel Haupt +* Hiroyuki Sato +* Katsuya Tajima +* Muga Nishizawa +* Sadayuki Furuhashi +* Satoru Kamikaseda +* Shota Suzuki +* sonots +* You Yamagata diff --git a/digdag-docs/src/releases/release-0.9.38.rst b/digdag-docs/src/releases/release-0.9.38.rst new file mode 100644 index 0000000000..4827bab4d8 --- /dev/null +++ b/digdag-docs/src/releases/release-0.9.38.rst @@ -0,0 +1,40 @@ +Release 0.9.38 +============== + +General Changes +--------------- +* Introduce `max_response_content_size` system config for `http_call>` [#1138] +* Introduce `content_type_override` parameter in `http_call` [#1166] +* Improve error message and stacktrace on `py>` [#1143] +* Upgrade Sphinx version to 2.1.1 and now using python3 for document building. [#1154] + + +Fixed Issues +------------ +* Remove useless migration execution in CLI [#1137] +* Fix an issue on `bq_load>` [#1141] +* Stop using a deprecated module in `py>` to suppress warning message. [#1162] +* Document improvements. +* Build/CI improvements. +* Update some packages for security vulnerabilities. + + + +Release Date +------------ +2019-07-09 + +Contributors +------------ +* Hiroyuki Sato +* John Yani +* rubyu +* Aki Ariga +* Edd Steel +* Muga Nishizawa +* Sadayuki Furuhashi +* Satoru Kamikaseda +* Shota Suzuki +* Timothée Peignier +* yui-knk +* You Yamagata diff --git a/digdag-docs/src/releases/release-0.9.39.rst b/digdag-docs/src/releases/release-0.9.39.rst new file mode 100644 index 0000000000..60adbf318c --- /dev/null +++ b/digdag-docs/src/releases/release-0.9.39.rst @@ -0,0 +1,26 @@ +Release 0.9.39 +============== + +General Changes +--------------- + +* Introduce Authenticator SPI. [#1098] +* Introduce basic auth authenticator. [#1099] + +This release changed Authenticator interface. Please take care if you use DigdagEmbed and customize Authenticator. + +Fixed Issues +------------ +* Build/CI improvements. +* Update some packages for security vulnerabilities. + +Release Date +------------ +2019-07-17 + +Contributors +------------ +* Pierre Delagrave +* Shota Suzuki +* Muga Nishizawa +* You Yamagata diff --git a/digdag-docs/src/releases/release-0.9.40.rst b/digdag-docs/src/releases/release-0.9.40.rst new file mode 100644 index 0000000000..d27429520a --- /dev/null +++ b/digdag-docs/src/releases/release-0.9.40.rst @@ -0,0 +1,49 @@ +Release 0.9.40 +============== + +General Changes +--------------- + +* Improve performance of project list API. [#1187] +* Task log is split by size in configuration. [#1209] +* Output of echo> operator is stored to task log. [#1221] +* Upgrade Guice. [#791] +* Document improvements. [#1144 #1181 #1201 #1218 #1236 #1273] + + +Fixed Issues +------------ +* Fix BigQuery operators parameter name. [#1225] +* Fix migration command issue. [#1248] +* CLI related improvements. [#1257 #1250] +* UI packages update. [#1185 #1186 #1214] +* CI related improvements. [#1230 #1255] + +Release Date +------------ +2019-12-11 + +Contributors +------------ +* Aki Ariga +* Edd Steel +* Hiroyuki Sato +* John Yani +* Kohki Sato +* Muga Nishizawa +* NARUSE, Yui +* NomadBlacky +* Pierre Delagrave +* Sadayuki Furuhashi +* Satoru Kamikaseda +* Shota Suzuki +* Timothée Peignier +* Weiming-Zhu +* Y.Kentaro +* katsuyan +* makoto.toriyama +* morihaya +* rubyu +* yui-knk +* zaimy +* yoyama diff --git a/digdag-docs/src/rest_api.rst b/digdag-docs/src/rest_api.rst new file mode 100644 index 0000000000..36ddb89f9c --- /dev/null +++ b/digdag-docs/src/rest_api.rst @@ -0,0 +1,5 @@ +REST API +================================== + +Open API document is available at `docs.digdag.io/api `_. + diff --git a/digdag-docs/src/scheduling_workflow.rst b/digdag-docs/src/scheduling_workflow.rst index 114a25fef8..ed2551c41d 100644 --- a/digdag-docs/src/scheduling_workflow.rst +++ b/digdag-docs/src/scheduling_workflow.rst @@ -24,30 +24,46 @@ In ``schedule:`` directive, you can choose one of following options: =============================== =========================================== ========================== Syntax Description Example =============================== =========================================== ========================== -daily>: ``HH:MM:SS`` Run this job every day at HH:MM:SS daily>: 07:00:00 hourly>: ``MM:SS`` Run this job every hour at MM:SS hourly>: 30:00 +daily>: ``HH:MM:SS`` Run this job every day at HH:MM:SS daily>: 07:00:00 weekly>: ``DDD,HH:MM:SS`` Run this job every week on DDD at HH:MM:SS weekly>: Sun,09:00:00 monthly>: ``D,HH:MM:SS`` Run this job every month on D at HH:MM:SS monthly>: 1,09:00:00 minutes_interval>: ``M`` Run this job every this number of minutes minutes_interval>: 30 cron>: ``CRON`` Use cron format for complex scheduling cron>: 42 4 1 * * =============================== =========================================== ========================== +.. note:: + + When a field is starting with ``*`` , enclosing in quotes is necessary by a limitasion to be a vaild YAML. + ``digdag check`` command shows when the first schedule will start: .. code-block:: console $ ./digdag check ... - + Schedules (1 entries): daily_job: daily>: "07:00:00" first session time: 2016-02-10 16:00:00 -0800 - first runs at: 2016-02-10 23:00:00 -0800 (11h 16m 32s later) + first scheduled to run at: 2016-02-10 23:00:00 -0800 (in 11h 16m 32s) .. note:: - When a field is starting with ``*`` , enclosing in quotes is necessary by a limitasion to be a vaild YAML. + | When you use ``hourly``, ``daily``, ``weekly`` or ``monthly``, a session time may not be same with actual run time. + | The session time is actual run day's 00:00:00 (in case ``hourly``, hour's 00:00). + + .. table:: Schedule Examples (As of system clock: 2019-02-24 14:20:10 +0900) + + ======================= ========================= ========================= + schedule first session time first scheduled to run at + ======================= ========================= ========================= + hourly>: "32:32" 2019-02-24 14:00:00 +0900 2019-02-24 14:32:32 +0900 + daily>: "10:32:32" 2019-02-25 00:00:00 +0900 2019-02-25 10:32:32 +0900 + weekly>: "2,10:32:32" 2019-02-26 00:00:00 +0900 2019-02-24 14:32:32 +0900 + monthly>: "2,10:32:32" 2019-03-02 00:00:00 +0900 2019-03-02 10:32:32 +0900 + ======================= ========================= ========================= Running scheduler @@ -89,6 +105,23 @@ Setting an alert if a workflow doesn't finish within expected time +long_running_job: sh>: long_running_job.sh +In sla: directive, you can select either the ``time`` or ``duration`` option. + +=============================== ================================================== ========================== +Syntax Description Example +=============================== ================================================== ========================== +time>: ``HH:MM:SS`` Set this job must be completed by ``HH:MM:SS`` time>: 12:30:00 +duration>: ``HH:MM:SS`` Set this job must be completed during ``HH:MM:SS`` duration>: 00:05:00 +=============================== ================================================== ========================== + +Options +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +This parameter supports fail: BOOLEAN and alert: BOOLEAN options. Setting fail: true makes the workflow failed. Setting alert: true sends an notification using above notification mechanism. + +* Setting ``fail: true`` makes the workflow failed. +* Setting ``alert: true`` sends an notification using above notification mechanism. + Skipping a next workflow session ---------------------------------- @@ -105,7 +138,7 @@ It’s this case it’s best to skip the next hour’s workflow session, and ins Skipping backfill. ------------------ -The `skip_delayed_by` option enables `backfill `_ command to skip creating sessions delayed by the specified time. When Digdag restarts, sessions of a schedule are automatically created until the next of `last_session_time`. +The `skip_delayed_by` option enables `backfill `_ command to skip creating sessions delayed by the specified time. When Digdag restarts, sessions of a schedule are automatically created until the next of `last_session_time`. For example, If Digdag restarts at 20:00:00 and a workflow scheduled as below, it creates three sessions (19:59:00, 19:58:00 and 19:57:00). And then, Digdag doesn't create sessions which are before 19:56:00 by the option. diff --git a/digdag-docs/src/workflow_definition.rst b/digdag-docs/src/workflow_definition.rst index 1ea7295e5d..4ad042b362 100644 --- a/digdag-docs/src/workflow_definition.rst +++ b/digdag-docs/src/workflow_definition.rst @@ -37,7 +37,7 @@ Key names starting with ``+`` sign is a task. Tasks run from the top to bottom i operators> ---------------------------------- -A task with ``type>: command`` or ``_type: NAME`` parameter executes an action. You can choose various kinds of operators such as `running shell scripts `_, `Python methods `_, `sending email `_, etc. See `Operators `_ page for the list of built-in operators. +A task with ``type>: command`` or ``_type: NAME`` parameter executes an action. You can choose various kinds of operators such as `running shell scripts `_, `Python methods `_, `sending email `_, etc. See `Operators `_ page for the list of built-in operators. .. note:: @@ -55,6 +55,7 @@ Here is the list of built-in variables: Name Description Example =============================== =========================================== ========================== **timezone** Timezone of this workflow America/Los_Angeles +**project_id** The project ID of this workflow 12345 **session_uuid** Unique UUID of this session 414a8b9e-b365-4394-916a-f0ed9987bd2b **session_id** Integer ID of this session 2381 **session_time** Time of this session with time zone 2016-01-30T00:00:00-08:00 @@ -78,6 +79,8 @@ Name Example (hourly schedule) Example (daily s **last_session_local_time** 2016-01-29 23:00:00 2016-01-29 00:00:00 **last_session_tz_offset** -0800 -0800 **last_session_unixtime** 1454137200 1454054400 +**last_executed_session_time** 2016-01-29T23:00:00-08:00 2016-01-29T00:00:00-08:00 +**last_executed_session_unixtime** 1454137200 1454054400 **next_session_time** 2016-01-30T01:00:00-08:00 2016-01-31T00:00:00-08:00 **next_session_date** 2016-01-30 2016-01-31 **next_session_date_compact** 20160130 20160131 @@ -87,6 +90,7 @@ Name Example (hourly schedule) Example (daily s ==================================== ========================== ========================== last_session_time is the timestamp of the last schedule. If the schedule is hourly, it's the last hour. If the schedule is daily, it's yesterday. It doesn't matter whether the last schedule actually ran or not. It's simply set to the last timestamp calculated from the current session time. +last_executed_session_time variable is the previously executed session time. Calculating variables ---------------------------------- @@ -258,7 +262,7 @@ If ``_background: true`` parameter is set to a task or group, the task or group Retrying failed tasks automatically ----------------------------------- -If ``_retry: N`` (N is an integer: 1, 2, 3, ...) parameter is set to a group, it retires the group from the beginning when one or more children failed. +If ``_retry: N`` (N is an integer: 1, 2, 3, ...) parameter is set to a group, it retries the group from the beginning when one or more children failed. .. code-block:: yaml @@ -280,7 +284,7 @@ If ``_retry: N`` (N is an integer: 1, 2, 3, ...) parameter is set to a group, it sh>: tasks/analyze_prepared_data_sets.sh -Tasks also support ``_retry: N`` parameter to retry the specific task. Note that some operators don't support the generic ``_retry`` option but has its own options to control retrying behavior. +Tasks also support ``_retry: N`` parameter to retry the specific task. Note that some operators don't support the generic ``_retry`` option but have their own options to control retrying behavior. Operators that involve external systems may reuse previous results. To ensure an external task is repeated, you may use ``_retry`` at the group level. You can set interval to _retry as follows. @@ -316,5 +320,5 @@ If an operator configuration is set at ``_error:`` parameter, the operator runs +analyze: sh>: tasks/analyze_prepared_data_sets.sh -To send mails, you can use `mail> operator `_. +To send mails, you can use `mail> operator `_. diff --git a/digdag-guice-rs/build.gradle b/digdag-guice-rs/build.gradle index 5735b4ed26..07f46ac22e 100644 --- a/digdag-guice-rs/build.gradle +++ b/digdag-guice-rs/build.gradle @@ -1,6 +1,6 @@ dependencies { - compile 'com.google.inject:guice:4.0' + compile 'com.google.inject:guice:4.2.2' compile 'javax.servlet:javax.servlet-api:3.1.0' compile 'org.jboss.resteasy:resteasy-jaxrs:3.0.13.Final' compile 'org.jboss.resteasy:async-http-servlet-3.0:3.0.13.Final' diff --git a/digdag-plugin-utils/src/main/java/io/digdag/util/RetryControl.java b/digdag-plugin-utils/src/main/java/io/digdag/util/RetryControl.java index c7a74bfe9e..f9af6172d8 100644 --- a/digdag-plugin-utils/src/main/java/io/digdag/util/RetryControl.java +++ b/digdag-plugin-utils/src/main/java/io/digdag/util/RetryControl.java @@ -1,9 +1,9 @@ package io.digdag.util; import com.fasterxml.jackson.databind.JsonNode; +import com.google.common.base.Optional; import io.digdag.client.config.Config; import io.digdag.client.config.ConfigException; -//import io.digdag.core.workflow.TaskConfig; public class RetryControl { @@ -12,13 +12,19 @@ public static RetryControl prepare(Config config, Config stateParams, boolean en return new RetryControl(config, stateParams, enableByDefault); } - private enum RetryIntervalType { + private enum RetryIntervalType + { CONSTATNT("constant"), EXPONENTIAL("exponential"); + String type; - private RetryIntervalType(final String type) { + + private RetryIntervalType(final String type) + { this.type = type; } - public static RetryIntervalType find(String value) { + + public static RetryIntervalType find(String value) + { for (RetryIntervalType r : RetryIntervalType.values()) { if (r.type.equalsIgnoreCase(value)) { return r; @@ -32,53 +38,42 @@ public static RetryIntervalType find(String value) { private final int retryLimit; private final int retryCount; private final int retryInterval; + private final Optional maxRetryInterval; private final RetryIntervalType retryIntervalType; - private int intValueTextual(JsonNode node){ - if(node.isTextual()){ - return Integer.parseInt(node.asText()); - } - else { - return node.intValue(); - } - } - private RetryControl(Config config, Config stateParams, boolean enableByDefault) { this.stateParams = stateParams; this.retryCount = stateParams.get("retry_count", int.class, 0); - final JsonNode retry = config.getInternalObjectNode().get("_retry"); + final JsonNode retryNode = config.getInternalObjectNode().get("_retry"); try { - if (retry == null) { // No _retry description. default. + if (retryNode == null) { // No _retry description. default. this.retryLimit = enableByDefault ? 3 : 0; this.retryInterval = 0; + this.maxRetryInterval = Optional.absent(); this.retryIntervalType = RetryIntervalType.CONSTATNT; } - else if (retry.isNumber() || retry.isTextual()) { // Only limit is set. - //If set as variable ${..}, the value become text. So text data is also accepted. - this.retryLimit = intValueTextual(retry); + else if (retryNode.isNumber() || retryNode.isTextual()) { // Only limit is set. + // If set as variable ${..}, the value become text. Here uses Config.get(type, key) + // to get retryLimit so that text is also accepted. + this.retryLimit = config.get("_retry", int.class); this.retryInterval = 0; + this.maxRetryInterval = Optional.absent(); this.retryIntervalType = RetryIntervalType.CONSTATNT; } - else if (retry.isObject()) { // json format - this.retryLimit = intValueTextual(retry.get("limit")); - if (retry.has("interval")) { - this.retryInterval = intValueTextual(retry.get("interval")); - } - else { - this.retryInterval = 0; - } - if (retry.has("interval_type")) { - this.retryIntervalType = RetryIntervalType.find(retry.get("interval_type").textValue()); - } - else { - this.retryIntervalType = RetryIntervalType.CONSTATNT; - } + else if (retryNode.isObject()) { // json format + Config retry = config.getNested("_retry"); + this.retryLimit = retry.get("limit", int.class); + this.retryInterval = retry.getOptional("interval", int.class).or(0).intValue(); + this.maxRetryInterval = retry.getOptional("max_interval", int.class); + this.retryIntervalType = retry.getOptional("interval_type", String.class) + .transform(RetryIntervalType::find) + .or(RetryIntervalType.CONSTATNT); } else { // Unknown format - throw new ConfigException(String.format("Invalid _retry format:%s", retry.toString())); + throw new ConfigException(String.format("Invalid _retry format:%s", retryNode.toString())); } } catch(NumberFormatException nfe) { @@ -98,7 +93,10 @@ public int getNextRetryInterval() interval = retryInterval; break; case EXPONENTIAL: - interval = retryInterval * (int)Math.pow(2, retryCount); + interval = retryInterval * (int) Math.pow(2, retryCount); + if (maxRetryInterval.isPresent()) { + interval = Math.min(interval, maxRetryInterval.get()); + } break; } return interval; diff --git a/digdag-server/src/main/java/io/digdag/server/AuthRequestFilter.java b/digdag-server/src/main/java/io/digdag/server/AuthRequestFilter.java index e46caecf67..ea1abe3a63 100644 --- a/digdag-server/src/main/java/io/digdag/server/AuthRequestFilter.java +++ b/digdag-server/src/main/java/io/digdag/server/AuthRequestFilter.java @@ -4,6 +4,7 @@ import com.google.common.collect.ImmutableMap; import com.google.inject.Inject; import io.digdag.client.config.ConfigFactory; +import io.digdag.spi.Authenticator; import javax.ws.rs.NotAuthorizedException; import javax.ws.rs.container.ContainerRequestContext; diff --git a/digdag-server/src/main/java/io/digdag/server/ServerBootstrap.java b/digdag-server/src/main/java/io/digdag/server/ServerBootstrap.java index 9ab44cefd7..e62d60269b 100644 --- a/digdag-server/src/main/java/io/digdag/server/ServerBootstrap.java +++ b/digdag-server/src/main/java/io/digdag/server/ServerBootstrap.java @@ -10,6 +10,7 @@ import io.digdag.client.config.Config; import io.digdag.core.agent.ExtractArchiveWorkspaceManager; import io.digdag.core.agent.WorkspaceManager; +import io.digdag.core.plugin.PluginSet; import io.digdag.guice.rs.GuiceRsServerControl; import io.digdag.guice.rs.server.undertow.UndertowServer; import io.digdag.guice.rs.server.undertow.UndertowServerControl; @@ -30,11 +31,18 @@ public class ServerBootstrap protected final Version version; protected final ServerConfig serverConfig; + private final PluginSet systemPlugins; - public ServerBootstrap(Version version, ServerConfig serverConfig) + public ServerBootstrap(Version version, ServerConfig serverConfig, PluginSet systemPlugins) { this.version = version; this.serverConfig = serverConfig; + this.systemPlugins = systemPlugins; + } + + public ServerBootstrap(Version version, ServerConfig serverConfig) + { + this(version, serverConfig, PluginSet.empty()); } @Override @@ -49,7 +57,7 @@ protected DigdagEmbed.Bootstrap digdagBootstrap() return new DigdagEmbed.Bootstrap() .setEnvironment(serverConfig.getEnvironment()) .setSystemConfig(serverConfig.getSystemConfig()) - //.setSystemPlugins(loadSystemPlugins(serverConfig.getSystemConfig())) + .setSystemPlugins(systemPlugins) .overrideModulesWith((binder) -> { binder.bind(WorkspaceManager.class).to(ExtractArchiveWorkspaceManager.class).in(Scopes.SINGLETON); binder.bind(Version.class).toInstance(version); diff --git a/digdag-server/src/main/java/io/digdag/server/ServerConfig.java b/digdag-server/src/main/java/io/digdag/server/ServerConfig.java index 67afa29ef2..a02003401b 100644 --- a/digdag-server/src/main/java/io/digdag/server/ServerConfig.java +++ b/digdag-server/src/main/java/io/digdag/server/ServerConfig.java @@ -29,6 +29,7 @@ public interface ServerConfig public static final int DEFAULT_PORT = 65432; public static final String DEFAULT_BIND = "127.0.0.1"; public static final String DEFAULT_ACCESS_LOG_PATTERN = "json"; + public static final String DEFAULT_AUTHENTICATOR_CLASS = "io.digdag.standards.auth.jwt.JwtAuthenticator"; public Optional getServerRuntimeInfoPath(); @@ -50,12 +51,15 @@ public interface ServerConfig public Map getEnvironment(); + public String getAuthenticatorClass(); + public static ImmutableServerConfig.Builder defaultBuilder() { return ImmutableServerConfig.builder() .port(DEFAULT_PORT) .bind(DEFAULT_BIND) .accessLogPattern(DEFAULT_ACCESS_LOG_PATTERN) + .authenticatorClass(DEFAULT_AUTHENTICATOR_CLASS) .executorEnabled(true); } @@ -91,6 +95,7 @@ public static ServerConfig convertFrom(Config config) .headers(readPrefixed.apply("server.http.headers.")) .systemConfig(ConfigElement.copyOf(config)) // systemConfig needs to include other keys such as server.port so that ServerBootstrap.initialize can recover ServerConfig from this systemConfig .environment(readPrefixed.apply("server.environment.")) + .authenticatorClass(config.get("server.authenticator-class", String.class, DEFAULT_AUTHENTICATOR_CLASS)) .build(); } diff --git a/digdag-server/src/main/java/io/digdag/server/ServerModule.java b/digdag-server/src/main/java/io/digdag/server/ServerModule.java index e878d3359f..fa83a94937 100644 --- a/digdag-server/src/main/java/io/digdag/server/ServerModule.java +++ b/digdag-server/src/main/java/io/digdag/server/ServerModule.java @@ -3,7 +3,6 @@ import com.fasterxml.jackson.databind.DeserializationFeature; import com.fasterxml.jackson.databind.ObjectMapper; import com.fasterxml.jackson.jaxrs.json.JacksonJsonProvider; -import com.google.common.collect.ImmutableList; import com.google.inject.Inject; import com.google.inject.Scopes; import io.digdag.client.DigdagVersion; @@ -12,14 +11,12 @@ import io.digdag.core.crypto.SecretCryptoProvider; import io.digdag.core.database.DatabaseSecretControlStoreManager; import io.digdag.core.database.DatabaseSecretStoreManager; -import io.digdag.core.database.ThreadLocalTransactionManager; -import io.digdag.core.database.TransactionManager; +import io.digdag.core.plugin.PluginSet; import io.digdag.core.repository.ModelValidationException; import io.digdag.core.repository.ResourceConflictException; import io.digdag.core.repository.ResourceLimitExceededException; import io.digdag.core.repository.ResourceNotFoundException; import io.digdag.guice.rs.GuiceRsModule; -import io.digdag.guice.rs.GuiceRsServerControl; import io.digdag.server.rs.AdminResource; import io.digdag.server.rs.AdminRestricted; import io.digdag.server.rs.AttemptResource; @@ -30,20 +27,17 @@ import io.digdag.server.rs.UiResource; import io.digdag.server.rs.VersionResource; import io.digdag.server.rs.WorkflowResource; +import io.digdag.spi.Authenticator; import io.digdag.spi.SecretControlStoreManager; import io.digdag.spi.SecretStoreManager; import io.digdag.spi.StorageFileNotFoundException; -import io.swagger.jaxrs.Reader; import io.swagger.jaxrs.config.BeanConfig; -import io.swagger.jaxrs.config.DefaultJaxrsConfig; import io.swagger.jaxrs.listing.ApiListingResource; import io.swagger.jaxrs.listing.SwaggerSerializers; -import io.swagger.models.Swagger; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import javax.servlet.http.HttpServletRequest; -import javax.sql.DataSource; import javax.ws.rs.*; import javax.ws.rs.container.ContainerRequestContext; import javax.ws.rs.container.ContainerRequestFilter; @@ -52,14 +46,11 @@ import javax.ws.rs.core.Context; import javax.ws.rs.core.Response; import javax.ws.rs.ext.Provider; -import javax.ws.rs.ext.ReaderInterceptor; -import javax.ws.rs.ext.ReaderInterceptorContext; import java.io.IOException; import java.util.List; import java.util.Map; -import java.net.InetSocketAddress; -import static java.util.stream.Collectors.toList; + import static io.digdag.guice.rs.GuiceRsServerRuntimeInfo.LISTEN_ADDRESS_NAME_ATTRIBUTE; public class ServerModule @@ -116,7 +107,7 @@ protected void bindResources(ApplicationBindingBuilder builder) protected void bindAuthenticator() { - binder().bind(Authenticator.class).to(JwtAuthenticator.class); + binder().bind(Authenticator.class).toProvider(AuthenticatorProvider.class); } protected void bindExceptionhandlers(ApplicationBindingBuilder builder) @@ -175,6 +166,33 @@ public JacksonJsonProvider get() } } + public static class AuthenticatorProvider + implements com.google.inject.Provider + { + private final Authenticator authenticator; + + @Inject + public AuthenticatorProvider(PluginSet.WithInjector pluginSet, ServerConfig serverConfig) + { + List authenticators = pluginSet.getServiceProviders(Authenticator.class); + String configuredAuthenticatorClass = serverConfig.getAuthenticatorClass(); + + for (Authenticator candidate : authenticators) { + if (candidate.getClass().getName().equals(configuredAuthenticatorClass)) { + authenticator = candidate; + return; + } + } + throw new IllegalArgumentException("Configured authenticatorClass not found: " + configuredAuthenticatorClass); + } + + @Override + public Authenticator get() + { + return authenticator; + } + } + @Provider public static class CorsFilter implements ContainerResponseFilter { diff --git a/digdag-server/src/main/java/io/digdag/server/rs/AdminResource.java b/digdag-server/src/main/java/io/digdag/server/rs/AdminResource.java index af6a34080d..6b388b082f 100644 --- a/digdag-server/src/main/java/io/digdag/server/rs/AdminResource.java +++ b/digdag-server/src/main/java/io/digdag/server/rs/AdminResource.java @@ -9,6 +9,7 @@ import io.digdag.core.session.SessionStoreManager; import io.digdag.core.session.StoredSessionAttemptWithSession; import io.swagger.annotations.Api; +import io.swagger.annotations.ApiOperation; import javax.ws.rs.GET; import javax.ws.rs.NotFoundException; @@ -39,8 +40,10 @@ public AdminResource( this.tm = tm; } + @Deprecated @GET @Path("/api/admin/attempts/{id}/userinfo") + @ApiOperation("(deprecated)") public Config getUserInfo(@PathParam("id") long id) throws ResourceNotFoundException { diff --git a/digdag-server/src/main/java/io/digdag/server/rs/AttemptResource.java b/digdag-server/src/main/java/io/digdag/server/rs/AttemptResource.java index c4d8e3d84a..617fa8999c 100644 --- a/digdag-server/src/main/java/io/digdag/server/rs/AttemptResource.java +++ b/digdag-server/src/main/java/io/digdag/server/rs/AttemptResource.java @@ -32,6 +32,8 @@ import io.digdag.client.api.*; import io.digdag.spi.ScheduleTime; import io.swagger.annotations.Api; +import io.swagger.annotations.ApiOperation; +import io.swagger.annotations.ApiParam; @Api("Attempt") @Path("/") @@ -82,11 +84,17 @@ public AttemptResource( @GET @Path("/api/attempts") + @ApiOperation("List attempts with filters") public RestSessionAttemptCollection getAttempts( + @ApiParam(value="exact matching filter on project name", required=false) @QueryParam("project") String projName, + @ApiParam(value="exact matching filter on workflow name", required=false) @QueryParam("workflow") String wfName, + @ApiParam(value="list more than 1 attempts per session", required=false) @QueryParam("include_retried") boolean includeRetried, + @ApiParam(value="list attempts whose id is grater than this id for pagination", required=false) @QueryParam("last_id") Long lastId, + @ApiParam(value="number of attempts to return", required=false) @QueryParam("page_size") Integer pageSize) throws ResourceNotFoundException { @@ -119,7 +127,10 @@ public RestSessionAttemptCollection getAttempts( @GET @Path("/api/attempts/{id}") - public RestSessionAttempt getAttempt(@PathParam("id") long id) + @ApiOperation("Get an attempt") + public RestSessionAttempt getAttempt( + @ApiParam(value="attempt id", required=true) + @PathParam("id") long id) throws ResourceNotFoundException { return tm.begin(() -> { @@ -134,7 +145,10 @@ public RestSessionAttempt getAttempt(@PathParam("id") long id) @GET @Path("/api/attempts/{id}/retries") - public RestSessionAttemptCollection getAttemptRetries(@PathParam("id") long id) + @ApiOperation("List attempts of a session of a given attempt") + public RestSessionAttemptCollection getAttemptRetries( + @ApiParam(value="attempt id", required=true) + @PathParam("id") long id) throws ResourceNotFoundException { return tm.begin(() -> { @@ -147,7 +161,10 @@ public RestSessionAttemptCollection getAttemptRetries(@PathParam("id") long id) @GET @Path("/api/attempts/{id}/tasks") - public RestTaskCollection getTasks(@PathParam("id") long id) + @ApiOperation("List tasks of an attempt") + public RestTaskCollection getTasks( + @ApiParam(value="attempt id", required=true) + @PathParam("id") long id) { return tm.begin(() -> { List tasks = sm.getSessionStore(getSiteId()) @@ -159,6 +176,7 @@ public RestTaskCollection getTasks(@PathParam("id") long id) @PUT @Consumes("application/json") @Path("/api/attempts") + @ApiOperation("Start a workflow execution as a new session or a new attempt of an existing session") public Response startAttempt(RestSessionAttemptRequest request) throws AttemptLimitExceededException, TaskLimitExceededException, ResourceNotFoundException { @@ -273,7 +291,10 @@ private ArchivedTask matchTaskPattern(String pattern, List tasks) @POST @Consumes("application/json") @Path("/api/attempts/{id}/kill") - public void killAttempt(@PathParam("id") long id) + @ApiOperation("Set a cancel-requested flag on a running attempt") + public void killAttempt( + @ApiParam(value="attempt id", required=true) + @PathParam("id") long id) throws ResourceNotFoundException, ResourceConflictException { tm.begin(() -> { diff --git a/digdag-server/src/main/java/io/digdag/server/rs/LogResource.java b/digdag-server/src/main/java/io/digdag/server/rs/LogResource.java index 25b5c1a202..f157d39275 100644 --- a/digdag-server/src/main/java/io/digdag/server/rs/LogResource.java +++ b/digdag-server/src/main/java/io/digdag/server/rs/LogResource.java @@ -24,6 +24,8 @@ import io.digdag.client.api.*; import io.digdag.spi.*; import io.swagger.annotations.Api; +import io.swagger.annotations.ApiOperation; +import io.swagger.annotations.ApiParam; import static io.digdag.core.log.LogServerManager.logFilePrefixFromSessionAttempt; @@ -106,8 +108,11 @@ public DirectUploadHandle getFileHandles( @GET @Path("/api/logs/{attempt_id}/files") + @ApiOperation("List log files of an attempt with filters") public RestLogFileHandleCollection getFileHandles( + @ApiParam(value="attempt id", required=true) @PathParam("attempt_id") long attemptId, + @ApiParam(value="partial prefix match filter on task name", required=false) @QueryParam("task") String taskName) throws ResourceNotFoundException { @@ -121,8 +126,11 @@ public RestLogFileHandleCollection getFileHandles( @GET @Produces("application/gzip") @Path("/api/logs/{attempt_id}/files/{file_name}") + @ApiOperation("Download a log file") public byte[] getFile( + @ApiParam(value="attempt id", required=true) @PathParam("attempt_id") long attemptId, + @ApiParam(value="log file name", required=true) @PathParam("file_name") String fileName) throws ResourceNotFoundException, IOException, StorageFileNotFoundException { diff --git a/digdag-server/src/main/java/io/digdag/server/rs/ProjectResource.java b/digdag-server/src/main/java/io/digdag/server/rs/ProjectResource.java index 76afe87838..041048e3fa 100644 --- a/digdag-server/src/main/java/io/digdag/server/rs/ProjectResource.java +++ b/digdag-server/src/main/java/io/digdag/server/rs/ProjectResource.java @@ -72,8 +72,11 @@ import io.digdag.core.repository.ResourceNotFoundException; import io.digdag.core.repository.Revision; import io.digdag.core.repository.StoredProject; +import io.digdag.core.repository.StoredProjectWithRevision; import io.digdag.core.repository.StoredRevision; import io.digdag.core.repository.StoredWorkflowDefinition; +import io.digdag.core.repository.WorkflowDefinition; +import io.digdag.core.repository.WorkflowDefinitionList; import io.digdag.core.schedule.ScheduleStore; import io.digdag.core.schedule.ScheduleStoreManager; import io.digdag.core.schedule.SchedulerManager; @@ -82,7 +85,9 @@ import io.digdag.core.session.SessionStoreManager; import io.digdag.core.session.StoredSessionWithLastAttempt; import io.digdag.core.storage.ArchiveManager; +import io.digdag.core.workflow.Workflow; import io.digdag.core.workflow.WorkflowCompiler; +import io.digdag.core.workflow.WorkflowTask; import io.digdag.server.GenericJsonExceptionHandler; import io.digdag.spi.DirectDownloadHandle; import io.digdag.spi.SecretControlStore; @@ -93,6 +98,8 @@ import io.digdag.spi.StorageObject; import io.digdag.util.Md5CountInputStream; import io.swagger.annotations.Api; +import io.swagger.annotations.ApiOperation; +import io.swagger.annotations.ApiParam; import org.apache.commons.compress.archivers.tar.TarArchiveEntry; import org.apache.commons.compress.archivers.tar.TarArchiveInputStream; import org.apache.commons.compress.compressors.gzip.GzipCompressorInputStream; @@ -157,8 +164,11 @@ public class ProjectResource // GET /api/projects/{id}/workflow?name=name&revision=name # lookup a workflow of a past revision of a project by name private static final Logger logger = LoggerFactory.getLogger(ProjectResource.class); - private static final int ARCHIVE_TOTAL_SIZE_LIMIT = 2 * 1024 * 1024; - private static final int ARCHIVE_FILE_SIZE_LIMIT = ARCHIVE_TOTAL_SIZE_LIMIT; + private static int MAX_ARCHIVE_TOTAL_SIZE_LIMIT; + private static final int DEFAULT_ARCHIVE_TOTAL_SIZE_LIMIT = 2 * 1024 * 1024; + // TODO: we may want to limit bytes of one file for `MAX_ARCHIVE_FILE_SIZE_LIMIT ` in the future instead of total size limit. + // See also: https://github.com/treasure-data/digdag/pull/994#discussion_r258402647 + private static int MAX_ARCHIVE_FILE_SIZE_LIMIT; private static int MAX_SESSIONS_PAGE_SIZE; private static final int DEFAULT_SESSIONS_PAGE_SIZE = 100; @@ -204,6 +214,8 @@ public ProjectResource( this.scsp = scsp; this.projectArchiveLoader = projectArchiveLoader; MAX_SESSIONS_PAGE_SIZE = systemConfig.get("api.max_sessions_page_size", Integer.class, DEFAULT_SESSIONS_PAGE_SIZE); + MAX_ARCHIVE_TOTAL_SIZE_LIMIT = systemConfig.get("api.max_archive_total_size_limit", Integer.class, DEFAULT_ARCHIVE_TOTAL_SIZE_LIMIT); + MAX_ARCHIVE_FILE_SIZE_LIMIT = MAX_ARCHIVE_TOTAL_SIZE_LIMIT; } private static StoredProject ensureNotDeletedProject(StoredProject proj) @@ -217,8 +229,11 @@ private static StoredProject ensureNotDeletedProject(StoredProject proj) return proj; } + // / style is deprecated. Use /api/projects with filter instead + @Deprecated @GET @Path("/api/project") + @ApiOperation("(deprecated)") public RestProject getProject(@QueryParam("name") String name) throws ResourceNotFoundException { @@ -234,7 +249,10 @@ public RestProject getProject(@QueryParam("name") String name) @GET @Path("/api/projects") - public RestProjectCollection getProjects(@QueryParam("name") String name) + @ApiOperation("List projects with filters") + public RestProjectCollection getProjects( + @ApiParam(value="exact matching filter on project name", required=false) + @QueryParam("name") String name) { return tm.begin(() -> { ProjectStore ps = rm.getProjectStore(getSiteId()); @@ -251,19 +269,11 @@ public RestProjectCollection getProjects(@QueryParam("name") String name) } } else { - // TODO fix n-m db access - collection = ps.getProjects(100, Optional.absent()) + collection = ps.getProjectsWithLatestRevision(100, Optional.absent()) .stream() - .map(proj -> { - try { - StoredRevision rev = ps.getLatestRevision(proj.getId()); - return RestModels.project(proj, rev); - } - catch (ResourceNotFoundException ex) { - return null; - } + .map(projWithRev -> { + return RestModels.project(projWithRev); }) - .filter(proj -> proj != null) .collect(Collectors.toList()); } @@ -273,7 +283,10 @@ public RestProjectCollection getProjects(@QueryParam("name") String name) @GET @Path("/api/projects/{id}") - public RestProject getProject(@PathParam("id") int projId) + @ApiOperation("Get a project") + public RestProject getProject( + @ApiParam(value="project id", required=false) + @PathParam("id") int projId) throws ResourceNotFoundException { return tm.begin(() -> { @@ -286,7 +299,14 @@ public RestProject getProject(@PathParam("id") int projId) @GET @Path("/api/projects/{id}/revisions") - public RestRevisionCollection getRevisions(@PathParam("id") int projId, @QueryParam("last_id") Integer lastId) + @ApiOperation("List revisions of a project") + public RestRevisionCollection getRevisions( + @PathParam("id") int projId, + // last_id exists but impossible to use for pagination purpose because + // RestRevision doesn't return id. This is a REST API design bug. No + // clients can use this parameter appropriately. + @ApiParam(value="deprecated - do not use") + @QueryParam("last_id") Integer lastId) throws ResourceNotFoundException { return tm.begin(() -> { @@ -297,8 +317,11 @@ public RestRevisionCollection getRevisions(@PathParam("id") int projId, @QueryPa }, ResourceNotFoundException.class); } + // / style is deprecated. Use /api/projects/{id}/workflows with filter instead + @Deprecated @GET @Path("/api/projects/{id}/workflow") + @ApiOperation("(deprecated)") public RestWorkflowDefinition getWorkflow(@PathParam("id") int projId, @QueryParam("name") String name, @QueryParam("revision") String revName) throws ResourceNotFoundException { @@ -331,9 +354,13 @@ public RestWorkflowDefinition getWorkflowByName(@PathParam("id") int projId, @Pa @GET @Path("/api/projects/{id}/workflows") + @ApiOperation("List workflows of a project with filters") public RestWorkflowDefinitionCollection getWorkflows( + @ApiParam(value="project id", required=true) @PathParam("id") int projId, + @ApiParam(value="use a given revision of the project instead of the latest revision", required=true) @QueryParam("revision") String revName, + @ApiParam(value="exact matching filter on workflow name", required=false) @QueryParam("name") String name) throws ResourceNotFoundException { @@ -368,10 +395,14 @@ public RestWorkflowDefinitionCollection getWorkflows( } @GET + @ApiOperation("List schedules of a project with filters") @Path("/api/projects/{id}/schedules") public RestScheduleCollection getSchedules( + @ApiParam(value="project id", required=true) @PathParam("id") int projectId, + @ApiParam(value="exact matching filter on workflow name", required=false) @QueryParam("workflow") String workflowName, + @ApiParam(value="list schedules whose id is grater than this id for pagination", required=false) @QueryParam("last_id") Integer lastId) throws ResourceNotFoundException { @@ -401,11 +432,16 @@ public RestScheduleCollection getSchedules( } @GET + @ApiOperation("List sessions of a project with filters") @Path("/api/projects/{id}/sessions") public RestSessionCollection getSessions( + @ApiParam(value="project id", required=true) @PathParam("id") int projectId, + @ApiParam(value="exact matching filter on workflow name", required=false) @QueryParam("workflow") String workflowName, + @ApiParam(value="list sessions whose id is grater than this id for pagination", required=false) @QueryParam("last_id") Long lastId, + @ApiParam(value="number of sessions to return", required=false) @QueryParam("page_size") Integer pageSize) throws ResourceNotFoundException { @@ -431,7 +467,12 @@ public RestSessionCollection getSessions( @GET @Path("/api/projects/{id}/archive") @Produces("application/gzip") - public Response getArchive(@PathParam("id") int projId, @QueryParam("revision") String revName) + @ApiOperation("Download a project archive file") + public Response getArchive( + @ApiParam(value="project id", required=true) + @PathParam("id") int projId, + @ApiParam(value="use a given revision of a project instead of the latest revision", required=true) + @QueryParam("revision") String revName) throws ResourceNotFoundException { return tm.begin(() -> { @@ -489,6 +530,7 @@ public void write(OutputStream out) @DELETE @Path("/api/projects/{id}") + @ApiOperation("Delete a project") public RestProject deleteProject(@PathParam("id") int projId) throws ResourceNotFoundException { @@ -504,8 +546,15 @@ public RestProject deleteProject(@PathParam("id") int projId) @PUT @Consumes("application/gzip") @Path("/api/projects") - public RestProject putProject(@QueryParam("project") String name, @QueryParam("revision") String revision, - InputStream body, @HeaderParam("Content-Length") long contentLength, + @ApiOperation("Upload a project archive as a new project or a new revision of an existing project") + public RestProject putProject( + @ApiParam(value="project name", required=true) + @QueryParam("project") String name, + @ApiParam(value="revision", required=true) + @QueryParam("revision") String revision, + InputStream body, + @HeaderParam("Content-Length") long contentLength, + @ApiParam(value="start scheduling of new workflows from the given time instead of current time", required=false) @QueryParam("schedule_from") String scheduleFromString) throws ResourceConflictException, IOException, ResourceNotFoundException { @@ -526,10 +575,10 @@ public RestProject putProject(@QueryParam("project") String name, @QueryParam("r } } - if (contentLength > ARCHIVE_TOTAL_SIZE_LIMIT) { + if (contentLength > MAX_ARCHIVE_TOTAL_SIZE_LIMIT) { throw new IllegalArgumentException(String.format(ENGLISH, "Size of the uploaded archive file exceeds limit (%d bytes)", - ARCHIVE_TOTAL_SIZE_LIMIT)); + MAX_ARCHIVE_TOTAL_SIZE_LIMIT)); } int size = (int) contentLength; @@ -544,6 +593,8 @@ public RestProject putProject(@QueryParam("project") String name, @QueryParam("r if (md5Count.getCount() != contentLength) { throw new IllegalArgumentException("Content-Length header doesn't match with uploaded data size"); } + + validateWorkflowAndSchedule(meta); } ArchiveManager.Location location = @@ -627,10 +678,10 @@ private ArchiveMetadata readArchiveMetadata(InputStream in, String projectName) totalSize = extractConfigFiles(dir.get(), archive); } - if (totalSize > ARCHIVE_TOTAL_SIZE_LIMIT) { + if (totalSize > MAX_ARCHIVE_TOTAL_SIZE_LIMIT) { throw new IllegalArgumentException(String.format(ENGLISH, "Total size of the archive exceeds limit (%d > %d bytes)", - totalSize, ARCHIVE_TOTAL_SIZE_LIMIT)); + totalSize, MAX_ARCHIVE_TOTAL_SIZE_LIMIT)); } ProjectArchive archive = projectArchiveLoader.load(dir.get(), WorkflowResourceMatcher.defaultMatcher(), cf.create()); @@ -669,17 +720,43 @@ private long extractConfigFiles(java.nio.file.Path dir, TarArchiveInputStream ar private void validateTarEntry(TarArchiveEntry entry) { - if (entry.getSize() > ARCHIVE_FILE_SIZE_LIMIT) { + if (entry.getSize() > MAX_ARCHIVE_FILE_SIZE_LIMIT) { throw new IllegalArgumentException(String.format(ENGLISH, "Size of a file in the archive exceeds limit (%d > %d bytes): %s", - entry.getSize(), ARCHIVE_FILE_SIZE_LIMIT, entry.getName())); + entry.getSize(), MAX_ARCHIVE_FILE_SIZE_LIMIT, entry.getName())); + } + } + + private void validateWorkflowAndSchedule(ArchiveMetadata meta) + { + WorkflowDefinitionList defs = meta.getWorkflowList(); + for (WorkflowDefinition def : defs.get()) { + Workflow wf = compiler.compile(def.getName(), def.getConfig()); + + // validate workflow and schedule + for (WorkflowTask task : wf.getTasks()) { + // raise an exception if task doesn't valid. + task.getConfig(); + } + Revision rev = Revision.builderFromArchive("check", meta, getUserInfo()) + .archiveType(ArchiveType.NONE) + .build(); + // raise an exception if "schedule:" is invalid. + srm.tryGetScheduler(rev, def); + } } @PUT @Consumes("application/json") @Path("/api/projects/{id}/secrets/{key}") - public void putProjectSecret(@PathParam("id") int projectId, @PathParam("key") String key, RestSetSecretRequest request) + @ApiOperation("Set a secret to a project") + public void putProjectSecret( + @ApiParam(value="project id", required=true) + @PathParam("id") int projectId, + @ApiParam(value="secret key", required=true) + @PathParam("key") String key, + RestSetSecretRequest request) throws ResourceNotFoundException { tm.begin(() -> { @@ -701,7 +778,12 @@ public void putProjectSecret(@PathParam("id") int projectId, @PathParam("key") S @DELETE @Path("/api/projects/{id}/secrets/{key}") - public void deleteProjectSecret(@PathParam("id") int projectId, @PathParam("key") String key) + @ApiOperation("Delete a secret from a project") + public void deleteProjectSecret( + @ApiParam(value="project id", required=true) + @PathParam("id") int projectId, + @ApiParam(value="secret key", required=true) + @PathParam("key") String key) throws ResourceNotFoundException { tm.begin(() -> { @@ -724,7 +806,10 @@ public void deleteProjectSecret(@PathParam("id") int projectId, @PathParam("key" @GET @Path("/api/projects/{id}/secrets") @Produces("application/json") - public RestSecretList getProjectSecrets(@PathParam("id") int projectId) + @ApiOperation("List secret keys of a project") + public RestSecretList getProjectSecrets( + @ApiParam(value="project id", required=true) + @PathParam("id") int projectId) throws ResourceNotFoundException { return tm.begin(() -> { diff --git a/digdag-server/src/main/java/io/digdag/server/rs/RestModels.java b/digdag-server/src/main/java/io/digdag/server/rs/RestModels.java index 0df7bf62b0..43447493dc 100644 --- a/digdag-server/src/main/java/io/digdag/server/rs/RestModels.java +++ b/digdag-server/src/main/java/io/digdag/server/rs/RestModels.java @@ -29,6 +29,7 @@ import io.digdag.core.repository.ResourceNotFoundException; import io.digdag.core.repository.Revision; import io.digdag.core.repository.StoredProject; +import io.digdag.core.repository.StoredProjectWithRevision; import io.digdag.core.repository.StoredRevision; import io.digdag.core.repository.StoredWorkflowDefinition; import io.digdag.core.repository.StoredWorkflowDefinitionWithProject; @@ -56,6 +57,20 @@ public final class RestModels private RestModels() { } + public static RestProject project(StoredProjectWithRevision projWithRev) + { + return RestProject.builder() + .id(id(projWithRev.getId())) + .name(projWithRev.getName()) + .revision(projWithRev.getRevisionName()) + .createdAt(projWithRev.getCreatedAt()) + .updatedAt(projWithRev.getRevisionCreatedAt()) + .deletedAt(projWithRev.getDeletedAt()) + .archiveType(projWithRev.getRevisionArchiveType().getName()) + .archiveMd5(projWithRev.getRevisionArchiveMd5()) + .build(); + } + public static RestProject project(StoredProject proj, StoredRevision lastRevision) { return RestProject.builder() @@ -319,6 +334,7 @@ public static RestTask task(ArchivedTask task) .updatedAt(task.getUpdatedAt()) .retryAt(task.getRetryAt()) .startedAt(task.getStartedAt()) + .error(task.getError()) .build(); } diff --git a/digdag-server/src/main/java/io/digdag/server/rs/ScheduleResource.java b/digdag-server/src/main/java/io/digdag/server/rs/ScheduleResource.java index a4bbe93759..91ecdf2cbd 100644 --- a/digdag-server/src/main/java/io/digdag/server/rs/ScheduleResource.java +++ b/digdag-server/src/main/java/io/digdag/server/rs/ScheduleResource.java @@ -21,6 +21,8 @@ import io.digdag.core.schedule.StoredSchedule; import io.digdag.core.session.StoredSessionAttemptWithSession; import io.swagger.annotations.Api; +import io.swagger.annotations.ApiOperation; +import io.swagger.annotations.ApiParam; import javax.ws.rs.Consumes; import javax.ws.rs.GET; @@ -66,7 +68,10 @@ public ScheduleResource( @GET @Path("/api/schedules") - public RestScheduleCollection getSchedules(@QueryParam("last_id") Integer lastId) + @ApiOperation("List schedules") + public RestScheduleCollection getSchedules( + @ApiParam(value="list schedules whose id is grater than this id for pagination", required=false) + @QueryParam("last_id") Integer lastId) { return tm.begin(() -> { List scheds = sm.getScheduleStore(getSiteId()) @@ -78,7 +83,10 @@ public RestScheduleCollection getSchedules(@QueryParam("last_id") Integer lastId @GET @Path("/api/schedules/{id}") - public RestSchedule getSchedules(@PathParam("id") int id) + @ApiOperation("Get a schedule") + public RestSchedule getSchedules( + @ApiParam(value="schedule id", required=true) + @PathParam("id") int id) throws ResourceNotFoundException { return tm.begin(() -> { @@ -94,7 +102,11 @@ public RestSchedule getSchedules(@PathParam("id") int id) @POST @Consumes("application/json") @Path("/api/schedules/{id}/skip") - public RestScheduleSummary skipSchedule(@PathParam("id") int id, RestScheduleSkipRequest request) + @ApiOperation("Skip future sessions by count or time") + public RestScheduleSummary skipSchedule( + @ApiParam(value="session id", required=true) + @PathParam("id") int id, + RestScheduleSkipRequest request) throws ResourceConflictException, ResourceNotFoundException { return tm.begin(() -> { @@ -136,7 +148,11 @@ private ZoneId getTimeZoneOfSchedule(StoredSchedule sched) @POST @Consumes("application/json") @Path("/api/schedules/{id}/backfill") - public RestSessionAttemptCollection backfillSchedule(@PathParam("id") int id, RestScheduleBackfillRequest request) + @ApiOperation("Re-schedule past sessions by count or duration") + public RestSessionAttemptCollection backfillSchedule( + @ApiParam(value="session id", required=true) + @PathParam("id") int id, + RestScheduleBackfillRequest request) throws ResourceConflictException, ResourceLimitExceededException, ResourceNotFoundException { return tm.begin(() -> @@ -153,7 +169,10 @@ public RestSessionAttemptCollection backfillSchedule(@PathParam("id") int id, Re @POST @Path("/api/schedules/{id}/disable") - public RestScheduleSummary disableSchedule(@PathParam("id") int id) + @ApiOperation("Disable scheduling of new sessions") + public RestScheduleSummary disableSchedule( + @ApiParam(value="session id", required=true) + @PathParam("id") int id) throws ResourceNotFoundException, ResourceConflictException { return tm.begin(() -> @@ -175,7 +194,10 @@ public RestScheduleSummary disableSchedule(@PathParam("id") int id) @POST @Path("/api/schedules/{id}/enable") - public RestScheduleSummary enableSchedule(@PathParam("id") int id) + @ApiOperation("Re-enable disabled scheduling") + public RestScheduleSummary enableSchedule( + @ApiParam(value="session id", required=true) + @PathParam("id") int id) throws ResourceNotFoundException, ResourceConflictException { return tm.begin(() -> { diff --git a/digdag-server/src/main/java/io/digdag/server/rs/SessionResource.java b/digdag-server/src/main/java/io/digdag/server/rs/SessionResource.java index d6b4cd8d6f..2ce421ad4e 100644 --- a/digdag-server/src/main/java/io/digdag/server/rs/SessionResource.java +++ b/digdag-server/src/main/java/io/digdag/server/rs/SessionResource.java @@ -18,6 +18,8 @@ import io.digdag.core.session.StoredSessionAttempt; import io.digdag.core.session.StoredSessionWithLastAttempt; import io.swagger.annotations.Api; +import io.swagger.annotations.ApiOperation; +import io.swagger.annotations.ApiParam; import javax.ws.rs.GET; import javax.ws.rs.Path; @@ -62,8 +64,11 @@ public SessionResource( @GET @Path("/api/sessions") + @ApiOperation("List sessions") public RestSessionCollection getSessions( + @ApiParam(value="list sessions whose id is grater than this id for pagination", required=false) @QueryParam("last_id") Long lastId, + @ApiParam(value="number of sessions to return", required=false) @QueryParam("page_size") Integer pageSize) { int validPageSize = QueryParamValidator.validatePageSize(Optional.fromNullable(pageSize), MAX_SESSIONS_PAGE_SIZE, DEFAULT_SESSIONS_PAGE_SIZE); @@ -80,7 +85,10 @@ public RestSessionCollection getSessions( @GET @Path("/api/sessions/{id}") - public RestSession getSession(@PathParam("id") long id) + @ApiOperation("Get a session") + public RestSession getSession( + @ApiParam(value="session id", required=true) + @PathParam("id") long id) throws ResourceNotFoundException { return tm.begin(() -> { @@ -96,9 +104,13 @@ public RestSession getSession(@PathParam("id") long id) @GET @Path("/api/sessions/{id}/attempts") + @ApiOperation("List attempts of a session") public RestSessionAttemptCollection getSessionAttempts( + @ApiParam(value="session id", required=true) @PathParam("id") long id, + @ApiParam(value="list attempts whose id is grater than this id for pagination", required=false) @QueryParam("last_id") Long lastId, + @ApiParam(value="number of attempts to return", required=false) @QueryParam("page_size") Integer pageSize) throws ResourceNotFoundException { diff --git a/digdag-server/src/main/java/io/digdag/server/rs/VersionResource.java b/digdag-server/src/main/java/io/digdag/server/rs/VersionResource.java index bb963daf13..4603f68368 100644 --- a/digdag-server/src/main/java/io/digdag/server/rs/VersionResource.java +++ b/digdag-server/src/main/java/io/digdag/server/rs/VersionResource.java @@ -6,6 +6,8 @@ import io.digdag.client.api.RestVersionCheckResult; import io.digdag.server.ClientVersionChecker; import io.swagger.annotations.Api; +import io.swagger.annotations.ApiOperation; +import io.swagger.annotations.ApiParam; import java.util.Map; import javax.ws.rs.GET; @@ -33,6 +35,7 @@ public VersionResource(Version version, ClientVersionChecker clientVersionChecke @GET @Path("/api/version") + @ApiOperation("Get server version") public Map getVersion() { return ImmutableMap.of("version", version.toString()); @@ -40,7 +43,10 @@ public Map getVersion() @GET @Path("/api/version/check") - public RestVersionCheckResult checkClientVersion(@QueryParam("client") String clientVersionString) + @ApiOperation("Check client version compatibility") + public RestVersionCheckResult checkClientVersion( + @ApiParam(value="client version", required=true) + @QueryParam("client") String clientVersionString) { Version clientVersion = Version.parse(clientVersionString); return RestVersionCheckResult.builder() diff --git a/digdag-server/src/main/java/io/digdag/server/rs/WorkflowResource.java b/digdag-server/src/main/java/io/digdag/server/rs/WorkflowResource.java index 52b5fc5c61..bee012226a 100644 --- a/digdag-server/src/main/java/io/digdag/server/rs/WorkflowResource.java +++ b/digdag-server/src/main/java/io/digdag/server/rs/WorkflowResource.java @@ -40,6 +40,8 @@ import io.digdag.spi.Scheduler; import io.digdag.client.api.*; import io.swagger.annotations.Api; +import io.swagger.annotations.ApiOperation; +import io.swagger.annotations.ApiParam; import org.apache.commons.compress.compressors.gzip.GzipCompressorInputStream; import org.apache.commons.compress.archivers.ArchiveInputStream; import org.apache.commons.compress.archivers.ArchiveEntry; @@ -77,8 +79,11 @@ public WorkflowResource( this.tm = tm; } + // / style is deprecated. Use /api/workflows with filter instead + @Deprecated @GET @Path("/api/workflow") + @ApiOperation("(deprecated)") public RestWorkflowDefinition getWorkflowDefinition( @QueryParam("project") String projName, @QueryParam("revision") String revName, @@ -105,8 +110,11 @@ public RestWorkflowDefinition getWorkflowDefinition( @GET @Path("/api/workflows") + @ApiOperation("List workflows") public RestWorkflowDefinitionCollection getWorkflowDefinitions( + @ApiParam(value="list workflows whose id is grater than this id for pagination", required=false) @QueryParam("last_id") Long lastId, + @ApiParam(value="number of workflows to return", required=false) @QueryParam("count") Integer count) throws ResourceNotFoundException { @@ -120,7 +128,10 @@ public RestWorkflowDefinitionCollection getWorkflowDefinitions( @GET @Path("/api/workflows/{id}") - public RestWorkflowDefinition getWorkflowDefinition(@PathParam("id") long id) + @ApiOperation("Get a workflow") + public RestWorkflowDefinition getWorkflowDefinition( + @ApiParam(value="workflow id", required=true) + @PathParam("id") long id) throws ResourceNotFoundException { return tm.begin(() -> { @@ -133,9 +144,13 @@ public RestWorkflowDefinition getWorkflowDefinition(@PathParam("id") long id) @GET @Path("/api/workflows/{id}/truncated_session_time") + @ApiOperation("Get truncated local time based on the time zone of a workflow") public RestWorkflowSessionTime getWorkflowDefinition( + @ApiParam(value="workflow id", required=true) @PathParam("id") long id, + @ApiParam(value="session time to be truncated", required=true) @QueryParam("session_time") LocalTimeOrInstant localTime, + @ApiParam(value="truncation mode - second, minute, hour, day, schedule, or next_schedule", required=false) @QueryParam("mode") SessionTimeTruncate mode) throws ResourceNotFoundException { diff --git a/digdag-server/src/test/java/io/digdag/server/AuthRequestFilterTest.java b/digdag-server/src/test/java/io/digdag/server/AuthRequestFilterTest.java index cdce6ea5ab..bef8183ac5 100644 --- a/digdag-server/src/test/java/io/digdag/server/AuthRequestFilterTest.java +++ b/digdag-server/src/test/java/io/digdag/server/AuthRequestFilterTest.java @@ -5,6 +5,7 @@ import io.digdag.client.DigdagClient; import io.digdag.client.config.Config; import io.digdag.client.config.ConfigFactory; +import io.digdag.spi.Authenticator; import org.junit.Before; import org.junit.Test; import org.junit.runner.RunWith; diff --git a/digdag-server/src/test/java/io/digdag/server/AuthenticatorTest.java b/digdag-server/src/test/java/io/digdag/server/AuthenticatorTest.java index 4e7683c6b9..175b60c5d7 100644 --- a/digdag-server/src/test/java/io/digdag/server/AuthenticatorTest.java +++ b/digdag-server/src/test/java/io/digdag/server/AuthenticatorTest.java @@ -4,6 +4,7 @@ import io.digdag.client.DigdagClient; import io.digdag.client.config.Config; import io.digdag.client.config.ConfigFactory; +import io.digdag.spi.Authenticator; import org.junit.Test; import static org.hamcrest.Matchers.is; diff --git a/digdag-spi/build.gradle b/digdag-spi/build.gradle index 4f69ca925c..20fe50e5c8 100644 --- a/digdag-spi/build.gradle +++ b/digdag-spi/build.gradle @@ -1,5 +1,5 @@ dependencies { compile project(':digdag-client') - compile 'com.google.inject.extensions:guice-multibindings:4.0' + compile 'com.google.inject.extensions:guice-multibindings:4.2.2' } diff --git a/digdag-server/src/main/java/io/digdag/server/Authenticator.java b/digdag-spi/src/main/java/io/digdag/spi/Authenticator.java similarity index 98% rename from digdag-server/src/main/java/io/digdag/server/Authenticator.java rename to digdag-spi/src/main/java/io/digdag/spi/Authenticator.java index 09f9dfb780..b34576d058 100644 --- a/digdag-server/src/main/java/io/digdag/server/Authenticator.java +++ b/digdag-spi/src/main/java/io/digdag/spi/Authenticator.java @@ -1,4 +1,4 @@ -package io.digdag.server; +package io.digdag.spi; import com.fasterxml.jackson.databind.annotation.JsonDeserialize; import com.fasterxml.jackson.databind.annotation.JsonSerialize; diff --git a/digdag-spi/src/main/java/io/digdag/spi/ParamServerClient.java b/digdag-spi/src/main/java/io/digdag/spi/ParamServerClient.java index d3cfebc39f..d528e29ec9 100644 --- a/digdag-spi/src/main/java/io/digdag/spi/ParamServerClient.java +++ b/digdag-spi/src/main/java/io/digdag/spi/ParamServerClient.java @@ -7,7 +7,7 @@ public interface ParamServerClient { // default ttl for each record is 90 days - int DEFAULT_TTL = 60 * 24 * 90; + int DEFAULT_TTL_IN_SEC = 60 * 60 * 24 * 90; Optional get(String key, int sitedId); diff --git a/digdag-standards/build.gradle b/digdag-standards/build.gradle index 060848b9c0..10be965dc9 100644 --- a/digdag-standards/build.gradle +++ b/digdag-standards/build.gradle @@ -15,12 +15,12 @@ dependencies { compile 'com.sun.mail:javax.mail:1.5.6' // 'com.sun.mail:smtp' doesn't work because enabling mail.debug property throws java.lang.NoClassDefFoundError: com/sun/mail/util/MailLogger // td - compile ('com.treasuredata.client:td-client:0.8.6') { + compile ('com.treasuredata.client:td-client:0.9.0') { // digdag depends on guava 0.19.0 exclude group: 'com.google.guava', module: 'guava' } compile 'org.msgpack:msgpack-core:0.8.11' - compile 'org.yaml:snakeyaml:1.17' + compile 'org.yaml:snakeyaml:1.23' // postgresql compile 'org.postgresql:postgresql:9.4.1211' @@ -36,18 +36,21 @@ dependencies { compile ('com.google.apis:google-api-services-bigquery:v2-rev325-1.22.0') { exclude group: 'com.google.guava', module: 'guava-jdk5' } // gcs - compile ('com.google.apis:google-api-services-storage:v1-rev88-1.22.0') { exclude group: 'com.google.guava', module: 'guava-jdk5' } + compile ('com.google.apis:google-api-services-storage:v1-rev20190910-1.30.3') { + exclude group: 'com.google.guava', module: 'guava-jdk5' + exclude group: 'com.google.api-client', module: 'google-api-client' + } // dependency conflict resolution compile 'joda-time:joda-time:2.9.4' compile ('com.google.auth:google-auth-library-credentials:0.4.0') { exclude group: 'com.google.guava', module: 'guava-jdk5' } compile ('com.google.auth:google-auth-library-oauth2-http:0.4.0') { exclude group: 'com.google.guava', module: 'guava-jdk5' } - compile ('com.google.http-client:google-http-client:1.22.0') { exclude group: 'com.google.guava', module: 'guava-jdk5' } - compile ('com.google.http-client:google-http-client-jackson2:1.22.0') { exclude group: 'com.google.guava', module: 'guava-jdk5' } + compile ('com.google.http-client:google-http-client:1.24.1') { exclude group: 'com.google.guava', module: 'guava-jdk5' } + compile ('com.google.http-client:google-http-client-jackson2:1.24.1') { exclude group: 'com.google.guava', module: 'guava-jdk5' } compile ('com.google.oauth-client:google-oauth-client:1.22.0') { exclude group: 'com.google.guava', module: 'guava-jdk5' } - compile 'com.google.code.findbugs:jsr305:3.0.1' + compile 'com.google.code.findbugs:jsr305:3.0.2' // Newer version of jetty-client with some important bugfixes. // jetty-client is used by td-client-java, and ideally we would bump the version there but diff --git a/digdag-standards/src/main/java/io/digdag/standards/auth/basic/BasicAuthenticator.java b/digdag-standards/src/main/java/io/digdag/standards/auth/basic/BasicAuthenticator.java new file mode 100644 index 0000000000..d12edfaf23 --- /dev/null +++ b/digdag-standards/src/main/java/io/digdag/standards/auth/basic/BasicAuthenticator.java @@ -0,0 +1,51 @@ +package io.digdag.standards.auth.basic; + +import com.google.inject.Inject; +import io.digdag.spi.Authenticator; +import org.jboss.resteasy.util.BasicAuthHelper; + +import javax.ws.rs.container.ContainerRequestContext; +import java.util.Optional; + +import static javax.ws.rs.core.HttpHeaders.AUTHORIZATION; + +public class BasicAuthenticator + implements Authenticator +{ + private final Optional config; + + @Inject + public BasicAuthenticator(Optional config) + { + this.config = config; + } + + @Override + public Result authenticate(ContainerRequestContext requestContext) + { + if (!config.isPresent()) { + throw new IllegalStateException("The BasicAuthenticator wasn't property configured."); + } + BasicAuthenticatorConfig basicAuthenticatorConfig = config.get(); + String username = basicAuthenticatorConfig.getUsername(); + String password = basicAuthenticatorConfig.getPassword(); + boolean isAdmin = basicAuthenticatorConfig.isAdmin(); + + + String authHeader = requestContext.getHeaderString(AUTHORIZATION); + if (authHeader == null) { + return Result.reject("Missing Authorization header"); + } + + String[] parsedHeader = BasicAuthHelper.parseHeader(authHeader); + + if (parsedHeader[0].equals(username) && parsedHeader[1].equals(password)) { + return Result.builder() + .isAdmin(isAdmin) + .siteId(0) + .build(); + } else { + return Result.reject("unauthorized"); + } + } +} diff --git a/digdag-standards/src/main/java/io/digdag/standards/auth/basic/BasicAuthenticatorConfig.java b/digdag-standards/src/main/java/io/digdag/standards/auth/basic/BasicAuthenticatorConfig.java new file mode 100644 index 0000000000..8d428615ee --- /dev/null +++ b/digdag-standards/src/main/java/io/digdag/standards/auth/basic/BasicAuthenticatorConfig.java @@ -0,0 +1,19 @@ +package io.digdag.standards.auth.basic; + +import com.fasterxml.jackson.databind.annotation.JsonDeserialize; +import com.fasterxml.jackson.databind.annotation.JsonSerialize; +import org.immutables.value.Value; + +@Value.Immutable +@JsonSerialize(as = ImmutableBasicAuthenticatorConfig.class) +@JsonDeserialize(as = ImmutableBasicAuthenticatorConfig.class) +public abstract class BasicAuthenticatorConfig +{ + public abstract String getUsername(); + public abstract String getPassword(); + public abstract boolean isAdmin(); + + public static ImmutableBasicAuthenticatorConfig.Builder builder() { + return ImmutableBasicAuthenticatorConfig.builder(); + } +} diff --git a/digdag-standards/src/main/java/io/digdag/standards/auth/basic/BasicAuthenticatorConfigProvider.java b/digdag-standards/src/main/java/io/digdag/standards/auth/basic/BasicAuthenticatorConfigProvider.java new file mode 100644 index 0000000000..fa5dd520e3 --- /dev/null +++ b/digdag-standards/src/main/java/io/digdag/standards/auth/basic/BasicAuthenticatorConfigProvider.java @@ -0,0 +1,35 @@ +package io.digdag.standards.auth.basic; + +import com.google.inject.Inject; +import com.google.inject.Provider; +import io.digdag.client.config.Config; + +import java.util.Optional; + +public class BasicAuthenticatorConfigProvider + implements Provider> +{ + private final Config systemConfig; + + @Inject + public BasicAuthenticatorConfigProvider(Config systemConfig) + { + this.systemConfig = systemConfig; + } + + @Override + public Optional get() + { + try { + return Optional.of(BasicAuthenticatorConfig.builder() + .username(systemConfig.getOptional("basicauth.username", String.class).get()) + .password(systemConfig.getOptional("basicauth.password", String.class).get()) + .isAdmin(systemConfig.getOptional("basicauth.admin", Boolean.class).or(false)) + .build() + ); + } catch (Exception e) { + return Optional.empty(); + } + } +} + diff --git a/digdag-standards/src/main/java/io/digdag/standards/auth/basic/BasicAuthenticatorPlugin.java b/digdag-standards/src/main/java/io/digdag/standards/auth/basic/BasicAuthenticatorPlugin.java new file mode 100644 index 0000000000..9bf228bb85 --- /dev/null +++ b/digdag-standards/src/main/java/io/digdag/standards/auth/basic/BasicAuthenticatorPlugin.java @@ -0,0 +1,29 @@ +package io.digdag.standards.auth.basic; + +import com.google.inject.Binder; +import com.google.inject.TypeLiteral; +import io.digdag.spi.Authenticator; +import io.digdag.spi.Plugin; + +import java.util.Optional; + +public class BasicAuthenticatorPlugin + implements Plugin +{ + @Override + public Class getServiceProvider(Class type) + { + if (type == Authenticator.class) { + return BasicAuthenticator.class.asSubclass(type); + } + else { + return null; + } + } + + @Override + public void configureBinder(Class type, Binder binder) + { + binder.bind(new TypeLiteral>(){}).toProvider(BasicAuthenticatorConfigProvider.class).asEagerSingleton(); + } +} diff --git a/digdag-server/src/main/java/io/digdag/server/JwtAuthenticator.java b/digdag-standards/src/main/java/io/digdag/standards/auth/jwt/JwtAuthenticator.java similarity index 77% rename from digdag-server/src/main/java/io/digdag/server/JwtAuthenticator.java rename to digdag-standards/src/main/java/io/digdag/standards/auth/jwt/JwtAuthenticator.java index 41fa5e27e0..ae9a3f865c 100644 --- a/digdag-server/src/main/java/io/digdag/server/JwtAuthenticator.java +++ b/digdag-standards/src/main/java/io/digdag/standards/auth/jwt/JwtAuthenticator.java @@ -1,10 +1,7 @@ -package io.digdag.server; +package io.digdag.standards.auth.jwt; -import com.google.common.base.Optional; -import com.google.common.collect.ImmutableMap; import com.google.inject.Inject; -import io.digdag.client.api.RestApiKey; -import io.digdag.client.config.Config; +import io.digdag.spi.Authenticator; import io.jsonwebtoken.Claims; import io.jsonwebtoken.JwsHeader; import io.jsonwebtoken.JwtException; @@ -25,27 +22,12 @@ public class JwtAuthenticator { private static final Logger logger = LoggerFactory.getLogger(JwtAuthenticator.class); - private final Map userMap; - private final boolean allowPublicAccess; + private final JwtAuthenticatorConfig config; @Inject - public JwtAuthenticator(Config systemConfig) + public JwtAuthenticator(JwtAuthenticatorConfig config) { - Optional apiKey = systemConfig.getOptional("server.apikey", RestApiKey.class); - - if (apiKey.isPresent()) { - UserConfig user = UserConfig.builder() - .siteId(0) - .isAdmin(true) - .apiKey(apiKey.get()) - .build(); - this.userMap = ImmutableMap.of(user.getApiKey().getIdString(), user); - this.allowPublicAccess = false; - } - else { - this.userMap = ImmutableMap.of(); - this.allowPublicAccess = true; - } + this.config = config; } @Override @@ -56,7 +38,7 @@ public Result authenticate(ContainerRequestContext requestContext) String auth = requestContext.getHeaderString("Authorization"); if (auth == null) { - if (allowPublicAccess) { + if (config.isAllowPublicAccess()) { // OK siteId = 0; admin = true; @@ -75,6 +57,8 @@ public Result authenticate(ContainerRequestContext requestContext) } String token = typeData[1]; try { + Map userMap = config.getUserMap(); + String subject = Jwts.parser().setSigningKeyResolver(new SigningKeyResolver() { @Override public Key resolveSigningKey(JwsHeader header, Claims claims) diff --git a/digdag-standards/src/main/java/io/digdag/standards/auth/jwt/JwtAuthenticatorConfig.java b/digdag-standards/src/main/java/io/digdag/standards/auth/jwt/JwtAuthenticatorConfig.java new file mode 100644 index 0000000000..204376307a --- /dev/null +++ b/digdag-standards/src/main/java/io/digdag/standards/auth/jwt/JwtAuthenticatorConfig.java @@ -0,0 +1,21 @@ +package io.digdag.standards.auth.jwt; + +import com.fasterxml.jackson.databind.annotation.JsonDeserialize; +import com.fasterxml.jackson.databind.annotation.JsonSerialize; +import org.immutables.value.Value; + +import java.util.Map; + +@Value.Immutable +@JsonSerialize(as = ImmutableJwtAuthenticatorConfig.class) +@JsonDeserialize(as = ImmutableJwtAuthenticatorConfig.class) +public abstract class JwtAuthenticatorConfig +{ + public abstract Map getUserMap(); + + public abstract boolean isAllowPublicAccess(); + + public static ImmutableJwtAuthenticatorConfig.Builder builder() { + return ImmutableJwtAuthenticatorConfig.builder(); + } +} diff --git a/digdag-standards/src/main/java/io/digdag/standards/auth/jwt/JwtAuthenticatorConfigProvider.java b/digdag-standards/src/main/java/io/digdag/standards/auth/jwt/JwtAuthenticatorConfigProvider.java new file mode 100644 index 0000000000..cb4433b9c4 --- /dev/null +++ b/digdag-standards/src/main/java/io/digdag/standards/auth/jwt/JwtAuthenticatorConfigProvider.java @@ -0,0 +1,48 @@ +package io.digdag.standards.auth.jwt; + +import com.google.common.base.Optional; +import com.google.common.collect.ImmutableMap; +import com.google.inject.Inject; +import com.google.inject.Provider; +import io.digdag.client.api.RestApiKey; +import io.digdag.client.config.Config; + +public class JwtAuthenticatorConfigProvider + implements Provider +{ + + private final Config systemConfig; + + @Inject + public JwtAuthenticatorConfigProvider(Config systemConfig) + { + this.systemConfig = systemConfig; + } + + @Override + public JwtAuthenticatorConfig get() + { + ImmutableJwtAuthenticatorConfig.Builder builder = JwtAuthenticatorConfig.builder(); + + Optional apiKey = systemConfig.getOptional("server.apikey", RestApiKey.class); + + if (apiKey.isPresent()) { + UserConfig user = UserConfig.builder() + .siteId(0) + .isAdmin(true) + .apiKey(apiKey.get()) + .build(); + + builder + .userMap(ImmutableMap.of(user.getApiKey().getIdString(), user)) + .isAllowPublicAccess(false); + } + else { + builder + .userMap(ImmutableMap.of()) + .isAllowPublicAccess(true); + } + + return builder.build(); + } +} diff --git a/digdag-standards/src/main/java/io/digdag/standards/auth/jwt/JwtAuthenticatorPlugin.java b/digdag-standards/src/main/java/io/digdag/standards/auth/jwt/JwtAuthenticatorPlugin.java new file mode 100644 index 0000000000..c859427db9 --- /dev/null +++ b/digdag-standards/src/main/java/io/digdag/standards/auth/jwt/JwtAuthenticatorPlugin.java @@ -0,0 +1,26 @@ +package io.digdag.standards.auth.jwt; + +import com.google.inject.Binder; +import io.digdag.spi.Authenticator; +import io.digdag.spi.Plugin; + +public class JwtAuthenticatorPlugin + implements Plugin +{ + @Override + public Class getServiceProvider(Class type) + { + if (type == Authenticator.class) { + return JwtAuthenticator.class.asSubclass(type); + } + else { + return null; + } + } + + @Override + public void configureBinder(Class type, Binder binder) + { + binder.bind(JwtAuthenticatorConfig.class).toProvider(JwtAuthenticatorConfigProvider.class).asEagerSingleton(); + } +} diff --git a/digdag-server/src/main/java/io/digdag/server/UserConfig.java b/digdag-standards/src/main/java/io/digdag/standards/auth/jwt/UserConfig.java similarity index 93% rename from digdag-server/src/main/java/io/digdag/server/UserConfig.java rename to digdag-standards/src/main/java/io/digdag/standards/auth/jwt/UserConfig.java index e1deb769e4..a5f5a0ab46 100644 --- a/digdag-server/src/main/java/io/digdag/server/UserConfig.java +++ b/digdag-standards/src/main/java/io/digdag/standards/auth/jwt/UserConfig.java @@ -1,4 +1,4 @@ -package io.digdag.server; +package io.digdag.standards.auth.jwt; import io.digdag.client.api.RestApiKey; import com.fasterxml.jackson.databind.annotation.JsonSerialize; diff --git a/digdag-standards/src/main/java/io/digdag/standards/command/DockerCommandExecutor.java b/digdag-standards/src/main/java/io/digdag/standards/command/DockerCommandExecutor.java index 907f75457b..0f35f8ae87 100644 --- a/digdag-standards/src/main/java/io/digdag/standards/command/DockerCommandExecutor.java +++ b/digdag-standards/src/main/java/io/digdag/standards/command/DockerCommandExecutor.java @@ -61,22 +61,25 @@ private Process startWithDocker(Path projectPath, TaskRequest request, ProcessBu { Config dockerConfig = request.getConfig().getNestedOrGetEmpty("docker"); String baseImageName = dockerConfig.get("image", String.class); + String dockerCommand = dockerConfig.get("docker", String.class, "docker"); String imageName; if (dockerConfig.has("build")) { List buildCommands = dockerConfig.getList("build", String.class); + List buildOptions = dockerConfig.getListOrEmpty("build_options", String.class); imageName = uniqueImageName(request, baseImageName, buildCommands); - buildImage(imageName, projectPath, baseImageName, buildCommands); + buildImage(dockerCommand, buildOptions, imageName, projectPath, baseImageName, buildCommands); } else { imageName = baseImageName; if (dockerConfig.get("pull_always", Boolean.class, false)) { - pullImage(imageName); + pullImage(dockerCommand, imageName); } } ImmutableList.Builder command = ImmutableList.builder(); - command.add("docker").add("run"); + List runOptions = dockerConfig.getListOrEmpty("run_options", String.class); + command.add(dockerCommand).add("run").addAll(runOptions); try { // misc @@ -148,7 +151,8 @@ private static String uniqueImageName(TaskRequest request, return name + ':' + tag; } - private void buildImage(String imageName, Path projectPath, + private void buildImage(String dockerCommand, List buildOptions, + String imageName, Path projectPath, String baseImageName, List buildCommands) { try { @@ -164,7 +168,7 @@ private void buildImage(String imageName, Path projectPath, int ecode; String message; try (ByteArrayOutputStream buffer = new ByteArrayOutputStream()) { - ProcessBuilder pb = new ProcessBuilder("docker", "images"); + ProcessBuilder pb = new ProcessBuilder(dockerCommand, "images"); pb.redirectErrorStream(true); Process p = pb.start(); @@ -215,12 +219,14 @@ private void buildImage(String imageName, Path projectPath, } ImmutableList.Builder command = ImmutableList.builder(); - command.add("docker").add("build"); + command.add(dockerCommand).add("build").addAll(buildOptions); command.add("-f").add(dockerFilePath.toString()); command.add("--force-rm"); command.add("-t").add(imageName); command.add(projectPath.toString()); + logger.debug("Building docker image: {}", command.build().stream().collect(Collectors.joining(" "))); + ProcessBuilder docker = new ProcessBuilder(command.build()); docker.redirectError(ProcessBuilder.Redirect.INHERIT); docker.redirectOutput(ProcessBuilder.Redirect.INHERIT); @@ -237,12 +243,14 @@ private void buildImage(String imageName, Path projectPath, } } - private void pullImage(String imageName) + private void pullImage(String dockerCommand, String imageName) { logger.info("Pulling docker image {}", imageName); try { ImmutableList.Builder command = ImmutableList.builder(); - command.add("docker").add("pull").add(imageName); + command.add(dockerCommand).add("pull").add(imageName); + + logger.debug("Pulling docker image: {}", command.build().stream().collect(Collectors.joining(" "))); ProcessBuilder docker = new ProcessBuilder(command.build()); docker.redirectError(ProcessBuilder.Redirect.INHERIT); diff --git a/digdag-standards/src/main/java/io/digdag/standards/operator/EchoOperatorFactory.java b/digdag-standards/src/main/java/io/digdag/standards/operator/EchoOperatorFactory.java index f8b0cdf3cc..66343e688e 100644 --- a/digdag-standards/src/main/java/io/digdag/standards/operator/EchoOperatorFactory.java +++ b/digdag-standards/src/main/java/io/digdag/standards/operator/EchoOperatorFactory.java @@ -2,12 +2,16 @@ import com.google.inject.Inject; import io.digdag.client.config.Config; +import io.digdag.core.log.TaskContextLogging; +import io.digdag.core.log.TaskLogger; import io.digdag.spi.Operator; import io.digdag.spi.OperatorContext; import io.digdag.spi.OperatorFactory; import io.digdag.spi.TaskRequest; import io.digdag.spi.TaskResult; +import java.nio.charset.StandardCharsets; + public class EchoOperatorFactory implements OperatorFactory { @@ -45,6 +49,11 @@ public TaskResult run() System.out.println(message); + // To store the message to task log + TaskLogger logger = TaskContextLogging.getContext().getLogger(); + byte[] messageBytes = message.getBytes(StandardCharsets.UTF_8); + logger.log(messageBytes, 0, messageBytes.length); + return TaskResult.empty(request); } } diff --git a/digdag-standards/src/main/java/io/digdag/standards/operator/HttpCallOperatorFactory.java b/digdag-standards/src/main/java/io/digdag/standards/operator/HttpCallOperatorFactory.java new file mode 100644 index 0000000000..2cca130f90 --- /dev/null +++ b/digdag-standards/src/main/java/io/digdag/standards/operator/HttpCallOperatorFactory.java @@ -0,0 +1,222 @@ +package io.digdag.standards.operator; + +import com.fasterxml.jackson.databind.ObjectMapper; +import com.fasterxml.jackson.dataformat.yaml.YAMLFactory; +import com.fasterxml.jackson.dataformat.yaml.YAMLGenerator; +import com.google.common.base.Strings; +import com.google.inject.Inject; +import io.digdag.client.config.Config; +import io.digdag.client.config.ConfigException; +import io.digdag.client.config.ConfigFactory; +import io.digdag.core.Environment; +import io.digdag.core.archive.ProjectArchiveLoader; +import io.digdag.core.archive.WorkflowFile; +import io.digdag.core.config.ConfigLoaderManager; +import io.digdag.core.config.YamlConfigLoader; +import io.digdag.spi.Operator; +import io.digdag.spi.OperatorContext; +import io.digdag.spi.TaskExecutionException; +import io.digdag.spi.TaskResult; +import io.digdag.util.UserSecretTemplate; +import java.io.BufferedWriter; +import java.io.IOException; +import java.io.StringWriter; +import java.io.UnsupportedEncodingException; +import java.net.URI; +import java.nio.charset.UnsupportedCharsetException; +import java.nio.file.Files; +import java.nio.file.Path; +import java.util.Map; +import javax.ws.rs.core.MediaType; +import org.eclipse.jetty.client.HttpClient; +import org.eclipse.jetty.client.api.ContentResponse; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import static io.digdag.util.Workspace.propagateIoException; +import static java.nio.charset.StandardCharsets.UTF_8; +import static java.util.Locale.ENGLISH; + +public class HttpCallOperatorFactory + extends HttpOperatorFactory +{ + private static final Logger logger = LoggerFactory.getLogger(HttpCallOperatorFactory.class); + + private static final String WORKFLOW_FILE_NAME = "http_call.dig"; + + private final ConfigFactory cf; + private final ObjectMapper mapper; + private final YAMLFactory yaml; + private final ProjectArchiveLoader projectLoader; + private final int maxResponseContentSize; + + @Inject + public HttpCallOperatorFactory(ConfigFactory cf, + Config systemConfig, @Environment Map env) + { + super(systemConfig, env); + this.cf = cf; + this.mapper = new ObjectMapper(); + this.yaml = new YAMLFactory() + .configure(YAMLGenerator.Feature.WRITE_DOC_START_MARKER, false); + this.projectLoader = new ProjectArchiveLoader( + new ConfigLoaderManager( + cf, + new YamlConfigLoader())); + this.maxResponseContentSize = systemConfig.get("config.http_call.max_response_content_size", int.class, 64 * 1024); + } + + @Override + public String getType() + { + return "http_call"; + } + + @Override + public Operator newOperator(OperatorContext context) + { + return new HttpCallOperator(context); + } + + class HttpCallOperator + extends HttpOperator + { + public HttpCallOperator(OperatorContext context) + { + super(context); + } + + @Override + public TaskResult runTask() + { + UserSecretTemplate uriTemplate = UserSecretTemplate.of(params.get("_command", String.class)); + boolean uriIsSecret = uriTemplate.containsSecrets(); + URI uri = URI.create(uriTemplate.format(context.getSecrets())); + String mediaTypeOverride = params.getOptional("content_type_override", String.class).orNull(); + + ContentResponse response; + + HttpClient httpClient = client(); + try { + response = runHttp(httpClient, uri, uriIsSecret); + } + finally { + stop(httpClient); + } + + String content; + if (Strings.isNullOrEmpty(mediaTypeOverride)) { + // This ContentResponse::getContentAsString considers ;charset= parameter + // of Content-Type. If not set, it uses UTF-8. + content = response.getContentAsString(); + } + else { + // This logic mimics how org.eclipse.jetty.client.HttpContentResponse::getContentAsString handles Content-Type + int index = mediaTypeOverride.toLowerCase(ENGLISH).indexOf("charset="); + if (index > 0) { + String encoding = mediaTypeOverride.substring(index + "charset=".length()); + try { + content = new String(response.getContent(), encoding); + } + catch (UnsupportedEncodingException e) { + throw new UnsupportedCharsetException(encoding); + } + } + else { + content = new String(response.getContent(), UTF_8); + } + } + + // validate response length + if (content.length() > maxResponseContentSize) { + throw new TaskExecutionException("Response content too large: " + content.length() + " > " + maxResponseContentSize); + } + + // parse content based on response media type + String digFileSource = reformatDigFile(content, response.getMediaType(), mediaTypeOverride); + // write to http_call.dig file + Path workflowPath = writeDigFile(digFileSource); + + // following code is almost same with CallOperatorFactory.CallOperator.runTask + Config config = request.getConfig(); + + WorkflowFile workflowFile; + try { + workflowFile = projectLoader.loadWorkflowFileFromPath( + workspace.getProjectPath(), workflowPath, config.getFactory().create()); + } + catch (IOException ex) { + throw propagateIoException(ex, WORKFLOW_FILE_NAME, ConfigException::new); + } + + Config def = workflowFile.toWorkflowDefinition().getConfig(); + + return TaskResult.defaultBuilder(request) + .subtaskConfig(def) + .build(); + } + + private String reformatDigFile(String content, String mediaTypeString, String mediaTypeOverride) + { + MediaType mediaType; + if (Strings.isNullOrEmpty(mediaTypeOverride)) { + if (Strings.isNullOrEmpty(mediaTypeString)) { + throw new TaskExecutionException("Content-Type must be set in the HTTP response but not set"); + } + mediaType = MediaType.valueOf(mediaTypeString); + } + else { + mediaType = MediaType.valueOf(mediaTypeOverride); + } + + String t = mediaType.getType() + "/" + mediaType.getSubtype(); // without ;charset= or other params + switch (t) { + case MediaType.APPLICATION_JSON: + try { + // parse as json + Config sourceConfig = cf.fromJsonString(content); + // reformat as yaml + return formatYaml(sourceConfig); + } + catch (ConfigException ex) { + throw new RuntimeException("Failed to parse response as JSON: " + ex.getMessage(), ex); + } + + case "application/x-yaml": + // use as-is; let projectLoader.loadWorkflowFileFromPath handle parse errors + return content; + + //case MediaType.TEXT_PLAIN: + //case MediaType.APPLICATION_OCTET_STREAM: + + default: + throw new TaskExecutionException("Unsupported Content-Type (expected application/json or application/x-yaml): " + mediaTypeString); + } + } + + private String formatYaml(Config value) + { + try { + StringWriter writer = new StringWriter(); + try (YAMLGenerator out = yaml.createGenerator(writer)) { + mapper.writeValue(out, value); + } + return writer.toString(); + } + catch (IOException ex) { + throw new RuntimeException(ex); + } + } + + private Path writeDigFile(String source) + { + Path workflowPath = workspace.getPath(WORKFLOW_FILE_NAME); + try (BufferedWriter writer = Files.newBufferedWriter(workflowPath, UTF_8)) { + writer.write(source); + } + catch (IOException ex) { + throw new RuntimeException(ex); + } + return workflowPath; + } + } +} diff --git a/digdag-standards/src/main/java/io/digdag/standards/operator/HttpOperatorFactory.java b/digdag-standards/src/main/java/io/digdag/standards/operator/HttpOperatorFactory.java index 0449e70cb2..97b7337170 100644 --- a/digdag-standards/src/main/java/io/digdag/standards/operator/HttpOperatorFactory.java +++ b/digdag-standards/src/main/java/io/digdag/standards/operator/HttpOperatorFactory.java @@ -4,7 +4,7 @@ import com.fasterxml.jackson.databind.node.ArrayNode; import com.fasterxml.jackson.databind.node.ObjectNode; import com.fasterxml.jackson.databind.node.TextNode; -import com.google.api.client.repackaged.com.google.common.base.Throwables; +import com.google.common.base.Throwables; import com.google.common.base.Optional; import com.google.common.collect.LinkedHashMultimap; import com.google.inject.Inject; @@ -109,16 +109,17 @@ public Operator newOperator(OperatorContext context) return new HttpOperator(context); } - private class HttpOperator + class HttpOperator extends BaseOperator { private final TaskState state; - private final Config params; - private final String method; - private final boolean retry; - private final long timeout; + final Config params; + final String method; + final boolean retry; + final long timeout; + final SecretProvider httpSecrets; - private HttpOperator(OperatorContext context) + protected HttpOperator(OperatorContext context) { super(context); this.state = TaskState.of(request); @@ -128,6 +129,7 @@ private HttpOperator(OperatorContext context) this.retry = params.getOptional("retry", boolean.class) .or(defaultRetry(method)); this.timeout = params.get("timeout", Long.class, 30L); + this.httpSecrets = context.getSecrets().getSecrets("http"); } @Override @@ -144,8 +146,6 @@ public TaskResult runTask() private TaskResult run(HttpClient httpClient) { - SecretProvider httpSecrets = context.getSecrets().getSecrets("http"); - Optional secretUri = httpSecrets.getSecretOptional("uri"); String rawUri; boolean uriIsSecret; @@ -160,6 +160,14 @@ private TaskResult run(HttpClient httpClient) } URI uri = URI.create(rawUri); + boolean storeContent = params.get("store_content", boolean.class, false); + + ContentResponse response = runHttp(httpClient, uri, uriIsSecret); + return result(response, storeContent); + } + + ContentResponse runHttp(HttpClient httpClient, URI uri, boolean uriIsSecret) + { Optional user = httpSecrets.getSecretOptional("user"); Optional authorization = httpSecrets.getSecretOptional("authorization"); @@ -178,7 +186,6 @@ else if (user.isPresent()) { Optional content = params.getOptional("content", JsonNode.class); Optional contentFormat = params.getOptional("content_format", String.class).transform(s -> s.toLowerCase(Locale.ROOT)); Optional contentType = params.getOptional("content_type", String.class); - boolean storeContent = params.get("store_content", boolean.class, false); if (content.isPresent()) { // TODO: support files on disk etc @@ -196,7 +203,7 @@ else if (user.isPresent()) { .withErrorMessage("HTTP request failed") .run(s -> execute(request, uriIsSecret)); - return result(response, storeContent); + return response; } private void configureQueryParameters(Request request) @@ -387,7 +394,7 @@ private TaskResult result(ContentResponse response, boolean storeContent) .build(); } - private HttpClient client() + HttpClient client() { boolean insecure = params.get("insecure", boolean.class, false); @@ -434,7 +441,7 @@ private void configureProxy(HttpClient httpClient) } } - private void stop(HttpClient httpClient) + void stop(HttpClient httpClient) { try { httpClient.stop(); diff --git a/digdag-standards/src/main/java/io/digdag/standards/operator/OperatorModule.java b/digdag-standards/src/main/java/io/digdag/standards/operator/OperatorModule.java index 19a9a20bbf..77dfbaaba3 100644 --- a/digdag-standards/src/main/java/io/digdag/standards/operator/OperatorModule.java +++ b/digdag-standards/src/main/java/io/digdag/standards/operator/OperatorModule.java @@ -57,6 +57,7 @@ public void configure(Binder binder) addStandardOperatorFactory(binder, S3WaitOperatorFactory.class); addStandardOperatorFactory(binder, EmrOperatorFactory.class); addStandardOperatorFactory(binder, HttpOperatorFactory.class); + addStandardOperatorFactory(binder, HttpCallOperatorFactory.class); addStandardOperatorFactory(binder, ParamSetOperatorFactory.class); addStandardOperatorFactory(binder, ParamGetOperatorFactory.class); } diff --git a/digdag-standards/src/main/java/io/digdag/standards/operator/PyOperatorFactory.java b/digdag-standards/src/main/java/io/digdag/standards/operator/PyOperatorFactory.java index 11536c277a..f296860d40 100644 --- a/digdag-standards/src/main/java/io/digdag/standards/operator/PyOperatorFactory.java +++ b/digdag-standards/src/main/java/io/digdag/standards/operator/PyOperatorFactory.java @@ -1,6 +1,7 @@ package io.digdag.standards.operator; import java.util.List; +import java.util.stream.Collectors; import java.io.Writer; import java.io.BufferedWriter; import java.io.OutputStreamWriter; @@ -9,12 +10,16 @@ import java.io.InputStreamReader; import java.nio.file.Path; import java.nio.charset.StandardCharsets; +import java.util.Arrays; import java.util.Map; +import com.google.common.base.Optional; import com.google.common.base.Throwables; import com.google.common.collect.ImmutableList; import com.google.common.collect.ImmutableMap; import com.google.common.io.CharStreams; +import com.fasterxml.jackson.databind.JsonNode; import com.fasterxml.jackson.databind.ObjectMapper; +import com.fasterxml.jackson.databind.JsonMappingException; import com.google.inject.Inject; import io.digdag.spi.OperatorContext; import org.slf4j.Logger; @@ -26,6 +31,7 @@ import io.digdag.spi.Operator; import io.digdag.spi.OperatorFactory; import io.digdag.client.config.Config; +import io.digdag.client.config.ConfigException; import io.digdag.util.BaseOperator; import static io.digdag.standards.operator.ShOperatorFactory.collectEnvironmentVariables; @@ -124,12 +130,29 @@ private Config runCode(Config params) mapper.writeValue(fo, ImmutableMap.of("params", params)); } - final String python = params.get("python", String.class, "python"); + List python; + final JsonNode pythonJsonNode = params.getInternalObjectNode().get("python"); + if (pythonJsonNode == null) { + python = ImmutableList.of("python"); + } + else if (pythonJsonNode.isTextual()) { + final String path = pythonJsonNode.asText(); + python = ImmutableList.of(path); + } + else if (pythonJsonNode.isArray()) { + python = Arrays.asList(mapper.readValue(pythonJsonNode.traverse(), String[].class)); + } + else { + throw new ConfigException("Invalid python: " + pythonJsonNode.asText()); + } + List cmdline = ImmutableList.builder() - .add(python).add("-") // script is fed from stdin + .addAll(python).add("-") // script is fed from stdin .addAll(args) .build(); + logger.trace("Running py operator: {}", cmdline.stream().collect(Collectors.joining(" "))); + ProcessBuilder pb = new ProcessBuilder(cmdline); pb.directory(workspace.getPath().toFile()); pb.redirectErrorStream(true); @@ -151,7 +174,30 @@ private Config runCode(Config params) int ecode = p.waitFor(); if (ecode != 0) { - throw new RuntimeException("Python command failed with code " + ecode); + StringBuilder reason = new StringBuilder(); + reason.append("Python command failed with code ").append(ecode); + + try { + Config out = mapper.readValue(workspace.getFile(outFile), Config.class); + Config err = out.getNestedOrGetEmpty("error"); + Optional errClass = err.getOptional("class", String.class); + Optional errMessage = err.getOptional("message", String.class); + List errBacktrace = err.getListOrEmpty("backtrace", String.class); + if (errClass.isPresent()) { + reason.append(": from ").append(errClass.get()); + } + if (errMessage.isPresent()) { + reason.append(": ").append(errMessage.get()); + } + if (!errBacktrace.isEmpty()) { + reason.append("\n "); + reason.append(String.join(" ", errBacktrace)); + } + } + catch (JsonMappingException ex) { + // comes here if runner.py fails before writing outFile. + } + throw new RuntimeException(reason.toString()); } return mapper.readValue(workspace.getFile(outFile), Config.class); diff --git a/digdag-standards/src/main/java/io/digdag/standards/operator/RbOperatorFactory.java b/digdag-standards/src/main/java/io/digdag/standards/operator/RbOperatorFactory.java index f9fd127614..1facc312a2 100644 --- a/digdag-standards/src/main/java/io/digdag/standards/operator/RbOperatorFactory.java +++ b/digdag-standards/src/main/java/io/digdag/standards/operator/RbOperatorFactory.java @@ -9,13 +9,17 @@ import java.io.InputStreamReader; import java.nio.file.Path; import java.nio.charset.StandardCharsets; +import java.util.Arrays; import java.util.Map; +import java.util.stream.Collectors; +import com.fasterxml.jackson.databind.JsonNode; import com.google.common.base.Optional; import com.google.common.base.Throwables; import com.google.common.collect.ImmutableList; import com.google.common.collect.ImmutableMap; import com.google.common.io.CharStreams; import com.fasterxml.jackson.databind.ObjectMapper; +import com.fasterxml.jackson.databind.JsonMappingException; import com.google.inject.Inject; import io.digdag.spi.OperatorContext; import org.slf4j.Logger; @@ -27,6 +31,7 @@ import io.digdag.spi.Operator; import io.digdag.spi.OperatorFactory; import io.digdag.client.config.Config; +import io.digdag.client.config.ConfigException; import io.digdag.util.BaseOperator; import static io.digdag.standards.operator.ShOperatorFactory.collectEnvironmentVariables; @@ -127,9 +132,24 @@ private Config runCode(Config params) mapper.writeValue(fo, ImmutableMap.of("params", params)); } - final String ruby = params.get("ruby", String.class, "ruby"); + List ruby; + final JsonNode rubyJsonNode = params.getInternalObjectNode().get("ruby"); + if (rubyJsonNode == null) { + ruby = ImmutableList.of("ruby"); + } + else if (rubyJsonNode.isTextual()) { + final String path = rubyJsonNode.asText(); + ruby = ImmutableList.of(path); + } + else if (rubyJsonNode.isArray()) { + ruby = Arrays.asList(mapper.readValue(rubyJsonNode.traverse(), String[].class)); + } + else { + throw new ConfigException("Invalid ruby: " + rubyJsonNode.asText()); + } + ImmutableList.Builder cmdline = ImmutableList.builder(); - cmdline.add(ruby); + cmdline.addAll(ruby); cmdline.add("-I").add(workspace.getPath().toString()); if (feature.isPresent()) { cmdline.add("-r").add(feature.get()); @@ -137,6 +157,8 @@ private Config runCode(Config params) cmdline.add("--").add("-"); // script is fed from stdin TODO: this doesn't work with jruby cmdline.addAll(args); + logger.trace("Running rb operator: {}", cmdline.build().stream().collect(Collectors.joining(" "))); + ProcessBuilder pb = new ProcessBuilder(cmdline.build()); pb.directory(workspace.getPath().toFile()); pb.redirectErrorStream(true); @@ -158,7 +180,31 @@ private Config runCode(Config params) int ecode = p.waitFor(); if (ecode != 0) { - throw new RuntimeException("Ruby command failed with code " + ecode); + StringBuilder reason = new StringBuilder(); + reason.append("Ruby command failed with code ").append(ecode); + // If a ruby error message and stacktrace are available in outFile, + // throw RuntimeException with them. + try { + Config out = mapper.readValue(workspace.getFile(outFile), Config.class); + Config err = out.getNestedOrGetEmpty("error"); + Optional errClass = err.getOptional("class", String.class); + Optional errMessage = err.getOptional("message", String.class); + List errBacktrace = err.getListOrEmpty("backtrace", String.class); + if (errMessage.isPresent()) { + reason.append(": ").append(errMessage.get()); + } + if (errClass.isPresent()) { + reason.append(" (").append(errClass.get()).append(")"); + } + if (!errBacktrace.isEmpty()) { + reason.append("\n\tfrom "); + reason.append(String.join("\n\tfrom ", errBacktrace)); + } + } + catch (JsonMappingException ex) { + // comes here if runner.rb fails before writing outFile. + } + throw new RuntimeException(reason.toString()); } return mapper.readValue(workspace.getFile(outFile), Config.class); diff --git a/digdag-standards/src/main/java/io/digdag/standards/operator/aws/EmrOperatorFactory.java b/digdag-standards/src/main/java/io/digdag/standards/operator/aws/EmrOperatorFactory.java index 2ab29485c2..dd37efa1c7 100644 --- a/digdag-standards/src/main/java/io/digdag/standards/operator/aws/EmrOperatorFactory.java +++ b/digdag-standards/src/main/java/io/digdag/standards/operator/aws/EmrOperatorFactory.java @@ -57,8 +57,8 @@ import com.fasterxml.jackson.databind.ObjectMapper; import com.fasterxml.jackson.databind.annotation.JsonDeserialize; import com.fasterxml.jackson.databind.annotation.JsonSerialize; -import com.google.api.client.repackaged.com.google.common.base.Splitter; -import com.google.api.client.repackaged.com.google.common.base.Throwables; +import com.google.common.base.Splitter; +import com.google.common.base.Throwables; import com.google.common.base.Optional; import com.google.common.base.Preconditions; import com.google.common.collect.ImmutableList; diff --git a/digdag-standards/src/main/java/io/digdag/standards/operator/gcp/BaseBqJobOperator.java b/digdag-standards/src/main/java/io/digdag/standards/operator/gcp/BaseBqJobOperator.java index cc22accf3b..a802c860c5 100644 --- a/digdag-standards/src/main/java/io/digdag/standards/operator/gcp/BaseBqJobOperator.java +++ b/digdag-standards/src/main/java/io/digdag/standards/operator/gcp/BaseBqJobOperator.java @@ -31,9 +31,11 @@ private TaskResult result(Job job) ConfigFactory cf = request.getConfig().getFactory(); Config result = cf.create(); Config bq = result.getNestedOrSetEmpty("bq"); + bq.set("last_job_id", job.getId()); bq.set("last_jobid", job.getId()); return TaskResult.defaultBuilder(request) .storeParams(result) + .addResetStoreParams(ConfigKey.of("bq", "last_job_id")) .addResetStoreParams(ConfigKey.of("bq", "last_jobid")) .build(); } diff --git a/digdag-standards/src/main/java/io/digdag/standards/operator/gcp/BqLoadOperatorFactory.java b/digdag-standards/src/main/java/io/digdag/standards/operator/gcp/BqLoadOperatorFactory.java index 5d6dc94c7c..c9cbad5ae4 100644 --- a/digdag-standards/src/main/java/io/digdag/standards/operator/gcp/BqLoadOperatorFactory.java +++ b/digdag-standards/src/main/java/io/digdag/standards/operator/gcp/BqLoadOperatorFactory.java @@ -96,9 +96,9 @@ protected JobConfiguration jobConfiguration(String projectId) params.getOptional("allow_quoted_newlines", boolean.class).transform(cfg::setAllowQuotedNewlines); params.getOptional("allow_jagged_rows", boolean.class).transform(cfg::setAllowJaggedRows); params.getOptional("ignore_unknown_values", boolean.class).transform(cfg::setIgnoreUnknownValues); - params.getOptional("projection_fields", new TypeReference>() {}).transform(cfg::setProjectionFields); + Optional.of(params.getListOrEmpty("projection_fields", String.class)).transform(cfg::setProjectionFields); params.getOptional("autodetect", boolean.class).transform(cfg::setAutodetect); - params.getOptional("schema_update_options", new TypeReference>() {}).transform(cfg::setSchemaUpdateOptions); + Optional.of(params.getListOrEmpty("schema_update_options", String.class)).transform(cfg::setSchemaUpdateOptions); return new JobConfiguration() .setLoad(cfg); diff --git a/digdag-standards/src/main/java/io/digdag/standards/operator/param/PostgresqlParamServerClient.java b/digdag-standards/src/main/java/io/digdag/standards/operator/param/PostgresqlParamServerClient.java index 979190a06d..8cd2ecf70a 100644 --- a/digdag-standards/src/main/java/io/digdag/standards/operator/param/PostgresqlParamServerClient.java +++ b/digdag-standards/src/main/java/io/digdag/standards/operator/param/PostgresqlParamServerClient.java @@ -44,7 +44,7 @@ public Optional get(String key, int siteId) "select key, value, value_type" + " from params" + " where key = :key and site_id = :site_id" + - " and updated_at + INTERVAL '" + String.valueOf(DEFAULT_TTL) + " seconds' >= now()" + + " and updated_at + INTERVAL '" + String.valueOf(DEFAULT_TTL_IN_SEC) + " seconds' >= now()" + " limit 1") .bind("key", key) .bind("site_id", siteId) diff --git a/digdag-standards/src/main/java/io/digdag/standards/operator/param/RedisParamServerClient.java b/digdag-standards/src/main/java/io/digdag/standards/operator/param/RedisParamServerClient.java index e03b117d52..45cd5efb8b 100644 --- a/digdag-standards/src/main/java/io/digdag/standards/operator/param/RedisParamServerClient.java +++ b/digdag-standards/src/main/java/io/digdag/standards/operator/param/RedisParamServerClient.java @@ -98,7 +98,7 @@ public void commit() if (!msetTarget.isEmpty()) { Transaction multi = connection.multi(); for (Map.Entry entry : msetTarget.entrySet()) { - multi.setex(entry.getKey(), DEFAULT_TTL, entry.getValue()); + multi.setex(entry.getKey(), DEFAULT_TTL_IN_SEC, entry.getValue()); } multi.exec(); } diff --git a/digdag-standards/src/main/java/io/digdag/standards/operator/td/TdForEachOperatorFactory.java b/digdag-standards/src/main/java/io/digdag/standards/operator/td/TdForEachOperatorFactory.java index fa8f91d6ff..b742275c23 100644 --- a/digdag-standards/src/main/java/io/digdag/standards/operator/td/TdForEachOperatorFactory.java +++ b/digdag-standards/src/main/java/io/digdag/standards/operator/td/TdForEachOperatorFactory.java @@ -2,6 +2,7 @@ import com.google.common.base.Optional; import com.google.inject.Inject; +import com.treasuredata.client.model.TDJob; import com.treasuredata.client.model.TDJobRequest; import com.treasuredata.client.model.TDJobRequestBuilder; import io.digdag.client.config.Config; @@ -68,6 +69,7 @@ private class TdForEachOperator private final int priority; private final int jobRetry; private final String engine; + private final Optional engineVersion; private final Optional poolName; private final Config doConfig; @@ -84,6 +86,7 @@ private TdForEachOperator(OperatorContext context) this.engine = params.get("engine", String.class, "presto"); this.poolName = poolNameOfEngine(params, engine); this.doConfig = request.getConfig().getNested("_do"); + this.engineVersion = params.getOptional("engine_version", String.class); } @Override @@ -127,6 +130,7 @@ protected String startJob(TDOperator op, String domainkey) .setPoolName(poolName.orNull()) .setDomainKey(domainkey) .setScheduledTime(request.getSessionTime().getEpochSecond()) + .setEngineVersion(engineVersion.transform(e -> TDJob.EngineVersion.fromString(e)).orNull()) .createTDJobRequest(); String jobId = op.submitNewJobWithRetry(req); diff --git a/digdag-standards/src/main/java/io/digdag/standards/operator/td/TdOperatorFactory.java b/digdag-standards/src/main/java/io/digdag/standards/operator/td/TdOperatorFactory.java index ba341047da..97d44f0f7a 100644 --- a/digdag-standards/src/main/java/io/digdag/standards/operator/td/TdOperatorFactory.java +++ b/digdag-standards/src/main/java/io/digdag/standards/operator/td/TdOperatorFactory.java @@ -8,6 +8,7 @@ import com.google.common.collect.ImmutableList; import com.google.inject.Inject; import com.treasuredata.client.TDClientHttpNotFoundException; +import com.treasuredata.client.model.TDJob; import com.treasuredata.client.model.TDJobRequest; import com.treasuredata.client.model.TDJobRequestBuilder; import io.digdag.client.config.Config; @@ -95,6 +96,7 @@ private class TdOperator private final Optional resultUrl; private final int jobRetry; private final String engine; + private final Optional engineVersion; private final Optional poolName; private final Optional downloadFile; private final Optional resultConnection; @@ -146,6 +148,8 @@ private TdOperator(OperatorContext context) this.storeLastResults = params.get("store_last_results", boolean.class, false); this.preview = params.get("preview", boolean.class, false); + + this.engineVersion = params.getOptional("engine_version", String.class); } @Override @@ -225,6 +229,7 @@ else if (createTable.isPresent()) { .setResultConnectionId(resultConnection.transform(name -> getResultConnectionId(name, op))) .setResultConnectionSettings(resultSettings.transform(t -> t.format(context.getSecrets()))) .setDomainKey(domainKey) + .setEngineVersion(engineVersion.transform(e -> TDJob.EngineVersion.fromString(e)).orNull()) .createTDJobRequest(); String jobId = op.submitNewJobWithRetry(req); diff --git a/digdag-standards/src/main/java/io/digdag/standards/operator/td/TdRunOperatorFactory.java b/digdag-standards/src/main/java/io/digdag/standards/operator/td/TdRunOperatorFactory.java index 37f09d5e97..67ad8b2733 100644 --- a/digdag-standards/src/main/java/io/digdag/standards/operator/td/TdRunOperatorFactory.java +++ b/digdag-standards/src/main/java/io/digdag/standards/operator/td/TdRunOperatorFactory.java @@ -96,7 +96,7 @@ private String startById(TDOperator op, String domainKey, long id) .build(); String jobId = op.submitNewJobWithRetry(client -> client.startSavedQuery(req)); - logger.info("Started a saved query id={} with time={}, job id= {}", id, sessionTime, jobId); + logger.info("Started a saved query id={} with time={}, job id={}", id, sessionTime, jobId); return jobId; } @@ -109,7 +109,7 @@ private String startByName(TDOperator op, String domainKey, String name) .build(); String jobId = op.submitNewJobWithRetry(client -> client.startSavedQuery(req)); - logger.info("Started a saved query name={} with time={}, job id= {}", name, sessionTime, jobId); + logger.info("Started a saved query name={} with time={}, job id={}", name, sessionTime, jobId); return jobId; } diff --git a/digdag-standards/src/main/java/io/digdag/standards/operator/td/TdWaitOperatorFactory.java b/digdag-standards/src/main/java/io/digdag/standards/operator/td/TdWaitOperatorFactory.java index 2b0b6d4d91..d8acc1cd31 100644 --- a/digdag-standards/src/main/java/io/digdag/standards/operator/td/TdWaitOperatorFactory.java +++ b/digdag-standards/src/main/java/io/digdag/standards/operator/td/TdWaitOperatorFactory.java @@ -1,8 +1,10 @@ package io.digdag.standards.operator.td; +import com.google.common.annotations.VisibleForTesting; import com.google.common.base.Optional; import com.google.inject.Inject; import com.treasuredata.client.TDClientException; +import com.treasuredata.client.model.TDJob; import com.treasuredata.client.model.TDJobRequest; import com.treasuredata.client.model.TDJobRequestBuilder; import io.digdag.client.config.Config; @@ -68,13 +70,15 @@ public Operator newOperator(OperatorContext context) return new TdWaitOperator(context); } - private class TdWaitOperator + @VisibleForTesting + class TdWaitOperator extends BaseOperator { private final Config params; private final String query; private final int queryPollInterval; private final String engine; + private final Optional engineVersion; private final Optional poolName; private final int priority; private final int jobRetry; @@ -96,6 +100,7 @@ private TdWaitOperator(OperatorContext context) this.poolName = poolNameOfEngine(params, engine); this.jobRetry = params.get("job_retry", int.class, 0); this.state = TaskState.of(request); + this.engineVersion = params.getOptional("engine_version", String.class); } @Override @@ -124,7 +129,8 @@ public TaskResult runTask() } } - private String startJob(TDOperator op, String domainKey) + @VisibleForTesting + String startJob(TDOperator op, String domainKey) { TDJobRequest req = new TDJobRequestBuilder() .setType(engine) @@ -135,6 +141,7 @@ private String startJob(TDOperator op, String domainKey) .setScheduledTime(request.getSessionTime().getEpochSecond()) .setPoolName(poolName.orNull()) .setDomainKey(domainKey) + .setEngineVersion(engineVersion.transform(e -> TDJob.EngineVersion.fromString(e)).orNull()) .createTDJobRequest(); String jobId = op.submitNewJobWithRetry(req); diff --git a/digdag-standards/src/main/java/io/digdag/standards/operator/td/TdWaitTableOperatorFactory.java b/digdag-standards/src/main/java/io/digdag/standards/operator/td/TdWaitTableOperatorFactory.java index c045c65bae..5456bb0456 100644 --- a/digdag-standards/src/main/java/io/digdag/standards/operator/td/TdWaitTableOperatorFactory.java +++ b/digdag-standards/src/main/java/io/digdag/standards/operator/td/TdWaitTableOperatorFactory.java @@ -1,8 +1,10 @@ package io.digdag.standards.operator.td; +import com.google.common.annotations.VisibleForTesting; import com.google.common.base.Optional; import com.google.inject.Inject; import com.treasuredata.client.TDClientException; +import com.treasuredata.client.model.TDJob; import com.treasuredata.client.model.TDJobRequest; import com.treasuredata.client.model.TDJobRequestBuilder; import io.digdag.client.config.Config; @@ -72,7 +74,8 @@ public Operator newOperator(OperatorContext context) return new TdWaitTableOperator(context); } - private class TdWaitTableOperator + @VisibleForTesting + class TdWaitTableOperator extends BaseOperator { private final Config params; @@ -81,6 +84,7 @@ private class TdWaitTableOperator private final int tableExistencePollInterval; private final int rows; private final String engine; + private final Optional engineVersion; private final int priority; private final Optional poolName; private final int jobRetry; @@ -104,6 +108,7 @@ private TdWaitTableOperator(OperatorContext context) this.poolName = poolNameOfEngine(params, engine); this.jobRetry = params.get("job_retry", int.class, 0); this.state = TaskState.of(request); + this.engineVersion = params.getOptional("engine_version", String.class); } @Override @@ -189,7 +194,8 @@ private boolean fetchJobResult(int rows, TDJobOperator job) return BigInteger.valueOf(rows).compareTo(actualRows.asBigInteger()) <= 0; } - private String startJob(TDOperator op, String domainKey) + @VisibleForTesting + String startJob(TDOperator op, String domainKey) { String query = createQuery(); @@ -201,6 +207,7 @@ private String startJob(TDOperator op, String domainKey) .setPriority(priority) .setPoolName(poolName.orNull()) .setDomainKey(domainKey) + .setEngineVersion(engineVersion.transform(e -> TDJob.EngineVersion.fromString(e)).orNull()) .createTDJobRequest(); String jobId = op.submitNewJobWithRetry(req); diff --git a/digdag-standards/src/main/resources/META-INF/services/io.digdag.spi.Plugin b/digdag-standards/src/main/resources/META-INF/services/io.digdag.spi.Plugin index 101ea1f74e..47c915fa3d 100644 --- a/digdag-standards/src/main/resources/META-INF/services/io.digdag.spi.Plugin +++ b/digdag-standards/src/main/resources/META-INF/services/io.digdag.spi.Plugin @@ -1 +1,3 @@ io.digdag.standards.td.TdDigdagClientConfigurationPlugin +io.digdag.standards.auth.jwt.JwtAuthenticatorPlugin +io.digdag.standards.auth.basic.BasicAuthenticatorPlugin \ No newline at end of file diff --git a/digdag-standards/src/main/resources/digdag/standards/py/runner.py b/digdag-standards/src/main/resources/digdag/standards/py/runner.py index e8b0751b64..d4c7d9acbb 100644 --- a/digdag-standards/src/main/resources/digdag/standards/py/runner.py +++ b/digdag-standards/src/main/resources/digdag/standards/py/runner.py @@ -1,9 +1,10 @@ import sys import os import json -import imp +import types import inspect import collections +import traceback command = sys.argv[1] in_file = sys.argv[2] @@ -14,7 +15,7 @@ params = in_data['params'] # fake digdag_env module already imported -digdag_env_mod = sys.modules['digdag_env'] = imp.new_module('digdag_env') +digdag_env_mod = sys.modules['digdag_env'] = types.ModuleType('digdag_env') digdag_env_mod.params = params digdag_env_mod.subtask_config = collections.OrderedDict() digdag_env_mod.export_params = {} @@ -23,7 +24,7 @@ import digdag_env # fake digdag module already imported -digdag_mod = sys.modules['digdag'] = imp.new_module('digdag') +digdag_mod = sys.modules['digdag'] = types.ModuleType('digdag') class Env(object): def __init__(self, digdag_env_mod): @@ -72,7 +73,7 @@ def add_subtask(self, function=None, **params): digdag_mod.env = Env(digdag_env_mod) import digdag -# add the archive path to improt path +# add the archive path to import path sys.path.append(os.path.abspath(os.getcwd())) def digdag_inspect_command(command): @@ -140,6 +141,9 @@ def digdag_inspect_arguments(callable_type, exclude_self, params): return args callable_type, method_name = digdag_inspect_command(command) +error = None +error_value = None +error_traceback = None if method_name: init_args = digdag_inspect_arguments(callable_type.__init__, True, params) @@ -147,11 +151,21 @@ def digdag_inspect_arguments(callable_type, exclude_self, params): method = getattr(instance, method_name) method_args = digdag_inspect_arguments(method, True, params) - result = method(**method_args) + try: + result = method(**method_args) + except Exception as e: + error = e + error_type, error_value, _tb = sys.exc_info() + error_traceback = traceback.format_exception(error_type, error_value, _tb) else: args = digdag_inspect_arguments(callable_type, False, params) - result = callable_type(**args) + try: + result = callable_type(**args) + except Exception as e: + error = e + error_type, error_value, _tb = sys.exc_info() + error_traceback = traceback.format_exception(error_type, error_value, _tb) out = { 'subtask_config': digdag_env.subtask_config, @@ -160,6 +174,15 @@ def digdag_inspect_arguments(callable_type, exclude_self, params): #'state_params': digdag_env.state_params, # only for retrying } +if error: + out['error'] = { + 'class': error_value.__class__.__name__, + 'message': str(error_value), + 'backtrace': error_traceback + } + with open(out_file, 'w') as f: json.dump(out, f) +if error: + raise error diff --git a/digdag-standards/src/main/resources/digdag/standards/rb/runner.rb b/digdag-standards/src/main/resources/digdag/standards/rb/runner.rb index b3eac631aa..664aef808f 100644 --- a/digdag-standards/src/main/resources/digdag/standards/rb/runner.rb +++ b/digdag-standards/src/main/resources/digdag/standards/rb/runner.rb @@ -258,21 +258,31 @@ def digdag_symbolize_keys(hash) end klass, method_name, is_instance_method = digdag_inspect_command(command) +error = nil if klass.nil? method_args = digdag_inspect_arguments(nil, method_name, DigdagEnv::PARAMS) - result = send(method_name, *method_args) + begin + result = send(method_name, *method_args) + rescue => error + end elsif is_instance_method new_args = digdag_inspect_arguments(klass, :new, DigdagEnv::PARAMS) instance = klass.new(*new_args) method_args = digdag_inspect_arguments(instance, method_name, DigdagEnv::PARAMS) - result = instance.send(method_name, *method_args) + begin + result = instance.send(method_name, *method_args) + rescue => error + end else method_args = digdag_inspect_arguments(klass, method_name, DigdagEnv::PARAMS) - result = klass.send(method_name, *method_args) + begin + result = klass.send(method_name, *method_args) + rescue => error + end end out = { @@ -282,5 +292,14 @@ def digdag_symbolize_keys(hash) #'state_params' => DigdagEnv::STATE_PARAMS, # only for retrying } +if error + out['error'] = { + 'class' => error.class.to_s, + 'message' => error.message, + 'backtrace' => error.backtrace, + } +end + File.open(out_file, "w") {|f| f.write out.to_json } +raise error if error diff --git a/digdag-standards/src/test/java/io/digdag/standards/operator/td/TdForEachOperatorFactoryTest.java b/digdag-standards/src/test/java/io/digdag/standards/operator/td/TdForEachOperatorFactoryTest.java new file mode 100644 index 0000000000..bf3cccdd6d --- /dev/null +++ b/digdag-standards/src/test/java/io/digdag/standards/operator/td/TdForEachOperatorFactoryTest.java @@ -0,0 +1,101 @@ +package io.digdag.standards.operator.td; + +import com.google.common.base.Optional; +import com.treasuredata.client.model.TDJobRequest; +import io.digdag.client.config.Config; +import org.junit.Rule; +import org.junit.Test; +import org.junit.rules.ExpectedException; +import org.junit.runner.RunWith; +import org.mockito.ArgumentCaptor; +import org.mockito.Mock; +import org.mockito.Mockito; +import org.mockito.runners.MockitoJUnitRunner; + +import java.nio.file.Path; +import java.nio.file.Paths; + +import static io.digdag.client.config.ConfigUtils.newConfig; +import static io.digdag.core.workflow.OperatorTestingUtils.*; +import static io.digdag.standards.operator.td.TdOperatorFactory.insertCommandStatement; +import static org.hamcrest.Matchers.is; +import static org.junit.Assert.*; +import static org.mockito.Mockito.any; +import static org.mockito.Mockito.when; + +@RunWith(MockitoJUnitRunner.class) +public class TdForEachOperatorFactoryTest +{ + @Mock + TDOperator op; + + /** + * Check config parameters are set to TDJobRequest + */ + @Test + public void testTDJobRequestParams() + throws Exception + { + Path projectPath = Paths.get("").normalize().toAbsolutePath(); + + Config config = newConfig() + .set("database", "testdb") + .set("query", "select 1") + .set("engine", "presto") + .set("_do", newConfig().set("+show", newConfig().set("echo>", "aaaa"))); + + when(op.submitNewJobWithRetry(any(TDJobRequest.class))).thenReturn(""); + when(op.getDatabase()).thenReturn("testdb"); + + TDJobRequest jobRequest = testTDJobRequestParams(projectPath, config); + + assertEquals("testdb", jobRequest.getDatabase()); + assertEquals("select 1", jobRequest.getQuery()); + assertEquals("presto", jobRequest.getType().toString()); + assertEquals(Optional.absent(), jobRequest.getEngineVersion()); + + } + + /** + * Check config parameters are set to TDJobRequest with engine_version + */ + @Test + public void testTDJobRequestParamsWithEngineVersion() + throws Exception + { + Path projectPath = Paths.get("").normalize().toAbsolutePath(); + + Config config = newConfig() + .set("database", "testdb") + .set("query", "select 1") + .set("engine", "hive") + .set("engine_version", "stable") + .set("_do", newConfig().set("+show", newConfig().set("echo>", "aaaa"))); + + when(op.submitNewJobWithRetry(any(TDJobRequest.class))).thenReturn(""); + when(op.getDatabase()).thenReturn("testdb"); + + TDJobRequest jobRequest = testTDJobRequestParams(projectPath, config); + + assertEquals("testdb", jobRequest.getDatabase()); + assertEquals("select 1", jobRequest.getQuery()); + assertEquals("hive", jobRequest.getType().toString()); + assertTrue(jobRequest.getEngineVersion().isPresent()); + assertEquals("stable", jobRequest.getEngineVersion().get().toString()); + } + + private TDJobRequest testTDJobRequestParams(Path projectPath, Config config) + { + ArgumentCaptor captor = ArgumentCaptor.forClass(TDJobRequest.class); + + BaseTdJobOperator operator = + (BaseTdJobOperator) newOperatorFactory(TdForEachOperatorFactory.class) + .newOperator(newContext(projectPath, newTaskRequest().withConfig(config))); + + operator.startJob(op, ""); + + Mockito.verify(op).submitNewJobWithRetry(captor.capture()); + TDJobRequest jobRequest = captor.getValue(); + return jobRequest; + } +} diff --git a/digdag-standards/src/test/java/io/digdag/standards/operator/td/TdOperatorFactoryTest.java b/digdag-standards/src/test/java/io/digdag/standards/operator/td/TdOperatorFactoryTest.java index 2c81575e85..2526191f8e 100644 --- a/digdag-standards/src/test/java/io/digdag/standards/operator/td/TdOperatorFactoryTest.java +++ b/digdag-standards/src/test/java/io/digdag/standards/operator/td/TdOperatorFactoryTest.java @@ -1,30 +1,116 @@ package io.digdag.standards.operator.td; +import com.google.common.base.Optional; +import com.treasuredata.client.model.TDJobRequest; +import org.junit.Before; import org.junit.Test; import org.junit.Rule; import org.junit.rules.ExpectedException; -import org.junit.rules.TemporaryFolder; import java.nio.file.Path; import java.nio.file.Paths; import io.digdag.client.config.Config; -import io.digdag.spi.Operator; +import org.junit.runner.RunWith; +import org.mockito.ArgumentCaptor; +import org.mockito.Mock; +import org.mockito.Mockito; +import org.mockito.runners.MockitoJUnitRunner; import static io.digdag.standards.operator.td.TdOperatorFactory.insertCommandStatement; import static org.hamcrest.Matchers.is; import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertThat; +import static org.junit.Assert.assertTrue; + import static io.digdag.client.config.ConfigUtils.newConfig; import static io.digdag.core.workflow.OperatorTestingUtils.newContext; import static io.digdag.core.workflow.OperatorTestingUtils.newOperatorFactory; import static io.digdag.core.workflow.OperatorTestingUtils.newTaskRequest; +import static org.mockito.Mockito.any; +import static org.mockito.Mockito.when; +@RunWith(MockitoJUnitRunner.class) public class TdOperatorFactoryTest { + @Mock + TDOperator op; + @Rule public final ExpectedException exception = ExpectedException.none(); + /** + * + * Check config parameters are set to TDJobRequest + */ + @Test + public void testTDJobRequestParams() + throws Exception + { + Path projectPath = Paths.get("").normalize().toAbsolutePath(); + + Config config = newConfig() + .set("database", "testdb") + .set("query", "select 1") + .set("engine", "presto"); + + when(op.submitNewJobWithRetry(any(TDJobRequest.class))).thenReturn(""); + when(op.getDatabase()).thenReturn("testdb"); + + ArgumentCaptor captor = ArgumentCaptor.forClass(TDJobRequest.class); + + TDJobRequest jobRequest = testTDJobRequestParams(projectPath, config); + + assertEquals("testdb", jobRequest.getDatabase()); + assertEquals("select 1", jobRequest.getQuery()); + assertEquals("presto", jobRequest.getType().toString() ); + assertEquals(Optional.absent(), jobRequest.getEngineVersion()); + } + + /** + * + * Check config parameters are set to TDJobRequest with engine_version + */ + @Test + public void testTDJobRequestParamsWithEngineVersion() + throws Exception + { + Path projectPath = Paths.get("").normalize().toAbsolutePath(); + + Config config = newConfig() + .set("database", "testdb") + .set("query", "select 1") + .set("engine", "hive") + .set("engine_version", "stable"); + + when(op.submitNewJobWithRetry(any(TDJobRequest.class))).thenReturn(""); + when(op.getDatabase()).thenReturn("testdb"); + + TDJobRequest jobRequest = testTDJobRequestParams(projectPath, config); + + assertEquals("testdb", jobRequest.getDatabase()); + assertEquals("select 1", jobRequest.getQuery()); + assertEquals("hive", jobRequest.getType().toString() ); + assertTrue(jobRequest.getEngineVersion().isPresent()); + assertEquals("stable", jobRequest.getEngineVersion().get().toString()); + } + + private TDJobRequest testTDJobRequestParams(Path projectPath, Config config) + { + when(op.submitNewJobWithRetry(any(TDJobRequest.class))).thenReturn(""); + ArgumentCaptor captor = ArgumentCaptor.forClass(TDJobRequest.class); + BaseTdJobOperator operator = + (BaseTdJobOperator)newOperatorFactory(TdOperatorFactory.class) + .newOperator(newContext(projectPath, newTaskRequest().withConfig(config))); + + operator.startJob(op, ""); + + Mockito.verify(op).submitNewJobWithRetry(captor.capture()); + TDJobRequest jobRequest = captor.getValue(); + return jobRequest; + + } + @Test public void verifyCommandInserts() { diff --git a/digdag-standards/src/test/java/io/digdag/standards/operator/td/TdWaitOperatorFactoryTest.java b/digdag-standards/src/test/java/io/digdag/standards/operator/td/TdWaitOperatorFactoryTest.java new file mode 100644 index 0000000000..4dbedace1a --- /dev/null +++ b/digdag-standards/src/test/java/io/digdag/standards/operator/td/TdWaitOperatorFactoryTest.java @@ -0,0 +1,101 @@ +package io.digdag.standards.operator.td; + +import com.google.common.base.Optional; +import com.treasuredata.client.model.TDJobRequest; +import io.digdag.client.config.Config; +import io.digdag.util.BaseOperator; +import org.junit.Rule; +import org.junit.Test; +import org.junit.rules.ExpectedException; +import org.junit.runner.RunWith; +import org.mockito.ArgumentCaptor; +import org.mockito.Mock; +import org.mockito.Mockito; +import org.mockito.runners.MockitoJUnitRunner; +import org.mockito.stubbing.Answer; + +import java.nio.file.Path; +import java.nio.file.Paths; + +import static io.digdag.client.config.ConfigUtils.newConfig; +import static io.digdag.core.workflow.OperatorTestingUtils.*; +import static io.digdag.standards.operator.td.TdOperatorFactory.insertCommandStatement; +import static org.hamcrest.Matchers.is; +import static org.junit.Assert.*; +import static org.mockito.Mockito.*; + +@RunWith(MockitoJUnitRunner.class) +public class TdWaitOperatorFactoryTest +{ + @Mock + TDOperator op; + + /** + * Check config parameters are set to TDJobRequest + */ + @Test + public void testTDJobRequestParams() + throws Exception + { + Path projectPath = Paths.get("").normalize().toAbsolutePath(); + + Config config = newConfig() + .set("database", "testdb") + .set("query", "select 1") + .set("engine", "presto"); + + when(op.submitNewJobWithRetry(any(TDJobRequest.class))).thenReturn(""); + when(op.getDatabase()).thenReturn("testdb"); + + TDJobRequest jobRequest = testTDJobRequestParams(projectPath, config); + + assertEquals("testdb", jobRequest.getDatabase()); + assertEquals("select 1", jobRequest.getQuery()); + assertEquals("presto", jobRequest.getType().toString()); + assertEquals(Optional.absent(), jobRequest.getEngineVersion()); + + } + + /** + * Check config parameters are set to TDJobRequest with engine_version + */ + @Test + public void testTDJobRequestParamsWithEngineVersion() + throws Exception + { + Path projectPath = Paths.get("").normalize().toAbsolutePath(); + + Config config = newConfig() + .set("database", "testdb") + .set("query", "select 1") + .set("engine", "hive") + .set("engine_version", "stable"); + + when(op.submitNewJobWithRetry(any(TDJobRequest.class))).thenReturn(""); + when(op.getDatabase()).thenReturn("testdb"); + + TDJobRequest jobRequest = testTDJobRequestParams(projectPath, config); + + assertEquals("testdb", jobRequest.getDatabase()); + assertEquals("select 1", jobRequest.getQuery()); + assertEquals("hive", jobRequest.getType().toString()); + assertTrue(jobRequest.getEngineVersion().isPresent()); + assertEquals("stable", jobRequest.getEngineVersion().get().toString()); + + } + + private TDJobRequest testTDJobRequestParams(Path projectPath, Config config) + { + ArgumentCaptor captor = ArgumentCaptor.forClass(TDJobRequest.class); + + TdWaitOperatorFactory.TdWaitOperator operator = + (TdWaitOperatorFactory.TdWaitOperator) newOperatorFactory(TdWaitOperatorFactory.class) + .newOperator(newContext(projectPath, newTaskRequest().withConfig(config))); + + operator.startJob(op, ""); + + Mockito.verify(op).submitNewJobWithRetry(captor.capture()); + TDJobRequest jobRequest = captor.getValue(); + return jobRequest; + } +} \ No newline at end of file diff --git a/digdag-standards/src/test/java/io/digdag/standards/operator/td/TdWaitTableOperatorFactoryTest.java b/digdag-standards/src/test/java/io/digdag/standards/operator/td/TdWaitTableOperatorFactoryTest.java new file mode 100644 index 0000000000..9fe6adcc40 --- /dev/null +++ b/digdag-standards/src/test/java/io/digdag/standards/operator/td/TdWaitTableOperatorFactoryTest.java @@ -0,0 +1,96 @@ +package io.digdag.standards.operator.td; + +import com.google.common.base.Optional; +import com.treasuredata.client.model.TDJobRequest; +import io.digdag.client.config.Config; +import org.junit.Test; +import org.junit.runner.RunWith; +import org.mockito.ArgumentCaptor; +import org.mockito.Mock; +import org.mockito.Mockito; +import org.mockito.runners.MockitoJUnitRunner; + +import java.nio.file.Path; +import java.nio.file.Paths; + +import static io.digdag.client.config.ConfigUtils.newConfig; +import static io.digdag.core.workflow.OperatorTestingUtils.*; +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertTrue; +import static org.mockito.Mockito.any; +import static org.mockito.Mockito.when; + +@RunWith(MockitoJUnitRunner.class) +public class TdWaitTableOperatorFactoryTest +{ + @Mock + TDOperator op; + + /** + * Check config parameters are set to TDJobRequest + */ + @Test + public void testTDJobRequestParams() + throws Exception + { + Path projectPath = Paths.get("").normalize().toAbsolutePath(); + + Config config = newConfig() + .set("_command", "target_table_00") + .set("database", "testdb") + .set("engine", "presto"); + + when(op.submitNewJobWithRetry(any(TDJobRequest.class))).thenReturn(""); + when(op.getDatabase()).thenReturn("testdb"); + + TDJobRequest jobRequest = testTDJobRequestParams(projectPath, config); + + assertEquals("testdb", jobRequest.getDatabase()); + assertTrue(jobRequest.getQuery().length() > 0); + assertEquals("presto", jobRequest.getType().toString()); + assertEquals(Optional.absent(), jobRequest.getEngineVersion()); + } + + /** + * Check config parameters are set to TDJobRequest + */ + @Test + public void testTDJobRequestParamsWithEngineVersion() + throws Exception + { + Path projectPath = Paths.get("").normalize().toAbsolutePath(); + + Config config = newConfig() + .set("_command", "target_table_00") + .set("database", "testdb") + .set("engine", "hive") + .set("engine_version", "stable"); + + when(op.submitNewJobWithRetry(any(TDJobRequest.class))).thenReturn(""); + when(op.getDatabase()).thenReturn("testdb"); + + TDJobRequest jobRequest = testTDJobRequestParams(projectPath, config); + + assertEquals("testdb", jobRequest.getDatabase()); + assertTrue(jobRequest.getQuery().length() > 0); + assertEquals("hive", jobRequest.getType().toString()); + assertTrue(jobRequest.getEngineVersion().isPresent()); + assertEquals("stable", jobRequest.getEngineVersion().get().toString()); + + } + + private TDJobRequest testTDJobRequestParams(Path projectPath, Config config) + { + ArgumentCaptor captor = ArgumentCaptor.forClass(TDJobRequest.class); + + TdWaitTableOperatorFactory.TdWaitTableOperator operator = + (TdWaitTableOperatorFactory.TdWaitTableOperator) newOperatorFactory(TdWaitTableOperatorFactory.class) + .newOperator(newContext(projectPath, newTaskRequest().withConfig(config))); + + operator.startJob(op, ""); + + Mockito.verify(op).submitNewJobWithRetry(captor.capture()); + TDJobRequest jobRequest = captor.getValue(); + return jobRequest; + } +} diff --git a/digdag-storage-gcs/build.gradle b/digdag-storage-gcs/build.gradle new file mode 100644 index 0000000000..be06a20c96 --- /dev/null +++ b/digdag-storage-gcs/build.gradle @@ -0,0 +1,27 @@ + + +dependencies { + compile project(':digdag-spi') + compile project(':digdag-plugin-utils') + testCompile project(':digdag-core') + + compile ("com.google.cloud:google-cloud-storage:1.101.0") { + // Avoid compilation failures due to dependencies + exclude group: 'com.google.guava', module: 'guava' + exclude group: 'com.google.j2objc', module: 'j2objc-annotations' + exclude group: 'com.google.errorprone', module: 'error_prone_annotations' + exclude group: 'com.google.http-client', module: 'google-http-client-jackson2' + exclude group: 'com.google.http-client', module: 'google-http-client' + exclude group: 'com.google.auth', module: 'google-auth-library-oauth2-http' + exclude group: 'com.google.auth', module: 'google-auth-library-credentials' + exclude group: 'com.google.api-client', module: 'google-api-client' + exclude group: 'org.apache.httpcomponents', module: 'httpclient' + } + + compile ('com.google.auth:google-auth-library-oauth2-http:0.4.0') { exclude group: 'com.google.guava', module: 'guava-jdk5' } + compile ("com.google.cloud:google-cloud-nio:0.119.0-alpha") { + // Avoid compilation failures due to dependencies + exclude group: 'com.google.guava', module: 'guava' + exclude group: 'com.google.code.findbugs', module: 'jsr305' + } +} diff --git a/digdag-storage-gcs/src/main/java/io/digdag/storage/gcs/GCSStorage.java b/digdag-storage-gcs/src/main/java/io/digdag/storage/gcs/GCSStorage.java new file mode 100644 index 0000000000..631d43576d --- /dev/null +++ b/digdag-storage-gcs/src/main/java/io/digdag/storage/gcs/GCSStorage.java @@ -0,0 +1,173 @@ +package io.digdag.storage.gcs; + +import com.google.api.gax.paging.Page; +import com.google.cloud.WriteChannel; +import com.google.cloud.storage.Blob; +import com.google.cloud.storage.BlobInfo; +import com.google.cloud.storage.Storage.BlobListOption; +import com.google.cloud.storage.StorageException; +import com.google.common.base.Throwables; +import io.digdag.client.config.Config; +import io.digdag.spi.StorageObject; +import io.digdag.spi.StorageObjectSummary; +import io.digdag.util.RetryExecutor; +import io.digdag.util.RetryExecutor.RetryGiveupException; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import java.io.ByteArrayInputStream; +import java.io.IOException; +import java.io.InputStream; +import java.nio.ByteBuffer; +import java.time.Instant; +import java.util.ArrayList; +import java.util.List; +import java.util.concurrent.Callable; + +import static com.google.common.base.Preconditions.checkArgument; +import static com.google.common.base.Strings.isNullOrEmpty; + +public class GCSStorage + implements io.digdag.spi.Storage +{ + private static Logger logger = LoggerFactory.getLogger(GCSStorage.class); + + private final Config config; + private final com.google.cloud.storage.Storage storage; + private final String bucket; + + public GCSStorage(final Config config, com.google.cloud.storage.Storage storage, String bucket) + { + checkArgument(!isNullOrEmpty(bucket), "bucket is null or empty"); + this.config = config; + this.storage = storage; + this.bucket = bucket; + } + + private RetryExecutor uploadRetryExecutor() + { + return RetryExecutor.retryExecutor(); + } + + private RetryExecutor getRetryExecutor() + { + return RetryExecutor.retryExecutor(); + } + + @Override + public StorageObject open(String object) + { + checkArgument(object != null, "object is null"); + Blob blob = storage.get(bucket, object); + String errorMessage = "opening file bucket " + bucket + " key " + object; + byte[] content = getWithRetry(errorMessage, () -> blob.getContent()); + InputStream byteStream = new ByteArrayInputStream(content); + return new StorageObject(byteStream, content.length); + } + + @Override + public String put(String object, long contentLength, + UploadStreamProvider payload) + throws IOException + { + checkArgument(object != null, "object is null"); + BlobInfo blobInfo = BlobInfo.newBuilder(bucket, object).build(); + try { + return uploadRetryExecutor() + .onRetry((exception, retryCount, retryLimit, retryWait) -> { + logger.warn("Retrying uploading file bucket " + bucket + " object " + object + " error: " + exception); + }) + .retryIf((exception) -> { + if (exception instanceof IOException || exception instanceof InterruptedException) { + return false; + } + return true; + }) + .runInterruptible(() -> { + try (InputStream in = payload.open()) { + try (WriteChannel writer = storage.writer(blobInfo)) { + byte[] buffer = new byte[1024]; + int limit; + while ((limit = in.read(buffer)) >= 0) { + try { + writer.write(ByteBuffer.wrap(buffer, 0, limit)); + } + catch (Exception ex) { + ex.printStackTrace(); + } + } + } + return storage.get(bucket, object).getMd5ToHexString(); + } + }); + } + catch (InterruptedException ex) { + throw Throwables.propagate(ex); + } + catch (RetryGiveupException ex) { + Throwable cause = ex.getCause(); + Throwables.propagateIfInstanceOf(cause, IOException.class); + throw Throwables.propagate(cause); + } + } + + @Override + public void list(String objectPrefix, FileListing callback) + { + checkArgument(objectPrefix != null, "objectPrefix is null"); + + String errorMessage = "listing files on bucket " + bucket + " prefix " + objectPrefix; + Page blobs = getWithRetry(errorMessage, () -> + storage.list(bucket, BlobListOption.prefix(objectPrefix)) + ); + + List objectSummaryList = new ArrayList<>(); + for (Blob blob : blobs.iterateAll()) { + objectSummaryList.add( + StorageObjectSummary.builder() + .key(blob.getName()) + .contentLength(blob.getSize()) + .lastModified(convertToInstant(blob)) + .build() + ); + } + callback.accept(objectSummaryList); + } + + private T getWithRetry(String message, Callable callable) + throws StorageException + { + try { + return getRetryExecutor() + .onRetry((exception, retryCount, retryLimit, retryWait) -> { + logger.warn(String.format("Retrying %s (%d/%d): %s", message, retryCount, retryLimit, exception)); + }) + .retryIf((exception) -> !isNotFoundException(exception)) + .runInterruptible(() -> callable.call()); + } + catch (InterruptedException ex) { + throw Throwables.propagate(ex); + } + catch (RetryGiveupException ex) { + Exception cause = ex.getCause(); + throw Throwables.propagate(cause); + } + } + + private static Instant convertToInstant(Blob blob){ + try { + return Instant.ofEpochMilli(blob.getUpdateTime()); + } catch (NullPointerException e) { + // NOTE: 1970-01-01T00:00:00Z + return Instant.ofEpochMilli(0L); + } + } + + private static boolean isNotFoundException(Exception ex) + { + // This includes NoSuchBucket and NoSuchKey. See also: + // https://cloud.google.com/storage/docs/json_api/v1/status-codes + return ex instanceof StorageException && + ((StorageException) ex).getCode() == 404; + } +} diff --git a/digdag-storage-gcs/src/main/java/io/digdag/storage/gcs/GCSStorageExtension.java b/digdag-storage-gcs/src/main/java/io/digdag/storage/gcs/GCSStorageExtension.java new file mode 100644 index 0000000000..19c6eecf5d --- /dev/null +++ b/digdag-storage-gcs/src/main/java/io/digdag/storage/gcs/GCSStorageExtension.java @@ -0,0 +1,32 @@ +package io.digdag.storage.gcs; + +import com.google.inject.Binder; +import com.google.inject.Module; +import com.google.inject.Scopes; +import com.google.inject.multibindings.Multibinder; +import io.digdag.spi.Extension; +import io.digdag.spi.StorageFactory; + +import java.util.Arrays; +import java.util.List; + +public class GCSStorageExtension + implements Extension +{ + @Override + public List getModules() + { + return Arrays.asList(new GCSStorageModule()); + } + + public static class GCSStorageModule + implements Module + { + @Override + public void configure(Binder binder) + { + Multibinder.newSetBinder(binder, StorageFactory.class) + .addBinding().to(GCSStorageFactory.class).in(Scopes.SINGLETON); + } + } +} diff --git a/digdag-storage-gcs/src/main/java/io/digdag/storage/gcs/GCSStorageFactory.java b/digdag-storage-gcs/src/main/java/io/digdag/storage/gcs/GCSStorageFactory.java new file mode 100644 index 0000000000..4750495cc2 --- /dev/null +++ b/digdag-storage-gcs/src/main/java/io/digdag/storage/gcs/GCSStorageFactory.java @@ -0,0 +1,88 @@ +package io.digdag.storage.gcs; + +import com.google.auth.oauth2.ServiceAccountCredentials; +import com.google.cloud.storage.StorageOptions; +import com.google.common.annotations.VisibleForTesting; +import io.digdag.client.config.Config; +import io.digdag.client.config.ConfigException; +import io.digdag.spi.Storage; +import io.digdag.spi.StorageFactory; + +import java.io.ByteArrayInputStream; +import java.io.FileInputStream; +import java.io.FileNotFoundException; +import java.io.IOException; +import java.io.InputStream; +import java.io.UnsupportedEncodingException; + +public class GCSStorageFactory + implements StorageFactory +{ + private static final String PATH_KEY = "credentials.json.path"; + private static final String CONTENT_KEY = "credentials.json.content"; + + @Override + public String getType() + { + return "gcs"; + } + + @Override + public Storage newStorage(Config config) + { + com.google.cloud.storage.Storage storage; + if (config.has(PATH_KEY)) { + storage = getStorageFromJsonKey(config, PATH_KEY); + } + else if (config.has(CONTENT_KEY)) { + storage = getStorageFromJsonKey(config, CONTENT_KEY); + } + else { + storage = StorageOptions.getDefaultInstance().getService(); + } + + String bucket = config.get("bucket", String.class); + return new GCSStorage(config, storage, bucket); + } + + @VisibleForTesting + Storage newStorage(com.google.cloud.storage.Storage storage, Config config) + { + String bucket = config.get("bucket", String.class); + return new GCSStorage(config, storage, bucket); + } + + private static com.google.cloud.storage.Storage getStorageFromJsonKey(Config config, String configKey) + throws ConfigException + { + try { + InputStream in; + if (PATH_KEY.equals(configKey)) { + String credentialsPath = config.get(PATH_KEY, String.class); + in = new FileInputStream(credentialsPath); + } + else if (CONTENT_KEY.equals(configKey)) { + String credentials = config.get(CONTENT_KEY, String.class); + in = new ByteArrayInputStream(credentials.getBytes("utf-8")); + } + else { + throw new ConfigException("credentials config must have credentials.json: or credentials.json.content:"); + } + + return StorageOptions.newBuilder() + .setCredentials(ServiceAccountCredentials.fromStream(in)) + .build() + .getService(); + } + catch (FileNotFoundException e) { + throw new ConfigException("Credential File could not be found. Please check credentials.json"); + } + catch (UnsupportedEncodingException e) { + throw new ConfigException("Could not read credentials.json.content caused by use unsupported encoding type (utf-8)"); + } + catch (IOException e) { + throw new ConfigException("The credential cannot be created from the stream"); + } + } +} + diff --git a/digdag-storage-gcs/src/main/resources/META-INF/services/io.digdag.spi.Extension b/digdag-storage-gcs/src/main/resources/META-INF/services/io.digdag.spi.Extension new file mode 100644 index 0000000000..4d2728ca2e --- /dev/null +++ b/digdag-storage-gcs/src/main/resources/META-INF/services/io.digdag.spi.Extension @@ -0,0 +1 @@ +io.digdag.storage.gcs.GCSStorageExtension diff --git a/digdag-storage-gcs/src/test/java/io/digdag/storage/gcs/GCSStorageTest.java b/digdag-storage-gcs/src/test/java/io/digdag/storage/gcs/GCSStorageTest.java new file mode 100644 index 0000000000..0216d58390 --- /dev/null +++ b/digdag-storage-gcs/src/test/java/io/digdag/storage/gcs/GCSStorageTest.java @@ -0,0 +1,145 @@ +package io.digdag.storage.gcs; + +import com.google.cloud.storage.contrib.nio.testing.LocalStorageHelper; +import com.google.auth.oauth2.GoogleCredentials; +import com.google.auth.oauth2.ServiceAccountCredentials; +import com.google.auth.oauth2.AccessToken; +import com.google.cloud.storage.BucketInfo; +import com.google.cloud.storage.StorageClass; +import com.google.cloud.storage.StorageOptions; +import com.google.common.io.ByteStreams; +import io.digdag.client.config.Config; +import io.digdag.client.config.ConfigFactory; +import io.digdag.spi.Storage; +import io.digdag.spi.Storage.UploadStreamProvider; +import io.digdag.spi.StorageObjectSummary; +import org.junit.After; +import org.junit.Before; +import org.junit.Test; + +import com.google.cloud.storage.Blob; +import org.mockito.Mock; +import java.io.ByteArrayInputStream; +import java.io.FileInputStream; +import java.io.IOException; +import java.io.InputStream; +import java.util.ArrayList; +import java.util.stream.Collectors; +import java.util.List; +import java.util.UUID; +import java.lang.Thread; +import java.time.Instant; + +import static io.digdag.client.DigdagClient.objectMapper; +import static io.digdag.core.storage.StorageManager.encodeHex; +import static io.digdag.util.Md5CountInputStream.digestMd5; +import static java.nio.charset.StandardCharsets.UTF_8; +import static org.hamcrest.Matchers.is; +import static org.hamcrest.Matchers.either; +import static org.hamcrest.Matchers.contains; +import static org.hamcrest.Matchers.containsInAnyOrder; + +import static org.junit.Assert.assertThat; +import static org.hamcrest.core.IsNull.nullValue; + +public class GCSStorageTest +{ + private Storage storage; + @Mock private GoogleCredentials googleCredentials; + + @Before + public void setUp() + throws Exception + { + com.google.cloud.storage.Storage gcsStorage = LocalStorageHelper.getOptions().getService(); + + ConfigFactory cf = new ConfigFactory(objectMapper()); + String bucket = UUID.randomUUID().toString(); + Config config = cf.create() + .set("bucket", bucket); // use unique bucket name + storage = new GCSStorageFactory().newStorage(gcsStorage, config); + } + + @Test + public void putReturnsMd5() + throws Exception + { + String checksum1 = storage.put("key1", 10, contents("0123456789")); + String checksum2 = storage.put("key2", 5, contents("01234")); + // if use LocalStorageHelper, return value is "". + assertThat(checksum1, either(is(md5hex("0123456789"))).or(is(""))); + assertThat(checksum2, either(is(md5hex("01234"))).or(is(""))); + } + + @Test + public void putGet() + throws Exception + { + storage.put("key/file/1", 3, contents("xxx")); + storage.put("key/file/2", 1, contents("a")); + storage.put("key/file/3", 4, contents("data")); + assertThat(readString(storage.open("key/file/1").getContentInputStream()), is("xxx")); + assertThat(readString(storage.open("key/file/2").getContentInputStream()), is("a")); + assertThat(readString(storage.open("key/file/3").getContentInputStream()), is("data")); + } + + @Test + public void listAll() + throws Exception + { + storage.put("key/file/1", 3, contents("xxx")); + storage.put("key/file/2", 1, contents("1")); + + List all = new ArrayList<>(); + storage.list("key", (chunk) -> all.addAll(chunk)); + + // if use LocalStorageHelper, returned elements order is randomize. + assertThat(all.size(), is(2)); + assertThat(all, containsInAnyOrder(dummyStorageObjectSummary("key/file/1", 3), dummyStorageObjectSummary("key/file/2", 1))); + } + + @Test + public void listWithPrefix() + throws Exception + { + storage.put("key1", 1, contents("0")); + storage.put("test/file/1", 1, contents("1")); + storage.put("test/file/2", 1, contents("1")); + + List all = new ArrayList<>(); + storage.list("test", (chunk) -> all.addAll(chunk)); + + // if use LocalStorageHelper, returned elements order is randomize. + assertThat(all.size(), is(2)); + assertThat(all, containsInAnyOrder(dummyStorageObjectSummary("test/file/1", 1), dummyStorageObjectSummary("test/file/2", 1))); + } + + public static StorageObjectSummary dummyStorageObjectSummary(String object, int contentLength){ + return StorageObjectSummary.builder() + .key(object) + .contentLength(contentLength) + .lastModified(Instant.ofEpochMilli(0L)) + .build(); + } + + private static Storage.UploadStreamProvider contents(String data) + { + return () -> new ByteArrayInputStream(data.getBytes(UTF_8)); + } + + private static String md5hex(String data) + { + return md5hex(data.getBytes(UTF_8)); + } + + private static String md5hex(byte[] data) + { + return encodeHex(digestMd5(data)); + } + + private static String readString(InputStream in) + throws IOException + { + return new String(ByteStreams.toByteArray(in), UTF_8); + } +} diff --git a/digdag-tests/build.gradle b/digdag-tests/build.gradle index e7965a4f1f..e7a68b57a0 100644 --- a/digdag-tests/build.gradle +++ b/digdag-tests/build.gradle @@ -2,11 +2,14 @@ dependencies { testCompile project(':digdag-cli') testCompile project(':digdag-storage-s3') + testCompile project(':digdag-storage-gcs') + testCompile "com.google.code.findbugs:jsr305:3.0.2" testCompile 'com.google.code.findbugs:annotations:3.0.1' testCompile 'org.subethamail:subethasmtp:3.1.7' - testCompile 'com.squareup.okhttp3:okhttp:3.9.0' - testCompile 'com.squareup.okhttp3:mockwebserver:3.9.0' - testCompile('org.littleshoot:littleproxy:1.1.2') { + testCompile 'com.squareup.okhttp3:okhttp:3.12.0' + testCompile 'com.squareup.okhttp3:okhttp-tls:3.12.0' + testCompile 'com.squareup.okhttp3:mockwebserver:3.12.0' + testCompile('xyz.rogfam:littleproxy:2.0.0-beta-4') { // littleproxy depends on guava:20 and it conflicts with digdag-client exclude group: 'com.google.guava', module: 'guava' // littleproxy depends on slf4j-api:1.7.24 and it conflicts with others @@ -32,4 +35,12 @@ test { System.getProperty("test.single") == null && filter.includePatterns.empty } } + + if (project.hasProperty("testFilter")) { + List props = project.getProperties().get("testFilter").split("\\s+") + props.each { + String converted = it.replace("digdag-tests/src/test/java/acceptance/td/", "**/").replace(".java", ".class") + include(converted) + } + } } diff --git a/digdag-tests/src/test/java/acceptance/BackfillIT.java b/digdag-tests/src/test/java/acceptance/BackfillIT.java index 54594f0cde..b7125d4376 100644 --- a/digdag-tests/src/test/java/acceptance/BackfillIT.java +++ b/digdag-tests/src/test/java/acceptance/BackfillIT.java @@ -57,7 +57,55 @@ public void setUp() } @Test - public void initPushBackfill() + public void initPushBackfillScheduleId() + throws Exception + { + // Create new project + { + CommandStatus cmd = main("init", + "-c", config.toString(), + projectDir.toString()); + assertThat(cmd.code(), is(0)); + } + + copyResource("acceptance/backfill/backfill.dig", projectDir.resolve("backfill.dig")); + + // Push + { + CommandStatus cmd = main("push", + "-c", config.toString(), + "-e", server.endpoint(), + "--project", projectDir.toString(), + "backfill-test"); + assertThat(cmd.errUtf8(), cmd.code(), is(0)); + } + + // Backfill the workflow + { + CommandStatus cmd = main("backfill", + "-c", config.toString(), + "-e", server.endpoint(), + "1", + "--from", "2016-01-01", + "--count", "2"); + assertThat(cmd.errUtf8(), cmd.code(), is(0)); + } + + // Verify that 2 sessions are started + List sessions = client.getSessions().getSessions(); + assertThat(sessions.size(), is(2)); + + // sessions API return results in reversed order + + RestSession session1 = sessions.get(1); + assertThat(session1.getSessionTime(), is(OffsetDateTime.parse("2016-01-01T00:00:00+09:00"))); + + RestSession session2 = sessions.get(0); + assertThat(session2.getSessionTime(), is(OffsetDateTime.parse("2016-01-02T00:00:00+09:00"))); + } + + @Test + public void initPushBackfillWorkflow() throws Exception { // Create new project diff --git a/digdag-tests/src/test/java/acceptance/BasicAuthIT.java b/digdag-tests/src/test/java/acceptance/BasicAuthIT.java new file mode 100644 index 0000000000..a7db315733 --- /dev/null +++ b/digdag-tests/src/test/java/acceptance/BasicAuthIT.java @@ -0,0 +1,121 @@ +package acceptance; + +import io.digdag.client.DigdagClient; +import org.eclipse.jetty.client.HttpClient; +import org.hamcrest.MatcherAssert; +import org.jboss.resteasy.util.BasicAuthHelper; +import org.junit.After; +import org.junit.Before; +import org.junit.Rule; +import org.junit.Test; +import org.junit.rules.ExpectedException; +import utils.CommandStatus; +import utils.TemporaryDigdagServer; + +import javax.ws.rs.NotAuthorizedException; + +import static javax.ws.rs.core.HttpHeaders.AUTHORIZATION; +import static org.hamcrest.Matchers.is; +import static utils.TestUtils.main; + +public class BasicAuthIT +{ + @Rule + public ExpectedException expectedException = ExpectedException.none(); + + @Rule + public TemporaryDigdagServer server = TemporaryDigdagServer.builder() + .configuration("server.authenticator-class = io.digdag.standards.auth.basic.BasicAuthenticator") + .configuration("basicauth.username = user123") + .configuration("basicauth.password = secret456") + .build(); + + private HttpClient httpClient; + + @Before + public void setUp() + throws Exception + { + httpClient = new HttpClient(); + httpClient.start(); + } + + @After + public void tearDown() + throws Exception + { + if (httpClient != null) { + httpClient.stop(); + } + } + + @Test + public void verifyUnauthorizedRequestFails() + { + try (DigdagClient digdagClient = DigdagClient.builder() + .host(server.host()) + .port(server.port()) + .build()) { + + expectedException.expect(NotAuthorizedException.class); + + digdagClient.getProjects(); + } + } + + @Test + public void verifyUnauthorizedRequestFailsWithBadUsername() + { + try (DigdagClient digdagClient = DigdagClient.builder() + .host(server.host()) + .port(server.port()) + .header(AUTHORIZATION, BasicAuthHelper.createHeader("bad username", "secret456")) + .build()) { + + expectedException.expect(NotAuthorizedException.class); + + digdagClient.getProjects(); + } + } + + @Test + public void verifyUnauthorizedRequestFailsWithBadPassword() + { + try (DigdagClient digdagClient = DigdagClient.builder() + .host(server.host()) + .port(server.port()) + .header(AUTHORIZATION, BasicAuthHelper.createHeader("user123", "bad password")) + .build()) { + + expectedException.expect(NotAuthorizedException.class); + + digdagClient.getProjects(); + } + } + + @Test + public void verifyAuthorizedRequestSucceeds() + { + try (DigdagClient digdagClient = DigdagClient.builder() + .host(server.host()) + .port(server.port()) + .header(AUTHORIZATION, BasicAuthHelper.createHeader("user123", "secret456")) + .build()) { + + digdagClient.getProjects(); + } + } + + @Test + public void verifyAuthorizedRequestSucceedsUsingCli() + throws Exception + { + + CommandStatus showProjectStatus = main("projects", + "-e", server.endpoint(), + "--basic-auth", "user123:secret456" + ); + + MatcherAssert.assertThat(showProjectStatus.errUtf8(), showProjectStatus.code(), is(0)); + } +} diff --git a/digdag-tests/src/test/java/acceptance/CliArchiveIT.java b/digdag-tests/src/test/java/acceptance/CliArchiveIT.java new file mode 100644 index 0000000000..cf01ba94cd --- /dev/null +++ b/digdag-tests/src/test/java/acceptance/CliArchiveIT.java @@ -0,0 +1,71 @@ +package acceptance; + +import org.junit.Before; +import org.junit.Rule; +import org.junit.Test; +import org.junit.rules.TemporaryFolder; +import utils.CommandStatus; +import utils.TemporaryDigdagServer; + +import java.nio.file.Path; + +import static org.hamcrest.MatcherAssert.assertThat; +import static org.hamcrest.Matchers.is; +import static utils.TestUtils.copyResource; +import static utils.TestUtils.main; + +public class CliArchiveIT +{ + @Rule + public TemporaryFolder folder = new TemporaryFolder(); + + @Rule + public TemporaryDigdagServer server = TemporaryDigdagServer.of(); + + private Path config; + private Path projectDir; + + @Before + public void setUp() + throws Exception + { + projectDir = folder.getRoot().toPath().resolve("foobar"); + config = folder.newFile().toPath(); + } + + @Test + public void archiveProject() + throws Exception + { + + // Create new project + CommandStatus initStatus = main("init", + "-c", config.toString(), + projectDir.toString()); + assertThat(initStatus.code(), is(0)); + + copyResource("acceptance/basic.dig", projectDir.resolve("basic.dig")); + + // 1. archive project + { + CommandStatus archiveStatus = main( + "archive", + "--project", projectDir.toString(), + "--output", "test_archive.tar.gz", + "-c", config.toString() + ); + assertThat(archiveStatus.errUtf8(), archiveStatus.code(), is(0)); + } + + // 2. then upload it. + { + CommandStatus uploadStatus = main( + "upload", + "test_archive.tar.gz", + "test_archive_proj", + "-c", config.toString(), + "-e", server.endpoint()); + assertThat(uploadStatus.errUtf8(), uploadStatus.code(), is(0)); + } + } +} diff --git a/digdag-tests/src/test/java/acceptance/CliDownloadIT.java b/digdag-tests/src/test/java/acceptance/CliDownloadIT.java new file mode 100644 index 0000000000..3970f05c99 --- /dev/null +++ b/digdag-tests/src/test/java/acceptance/CliDownloadIT.java @@ -0,0 +1,140 @@ +package acceptance; + +import io.netty.handler.codec.http.FullHttpRequest; +import org.junit.After; +import org.junit.Before; +import org.junit.Rule; +import org.junit.Test; +import org.junit.rules.TemporaryFolder; +import org.littleshoot.proxy.HttpProxyServer; +import utils.CommandStatus; +import utils.TemporaryDigdagServer; +import utils.TestUtils; + +import java.nio.file.Files; +import java.nio.file.Path; +import java.util.ArrayList; +import java.util.Arrays; +import java.util.Collections; +import java.util.HashMap; +import java.util.List; +import java.util.Map; + +import static org.hamcrest.MatcherAssert.assertThat; +import static org.hamcrest.Matchers.is; +import static utils.TestUtils.copyResource; +import static utils.TestUtils.main; + +public class CliDownloadIT +{ + @Rule + public TemporaryFolder folder = new TemporaryFolder(); + + public TemporaryDigdagServer server; + private HttpProxyServer proxyServer; + + private Map env; + private Path config; + private Path projectDir; + + private List requests = Collections.synchronizedList(new ArrayList<>()); + + @Before + public void setUp() + throws Exception + { + env = new HashMap<>(); + proxyServer = TestUtils.startRequestTrackingProxy(requests); + server = TemporaryDigdagServer.builder() + .withRandomSecretEncryptionKey() + .build(); + server.start(); + projectDir = folder.getRoot().toPath().resolve("foobar"); + String proxyUrl = "http://" + proxyServer.getListenAddress().getHostString() + ":" + proxyServer.getListenAddress().getPort(); + env.put("http_proxy", proxyUrl); + + config = folder.newFile().toPath(); + } + + @Test + public void disableDirectDownload() + throws Exception + { + // Create new project + CommandStatus initStatus = main("init", + "-c", config.toString(), + projectDir.toString()); + assertThat(initStatus.code(), is(0)); + + copyResource("acceptance/basic.dig", projectDir.resolve("basic.dig")); + + { + CommandStatus pushStatus = main( + "push", + "--project", projectDir.toString(), + "test_proj", + "-c", config.toString(), + "-e", server.endpoint() + ); + assertThat(pushStatus.errUtf8(), pushStatus.code(), is(0)); + } + + // No configuration "client.http.disable_direct_download=true" + { + requests.clear(); + CommandStatus status = main(env, + "download", + "test_proj", + "-c", config.toString(), + "-e", server.endpoint(), + "-o", folder.getRoot().toPath().resolve("test1").toString() + ); + assertThat(status.errUtf8(), status.code(), is(0)); + boolean match = false; + for (FullHttpRequest req : requests) { + if (req.uri().matches(".*/api/projects/.*/archive.*")) { + match = true; + assertThat("direct_download= must not be set.", + !req.uri().matches(".*direct_download=.*")); + } + } + assertThat("No record", match); + } + + // Set configuration "client.http.disable_direct_download=true" + { + requests.clear(); + Files.write(config, Arrays.asList("client.http.disable_direct_download=true")); + CommandStatus status = main(env, + "download", + "test_proj", + "-c", config.toString(), + "-e", server.endpoint(), + "-o", folder.getRoot().toPath().resolve("test3").toString() + ); + assertThat(status.errUtf8(), status.code(), is(0)); + boolean match = false; + for (FullHttpRequest req : requests) { + if (req.uri().matches(".*/api/projects/.*/archive.*")) { + match = true; + assertThat("direct_download= must be set.",req.uri().matches(".*direct_download=.*")); + } + } + assertThat("No record", match); + } + } + + @After + public void tearDown() + throws Exception + { + if (proxyServer != null) { + proxyServer.stop(); + proxyServer = null; + } + if (server != null) { + server.close(); + server = null; + } + } +} diff --git a/digdag-tests/src/test/java/acceptance/CliLogIT.java b/digdag-tests/src/test/java/acceptance/CliLogIT.java new file mode 100644 index 0000000000..3d69db0955 --- /dev/null +++ b/digdag-tests/src/test/java/acceptance/CliLogIT.java @@ -0,0 +1,120 @@ +package acceptance; + +import io.digdag.client.DigdagClient; +import io.netty.handler.codec.http.FullHttpRequest; +import org.junit.After; +import org.junit.Before; +import org.junit.Rule; +import org.junit.Test; +import org.junit.rules.TemporaryFolder; +import org.littleshoot.proxy.HttpProxyServer; +import utils.CommandStatus; +import utils.TemporaryDigdagServer; +import utils.TestUtils; + +import java.nio.file.Files; +import java.nio.file.Path; +import java.util.ArrayList; +import java.util.Arrays; +import java.util.Collections; +import java.util.HashMap; +import java.util.List; +import java.util.Map; + +import static org.hamcrest.MatcherAssert.assertThat; +import static org.hamcrest.Matchers.is; +import static utils.TestUtils.copyResource; +import static utils.TestUtils.main; + +public class CliLogIT +{ + @Rule + public TemporaryFolder folder = new TemporaryFolder(); + + public TemporaryDigdagServer server; + private HttpProxyServer proxyServer; + + private Map env; + private Path config; + private Path projectDir; + + private List requests = Collections.synchronizedList(new ArrayList<>()); + + @Before + public void setUp() + throws Exception + { + env = new HashMap<>(); + proxyServer = TestUtils.startRequestTrackingProxy(requests); + server = TemporaryDigdagServer.builder() + .withRandomSecretEncryptionKey() + .build(); + server.start(); + projectDir = folder.getRoot().toPath().resolve("foobar"); + String proxyUrl = "http://" + proxyServer.getListenAddress().getHostString() + ":" + proxyServer.getListenAddress().getPort(); + env.put("http_proxy", proxyUrl); + + config = folder.newFile().toPath(); + + } + + @Test + public void disableDirectDownload() + throws Exception + { + // No configuration "client.http.disable_direct_download=true" + { + requests.clear(); + CommandStatus status = main(env, + "log", + "1", + "-c", config.toString(), + "-e", server.endpoint() + ); + boolean match = false; + for (FullHttpRequest req :requests) { + if (req.uri().matches(".*/api/logs/1/.*")) { + assertThat("direct_download= must not be set.", + !req.uri().matches(".*direct_download=.*")); + match = true; + } + } + assertThat("No record", match); + } + + // Set configuration "client.http.disable_direct_download=true" + { + requests.clear(); + Files.write(config, Arrays.asList("client.http.disable_direct_download=true")); + CommandStatus status = main(env, + "log", + "3", + "-c", config.toString(), + "-e", server.endpoint() + ); + boolean match = false; + for (FullHttpRequest req :requests) { + if (req.uri().matches(".*/api/logs/3/.*")) { + assertThat("direct_download=false must be set with client.http.disable_direct_download=true", + req.uri().matches(".*direct_download=false.*")); + match = true; + } + } + assertThat("No record", match); + } + } + + @After + public void tearDown() + throws Exception + { + if (proxyServer != null) { + proxyServer.stop(); + proxyServer = null; + } + if (server != null) { + server.close(); + server = null; + } + } +} diff --git a/digdag-tests/src/test/java/acceptance/CliMigrateIT.java b/digdag-tests/src/test/java/acceptance/CliMigrateIT.java new file mode 100644 index 0000000000..798caaae1b --- /dev/null +++ b/digdag-tests/src/test/java/acceptance/CliMigrateIT.java @@ -0,0 +1,106 @@ +package acceptance; + +import com.google.common.io.Files; +import io.digdag.core.database.DatabaseConfig; +import io.digdag.core.database.RemoteDatabaseConfig; +import org.junit.Before; +import org.junit.Rule; +import org.junit.Test; +import org.junit.rules.TemporaryFolder; +import utils.CommandStatus; +import utils.TemporaryDigdagServer; + +import java.io.IOException; +import java.nio.file.Path; + +import static java.nio.charset.StandardCharsets.UTF_8; +import static org.hamcrest.Matchers.containsString; +import static org.hamcrest.Matchers.is; +import static org.junit.Assert.assertThat; +import static org.junit.Assume.assumeFalse; +import static org.junit.Assume.assumeTrue; +import static utils.TestUtils.*; + +public class CliMigrateIT +{ + @Rule + public TemporaryFolder folder = new TemporaryFolder(); + + @Rule + public TemporaryDigdagServer server = TemporaryDigdagServer.builder() + .inProcess(false) + .build(); + + private Path config; + + private void createTestDBConfig(Path path, DatabaseConfig dbConfig) + throws IOException + { + + StringBuffer sbuf = new StringBuffer(); + sbuf.append(String.format("database.type = %s%n", dbConfig.getType())); + if (dbConfig.getRemoteDatabaseConfig().isPresent()) { + RemoteDatabaseConfig rdbConfig = dbConfig.getRemoteDatabaseConfig().get(); + sbuf.append(String.format("database.user = %s%n", rdbConfig.getUser())); + sbuf.append(String.format("database.password = %s%n", rdbConfig.getPassword())); + sbuf.append(String.format("database.host = %s%n", rdbConfig.getHost())); + sbuf.append(String.format("database.database = %s%n", rdbConfig.getDatabase())); + } + Files.write(sbuf.toString().getBytes(UTF_8), path.toFile()); + } + + @Before + public void setUp() + throws Exception + { + config = folder.newFile().toPath(); + if ( server.isRemoteDatabase()) { // migrate command directly connect to database + createTestDBConfig(config, server.getTestDatabaseConfig()); + } + } + + @Test + public void migratePostgresql() + throws Exception + { + assumeTrue(server.isRemoteDatabase()); + + { // test 'digdag migrate run' + CommandStatus status = main("migrate", "run", + "-c", config.toString()); + assertThat(status.code(), is(0)); + // When digdag server boot up, already all migrations should be done. + assertThat(status.outUtf8(), containsString("No update")); + } + { // test 'digdag migrate check' + CommandStatus status = main("migrate", "check", + "-c", config.toString()); + assertThat(status.code(), is(0)); + // When digdag server boot up, already all migrations should be done. + assertThat(status.outUtf8(), containsString("No update")); + } + } + + + // This test ignore TemporaryDigdagServer and test to disk H2 database + @Test + public void migrateH2() + throws Exception + { + assumeFalse(server.isRemoteDatabase()); + String dbPath = folder.newFolder().toString(); + { + CommandStatus status = main("migrate", "run", + "-o", dbPath); + assertThat(status.code(), is(0)); + assertThat(status.outUtf8(), containsString("successfully finished")); + } + { // test 'digdag migrate check' + CommandStatus status = main("migrate", "check", + "-o", dbPath); + assertThat(status.code(), is(0)); + // all migrations should be done above 'migrate run'. + assertThat(status.outUtf8(), containsString("No update")); + } + } +} diff --git a/digdag-tests/src/test/java/acceptance/CliProxyEnvVarIT.java b/digdag-tests/src/test/java/acceptance/CliProxyEnvVarIT.java index 57a25dd83f..749b88a70c 100644 --- a/digdag-tests/src/test/java/acceptance/CliProxyEnvVarIT.java +++ b/digdag-tests/src/test/java/acceptance/CliProxyEnvVarIT.java @@ -2,9 +2,9 @@ import com.google.common.collect.ImmutableMap; import io.netty.handler.codec.http.HttpRequest; -import okhttp3.internal.tls.SslClient; import okhttp3.mockwebserver.MockResponse; import okhttp3.mockwebserver.MockWebServer; +import okhttp3.tls.HandshakeCertificates; import org.hamcrest.Matchers; import org.junit.Before; import org.junit.Ignore; @@ -18,11 +18,14 @@ import org.slf4j.LoggerFactory; import utils.CommandStatus; +import javax.net.ssl.SSLContext; +import javax.net.ssl.SSLSocketFactory; import java.util.Map; import java.util.concurrent.atomic.AtomicInteger; import static io.digdag.client.DigdagVersion.buildVersion; import static io.netty.handler.codec.http.HttpHeaders.Names.CONTENT_TYPE; +import static okhttp3.tls.internal.TlsUtil.localhost; import static org.hamcrest.Matchers.is; import static org.junit.Assert.assertThat; import static utils.TestUtils.main; @@ -54,7 +57,11 @@ public void setUp() httpMockServer.start(); httpsMockServer = new MockWebServer(); - httpsMockServer.useHttps(SslClient.localhost().socketFactory, false); + HandshakeCertificates handshakeCertificates = localhost(); + SSLSocketFactory socketFactory = handshakeCertificates.sslSocketFactory(); + + + httpsMockServer.useHttps(socketFactory, false); httpsMockServer.start(); httpProxy = DefaultHttpProxyServer diff --git a/digdag-tests/src/test/java/acceptance/CliShowProjectsIT.java b/digdag-tests/src/test/java/acceptance/CliShowProjectsIT.java new file mode 100644 index 0000000000..6312bad506 --- /dev/null +++ b/digdag-tests/src/test/java/acceptance/CliShowProjectsIT.java @@ -0,0 +1,169 @@ +package acceptance; + +import org.junit.Before; +import org.junit.Rule; +import org.junit.Test; +import org.junit.rules.TemporaryFolder; +import utils.CommandStatus; +import utils.TemporaryDigdagServer; + +import java.nio.file.Path; + +import static org.hamcrest.MatcherAssert.assertThat; +import static org.hamcrest.Matchers.containsString; +import static org.hamcrest.Matchers.is; +import static org.hamcrest.Matchers.not; +import static utils.TestUtils.copyResource; +import static utils.TestUtils.main; + +public class CliShowProjectsIT +{ + @Rule + public TemporaryFolder folder = new TemporaryFolder(); + + @Rule + public TemporaryDigdagServer server = TemporaryDigdagServer.of(); + + private Path config; + private Path projectDir; + + @Before + public void setUp() + throws Exception + { + projectDir = folder.getRoot().toPath().resolve("foobar"); + config = folder.newFile().toPath(); + } + + @Test + public void showProjects() + throws Exception + { + + // Create new project + CommandStatus initStatus = main("init", + "-c", config.toString(), + projectDir.toString()); + assertThat(initStatus.code(), is(0)); + + copyResource("acceptance/basic.dig", projectDir.resolve("basic.dig")); + + // digdag push first project. (named: foo) + { + CommandStatus pushStatus = main( + "push", + "--project", projectDir.toString(), + "foo", + "-c", config.toString(), + "-e", server.endpoint()); + assertThat(pushStatus.errUtf8(), pushStatus.code(), is(0)); + } + + // digdag push second project. (named: bar) + { + CommandStatus pushStatus = main( + "push", + "--project", projectDir.toString(), + "bar", + "-c", config.toString(), + "-e", server.endpoint()); + assertThat(pushStatus.errUtf8(), pushStatus.code(), is(0)); + } + + CommandStatus showProjectStatus = main("projects", + "-c", config.toString(), + "-e", server.endpoint()); + + assertThat(showProjectStatus.errUtf8(), showProjectStatus.code(), is(0)); + assertThat(showProjectStatus.outUtf8(), containsString(" name: foo")); + assertThat(showProjectStatus.outUtf8(), containsString(" name: bar")); + } + + @Test + public void showProjectWithProjectName() + throws Exception + { + + // Create new project + CommandStatus initStatus = main("init", + "-c", config.toString(), + projectDir.toString()); + assertThat(initStatus.code(), is(0)); + + copyResource("acceptance/basic.dig", projectDir.resolve("basic.dig")); + + // digdag push first project. (named: foo) + { + CommandStatus pushStatus = main( + "push", + "--project", projectDir.toString(), + "foo", + "-c", config.toString(), + "-e", server.endpoint()); + assertThat(pushStatus.errUtf8(), pushStatus.code(), is(0)); + } + + // digdag push second project. (named: bar) + { + CommandStatus pushStatus = main( + "push", + "--project", projectDir.toString(), + "bar", + "-c", config.toString(), + "-e", server.endpoint()); + assertThat(pushStatus.errUtf8(), pushStatus.code(), is(0)); + } + + CommandStatus showProjectStatus = main("projects","foo", + "-c", config.toString(), + "-e", server.endpoint()); + + assertThat(showProjectStatus.errUtf8(), showProjectStatus.code(), is(0)); + assertThat(showProjectStatus.outUtf8(), containsString(" name: foo")); + // This assert expect `digdag projects foo` doesn't show project `bar` detail. + assertThat(showProjectStatus.outUtf8(), not(containsString(" name: bar"))); + } + @Test + public void showProjectWithNonRegisteredProject() + throws Exception + { + + // Create new project + CommandStatus initStatus = main("init", + "-c", config.toString(), + projectDir.toString()); + assertThat(initStatus.code(), is(0)); + + copyResource("acceptance/basic.dig", projectDir.resolve("basic.dig")); + + // digdag push first project. (named: foo) + { + CommandStatus pushStatus = main( + "push", + "--project", projectDir.toString(), + "foo", + "-c", config.toString(), + "-e", server.endpoint()); + assertThat(pushStatus.errUtf8(), pushStatus.code(), is(0)); + } + + // digdag push second project. (named: bar) + { + CommandStatus pushStatus = main( + "push", + "--project", projectDir.toString(), + "bar", + "-c", config.toString(), + "-e", server.endpoint()); + assertThat(pushStatus.errUtf8(), pushStatus.code(), is(0)); + } + + CommandStatus showProjectStatus = main("projects","not_exist_project", + "-c", config.toString(), + "-e", server.endpoint()); + + assertThat(showProjectStatus.errUtf8(), showProjectStatus.code(), is(1)); + assertThat(showProjectStatus.errUtf8(), containsString("does not exist.")); + } + +} diff --git a/digdag-tests/src/test/java/acceptance/CliStartIT.java b/digdag-tests/src/test/java/acceptance/CliStartIT.java new file mode 100644 index 0000000000..72d6f588f7 --- /dev/null +++ b/digdag-tests/src/test/java/acceptance/CliStartIT.java @@ -0,0 +1,72 @@ +package acceptance; + +import org.junit.Before; +import org.junit.Rule; +import org.junit.Test; +import org.junit.rules.TemporaryFolder; +import utils.CommandStatus; +import utils.TemporaryDigdagServer; + +import java.nio.file.Path; + +import static org.hamcrest.MatcherAssert.assertThat; +import static org.hamcrest.Matchers.is; +import static utils.TestUtils.copyResource; +import static utils.TestUtils.main; + +public class CliStartIT +{ + @Rule + public TemporaryFolder folder = new TemporaryFolder(); + + @Rule + public TemporaryDigdagServer server = TemporaryDigdagServer.of(); + + private Path config; + private Path projectDir; + + @Before + public void setUp() + throws Exception + { + projectDir = folder.getRoot().toPath().resolve("foobar"); + config = folder.newFile().toPath(); + } + + @Test + public void startProject() + throws Exception + { + + // Create new project + CommandStatus initStatus = main("init", + "-c", config.toString(), + projectDir.toString()); + assertThat(initStatus.code(), is(0)); + + copyResource("acceptance/basic.dig", projectDir.resolve("basic.dig")); + + // 1. archive project + { + CommandStatus pushStatus = main( + "push", + "--project", projectDir.toString(), + "test_proj", + "-c", config.toString(), + "-e", server.endpoint() + ); + assertThat(pushStatus.errUtf8(), pushStatus.code(), is(0)); + } + + // 2. then start it. + { + CommandStatus uploadStatus = main( + "start", + "test_proj", + "--session", "now", + "-c", config.toString(), + "-e", server.endpoint()); + assertThat(uploadStatus.errUtf8(), uploadStatus.code(), is(0)); + } + } +} diff --git a/digdag-tests/src/test/java/acceptance/ConfigEvalEngineIT.java b/digdag-tests/src/test/java/acceptance/ConfigEvalEngineIT.java new file mode 100644 index 0000000000..b7db11e182 --- /dev/null +++ b/digdag-tests/src/test/java/acceptance/ConfigEvalEngineIT.java @@ -0,0 +1,80 @@ +package acceptance; + +import com.google.common.io.Resources; +import io.digdag.client.api.Id; +import org.junit.Before; +import org.junit.Rule; +import org.junit.Test; +import org.junit.rules.TemporaryFolder; +import utils.CommandStatus; +import utils.TemporaryDigdagServer; + +import java.nio.file.Files; +import java.nio.file.Path; +import java.nio.file.Paths; +import java.time.Duration; + +import static java.nio.charset.StandardCharsets.UTF_8; +import static org.hamcrest.Matchers.is; +import static org.junit.Assert.assertThat; +import static utils.TestUtils.*; + +public class ConfigEvalEngineIT +{ + @Rule + public TemporaryFolder folder = new TemporaryFolder(); + + @Rule + public TemporaryDigdagServer server = TemporaryDigdagServer.of(); + + private Path config; + private Path projectDir; + + private Path root() + { + return folder.getRoot().toPath().toAbsolutePath(); + } + + @Before + public void setUp() + throws Exception + { + projectDir = folder.getRoot().toPath().resolve("config_eval_engine_test"); + Files.createDirectories(projectDir); + config = folder.newFile().toPath(); + } + + + @Test + public void invalidConfigShouldNotInfiniteLoop() + throws Exception + { + copyResource("acceptance/config_eval_engine/invalid1.dig", projectDir); + // Push the project + CommandStatus pushStatus = main("push", + "--project", projectDir.toString(), + "config_eval_engine_test", + "-c", config.toString(), + "-e", server.endpoint()); + assertThat(pushStatus.errUtf8(), pushStatus.code(), is(0)); + + // Start the workflow + Id attemptId; + { + CommandStatus startStatus = main("start", + "-c", config.toString(), + "-e", server.endpoint(), + "config_eval_engine_test", "invalid1", + "--session", "now"); + assertThat(startStatus.code(), is(0)); + attemptId = getAttemptId(startStatus); + } + + // Wait for the attempt to complete + expect(Duration.ofMinutes(5), attemptFailure(server.endpoint(), attemptId)); + + // Verify that the file created by the child workflow is there + //assertThat(Files.exists(root().resolve("call_by_name.out")), is(true)); + + } +} diff --git a/digdag-tests/src/test/java/acceptance/DockerIT.java b/digdag-tests/src/test/java/acceptance/DockerIT.java new file mode 100644 index 0000000000..ad5231d75a --- /dev/null +++ b/digdag-tests/src/test/java/acceptance/DockerIT.java @@ -0,0 +1,144 @@ +package acceptance; + +import io.digdag.client.DigdagClient; +import io.digdag.client.api.Id; +import io.digdag.client.api.RestSessionAttempt; +import org.junit.Before; +import org.junit.Rule; +import org.junit.Test; +import org.junit.rules.TemporaryFolder; +import utils.CommandStatus; +import utils.TemporaryDigdagServer; + +import java.nio.file.Files; +import java.nio.file.Path; + +import static org.hamcrest.Matchers.containsString; +import static org.hamcrest.Matchers.is; +import static org.junit.Assert.assertThat; +import static utils.TestUtils.copyResource; +import static utils.TestUtils.getAttemptId; +import static utils.TestUtils.getAttemptLogs; +import static utils.TestUtils.main; + +public class DockerIT +{ + @Rule + public TemporaryFolder folder = new TemporaryFolder(); + + @Rule + public TemporaryDigdagServer server = TemporaryDigdagServer.of(); + + private Path config; + private DigdagClient client; + + @Before + public void setUp() + throws Exception + { + config = folder.newFile().toPath(); + + client = DigdagClient.builder() + .host(server.host()) + .port(server.port()) + .build(); + } + + @Test + public void verifyDockerBuild() + throws Exception + { + final Path tempdir = folder.getRoot().toPath().toAbsolutePath(); + final Path projectDir = tempdir.resolve("docker"); + final Path scriptsDir = projectDir.resolve("scripts"); + + // Create new project + final CommandStatus initStatus = main("init", + "-c", config.toString(), + projectDir.toString()); + assertThat(initStatus.code(), is(0)); + Files.createDirectories(scriptsDir); + copyResource("acceptance/docker/docker_build.dig", projectDir.resolve("docker_build.dig")); + + // Push the project + final CommandStatus pushStatus = main("push", + "--project", projectDir.toString(), + "docker", + "-c", config.toString(), + "-e", server.endpoint(), + "-r", "4711"); + assertThat(pushStatus.errUtf8(), pushStatus.code(), is(0)); + + // Start the workflow + final CommandStatus startStatus = main("start", + "-c", config.toString(), + "-e", server.endpoint(), + "docker", "docker_build", + "--session", "now"); + assertThat(startStatus.code(), is(0)); + final Id attemptId = getAttemptId(startStatus); + + // Wait for the attempt to complete + RestSessionAttempt attempt = null; + for (int i = 0; i < 30; i++) { + attempt = client.getSessionAttempt(attemptId); + if (attempt.getDone()) { + break; + } + Thread.sleep(1000); + } + assertThat(attempt.getSuccess(), is(true)); + + final String logs = getAttemptLogs(client, attemptId); + assertThat(logs, containsString("65536")); + } + + @Test + public void verifyDockerRunOptions() + throws Exception + { + final Path tempdir = folder.getRoot().toPath().toAbsolutePath(); + final Path projectDir = tempdir.resolve("docker"); + final Path scriptsDir = projectDir.resolve("scripts"); + + // Create new project + final CommandStatus initStatus = main("init", + "-c", config.toString(), + projectDir.toString()); + assertThat(initStatus.code(), is(0)); + Files.createDirectories(scriptsDir); + copyResource("acceptance/docker/docker_run_options.dig", projectDir.resolve("docker_run_options.dig")); + + // Push the project + final CommandStatus pushStatus = main("push", + "--project", projectDir.toString(), + "docker", + "-c", config.toString(), + "-e", server.endpoint(), + "-r", "4711"); + assertThat(pushStatus.errUtf8(), pushStatus.code(), is(0)); + + // Start the workflow + final CommandStatus startStatus = main("start", + "-c", config.toString(), + "-e", server.endpoint(), + "docker", "docker_run_options", + "--session", "now"); + assertThat(startStatus.code(), is(0)); + final Id attemptId = getAttemptId(startStatus); + + // Wait for the attempt to complete + RestSessionAttempt attempt = null; + for (int i = 0; i < 30; i++) { + attempt = client.getSessionAttempt(attemptId); + if (attempt.getDone()) { + break; + } + Thread.sleep(1000); + } + assertThat(attempt.getSuccess(), is(true)); + + final String logs = getAttemptLogs(client, attemptId); + assertThat(logs, containsString("65536")); + } +} diff --git a/digdag-tests/src/test/java/acceptance/HttpCallIT.java b/digdag-tests/src/test/java/acceptance/HttpCallIT.java new file mode 100644 index 0000000000..28c1775576 --- /dev/null +++ b/digdag-tests/src/test/java/acceptance/HttpCallIT.java @@ -0,0 +1,323 @@ +package acceptance; + +import com.fasterxml.jackson.dataformat.yaml.YAMLFactory; +import com.fasterxml.jackson.dataformat.yaml.YAMLGenerator; +import com.google.common.collect.ImmutableMap; +import com.google.common.io.Resources; +import io.digdag.client.config.Config; +import io.digdag.client.config.ConfigFactory; +import io.digdag.core.config.YamlConfigLoader; +import io.netty.handler.codec.http.FullHttpRequest; +import java.io.IOException; +import java.io.StringWriter; +import java.nio.file.Files; +import java.nio.file.Path; +import java.util.List; +import java.util.Map; +import java.util.concurrent.ConcurrentHashMap; +import java.util.concurrent.ConcurrentMap; +import okhttp3.Headers; +import okhttp3.mockwebserver.MockResponse; +import okhttp3.mockwebserver.MockWebServer; +import okhttp3.mockwebserver.QueueDispatcher; +import okhttp3.mockwebserver.RecordedRequest; +import org.hamcrest.Matchers; +import org.junit.After; +import org.junit.Before; +import org.junit.Rule; +import org.junit.Test; +import org.junit.rules.TemporaryFolder; +import org.littleshoot.proxy.HttpProxyServer; +import static java.nio.charset.StandardCharsets.UTF_8; +import static org.eclipse.jetty.http.HttpHeader.AUTHORIZATION; +import static org.eclipse.jetty.http.HttpHeader.CONTENT_TYPE; +import static org.hamcrest.CoreMatchers.containsString; +import static org.hamcrest.Matchers.empty; +import static org.hamcrest.Matchers.hasSize; +import static org.hamcrest.Matchers.is; +import static org.hamcrest.Matchers.lessThan; +import static org.hamcrest.Matchers.not; +import static org.hamcrest.Matchers.nullValue; +import static org.junit.Assert.assertThat; +import static utils.TestUtils.objectMapper; +import static utils.TestUtils.runWorkflow; +import static utils.TestUtils.startMockWebServer; +import utils.CommandStatus; +import utils.TestUtils; + +public class HttpCallIT +{ + private static final ConfigFactory CF = TestUtils.configFactory(); + private static final YamlConfigLoader Y = new YamlConfigLoader(); + + private MockWebServer httpMockWebServer; + private MockWebServer httpsMockWebServer; + + @Rule + public TemporaryFolder folder = new TemporaryFolder(); + private HttpProxyServer proxy; + private ConcurrentMap> requests; + + @Before + public void setUp() + throws Exception + { + httpMockWebServer = startMockWebServer(); + httpMockWebServer.setDispatcher(new QueueDispatcher()); + httpsMockWebServer = startMockWebServer(true); + requests = new ConcurrentHashMap<>(); + } + + @After + public void tearDownProxy() + throws Exception + { + if (proxy != null) { + proxy.stop(); + } + } + + @After + public void tearDownHttpServer() + throws Exception + { + if (httpMockWebServer != null) { + httpMockWebServer.shutdown(); + } + } + + @After + public void tearDownHttpsServer() + throws Exception + { + if (httpsMockWebServer != null) { + httpsMockWebServer.shutdown(); + } + } + + private Path root() + { + return folder.getRoot().toPath().toAbsolutePath(); + } + + private Config loadYamlResource(String name) + { + try { + String content = Resources.toString(Resources.getResource(name), UTF_8); + return Y.loadString(content).toConfig(CF); + } + catch (IOException ex) { + throw new RuntimeException(ex); + } + } + + @Test + public void testSubTasksByJson() + throws Exception + { + Config bodyConfig = loadYamlResource("acceptance/http_call/child.dig"); + httpMockWebServer.enqueue( + new MockResponse() + .addHeader("Content-Type: application/json") + .setBody(bodyConfig.toString())); + String uri = "http://localhost:" + httpMockWebServer.getPort() + "/test"; + runWorkflow(folder, "acceptance/http_call/http_call.dig", ImmutableMap.of( + "test_uri", uri, + "outdir", root().toString(), + "name", "child")); + assertThat(httpMockWebServer.getRequestCount(), is(1)); + assertThat(Files.exists(root().resolve("child.out")), is(true)); + RecordedRequest request = httpMockWebServer.takeRequest(); + assertThat(request.getMethod(), is("GET")); + } + + @Test + public void testSubTasksByYaml() + throws Exception + { + Config bodyConfig = loadYamlResource("acceptance/http_call/child.dig"); + httpMockWebServer.enqueue( + new MockResponse() + .addHeader("Content-Type: application/x-yaml") + .setBody(formatYaml(bodyConfig))); + String uri = "http://localhost:" + httpMockWebServer.getPort() + "/test"; + runWorkflow(folder, "acceptance/http_call/http_call.dig", ImmutableMap.of( + "test_uri", uri, + "outdir", root().toString(), + "name", "child")); + assertThat(httpMockWebServer.getRequestCount(), is(1)); + assertThat(Files.exists(root().resolve("child.out")), is(true)); + RecordedRequest request = httpMockWebServer.takeRequest(); + assertThat(request.getMethod(), is("GET")); + } + + @Test + public void testSubTasksWithUnknownContentType() + throws Exception + { + Config bodyConfig = loadYamlResource("acceptance/http_call/child.dig"); + httpMockWebServer.enqueue( + new MockResponse() + .addHeader("Content-Type: application/octet-stream") + .setBody(formatYaml(bodyConfig))); + String uri = "http://localhost:" + httpMockWebServer.getPort() + "/test"; + CommandStatus status = runWorkflow(folder, "acceptance/http_call/http_call.dig", ImmutableMap.of( + "test_uri", uri, + "outdir", root().toString(), + "name", "child"), ImmutableMap.of(), 1); + assertThat(status.errUtf8(), containsString("Unsupported Content-Type")); + assertThat(status.errUtf8(), containsString("application/octet-stream")); + } + + @Test + public void testSubTasksWithContentTypeOverride() + throws Exception + { + Config bodyConfig = loadYamlResource("acceptance/http_call/child.dig"); + httpMockWebServer.enqueue( + new MockResponse() + .addHeader("Content-Type: application/octet-stream") + .setBody(formatYaml(bodyConfig))); + String uri = "http://localhost:" + httpMockWebServer.getPort() + "/test"; + runWorkflow(folder, "acceptance/http_call/http_call_yaml_override.dig", ImmutableMap.of( + "test_uri", uri, + "outdir", root().toString(), + "name", "child")); + assertThat(httpMockWebServer.getRequestCount(), is(1)); + assertThat(Files.exists(root().resolve("child.out")), is(true)); + RecordedRequest request = httpMockWebServer.takeRequest(); + assertThat(request.getMethod(), is("GET")); + } + + private String formatYaml(Config value) + { + try { + StringWriter writer = new StringWriter(); + try (YAMLGenerator out = new YAMLFactory().createGenerator(writer)) { + objectMapper().writeValue(out, value); + } + return writer.toString(); + } + catch (IOException ex) { + throw new RuntimeException(ex); + } + } + + @Test + public void testSubTasksByInvalidJson() + throws Exception + { + httpMockWebServer.enqueue( + new MockResponse() + .addHeader("Content-Type: application/json") + .setBody("!invalid!")); + String uri = "http://localhost:" + httpMockWebServer.getPort() + "/test"; + runWorkflow(folder, "acceptance/http_call/http_call.dig", ImmutableMap.of( + "test_uri", uri, + "outdir", root().toString(), + "name", "child"), ImmutableMap.of(), 1); + } + + @Test + public void testSubTasksByInvalidYaml() + throws Exception + { + httpMockWebServer.enqueue( + new MockResponse() + .addHeader("Content-Type: application/x-yaml") + .setBody("!invalid!")); + String uri = "http://localhost:" + httpMockWebServer.getPort() + "/test"; + runWorkflow(folder, "acceptance/http_call/http_call.dig", ImmutableMap.of( + "test_uri", uri, + "outdir", root().toString(), + "name", "child"), ImmutableMap.of(), 1); + } + + @Test + public void testSubTasksWithQueryString() + throws Exception + { + Config bodyConfig = loadYamlResource("acceptance/http_call/child.dig"); + httpMockWebServer.enqueue( + new MockResponse() + .addHeader("Content-Type: application/json") + .setBody(bodyConfig.toString())); + String uri = "http://localhost:" + httpMockWebServer.getPort() + "/test"; + runWorkflow(folder, "acceptance/http_call/http_call_query.dig", ImmutableMap.of( + "test_uri", uri, + "outdir", root().toString(), + "name", "child")); + assertThat(httpMockWebServer.getRequestCount(), is(1)); + assertThat(Files.exists(root().resolve("child.out")), is(true)); + RecordedRequest request = httpMockWebServer.takeRequest(); + assertThat(request.getMethod(), is("GET")); + assertThat(request.getRequestUrl().queryParameter("k"), is("v")); + assertThat(request.getRequestUrl().queryParameter("foo"), is("bar")); + } + + @Test + public void testSubTasksByPost() + throws Exception + { + Config bodyConfig = loadYamlResource("acceptance/http_call/child.dig"); + httpMockWebServer.enqueue( + new MockResponse() + .addHeader("Content-Type: application/json") + .setBody(bodyConfig.toString())); + String uri = "http://localhost:" + httpMockWebServer.getPort() + "/test"; + runWorkflow(folder, "acceptance/http_call/http_call_post.dig", ImmutableMap.of( + "test_uri", uri, + "outdir", root().toString(), + "name", "child")); + assertThat(httpMockWebServer.getRequestCount(), is(1)); + assertThat(Files.exists(root().resolve("child.out")), is(true)); + RecordedRequest request = httpMockWebServer.takeRequest(); + assertThat(request.getMethod(), is("POST")); + assertThat(request.getBody().readUtf8(), is("{\"k\":\"v\",\"foo\":\"bar\"}")); + } + + @Test + public void testSystemProxy() + throws Exception + { + proxy = TestUtils.startRequestFailingProxy(1, requests); + httpMockWebServer.enqueue( + new MockResponse() + .addHeader("Content-Type: application/json") + .setBody("{}")); + String uri = "http://localhost:" + httpMockWebServer.getPort() + "/test"; + runWorkflow(folder, "acceptance/http_call/http_call.dig", + ImmutableMap.of( + "test_uri", uri + ), + ImmutableMap.of( + "config.http.proxy.enabled", "true", + "config.http.proxy.host", "localhost", + "config.http.proxy.port", Integer.toString(proxy.getListenAddress().getPort()) + )); + assertThat(httpMockWebServer.getRequestCount(), is(1)); + assertThat(requests.get(uri), is(not(empty()))); + } + + @Test + public void testUserProxy() + throws Exception + { + proxy = TestUtils.startRequestFailingProxy(1, requests); + httpMockWebServer.enqueue( + new MockResponse() + .addHeader("Content-Type: application/json") + .setBody("{}")); + String uri = "http://localhost:" + httpMockWebServer.getPort() + "/test"; + runWorkflow(folder, "acceptance/http_call/http_call.dig", + ImmutableMap.of( + "test_uri", uri, + "http.proxy.enabled", "true", + "http.proxy.host", "localhost", + "http.proxy.port", Integer.toString(proxy.getListenAddress().getPort()) + )); + assertThat(httpMockWebServer.getRequestCount(), is(1)); + assertThat(requests.get("GET " + uri), is(not(nullValue()))); + assertThat(requests.get("GET " + uri), is(not(empty()))); + } +} diff --git a/digdag-tests/src/test/java/acceptance/HttpIT.java b/digdag-tests/src/test/java/acceptance/HttpIT.java index 59c0738e6f..1c356adf44 100644 --- a/digdag-tests/src/test/java/acceptance/HttpIT.java +++ b/digdag-tests/src/test/java/acceptance/HttpIT.java @@ -3,7 +3,7 @@ import com.amazonaws.util.Base64; import com.fasterxml.jackson.databind.JsonNode; import com.fasterxml.jackson.databind.ObjectMapper; -import com.google.api.client.repackaged.com.google.common.base.Splitter; +import com.google.common.base.Splitter; import com.google.common.collect.ImmutableList; import com.google.common.collect.ImmutableMap; import com.google.common.io.Resources; diff --git a/digdag-tests/src/test/java/acceptance/LimitProjectArchiveFileSizeIT.java b/digdag-tests/src/test/java/acceptance/LimitProjectArchiveFileSizeIT.java new file mode 100644 index 0000000000..e79e6f8630 --- /dev/null +++ b/digdag-tests/src/test/java/acceptance/LimitProjectArchiveFileSizeIT.java @@ -0,0 +1,88 @@ +package acceptance; + +import org.junit.Before; +import org.junit.Rule; +import org.junit.Test; +import org.junit.rules.TemporaryFolder; +import utils.CommandStatus; +import utils.TemporaryDigdagServer; + +import java.nio.file.Path; + +import static org.hamcrest.MatcherAssert.assertThat; +import static org.hamcrest.Matchers.containsString; +import static org.hamcrest.Matchers.is; +import static utils.TestUtils.copyResource; +import static utils.TestUtils.main; + +public class LimitProjectArchiveFileSizeIT +{ + @Rule + public TemporaryFolder folder = new TemporaryFolder(); + + private Path projectDir; + private Path config; + + @Before + public void setUp() + throws Exception + { + projectDir = folder.getRoot().toPath().resolve("foobar"); + config = folder.newFile().toPath(); + } + + @Test + public void uploadProject() + throws Exception + { + try (final TemporaryDigdagServer server = TemporaryDigdagServer.builder() + .build()) { + server.start(); + + // Create new project + CommandStatus initStatus = main("init", + "-c", config.toString(), + projectDir.toString()); + assertThat(initStatus.code(), is(0)); + + copyResource("acceptance/basic.dig", projectDir.resolve("basic.dig")); + + // Push the project + CommandStatus pushStatus = main( + "push", + "--project", projectDir.toString(), + "foobar", + "-c", config.toString(), + "-e", server.endpoint()); + assertThat(pushStatus.code(), is(0)); + } + } + + @Test + public void uploadProjectLargerThanLimit() + throws Exception + { + try (final TemporaryDigdagServer server = TemporaryDigdagServer.builder() + .configuration("api.max_archive_total_size_limit = 1") + .build()) { + server.start(); + + // Create new project + CommandStatus initStatus = main("init", + "-c", config.toString(), + projectDir.toString()); + assertThat(initStatus.code(), is(0)); + + copyResource("acceptance/basic.dig", projectDir.resolve("basic.dig")); + + CommandStatus pushStatus = main( + "push", + "--project", projectDir.toString(), + "foobar", + "-c", config.toString(), + "-e", server.endpoint()); + assertThat(pushStatus.code(), is(1)); + assertThat(pushStatus.errUtf8(), containsString("Size of the uploaded archive file exceeds limit")); + } + } +} \ No newline at end of file diff --git a/digdag-tests/src/test/java/acceptance/MigrationIT.java b/digdag-tests/src/test/java/acceptance/MigrationIT.java new file mode 100644 index 0000000000..97bc650183 --- /dev/null +++ b/digdag-tests/src/test/java/acceptance/MigrationIT.java @@ -0,0 +1,91 @@ +package acceptance; + +import io.digdag.core.database.DatabaseMigrator; +import io.digdag.core.database.migrate.Migration; +import io.digdag.core.database.migrate.MigrationContext; +import io.digdag.core.database.migrate.Migration_20151204221156_CreateTables; +import org.junit.After; +import org.junit.Before; +import org.junit.Test; +import org.skife.jdbi.v2.DBI; +import org.skife.jdbi.v2.Handle; +import utils.TemporaryDigdagServer; + +import javax.sql.DataSource; +import java.sql.Connection; + +import static org.junit.Assert.fail; +import static org.junit.Assume.assumeTrue; + + +public class MigrationIT +{ + public TemporaryDigdagServer server = null; + + @Before + public void setUp() + { + server = TemporaryDigdagServer.of(); + } + + @After + public void tearDown() + { + if (server != null) { + server.close(); + server = null; + } + } + + /** + * Check the behavior for upgrading existing database + * @throws Exception + */ + @Test + public void checkDatabaseUpgrade() + { + assumeTrue(server.isRemoteDatabase()); + + try { + server.setupDatabase(); + DataSource ds = server.getTestDBDataSource(); + DBI dbi = new DBI(ds); + DatabaseMigrator migrator = new DatabaseMigrator(dbi, server.getRemoteTestDatabaseConfig()); + MigrationContext context = new MigrationContext(migrator.getDatabaseType()); + + //Prepare for tables + try (Handle handle = dbi.open()) { + migrator.createSchemaMigrationsTable(handle, context); + Migration m = new Migration_20151204221156_CreateTables(); + migrator.applyMigration(m, handle, context); + } + + //Apply rest migrations when digdag server start + server.start(true); + } + catch (Exception e) { + e.printStackTrace(); + fail(e.toString()); + } + } + + /** + * Check session_attempts_on_site_id_and_state_flags_partial_2 index exists + * @throws Exception + */ + @Test + public void checkMigration_20190318175338_AddIndexToSessionAttempts() + { + assumeTrue(server.isRemoteDatabase()); + + try { + server.start(); + DataSource ds = server.getTestDBDataSource(); + Connection con = ds.getConnection(); + con.createStatement().execute("drop index session_attempts_on_site_id_and_state_flags_partial_2"); + } + catch (Exception e) { + fail(e.toString()); + } + } +} diff --git a/digdag-tests/src/test/java/acceptance/ParamGetPostgresqlIT.java b/digdag-tests/src/test/java/acceptance/ParamGetPostgresqlIT.java index d26a595aae..1c4e2c513d 100644 --- a/digdag-tests/src/test/java/acceptance/ParamGetPostgresqlIT.java +++ b/digdag-tests/src/test/java/acceptance/ParamGetPostgresqlIT.java @@ -77,13 +77,13 @@ public void testGetExpiredParamsAreInvisible() SecretProvider secrets = getDatabaseSecrets(); try ( PgConnection conn = PgConnection.open(PgConnectionConfig.configure(secrets, EMPTY_CONFIG))) { - int expiredUpdatedAt = 60 * 24 * 90 + 1; + int expiredUpdatedAt = 60 * 60 * 24 * 90 + 1; // expired param(last update is 90 days + 1second ago) conn.executeUpdate(String.format( "insert into params (key, value, value_type, site_id, created_at, updated_at) " + "values ('%s', '%s', %d, %d, now(), now() - interval '" + String.valueOf(expiredUpdatedAt) + " second')", "key1", "{\"value\": \"value1\"}", 0, 0)); - int notExpiredUpdatedAt = 60 * 24 * 89; + int notExpiredUpdatedAt = 60 * 60 * 24 * 89; // not expired param(last update is 89 days ago) conn.executeUpdate(String.format( "insert into params (key, value, value_type, site_id, created_at, updated_at) " + diff --git a/digdag-tests/src/test/java/acceptance/ParamSetRedisIT.java b/digdag-tests/src/test/java/acceptance/ParamSetRedisIT.java index cfb425f3a9..ee18940a72 100644 --- a/digdag-tests/src/test/java/acceptance/ParamSetRedisIT.java +++ b/digdag-tests/src/test/java/acceptance/ParamSetRedisIT.java @@ -8,6 +8,7 @@ import java.nio.file.Path; import static java.util.Arrays.asList; +import static junit.framework.TestCase.assertTrue; import static org.hamcrest.core.Is.is; import static org.junit.Assert.assertThat; import static utils.TestUtils.addWorkflow; @@ -17,6 +18,9 @@ public class ParamSetRedisIT extends BaseParamRedisIT { + private static long TTL_90_DAYS = 60 * 60 * 24 * 90; // 90days + private static long TTL_89_DAYS = 60 * 60 * 24 * 89; // 89days + @Test public void setValueToRedis() throws IOException @@ -36,6 +40,13 @@ public void setValueToRedis() projectDir.resolve("set.dig").toString() ); assertCommandStatus(status); + + long key1_ttl = redisClient.ttl("0:key1"); + long key2_ttl = redisClient.ttl("0:key2"); + + assertTrue(key1_ttl <= TTL_90_DAYS && key1_ttl > TTL_89_DAYS); + assertTrue(key2_ttl <= TTL_90_DAYS && key2_ttl > TTL_89_DAYS); + assertThat(redisClient.get("0:key1"), is("{\"value_type\":0,\"value\":{\"value\":\"value1\"}}")); assertThat(redisClient.get("0:key2"), is("{\"value_type\":0,\"value\":{\"value\":\"value2\"}}")); } @@ -59,6 +70,13 @@ public void parallelSetValueToRedis() projectDir.resolve("parallel_set.dig").toString() ); assertCommandStatus(status); + + long key1_ttl = redisClient.ttl("0:key1"); + long key2_ttl = redisClient.ttl("0:key2"); + + assertTrue(key1_ttl <= TTL_90_DAYS && key1_ttl > TTL_89_DAYS); + assertTrue(key2_ttl <= TTL_90_DAYS && key2_ttl > TTL_89_DAYS); + assertThat(redisClient.get("0:key1"), is("{\"value_type\":0,\"value\":{\"value\":\"value1\"}}")); assertThat(redisClient.get("0:key2"), is("{\"value_type\":0,\"value\":{\"value\":\"value2\"}}")); } diff --git a/digdag-tests/src/test/java/acceptance/PyIT.java b/digdag-tests/src/test/java/acceptance/PyIT.java new file mode 100644 index 0000000000..ae8e84fcdc --- /dev/null +++ b/digdag-tests/src/test/java/acceptance/PyIT.java @@ -0,0 +1,206 @@ +package acceptance; + +import io.digdag.client.DigdagClient; +import io.digdag.client.api.Id; +import io.digdag.client.api.RestSessionAttempt; +import org.junit.Before; +import org.junit.Rule; +import org.junit.Test; +import org.junit.rules.TemporaryFolder; +import utils.CommandStatus; +import utils.TemporaryDigdagServer; + +import java.nio.file.Files; +import java.nio.file.Path; + +import static org.hamcrest.Matchers.containsString; +import static org.hamcrest.Matchers.is; +import static org.junit.Assert.assertThat; +import static utils.TestUtils.copyResource; +import static utils.TestUtils.getAttemptId; +import static utils.TestUtils.getAttemptLogs; +import static utils.TestUtils.main; + +public class PyIT +{ + @Rule + public TemporaryFolder folder = new TemporaryFolder(); + + @Rule + public TemporaryDigdagServer server = TemporaryDigdagServer.of(); + + private Path config; + private DigdagClient client; + + @Before + public void setUp() + throws Exception + { + config = folder.newFile().toPath(); + + client = DigdagClient.builder() + .host(server.host()) + .port(server.port()) + .build(); + } + + @Test + public void verifyDefaultConfigurationParamsAreNotUploadedIfConfigurationFileIsSpecified() + throws Exception + { + Path tempdir = folder.getRoot().toPath().toAbsolutePath(); + Path projectDir = tempdir.resolve("py"); + Path scriptsDir = projectDir.resolve("scripts"); + + // Create new project + CommandStatus initStatus = main("init", + "-c", config.toString(), + projectDir.toString()); + assertThat(initStatus.code(), is(0)); + Files.createDirectories(scriptsDir); + copyResource("acceptance/echo_params/echo_params.dig", projectDir.resolve("echo_params.dig")); + copyResource("acceptance/echo_params/scripts/__init__.py", scriptsDir.resolve("__init__.py")); + copyResource("acceptance/echo_params/scripts/echo_params.py", scriptsDir.resolve("echo_params.py")); + + // Push the project + CommandStatus pushStatus = main("push", + "--project", projectDir.toString(), + "py", + "-c", config.toString(), + "-e", server.endpoint(), + "-r", "4711"); + assertThat(pushStatus.errUtf8(), pushStatus.code(), is(0)); + + // Start the workflow + Id attemptId; + { + CommandStatus startStatus = main("start", + "-c", config.toString(), + "-e", server.endpoint(), + "py", "echo_params", + "--session", "now"); + assertThat(startStatus.code(), is(0)); + attemptId = getAttemptId(startStatus); + } + + // Wait for the attempt to complete + { + RestSessionAttempt attempt = null; + for (int i = 0; i < 30; i++) { + attempt = client.getSessionAttempt(attemptId); + if (attempt.getDone()) { + break; + } + Thread.sleep(1000); + } + assertThat(attempt.getSuccess(), is(true)); + } + + String logs = getAttemptLogs(client, attemptId); + assertThat(logs, containsString("digdag params")); + } + + @Test + public void verifyConfigurationPythonOption() + throws Exception + { + final Path tempdir = folder.getRoot().toPath().toAbsolutePath(); + final Path projectDir = tempdir.resolve("py"); + final Path scriptsDir = projectDir.resolve("scripts"); + + // Create new project + final CommandStatus initStatus = main("init", + "-c", config.toString(), + projectDir.toString()); + assertThat(initStatus.code(), is(0)); + Files.createDirectories(scriptsDir); + copyResource("acceptance/py/config_python.dig", projectDir.resolve("config_python.dig")); + copyResource("acceptance/echo_params/scripts/__init__.py", scriptsDir.resolve("__init__.py")); + copyResource("acceptance/echo_params/scripts/echo_params.py", scriptsDir.resolve("echo_params.py")); + + // Push the project + final CommandStatus pushStatus = main("push", + "--project", projectDir.toString(), + "py", + "-c", config.toString(), + "-e", server.endpoint(), + "-r", "4711"); + assertThat(pushStatus.errUtf8(), pushStatus.code(), is(0)); + + // Start the workflow + final CommandStatus startStatus = main("start", + "-c", config.toString(), + "-e", server.endpoint(), + "py", "config_python", + "--session", "now"); + assertThat(startStatus.code(), is(0)); + final Id attemptId = getAttemptId(startStatus); + + // Wait for the attempt to complete + RestSessionAttempt attempt = null; + for (int i = 0; i < 30; i++) { + attempt = client.getSessionAttempt(attemptId); + if (attempt.getDone()) { + break; + } + Thread.sleep(1000); + } + assertThat(attempt.getSuccess(), is(true)); + + final String logs = getAttemptLogs(client, attemptId); + assertThat(logs, containsString("python python")); + assertThat(logs, containsString("python [u'python', u'-v']")); + } + + @Test + public void testPythonErrorMessageAndStacktrace() + throws Exception + { + final Path tempdir = folder.getRoot().toPath().toAbsolutePath(); + final Path projectDir = tempdir.resolve("py"); + final Path scriptsDir = projectDir.resolve("scripts"); + + // Create new project + final CommandStatus initStatus = main("init", + "-c", config.toString(), + projectDir.toString()); + assertThat(initStatus.code(), is(0)); + Files.createDirectories(scriptsDir); + copyResource("acceptance/py/stacktrace_python.dig", projectDir.resolve("stacktrace_python.dig")); + copyResource("acceptance/py/scripts/stacktrace.py", scriptsDir.resolve("stacktrace.py")); + copyResource("acceptance/py/scripts/__init__.py", scriptsDir.resolve("__init__.py")); + + // Push the project + final CommandStatus pushStatus = main("push", + "--project", projectDir.toString(), + "py", + "-c", config.toString(), + "-e", server.endpoint(), + "-r", "4711"); + assertThat(pushStatus.errUtf8(), pushStatus.code(), is(0)); + + // Start the workflow + final CommandStatus startStatus = main("start", + "-c", config.toString(), + "-e", server.endpoint(), + "py", "stacktrace_python", + "--session", "now"); + assertThat(startStatus.code(), is(0)); + final Id attemptId = getAttemptId(startStatus); + + // Wait for the attempt to complete + RestSessionAttempt attempt = null; + for (int i = 0; i < 30; i++) { + attempt = client.getSessionAttempt(attemptId); + if (attempt.getDone()) { + break; + } + Thread.sleep(1000); + } + + final String logs = getAttemptLogs(client, attemptId); + assertThat(logs, containsString("Task failed with unexpected error: Python command failed with code 1: from MyError: my error message")); + assertThat(logs, containsString(", in run")); + assertThat(logs, containsString("ERROR_MESSAGE_BEGIN Python command failed with code 1: from MyError: my error message")); + } +} diff --git a/digdag-tests/src/test/java/acceptance/RbIT.java b/digdag-tests/src/test/java/acceptance/RbIT.java new file mode 100644 index 0000000000..b6f2c55c5f --- /dev/null +++ b/digdag-tests/src/test/java/acceptance/RbIT.java @@ -0,0 +1,200 @@ +package acceptance; + +import io.digdag.client.DigdagClient; +import io.digdag.client.api.Id; +import io.digdag.client.api.RestSessionAttempt; +import org.junit.Before; +import org.junit.Rule; +import org.junit.Test; +import org.junit.rules.TemporaryFolder; +import utils.CommandStatus; +import utils.TemporaryDigdagServer; + +import java.nio.file.Files; +import java.nio.file.Path; + +import static org.hamcrest.Matchers.containsString; +import static org.hamcrest.Matchers.is; +import static org.junit.Assert.assertThat; +import static utils.TestUtils.copyResource; +import static utils.TestUtils.getAttemptId; +import static utils.TestUtils.getAttemptLogs; +import static utils.TestUtils.main; + +public class RbIT +{ + @Rule + public TemporaryFolder folder = new TemporaryFolder(); + + @Rule + public TemporaryDigdagServer server = TemporaryDigdagServer.of(); + + private Path config; + private DigdagClient client; + + @Before + public void setUp() + throws Exception + { + config = folder.newFile().toPath(); + + client = DigdagClient.builder() + .host(server.host()) + .port(server.port()) + .build(); + } + + @Test + public void verifyConfigurationPararms() + throws Exception + { + final Path tempdir = folder.getRoot().toPath().toAbsolutePath(); + final Path projectDir = tempdir.resolve("rb"); + final Path scriptsDir = projectDir.resolve("scripts"); + + // Create new project + final CommandStatus initStatus = main("init", + "-c", config.toString(), + projectDir.toString()); + assertThat(initStatus.code(), is(0)); + Files.createDirectories(scriptsDir); + copyResource("acceptance/echo_params/echo_rb_params.dig", projectDir.resolve("echo_rb_params.dig")); + copyResource("acceptance/echo_params/scripts/echo_params.rb", scriptsDir.resolve("echo_params.rb")); + + // Push the project + final CommandStatus pushStatus = main("push", + "--project", projectDir.toString(), + "rb", + "-c", config.toString(), + "-e", server.endpoint(), + "-r", "4711"); + assertThat(pushStatus.errUtf8(), pushStatus.code(), is(0)); + + // Start the workflow + final CommandStatus startStatus = main("start", + "-c", config.toString(), + "-e", server.endpoint(), + "rb", "echo_rb_params", + "--session", "now"); + assertThat(startStatus.code(), is(0)); + final Id attemptId = getAttemptId(startStatus); + + // Wait for the attempt to complete + RestSessionAttempt attempt = null; + for (int i = 0; i < 30; i++) { + attempt = client.getSessionAttempt(attemptId); + if (attempt.getDone()) { + break; + } + Thread.sleep(1000); + } + assertThat(attempt.getSuccess(), is(true)); + + final String logs = getAttemptLogs(client, attemptId); + assertThat(logs, containsString("digdag params")); + } + + @Test + public void verifyConfigurationRubyOption() + throws Exception + { + final Path tempdir = folder.getRoot().toPath().toAbsolutePath(); + final Path projectDir = tempdir.resolve("rb"); + final Path scriptsDir = projectDir.resolve("scripts"); + + // Create new project + final CommandStatus initStatus = main("init", + "-c", config.toString(), + projectDir.toString()); + assertThat(initStatus.code(), is(0)); + Files.createDirectories(scriptsDir); + copyResource("acceptance/rb/config_ruby.dig", projectDir.resolve("config_ruby.dig")); + copyResource("acceptance/echo_params/scripts/echo_params.rb", scriptsDir.resolve("echo_params.rb")); + + // Push the project + final CommandStatus pushStatus = main("push", + "--project", projectDir.toString(), + "rb", + "-c", config.toString(), + "-e", server.endpoint(), + "-r", "4711"); + assertThat(pushStatus.errUtf8(), pushStatus.code(), is(0)); + + // Start the workflow + final CommandStatus startStatus = main("start", + "-c", config.toString(), + "-e", server.endpoint(), + "rb", "config_ruby", + "--session", "now"); + assertThat(startStatus.code(), is(0)); + final Id attemptId = getAttemptId(startStatus); + + // Wait for the attempt to complete + RestSessionAttempt attempt = null; + for (int i = 0; i < 30; i++) { + attempt = client.getSessionAttempt(attemptId); + if (attempt.getDone()) { + break; + } + Thread.sleep(1000); + } + assertThat(attempt.getSuccess(), is(true)); + + final String logs = getAttemptLogs(client, attemptId); + assertThat(logs, containsString("ruby ruby")); + assertThat(logs, containsString("ruby [\"ruby\", \"-w\"]")); + } + + @Test + public void testRubyErrorMessageAndStacktrace() + throws Exception + { + final Path tempdir = folder.getRoot().toPath().toAbsolutePath(); + final Path projectDir = tempdir.resolve("rb"); + final Path scriptsDir = projectDir.resolve("scripts"); + + // Create new project + final CommandStatus initStatus = main("init", + "-c", config.toString(), + projectDir.toString()); + assertThat(initStatus.code(), is(0)); + Files.createDirectories(scriptsDir); + copyResource("acceptance/rb/stacktrace_ruby.dig", projectDir.resolve("stacktrace_ruby.dig")); + copyResource("acceptance/rb/scripts/stacktrace_ruby.rb", scriptsDir.resolve("stacktrace_ruby.rb")); + + // Push the project + final CommandStatus pushStatus = main("push", + "--project", projectDir.toString(), + "rb", + "-c", config.toString(), + "-e", server.endpoint(), + "-r", "4711"); + assertThat(pushStatus.errUtf8(), pushStatus.code(), is(0)); + + // Start the workflow + final CommandStatus startStatus = main("start", + "-c", config.toString(), + "-e", server.endpoint(), + "rb", "stacktrace_ruby", + "--session", "now"); + assertThat(startStatus.code(), is(0)); + final Id attemptId = getAttemptId(startStatus); + + // Wait for the attempt to complete + RestSessionAttempt attempt = null; + for (int i = 0; i < 30; i++) { + attempt = client.getSessionAttempt(attemptId); + if (attempt.getDone()) { + break; + } + Thread.sleep(1000); + } + + final String logs = getAttemptLogs(client, attemptId); + assertThat(logs, containsString("Task failed with unexpected error: Ruby command failed with code 1: my error message (StacktraceRuby::MyErrorClass)")); + assertThat(logs, containsString(":in `private_run'")); + assertThat(logs, containsString(":in `run'")); + assertThat(logs, containsString(":in `
'")); + assertThat(logs, containsString("ERROR_MESSAGE_BEGIN Ruby command failed with code 1: my error message (StacktraceRuby::MyErrorClass)")); + } +} diff --git a/digdag-tests/src/test/java/acceptance/RescheduleIT.java b/digdag-tests/src/test/java/acceptance/RescheduleIT.java new file mode 100644 index 0000000000..b5e8ca4bad --- /dev/null +++ b/digdag-tests/src/test/java/acceptance/RescheduleIT.java @@ -0,0 +1,134 @@ +package acceptance; + +import io.digdag.client.DigdagClient; +import io.digdag.client.api.Id; +import io.digdag.client.api.RestSchedule; +import org.junit.Before; +import org.junit.Rule; +import org.junit.Test; +import org.junit.rules.TemporaryFolder; +import utils.CommandStatus; +import utils.TemporaryDigdagServer; + +import java.nio.file.Path; +import java.time.format.DateTimeFormatter; +import java.time.OffsetDateTime; + +import static utils.TestUtils.copyResource; +import static utils.TestUtils.main; +import static org.hamcrest.Matchers.is; +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertThat; + +public class RescheduleIT +{ + @Rule + public TemporaryFolder folder = new TemporaryFolder(); + + @Rule + public TemporaryDigdagServer server = TemporaryDigdagServer.of(); + + private Path config; + private Path projectDir; + private DigdagClient client; + private Path outdir; + + @Before + public void setUp() + throws Exception + { + projectDir = folder.getRoot().toPath().resolve("foobar"); + config = folder.newFile().toPath(); + + client = DigdagClient.builder() + .host(server.host()) + .port(server.port()) + .build(); + + outdir = projectDir.resolve("outdir"); + } + + @Test + public void initPushRescheduleScheduleId() + throws Exception + { + // Create new project + { + CommandStatus cmd = main("init", + "-c", config.toString(), + projectDir.toString()); + assertThat(cmd.code(), is(0)); + } + + final String projectName = "reschedule-test"; + copyResource("acceptance/reschedule/reschedule.dig", projectDir.resolve("reschedule.dig")); + + // Push + { + CommandStatus cmd = main("push", + "-c", config.toString(), + "-e", server.endpoint(), + "--project", projectDir.toString(), + projectName); + assertThat(cmd.errUtf8(), cmd.code(), is(0)); + } + + RestSchedule oldSchedule = client.getSchedule(Id.of("1")); + OffsetDateTime skipTo = oldSchedule.getNextScheduleTime().plusDays(1); + + // Reschedule the schedule + { + CommandStatus cmd = main("reschedule", + "-c", config.toString(), + "-e", server.endpoint(), + "--skip-to", skipTo.format(DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss Z")), + "1"); + assertThat(cmd.errUtf8(), cmd.code(), is(0)); + } + + RestSchedule newSchedule = client.getSchedule(Id.of("1")); + assertEquals(newSchedule.getNextScheduleTime(), oldSchedule.getNextScheduleTime().plusDays(1)); + } + + @Test + public void initPushRescheduleWorkflow() + throws Exception + { + // Create new project + { + CommandStatus cmd = main("init", + "-c", config.toString(), + projectDir.toString()); + assertThat(cmd.code(), is(0)); + } + + final String projectName = "reschedule-test"; + copyResource("acceptance/reschedule/reschedule.dig", projectDir.resolve("reschedule.dig")); + + // Push + { + CommandStatus cmd = main("push", + "-c", config.toString(), + "-e", server.endpoint(), + "--project", projectDir.toString(), + projectName); + assertThat(cmd.errUtf8(), cmd.code(), is(0)); + } + + RestSchedule oldSchedule = client.getSchedule(Id.of("1")); + OffsetDateTime skipTo = oldSchedule.getNextScheduleTime().plusDays(1); + + // Reschedule the schedule + { + CommandStatus cmd = main("reschedule", + "-c", config.toString(), + "-e", server.endpoint(), + "--skip-to", skipTo.format(DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss Z")), + projectName, "reschedule"); + assertThat(cmd.errUtf8(), cmd.code(), is(0)); + } + + RestSchedule newSchedule = client.getSchedule(Id.of("1")); + assertEquals(newSchedule.getNextScheduleTime(), oldSchedule.getNextScheduleTime().plusDays(1)); + } +} diff --git a/digdag-tests/src/test/java/acceptance/ServerJmxIT.java b/digdag-tests/src/test/java/acceptance/ServerJmxIT.java index 6932d107db..c95bdb35ee 100644 --- a/digdag-tests/src/test/java/acceptance/ServerJmxIT.java +++ b/digdag-tests/src/test/java/acceptance/ServerJmxIT.java @@ -25,6 +25,7 @@ import static org.hamcrest.Matchers.is; import static org.hamcrest.Matchers.instanceOf; import static org.junit.Assert.assertThat; +import static org.junit.Assert.assertTrue; import static org.junit.Assume.assumeThat; import static utils.TestUtils.expect; @@ -37,7 +38,9 @@ public class ServerJmxIT public TemporaryDigdagServer server = TemporaryDigdagServer.builder() .inProcess(false) .configuration( - "server.jmx.port=0") + "server.jmx.port=0", + "database.leakDetectionThreshold=60000", + "database.maximumPoolSize=3") .build(); private static JMXConnector connectJmx(TemporaryDigdagServer server) @@ -71,6 +74,22 @@ public void verifyJmx() } } + @Test + public void verifyHikariCP() + throws Exception + { + assumeThat(server.isRemoteDatabase(), is(true)); + try (JMXConnector con = connectJmx(server)) { + MBeanServerConnection beans = con.getMBeanServerConnection(); + + Object leakDetectionThreshold = beans.getAttribute(ObjectName.getInstance("com.zaxxer.hikari", "type", "PoolConfig (HikariPool-1)"), "LeakDetectionThreshold"); + assertThat(leakDetectionThreshold, is(60000L)); + + Object numConnection = beans.getAttribute(ObjectName.getInstance("com.zaxxer.hikari", "type", "Pool (HikariPool-1)"), "TotalConnections"); + assertTrue((int)numConnection >= 0); + } + } + @Test public void verifyUncaughtErrorCount() throws Exception diff --git a/digdag-tests/src/test/java/acceptance/ValidateProjectIT.java b/digdag-tests/src/test/java/acceptance/ValidateProjectIT.java new file mode 100644 index 0000000000..5c4d3dedb7 --- /dev/null +++ b/digdag-tests/src/test/java/acceptance/ValidateProjectIT.java @@ -0,0 +1,87 @@ +package acceptance; + +import org.junit.Before; +import org.junit.Rule; +import org.junit.Test; +import org.junit.rules.TemporaryFolder; +import utils.CommandStatus; +import utils.TemporaryDigdagServer; + +import java.nio.file.Path; + +import static org.hamcrest.MatcherAssert.assertThat; +import static org.hamcrest.Matchers.containsString; +import static org.hamcrest.Matchers.is; +import static utils.TestUtils.copyResource; +import static utils.TestUtils.main; + +// +// This file doesn't contain normal case. +// It defined in another test. +// +public class ValidateProjectIT +{ + @Rule + public TemporaryFolder folder = new TemporaryFolder(); + + @Rule + public TemporaryDigdagServer server = TemporaryDigdagServer.builder() + .build(); + + private Path config; + private Path projectDir; + + @Before + public void setUp() + throws Exception + { + projectDir = folder.getRoot().toPath().resolve("foobar"); + config = folder.newFile().toPath(); + } + + @Test + public void uploadInvalidTaskProject() + throws Exception + { + // Create new project + CommandStatus initStatus = main("init", + "-c", config.toString(), + projectDir.toString()); + assertThat(initStatus.code(), is(0)); + + copyResource("acceptance/error_task/invalid_at_group.dig", projectDir.resolve("invalid_at_group.dig")); + + // Push the project + CommandStatus pushStatus = main( + "push", + "--project", projectDir.toString(), + "foobar", + "-c", config.toString(), + "-e", server.endpoint()); + assertThat(pushStatus.code(), is(1)); + assertThat(pushStatus.errUtf8(), containsString("A task can't have more than one operator")); + } + + @Test + public void uploadInvalidScheduleProject() + throws Exception + { + // Create new project + CommandStatus initStatus = main("init", + "-c", config.toString(), + projectDir.toString()); + assertThat(initStatus.code(), is(0)); + + copyResource("acceptance/schedule/invalid_schedule.dig", projectDir.resolve("invalid_schedule.dig")); + + // Push the project + CommandStatus pushStatus = main( + "push", + "--project", projectDir.toString(), + "foobar", + "-c", config.toString(), + "-e", server.endpoint()); + assertThat(pushStatus.code(), is(1)); + assertThat(pushStatus.errUtf8(), containsString("scheduler requires mm:ss format")); + } +} diff --git a/digdag-tests/src/test/java/acceptance/td/EmrIT.java b/digdag-tests/src/test/java/acceptance/td/EmrIT.java index 02d1d085b8..d8fbd15bec 100644 --- a/digdag-tests/src/test/java/acceptance/td/EmrIT.java +++ b/digdag-tests/src/test/java/acceptance/td/EmrIT.java @@ -18,7 +18,7 @@ import com.amazonaws.services.s3.model.ObjectMetadata; import com.amazonaws.services.s3.model.S3Object; import com.amazonaws.services.s3.model.S3ObjectSummary; -import com.google.api.client.repackaged.com.google.common.base.Throwables; +import com.google.common.base.Throwables; import com.google.common.base.Optional; import com.google.common.collect.ImmutableMap; import com.google.common.io.CharStreams; diff --git a/digdag-tests/src/test/java/acceptance/td/GcpUtil.java b/digdag-tests/src/test/java/acceptance/td/GcpUtil.java index af3f78eb5e..571e5e7d78 100644 --- a/digdag-tests/src/test/java/acceptance/td/GcpUtil.java +++ b/digdag-tests/src/test/java/acceptance/td/GcpUtil.java @@ -3,7 +3,7 @@ import com.google.api.client.googleapis.json.GoogleJsonResponseException; import com.google.api.client.http.HttpResponseException; import com.google.api.client.http.HttpStatusCodes; -import com.google.api.client.repackaged.com.google.common.base.Throwables; +import com.google.common.base.Throwables; import com.google.api.services.bigquery.Bigquery; import com.google.api.services.bigquery.model.Dataset; import com.google.api.services.bigquery.model.DatasetList; diff --git a/digdag-tests/src/test/java/utils/TemporaryDigdagServer.java b/digdag-tests/src/test/java/utils/TemporaryDigdagServer.java index 9cb2224ad7..e40558df82 100644 --- a/digdag-tests/src/test/java/utils/TemporaryDigdagServer.java +++ b/digdag-tests/src/test/java/utils/TemporaryDigdagServer.java @@ -186,6 +186,24 @@ private void preparePostgres() adminDataSource = dsp.get(); } + /** + * Get DataSource for Test DB. (Not admin DB) + * @return + */ + public DataSource getTestDBDataSource() + { + if (isRemoteDatabase()) { + return new DataSourceProvider(testDatabaseConfig).get(); + } + else { + return null; + } + } + + public DatabaseConfig getTestDatabaseConfig() { return testDatabaseConfig; } + + + private static class Trampoline { private static final String NAME = ManagementFactory.getRuntimeMXBean().getName(); @@ -254,15 +272,22 @@ private void before() } start(); } - public void start() throws Exception + { + start(false); + } + + public void start(boolean skipSetupDatabase) + throws Exception { started = true; temporaryFolder.create(); - setupDatabase(); + if (!skipSetupDatabase) { + setupDatabase(); + } Path runtimeInfoPath = temporaryFolder.newFolder().toPath().resolve("runtime-info"); configuration.add("server.runtime-info.path = " + runtimeInfoPath.toAbsolutePath().normalize()); @@ -514,7 +539,7 @@ private static boolean isUnixProcess(Process p) return p.getClass().getName().equals("java.lang.UNIXProcess"); } - private void setupDatabase() + public void setupDatabase() throws SQLException { if (testDatabaseConfig == null) { @@ -769,4 +794,5 @@ public String toString() ", port=" + port + '}'; } + } diff --git a/digdag-tests/src/test/java/utils/TestUtils.java b/digdag-tests/src/test/java/utils/TestUtils.java index 2c643cf67a..1d39f368ca 100644 --- a/digdag-tests/src/test/java/utils/TestUtils.java +++ b/digdag-tests/src/test/java/utils/TestUtils.java @@ -32,8 +32,8 @@ import io.netty.handler.codec.http.HttpRequest; import io.netty.handler.codec.http.HttpResponse; import io.netty.handler.codec.http.HttpResponseStatus; -import okhttp3.internal.tls.SslClient; import okhttp3.mockwebserver.MockWebServer; +import okhttp3.tls.HandshakeCertificates; import org.apache.commons.io.FileUtils; import org.hamcrest.BaseMatcher; import org.hamcrest.Description; @@ -51,6 +51,7 @@ import org.subethamail.smtp.RejectException; import org.subethamail.wiser.Wiser; +import javax.net.ssl.SSLSocketFactory; import java.io.ByteArrayInputStream; import java.io.ByteArrayOutputStream; import java.io.IOException; @@ -65,7 +66,6 @@ import java.nio.file.Paths; import java.time.Duration; import java.time.Instant; -import java.time.temporal.ChronoUnit; import java.time.temporal.TemporalAmount; import java.util.ArrayList; import java.util.Arrays; @@ -93,6 +93,7 @@ import static java.nio.charset.StandardCharsets.UTF_8; import static java.nio.file.StandardCopyOption.REPLACE_EXISTING; import static java.util.Arrays.asList; +import static okhttp3.tls.internal.TlsUtil.localhost; import static org.hamcrest.CoreMatchers.containsString; import static org.hamcrest.Matchers.is; import static org.junit.Assert.assertThat; @@ -493,19 +494,19 @@ public static void addResource(Path project, String resource, String workflowNam copyResource(resource, project.resolve(workflowName)); } - public static void runWorkflow(TemporaryFolder folder, String resource, Map params) + public static CommandStatus runWorkflow(TemporaryFolder folder, String resource, Map params) throws IOException { - runWorkflow(folder, resource, params, ImmutableMap.of()); + return runWorkflow(folder, resource, params, ImmutableMap.of()); } - public static void runWorkflow(TemporaryFolder folder, String resource, Map params, Map config) + public static CommandStatus runWorkflow(TemporaryFolder folder, String resource, Map params, Map config) throws IOException { - runWorkflow(folder, resource, params, config, 0); + return runWorkflow(folder, resource, params, config, 0); } - public static void runWorkflow(TemporaryFolder folder, String resource, Map params, Map config, int expectedStatus) + public static CommandStatus runWorkflow(TemporaryFolder folder, String resource, Map params, Map config, int expectedStatus) throws IOException { Path workflow = Paths.get(resource); @@ -526,6 +527,7 @@ public static void runWorkflow(TemporaryFolder folder, String resource, Map requests) diff --git a/digdag-tests/src/test/resources/acceptance/config_eval_engine/invalid1.dig b/digdag-tests/src/test/resources/acceptance/config_eval_engine/invalid1.dig new file mode 100644 index 0000000000..006d5c31f9 --- /dev/null +++ b/digdag-tests/src/test/resources/acceptance/config_eval_engine/invalid1.dig @@ -0,0 +1,7 @@ ++test: + if>: ${td.last_results.cnt => 3} + _do: + echo>: "A,B,C" + _else_do: + fail>: "count is ${td.last_results.cnt}!!!" + diff --git a/digdag-tests/src/test/resources/acceptance/docker/docker_build.dig b/digdag-tests/src/test/resources/acceptance/docker/docker_build.dig new file mode 100644 index 0000000000..9021af0af8 --- /dev/null +++ b/digdag-tests/src/test/resources/acceptance/docker/docker_build.dig @@ -0,0 +1,9 @@ +_export: + docker: + image: alpine:latest + build_options: ["--ulimit", "nofile=65536:65536"] + build: + - ulimit -n > /tmp/ulimit.txt + ++check_build: + sh>: cat /tmp/ulimit.txt diff --git a/digdag-tests/src/test/resources/acceptance/docker/docker_run_options.dig b/digdag-tests/src/test/resources/acceptance/docker/docker_run_options.dig new file mode 100644 index 0000000000..0e5d79ee52 --- /dev/null +++ b/digdag-tests/src/test/resources/acceptance/docker/docker_run_options.dig @@ -0,0 +1,7 @@ +_export: + docker: + image: alpine:latest + run_options: ["--ulimit", "nofile=65536:65536"] + ++check_run_options: + sh>: ulimit -n diff --git a/digdag-tests/src/test/resources/acceptance/echo_params/echo_rb_params.dig b/digdag-tests/src/test/resources/acceptance/echo_params/echo_rb_params.dig new file mode 100644 index 0000000000..70d084e65f --- /dev/null +++ b/digdag-tests/src/test/resources/acceptance/echo_params/echo_rb_params.dig @@ -0,0 +1,6 @@ +_export: + rb: + require: 'scripts/echo_params' + ++foo: + rb>: EchoParams.echo_params diff --git a/digdag-tests/src/test/resources/acceptance/echo_params/scripts/echo_params.rb b/digdag-tests/src/test/resources/acceptance/echo_params/scripts/echo_params.rb new file mode 100644 index 0000000000..0a3e088d83 --- /dev/null +++ b/digdag-tests/src/test/resources/acceptance/echo_params/scripts/echo_params.rb @@ -0,0 +1,8 @@ +class EchoParams + def echo_params + puts 'digdag params' + Digdag.env.params.each do |k,v| + puts "#{k} #{v}" + end + end +end diff --git a/digdag-tests/src/test/resources/acceptance/http_call/child.dig b/digdag-tests/src/test/resources/acceptance/http_call/child.dig new file mode 100644 index 0000000000..556c9d0c69 --- /dev/null +++ b/digdag-tests/src/test/resources/acceptance/http_call/child.dig @@ -0,0 +1,2 @@ ++hello: + sh>: pwd > ${outdir}/${name}.out diff --git a/digdag-tests/src/test/resources/acceptance/http_call/http_call.dig b/digdag-tests/src/test/resources/acceptance/http_call/http_call.dig new file mode 100644 index 0000000000..6e6cd075d7 --- /dev/null +++ b/digdag-tests/src/test/resources/acceptance/http_call/http_call.dig @@ -0,0 +1,2 @@ ++http_call: + http_call>: ${test_uri} diff --git a/digdag-tests/src/test/resources/acceptance/http_call/http_call_post.dig b/digdag-tests/src/test/resources/acceptance/http_call/http_call_post.dig new file mode 100644 index 0000000000..a77b7d3b78 --- /dev/null +++ b/digdag-tests/src/test/resources/acceptance/http_call/http_call_post.dig @@ -0,0 +1,6 @@ ++http_call: + http_call>: ${test_uri} + method: POST + content: + k: v + foo: bar diff --git a/digdag-tests/src/test/resources/acceptance/http_call/http_call_query.dig b/digdag-tests/src/test/resources/acceptance/http_call/http_call_query.dig new file mode 100644 index 0000000000..d9efde7334 --- /dev/null +++ b/digdag-tests/src/test/resources/acceptance/http_call/http_call_query.dig @@ -0,0 +1,5 @@ ++http_call: + http_call>: ${test_uri} + query: + k: v + foo: bar diff --git a/digdag-tests/src/test/resources/acceptance/http_call/http_call_yaml_override.dig b/digdag-tests/src/test/resources/acceptance/http_call/http_call_yaml_override.dig new file mode 100644 index 0000000000..3f7ebc6d87 --- /dev/null +++ b/digdag-tests/src/test/resources/acceptance/http_call/http_call_yaml_override.dig @@ -0,0 +1,3 @@ ++http_call: + http_call>: ${test_uri} + content_type_override: application/x-yaml; charset=utf-8 diff --git a/digdag-tests/src/test/resources/acceptance/py/config_python.dig b/digdag-tests/src/test/resources/acceptance/py/config_python.dig new file mode 100644 index 0000000000..bede81fa97 --- /dev/null +++ b/digdag-tests/src/test/resources/acceptance/py/config_python.dig @@ -0,0 +1,9 @@ +# For tests of python: option + ++python_string_option: + py>: scripts.echo_params.echo_params + python: "python" + ++python_array_option: + py>: scripts.echo_params.echo_params + python: ["python", "-v"] diff --git a/digdag-tests/src/test/resources/acceptance/py/scripts/__init__.py b/digdag-tests/src/test/resources/acceptance/py/scripts/__init__.py new file mode 100644 index 0000000000..e69de29bb2 diff --git a/digdag-tests/src/test/resources/acceptance/py/scripts/stacktrace.py b/digdag-tests/src/test/resources/acceptance/py/scripts/stacktrace.py new file mode 100644 index 0000000000..68e98e01e8 --- /dev/null +++ b/digdag-tests/src/test/resources/acceptance/py/scripts/stacktrace.py @@ -0,0 +1,5 @@ +class MyError(Exception): + pass + +def run(): + raise MyError('my error message') diff --git a/digdag-tests/src/test/resources/acceptance/py/stacktrace_python.dig b/digdag-tests/src/test/resources/acceptance/py/stacktrace_python.dig new file mode 100644 index 0000000000..7acb000543 --- /dev/null +++ b/digdag-tests/src/test/resources/acceptance/py/stacktrace_python.dig @@ -0,0 +1,5 @@ ++stacktrace_python: + py>: scripts.stacktrace.run + +_error: + echo>: ERROR_MESSAGE_BEGIN ${error.message} ERROR_MESSAGE_END diff --git a/digdag-tests/src/test/resources/acceptance/rb/config_ruby.dig b/digdag-tests/src/test/resources/acceptance/rb/config_ruby.dig new file mode 100644 index 0000000000..afa2682660 --- /dev/null +++ b/digdag-tests/src/test/resources/acceptance/rb/config_ruby.dig @@ -0,0 +1,13 @@ +# For tests of ruby: option + +_export: + rb: + require: 'scripts/echo_params' + ++ruby_string_option: + rb>: EchoParams.echo_params + ruby: "ruby" + ++ruby_array_option: + rb>: EchoParams.echo_params + ruby: ["ruby", "-w"] diff --git a/digdag-tests/src/test/resources/acceptance/rb/scripts/stacktrace_ruby.rb b/digdag-tests/src/test/resources/acceptance/rb/scripts/stacktrace_ruby.rb new file mode 100644 index 0000000000..7dc034d3c7 --- /dev/null +++ b/digdag-tests/src/test/resources/acceptance/rb/scripts/stacktrace_ruby.rb @@ -0,0 +1,13 @@ +class StacktraceRuby + class MyErrorClass < StandardError; end + + def run + private_run + end + + private + + def private_run + raise MyErrorClass.new('my error message') + end +end diff --git a/digdag-tests/src/test/resources/acceptance/rb/stacktrace_ruby.dig b/digdag-tests/src/test/resources/acceptance/rb/stacktrace_ruby.dig new file mode 100644 index 0000000000..6bad34d473 --- /dev/null +++ b/digdag-tests/src/test/resources/acceptance/rb/stacktrace_ruby.dig @@ -0,0 +1,6 @@ ++stacktrace_ruby: + rb>: StacktraceRuby.run + require: 'scripts/stacktrace_ruby' + +_error: + echo>: ERROR_MESSAGE_BEGIN ${error.message} ERROR_MESSAGE_END diff --git a/digdag-tests/src/test/resources/acceptance/reschedule/reschedule.dig b/digdag-tests/src/test/resources/acceptance/reschedule/reschedule.dig new file mode 100644 index 0000000000..4723365c1e --- /dev/null +++ b/digdag-tests/src/test/resources/acceptance/reschedule/reschedule.dig @@ -0,0 +1,8 @@ +timezone: +09:00 + +schedule: + daily>: 09:00:00 + ++say_ok: + echo>: ok + diff --git a/digdag-tests/src/test/resources/acceptance/schedule/invalid_schedule.dig b/digdag-tests/src/test/resources/acceptance/schedule/invalid_schedule.dig new file mode 100644 index 0000000000..b076f2140c --- /dev/null +++ b/digdag-tests/src/test/resources/acceptance/schedule/invalid_schedule.dig @@ -0,0 +1,8 @@ +timezone: UTC + +schedule: + hourly>: "10:11:12" # correct format is "MM:SS" + ++foo: + sh>: "touch foo.out" + diff --git a/digdag-ui/.bootstraprc b/digdag-ui/.bootstraprc index 4c566264c3..0abfefdd18 100644 --- a/digdag-ui/.bootstraprc +++ b/digdag-ui/.bootstraprc @@ -1,6 +1,6 @@ loglevel: warn -bootstrapVersion: 3 +bootstrapVersion: 4 styleLoaders: - css-loader @@ -13,63 +13,46 @@ styles: mixins: true # Reset and dependencies - normalize: true print: true - glyphicons: true # Core CSS - scaffolding: true - type: true + buttons: true code: true + forms: true grid: true + images: true + reboot: true tables: true - forms: true - buttons: true + type: true # Components - component-animations: true - dropdowns: true - button-groups: true - input-groups: true - navs: true - navbar: true - breadcrumbs: true - pagination: true - pager: true - labels: true - badges: true + alert: true + badge: true + breadcrumb: true + button-group: true + card: true + close: true + custom-forms: true + dropdown: true + input-group: true jumbotron: true - thumbnails: true - alerts: true - progress-bars: true - media: true list-group: true - panels: true - wells: true - responsive-embed: true - close: true + media: true + nav: true + navbar: true + pagination: true + progress: true + transitions: true # Components w/ JavaScript - modals: true - tooltip: true - popovers: true carousel: true + modal: true + popover: true + tooltip: true # Utility classes utilities: true - responsive-utilities: true + spinners: true ### Bootstrap scripts -scripts: - transition: true - alert: true - button: true - carousel: true - collapse: true - dropdown: true - modal: true - tooltip: true - popover: true - scrollspy: true - tab: true - affix: true +scripts: true diff --git a/digdag-ui/console.jsx b/digdag-ui/console.jsx index 338dff05c7..a8e7d7d358 100644 --- a/digdag-ui/console.jsx +++ b/digdag-ui/console.jsx @@ -9,7 +9,15 @@ import 'bootstrap/dist/js/bootstrap' import _ from 'lodash' import React from 'react' -import { Router, Link, Route, browserHistory, withRouter } from 'react-router' +import PropTypes from 'prop-types' +import { + BrowserRouter as Router, + Route, + Link, + Switch, + withRouter, + matchPath +} from 'react-router-dom' import Measure from 'react-measure' import Tar from 'tar-js' import moment from 'moment' @@ -22,6 +30,14 @@ import uuidv4 from 'uuid/v4' import jQuery from 'jquery' import ReactInterval from 'react-interval' import { Buffer } from 'buffer/' +import { FontAwesomeIcon } from '@fortawesome/react-fontawesome' +import { + faSignOutAlt, + faCheckCircle, + faExclamationCircle, + faPlayCircle, + faSyncAlt +} from '@fortawesome/free-solid-svg-icons' // noinspection ES6UnusedImports import { TD_LOAD_VALUE_TOKEN, TD_RUN_VALUE_TOKEN } from './ace-digdag' @@ -119,7 +135,8 @@ class CodeViewer extends React.Component { showGutter: false, showPrintMargin: false, tabSize: 2, - useSoftTabs: true + useSoftTabs: true, + maxLines: Infinity } } @@ -157,6 +174,7 @@ class CodeViewer extends React.Component { require('./ace-digdag') this._editor = Ace.edit(this.editor) this._editor.setOptions(this.props.editorOptions) + this._editor.$blockScrolling = Infinity this._editor.on('click', this.editorClick.bind(this)) this._updateEditor(this.props) } @@ -247,9 +265,9 @@ class CacheLoader extends React.Component { const { children } = this.props if (!hasCache) { return ( -
- - Loading ... +
+ + Loading...
) } @@ -272,7 +290,7 @@ class ProjectListView extends React.Component { ) return (
- +
@@ -306,7 +324,7 @@ class WorkflowListView extends React.Component { ) return (
-
Name
+
@@ -326,17 +344,17 @@ class WorkflowListView extends React.Component { const AttemptStatusView = ({ attempt }) => { if (attempt.done) { if (attempt.success) { - return Success + return Success } else if (attempt.cancelRequested) { - return Canceled + return Canceled } else { - return Failure + return Failure } } else { if (attempt.cancelRequested) { - return Canceling + return Canceling } else { - return Pending + return Pending } } } @@ -366,11 +384,11 @@ const SessionStatusView = ({ session }:{session: Session}) => { const attempt = session.lastAttempt return attempt ? - : Pending + : Pending } SessionStatusView.propTypes = { - session: React.PropTypes.object.isRequired + session: PropTypes.object.isRequired } class SessionRevisionView extends React.Component { @@ -438,10 +456,10 @@ class AttemptListView extends React.Component { }) return ( -
+

Attempts

-
Name
+
@@ -487,7 +505,7 @@ class SessionListView extends React.Component { return (
-
ID
+
@@ -574,27 +592,27 @@ class ScheduleListView extends React.Component { }) const statusButton = isPaused ? ( ) : ( ) return ( -
-

+
+

Scheduling - {hasSchedule ? statusButton : ''}

+ {hasSchedule ? statusButton : ''}
-

ID
+
@@ -665,9 +683,9 @@ class StatusFilter extends React.Component { case StatusFilter.Status.SUCCESS: return sessions.filter(s => s.lastAttempt.done && s.lastAttempt.success) case StatusFilter.Status.FAILURE: - return sessions.filter(s => s.lastAttempt.done && !s.lastAttempt.success) + return sessions.filter(s => s.lastAttempt.done && !s.lastAttempt.success && !s.lastAttempt.cancelRequested) case StatusFilter.Status.PENDING: - return sessions.filter(s => !s.lastAttempt.done) + return sessions.filter(s => !s.lastAttempt.done && !s.lastAttempt.cancelRequested) case StatusFilter.Status.CANCELED: return sessions.filter(s => s.lastAttempt.cancelRequested && s.lastAttempt.done) case StatusFilter.Status.CANCELING: @@ -686,9 +704,9 @@ class StatusFilter extends React.Component { return (
-
- - this.setState({ selectedStatus: e.target.value })}> {StatusFilter.Status.allStatus().map(s => )} @@ -780,9 +798,9 @@ class ProjectView extends React.Component { const project = this.state.project return (
-
+

Project

-
ID
+
@@ -807,12 +825,19 @@ class ProjectView extends React.Component {
ID
-
-

Workflows

+
+

Workflows

+
+ + Edit workflows + +
-
Edit workflows
-
+

Sessions

@@ -885,16 +910,15 @@ class WorkflowView extends React.Component { const wf = this.props.workflow return (
-
-

Workflow - -

- + +
@@ -916,29 +940,35 @@ class WorkflowView extends React.Component {
ID
-
-

Definition

-
-            
-              { ({ width }) =>
-                
-              }
-            
-          
+
+

Definition

+ +
+
+
+                
+                  
+                    { ({ width }) =>
+                      
+                    }
+                  
+                
+              
+
+
-
Edit
-
+

Sessions

-
+

Files

@@ -1043,18 +1073,24 @@ function fileString (file:string, projectArchive:?ProjectArchive) { const FileView = ({ file, fileType, contents }:{file: string, fileType: string, contents: string}) =>

{file}

-
-      
-        { ({ width }) =>
-          
-        }
-      
-    
+
+
+
+          
+            
+              { ({ width }) =>
+                
+              }
+            
+          
+        
+
+
const WorkflowFilesView = ({ workflow, projectArchive }:{workflow: Workflow, projectArchive: ?ProjectArchive}) => @@ -1114,19 +1150,17 @@ class AttemptView extends React.Component { } return ( -
-

- Attempt - {canKill && +
+

Attempt

+ {canKill && - } -

- + } +
@@ -1160,6 +1194,10 @@ class AttemptView extends React.Component { + + + +
IDStatus
Params
this.fetch()} /> @@ -1196,28 +1234,27 @@ class SessionView extends React.Component { const canRetryAll = attemptCanRetryAll(lastAttempt) const canResume = attemptCanResume(lastAttempt) return ( -
-

+
+

Session - {canRetryAll && -

+ {canRetryAll && + - } - {canResume && - + } + {canResume && + - } -

- + + } +
@@ -1255,6 +1292,10 @@ class SessionView extends React.Component { + + + +
IDLast Attempt Duration:
Last Attempt Params:
@@ -1351,7 +1392,7 @@ const ParamsView = ({ params }:{params: Object}) => const TaskState = ({ state, cancelRequested }:{state: string, cancelRequested: boolean}) => { if (cancelRequested && ['ready', 'retry_waiting', 'group_retry_waiting', 'planned'].indexOf(state) >= 0) { // These state won't progress once cancelRequested is set. Planned tasks won't generate tasks. - return Canceling + return Canceling } switch (state) { @@ -1359,36 +1400,36 @@ const TaskState = ({ state, cancelRequested }:{state: string, cancelRequested: b case 'blocked': if (cancelRequested) { // Blocked tasks won't start once cancelRequested is set - return Canceled + return Canceled } else { - return Blocked + return Blocked } case 'ready': - return Ready + return Ready case 'retry_waiting': - return Retry Waiting + return Retry Waiting case 'group_retry_waiting': - return Group Retry Waiting + return Group Retry Waiting case 'planned': - return Planned + return Planned // Running case 'running': - return Running + return Running // Error case 'group_error': - return Group Error + return Group Error case 'error': - return Error + return Error // Warning case 'canceled': - return Canceled + return Canceled // Success case 'success': - return Success + return Success default: return {_.capitalize(state)} @@ -1468,7 +1509,7 @@ class TaskListView extends React.Component { render () { return (
- +
@@ -1563,15 +1604,15 @@ class TaskTimelineRow extends React.Component { // Error case 'group_error': case 'error': - return 'progress-bar-danger' + return 'bg-danger' // Warning case 'canceled': - return 'progress-bar-warning' + return 'bg-warning' // Success case 'success': - return 'progress-bar-success' + return 'bg-success' default: return '' @@ -1629,8 +1670,8 @@ class TaskTimelineRow extends React.Component { return ( -
ID
{taskName} -
+
+
{ this.progressBar = em }} data-toggle='tooltip' data-placement='bottom' title={tooltip} className={`progress-bar ${this.progressBarClasses()}`} role='progressbar' style={style}>{duration}
@@ -1646,7 +1687,7 @@ const TaskTimelineView = ({ tasks, startTime, endTime }:{ endTime: ?Object; }) =>
- +
@@ -1704,7 +1745,7 @@ class AttemptTasksView extends React.Component { render () { const { done } = this.state return ( -
+

Tasks

this.fetch()} /> @@ -1792,7 +1833,7 @@ class AttemptTimelineView extends React.Component { render () { const { done } = this.state return ( -
+

Timeline

this.fetch()} /> @@ -1847,8 +1888,17 @@ class LogFileView extends React.Component { return (

{this.props.file.taskName}

-
{pako.inflate(this.state.data, { to: 'string' })}
+ className='log-view'>{this.props.file.taskName} + +
+
+
+                
+                  {pako.inflate(this.state.data, { to: 'string' })}
+                
+              
+
+
) } else { @@ -1919,7 +1969,7 @@ class AttemptLogsView extends React.Component { render () { const { done } = this.state return ( -
+

Logs

{this.logFiles()} this.fetch()} /> @@ -1947,8 +1997,10 @@ class VersionView extends React.Component { } class Navbar extends React.Component { - static contextTypes = { - router: React.PropTypes.object + static propTypes = { + match: PropTypes.object.isRequired, + location: PropTypes.object.isRequired, + history: PropTypes.object.isRequired } logout (e) { @@ -1980,36 +2032,33 @@ class Navbar extends React.Component { } isActiveClass (path) { - const { router } = this.context - return router.isActive(path) ? 'active' : '' + const { location } = this.props + const match = matchPath(location.pathname, { + path: path, + exact: true + }) + return match ? 'active' : '' } render () { return ( -
Task
+
@@ -2395,26 +2453,26 @@ class ProjectEditor extends React.Component { } else { title = 'New Project' header = ( -
ID
+
- + - +
Name
Revision
) } return ( -
+

{title}

{header} - + { this._editor = value }} />
) @@ -2461,15 +2519,15 @@ const NewProjectPage = (props:{}) => const EditProjectPage = (props:{params: {projectId: string}}) =>
- +
-const AttemptPage = ({ params }:{params: {attemptId: string}}) => +const AttemptPage = ({ match }:{params: {attemptId: string}}) =>
- - - - + + + +
class SessionPage extends React.Component { @@ -2511,12 +2569,12 @@ class SessionPage extends React.Component { } fetch () { - model().fetchSession(this.props.params.sessionId).then(session => { + model().fetchSession(this.props.match.params.sessionId).then(session => { if (!this.ignoreLastFetch) { this.setState({ session }) } }) - model().fetchSessionAttempts(this.props.params.sessionId).then(({ attempts }) => { + model().fetchSessionAttempts(this.props.match.params.sessionId).then(({ attempts }) => { if (!this.ignoreLastFetch) { this.setState({ attempts }) } @@ -2644,7 +2702,7 @@ class LoginPage extends React.Component { }) return ( -
+

{DIGDAG_CONFIG.auth.title}

{authItems} @@ -2682,12 +2740,8 @@ class WorkflowsView extends React.Component { } class NotFoundPage extends React.Component { - props:{ - router: Object; - }; - componentDidMount () { - this.props.router.replace('/') + this.props.history.replace('/') } render () { @@ -2722,7 +2776,7 @@ class ParserTest extends React.Component { } render () { return ( -
+
) @@ -2731,10 +2785,13 @@ class ParserTest extends React.Component { class AppWrapper extends React.Component { render () { + const NavbarWithRouter = withRouter(Navbar) return ( -
- - {this.props.children} +
+ +
+ {this.props.children} +
) } @@ -2774,28 +2831,30 @@ export class CodeViewerTest extends React.Component { class ConsolePage extends React.Component { render () { return ( -
- - - - - - - - - - - - - {isDevelopmentEnv && - - - - - } - - - +
+ + + + + + + + + + + + + + {isDevelopmentEnv && + + + + + } + + + +
) diff --git a/digdag-ui/package-lock.json b/digdag-ui/package-lock.json index 6c6ea8fb28..e3b7a6df3c 100644 --- a/digdag-ui/package-lock.json +++ b/digdag-ui/package-lock.json @@ -10,7 +10,7 @@ "integrity": "sha512-OfC2uemaknXr87bdLUkWog7nYuliM9Ij5HUcajsVcMCpQrcLmtxRbVFTIqmcSkSeYRBFBRxs2FiUqFJDLdiebA==", "dev": true, "requires": { - "@babel/highlight": "7.0.0" + "@babel/highlight": "^7.0.0" } }, "@babel/core": { @@ -19,20 +19,20 @@ "integrity": "sha512-59vB0RWt09cAct5EIe58+NzGP4TFSD3Bz//2/ELy3ZeTeKF6VTD1AXlH8BGGbCX0PuobZBsIzO7IAI9PH67eKw==", "dev": true, "requires": { - "@babel/code-frame": "7.0.0", - "@babel/generator": "7.2.2", - "@babel/helpers": "7.2.0", - "@babel/parser": "7.2.3", - "@babel/template": "7.2.2", - "@babel/traverse": "7.2.3", - "@babel/types": "7.2.2", - "convert-source-map": "1.5.1", - "debug": "4.1.1", - "json5": "2.1.0", - "lodash": "4.17.11", - "resolve": "1.5.0", - "semver": "5.5.0", - "source-map": "0.5.7" + "@babel/code-frame": "^7.0.0", + "@babel/generator": "^7.2.2", + "@babel/helpers": "^7.2.0", + "@babel/parser": "^7.2.2", + "@babel/template": "^7.2.2", + "@babel/traverse": "^7.2.2", + "@babel/types": "^7.2.2", + "convert-source-map": "^1.1.0", + "debug": "^4.1.0", + "json5": "^2.1.0", + "lodash": "^4.17.10", + "resolve": "^1.3.2", + "semver": "^5.4.1", + "source-map": "^0.5.0" }, "dependencies": { "debug": { @@ -41,7 +41,7 @@ "integrity": "sha512-pYAIzeRo8J6KPEaJ0VWOh5Pzkbw/RetuzehGM7QRRX5he4fPHx2rdKMB256ehJCkX+XRQm16eZLqLNS8RSZXZw==", "dev": true, "requires": { - "ms": "2.1.1" + "ms": "^2.1.1" } }, "json5": { @@ -50,7 +50,7 @@ "integrity": "sha512-8Mh9h6xViijj36g7Dxi+Y4S6hNGV96vcJZr/SrlHh1LR/pEn/8j/+qIBbs44YKl69Lrfctp4QD+AdWLTMqEZAQ==", "dev": true, "requires": { - "minimist": "1.2.0" + "minimist": "^1.2.0" } }, "minimist": { @@ -73,11 +73,11 @@ "integrity": "sha512-I4o675J/iS8k+P38dvJ3IBGqObLXyQLTxtrR4u9cSUJOURvafeEWb/pFMOTwtNrmq73mJzyF6ueTbO1BtN0Zeg==", "dev": true, "requires": { - "@babel/types": "7.2.2", - "jsesc": "2.5.2", - "lodash": "4.17.11", - "source-map": "0.5.7", - "trim-right": "1.0.1" + "@babel/types": "^7.2.2", + "jsesc": "^2.5.1", + "lodash": "^4.17.10", + "source-map": "^0.5.0", + "trim-right": "^1.0.1" }, "dependencies": { "jsesc": { @@ -94,7 +94,7 @@ "integrity": "sha512-3UYcJUj9kvSLbLbUIfQTqzcy5VX7GRZ/CCDrnOaZorFFM01aXp1+GJwuFGV4NDDoAS+mOUyHcO6UD/RfqOks3Q==", "dev": true, "requires": { - "@babel/types": "7.2.2" + "@babel/types": "^7.0.0" } }, "@babel/helper-builder-binary-assignment-operator-visitor": { @@ -103,8 +103,8 @@ "integrity": "sha512-qNSR4jrmJ8M1VMM9tibvyRAHXQs2PmaksQF7c1CGJNipfe3D8p+wgNwgso/P2A2r2mdgBWAXljNWR0QRZAMW8w==", "dev": true, "requires": { - "@babel/helper-explode-assignable-expression": "7.1.0", - "@babel/types": "7.2.2" + "@babel/helper-explode-assignable-expression": "^7.1.0", + "@babel/types": "^7.0.0" } }, "@babel/helper-builder-react-jsx": { @@ -113,8 +113,8 @@ "integrity": "sha512-ebJ2JM6NAKW0fQEqN8hOLxK84RbRz9OkUhGS/Xd5u56ejMfVbayJ4+LykERZCOUM6faa6Fp3SZNX3fcT16MKHw==", "dev": true, "requires": { - "@babel/types": "7.2.2", - "esutils": "2.0.2" + "@babel/types": "^7.0.0", + "esutils": "^2.0.0" } }, "@babel/helper-call-delegate": { @@ -123,9 +123,9 @@ "integrity": "sha512-YEtYZrw3GUK6emQHKthltKNZwszBcHK58Ygcis+gVUrF4/FmTVr5CCqQNSfmvg2y+YDEANyYoaLz/SHsnusCwQ==", "dev": true, "requires": { - "@babel/helper-hoist-variables": "7.0.0", - "@babel/traverse": "7.2.3", - "@babel/types": "7.2.2" + "@babel/helper-hoist-variables": "^7.0.0", + "@babel/traverse": "^7.1.0", + "@babel/types": "^7.0.0" } }, "@babel/helper-create-class-features-plugin": { @@ -134,11 +134,11 @@ "integrity": "sha512-xO/3Gn+2C7/eOUeb0VRnSP1+yvWHNxlpAot1eMhtoKDCN7POsyQP5excuT5UsV5daHxMWBeIIOeI5cmB8vMRgQ==", "dev": true, "requires": { - "@babel/helper-function-name": "7.1.0", - "@babel/helper-member-expression-to-functions": "7.0.0", - "@babel/helper-optimise-call-expression": "7.0.0", - "@babel/helper-plugin-utils": "7.0.0", - "@babel/helper-replace-supers": "7.2.3" + "@babel/helper-function-name": "^7.1.0", + "@babel/helper-member-expression-to-functions": "^7.0.0", + "@babel/helper-optimise-call-expression": "^7.0.0", + "@babel/helper-plugin-utils": "^7.0.0", + "@babel/helper-replace-supers": "^7.2.3" } }, "@babel/helper-define-map": { @@ -147,9 +147,9 @@ "integrity": "sha512-yPPcW8dc3gZLN+U1mhYV91QU3n5uTbx7DUdf8NnPbjS0RMwBuHi9Xt2MUgppmNz7CJxTBWsGczTiEp1CSOTPRg==", "dev": true, "requires": { - "@babel/helper-function-name": "7.1.0", - "@babel/types": "7.2.2", - "lodash": "4.17.11" + "@babel/helper-function-name": "^7.1.0", + "@babel/types": "^7.0.0", + "lodash": "^4.17.10" } }, "@babel/helper-explode-assignable-expression": { @@ -158,8 +158,8 @@ "integrity": "sha512-NRQpfHrJ1msCHtKjbzs9YcMmJZOg6mQMmGRB+hbamEdG5PNpaSm95275VD92DvJKuyl0s2sFiDmMZ+EnnvufqA==", "dev": true, "requires": { - "@babel/traverse": "7.2.3", - "@babel/types": "7.2.2" + "@babel/traverse": "^7.1.0", + "@babel/types": "^7.0.0" } }, "@babel/helper-function-name": { @@ -168,9 +168,9 @@ "integrity": "sha512-A95XEoCpb3TO+KZzJ4S/5uW5fNe26DjBGqf1o9ucyLyCmi1dXq/B3c8iaWTfBk3VvetUxl16e8tIrd5teOCfGw==", "dev": true, "requires": { - "@babel/helper-get-function-arity": "7.0.0", - "@babel/template": "7.2.2", - "@babel/types": "7.2.2" + "@babel/helper-get-function-arity": "^7.0.0", + "@babel/template": "^7.1.0", + "@babel/types": "^7.0.0" } }, "@babel/helper-get-function-arity": { @@ -179,7 +179,7 @@ "integrity": "sha512-r2DbJeg4svYvt3HOS74U4eWKsUAMRH01Z1ds1zx8KNTPtpTL5JAsdFv8BNyOpVqdFhHkkRDIg5B4AsxmkjAlmQ==", "dev": true, "requires": { - "@babel/types": "7.2.2" + "@babel/types": "^7.0.0" } }, "@babel/helper-hoist-variables": { @@ -188,7 +188,7 @@ "integrity": "sha512-Ggv5sldXUeSKsuzLkddtyhyHe2YantsxWKNi7A+7LeD12ExRDWTRk29JCXpaHPAbMaIPZSil7n+lq78WY2VY7w==", "dev": true, "requires": { - "@babel/types": "7.2.2" + "@babel/types": "^7.0.0" } }, "@babel/helper-member-expression-to-functions": { @@ -197,7 +197,7 @@ "integrity": "sha512-avo+lm/QmZlv27Zsi0xEor2fKcqWG56D5ae9dzklpIaY7cQMK5N8VSpaNVPPagiqmy7LrEjK1IWdGMOqPu5csg==", "dev": true, "requires": { - "@babel/types": "7.2.2" + "@babel/types": "^7.0.0" } }, "@babel/helper-module-imports": { @@ -206,7 +206,7 @@ "integrity": "sha512-aP/hlLq01DWNEiDg4Jn23i+CXxW/owM4WpDLFUbpjxe4NS3BhLVZQ5i7E0ZrxuQ/vwekIeciyamgB1UIYxxM6A==", "dev": true, "requires": { - "@babel/types": "7.2.2" + "@babel/types": "^7.0.0" } }, "@babel/helper-module-transforms": { @@ -215,12 +215,12 @@ "integrity": "sha512-YRD7I6Wsv+IHuTPkAmAS4HhY0dkPobgLftHp0cRGZSdrRvmZY8rFvae/GVu3bD00qscuvK3WPHB3YdNpBXUqrA==", "dev": true, "requires": { - "@babel/helper-module-imports": "7.0.0", - "@babel/helper-simple-access": "7.1.0", - "@babel/helper-split-export-declaration": "7.0.0", - "@babel/template": "7.2.2", - "@babel/types": "7.2.2", - "lodash": "4.17.11" + "@babel/helper-module-imports": "^7.0.0", + "@babel/helper-simple-access": "^7.1.0", + "@babel/helper-split-export-declaration": "^7.0.0", + "@babel/template": "^7.2.2", + "@babel/types": "^7.2.2", + "lodash": "^4.17.10" } }, "@babel/helper-optimise-call-expression": { @@ -229,7 +229,7 @@ "integrity": "sha512-u8nd9NQePYNQV8iPWu/pLLYBqZBa4ZaY1YWRFMuxrid94wKI1QNt67NEZ7GAe5Kc/0LLScbim05xZFWkAdrj9g==", "dev": true, "requires": { - "@babel/types": "7.2.2" + "@babel/types": "^7.0.0" } }, "@babel/helper-plugin-utils": { @@ -244,7 +244,7 @@ "integrity": "sha512-TR0/N0NDCcUIUEbqV6dCO+LptmmSQFQ7q70lfcEB4URsjD0E1HzicrwUH+ap6BAQ2jhCX9Q4UqZy4wilujWlkg==", "dev": true, "requires": { - "lodash": "4.17.11" + "lodash": "^4.17.10" } }, "@babel/helper-remap-async-to-generator": { @@ -253,11 +253,11 @@ "integrity": "sha512-3fOK0L+Fdlg8S5al8u/hWE6vhufGSn0bN09xm2LXMy//REAF8kDCrYoOBKYmA8m5Nom+sV9LyLCwrFynA8/slg==", "dev": true, "requires": { - "@babel/helper-annotate-as-pure": "7.0.0", - "@babel/helper-wrap-function": "7.2.0", - "@babel/template": "7.2.2", - "@babel/traverse": "7.2.3", - "@babel/types": "7.2.2" + "@babel/helper-annotate-as-pure": "^7.0.0", + "@babel/helper-wrap-function": "^7.1.0", + "@babel/template": "^7.1.0", + "@babel/traverse": "^7.1.0", + "@babel/types": "^7.0.0" } }, "@babel/helper-replace-supers": { @@ -266,10 +266,10 @@ "integrity": "sha512-GyieIznGUfPXPWu0yLS6U55Mz67AZD9cUk0BfirOWlPrXlBcan9Gz+vHGz+cPfuoweZSnPzPIm67VtQM0OWZbA==", "dev": true, "requires": { - "@babel/helper-member-expression-to-functions": "7.0.0", - "@babel/helper-optimise-call-expression": "7.0.0", - "@babel/traverse": "7.2.3", - "@babel/types": "7.2.2" + "@babel/helper-member-expression-to-functions": "^7.0.0", + "@babel/helper-optimise-call-expression": "^7.0.0", + "@babel/traverse": "^7.2.3", + "@babel/types": "^7.0.0" } }, "@babel/helper-simple-access": { @@ -278,8 +278,8 @@ "integrity": "sha512-Vk+78hNjRbsiu49zAPALxTb+JUQCz1aolpd8osOF16BGnLtseD21nbHgLPGUwrXEurZgiCOUmvs3ExTu4F5x6w==", "dev": true, "requires": { - "@babel/template": "7.2.2", - "@babel/types": "7.2.2" + "@babel/template": "^7.1.0", + "@babel/types": "^7.0.0" } }, "@babel/helper-split-export-declaration": { @@ -288,7 +288,7 @@ "integrity": "sha512-MXkOJqva62dfC0w85mEf/LucPPS/1+04nmmRMPEBUB++hiiThQ2zPtX/mEWQ3mtzCEjIJvPY8nuwxXtQeQwUag==", "dev": true, "requires": { - "@babel/types": "7.2.2" + "@babel/types": "^7.0.0" } }, "@babel/helper-wrap-function": { @@ -297,10 +297,10 @@ "integrity": "sha512-o9fP1BZLLSrYlxYEYyl2aS+Flun5gtjTIG8iln+XuEzQTs0PLagAGSXUcqruJwD5fM48jzIEggCKpIfWTcR7pQ==", "dev": true, "requires": { - "@babel/helper-function-name": "7.1.0", - "@babel/template": "7.2.2", - "@babel/traverse": "7.2.3", - "@babel/types": "7.2.2" + "@babel/helper-function-name": "^7.1.0", + "@babel/template": "^7.1.0", + "@babel/traverse": "^7.1.0", + "@babel/types": "^7.2.0" } }, "@babel/helpers": { @@ -309,9 +309,9 @@ "integrity": "sha512-Fr07N+ea0dMcMN8nFpuK6dUIT7/ivt9yKQdEEnjVS83tG2pHwPi03gYmk/tyuwONnZ+sY+GFFPlWGgCtW1hF9A==", "dev": true, "requires": { - "@babel/template": "7.2.2", - "@babel/traverse": "7.2.3", - "@babel/types": "7.2.2" + "@babel/template": "^7.1.2", + "@babel/traverse": "^7.1.5", + "@babel/types": "^7.2.0" } }, "@babel/highlight": { @@ -320,9 +320,9 @@ "integrity": "sha512-UFMC4ZeFC48Tpvj7C8UgLvtkaUuovQX+5xNWrsIoMG8o2z+XFKjKaN9iVmS84dPwVN00W4wPmqvYoZF3EGAsfw==", "dev": true, "requires": { - "chalk": "2.4.2", - "esutils": "2.0.2", - "js-tokens": "4.0.0" + "chalk": "^2.0.0", + "esutils": "^2.0.2", + "js-tokens": "^4.0.0" }, "dependencies": { "ansi-styles": { @@ -331,7 +331,7 @@ "integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==", "dev": true, "requires": { - "color-convert": "1.9.1" + "color-convert": "^1.9.0" } }, "chalk": { @@ -340,9 +340,9 @@ "integrity": "sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==", "dev": true, "requires": { - "ansi-styles": "3.2.1", - "escape-string-regexp": "1.0.5", - "supports-color": "5.5.0" + "ansi-styles": "^3.2.1", + "escape-string-regexp": "^1.0.5", + "supports-color": "^5.3.0" } }, "js-tokens": { @@ -357,7 +357,7 @@ "integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==", "dev": true, "requires": { - "has-flag": "3.0.0" + "has-flag": "^3.0.0" } } } @@ -374,9 +374,9 @@ "integrity": "sha512-+Dfo/SCQqrwx48ptLVGLdE39YtWRuKc/Y9I5Fy0P1DDBB9lsAHpjcEJQt+4IifuSOSTLBKJObJqMvaO1pIE8LQ==", "dev": true, "requires": { - "@babel/helper-plugin-utils": "7.0.0", - "@babel/helper-remap-async-to-generator": "7.1.0", - "@babel/plugin-syntax-async-generators": "7.2.0" + "@babel/helper-plugin-utils": "^7.0.0", + "@babel/helper-remap-async-to-generator": "^7.1.0", + "@babel/plugin-syntax-async-generators": "^7.2.0" } }, "@babel/plugin-proposal-class-properties": { @@ -385,8 +385,8 @@ "integrity": "sha512-FVuQngLoN2iDrpW7LmhPZ2sO4DJxf35FOcwidwB9Ru9tMvI5URthnkVHuG14IStV+TzkMTyLMoOUlSTtrdVwqw==", "dev": true, "requires": { - "@babel/helper-create-class-features-plugin": "7.2.3", - "@babel/helper-plugin-utils": "7.0.0" + "@babel/helper-create-class-features-plugin": "^7.2.3", + "@babel/helper-plugin-utils": "^7.0.0" } }, "@babel/plugin-proposal-decorators": { @@ -395,9 +395,9 @@ "integrity": "sha512-jhCFm7ftmue02EWIYqbhzP0iConEPsgVQeDriOs/Qc2lgr6MDtHTTrv3hE2GOOQDFjQ9tjP7nWQq0ad0JhIsQg==", "dev": true, "requires": { - "@babel/helper-create-class-features-plugin": "7.2.3", - "@babel/helper-plugin-utils": "7.0.0", - "@babel/plugin-syntax-decorators": "7.2.0" + "@babel/helper-create-class-features-plugin": "^7.2.3", + "@babel/helper-plugin-utils": "^7.0.0", + "@babel/plugin-syntax-decorators": "^7.2.0" } }, "@babel/plugin-proposal-do-expressions": { @@ -406,8 +406,8 @@ "integrity": "sha512-2bWN48zQHf/W5T8XvemGQJSi8hzhIo7y4kv/RiA08UcMLQ73lkTknhlaFGf1HjCJzG8FGopgsq6pSe1C+10fPg==", "dev": true, "requires": { - "@babel/helper-plugin-utils": "7.0.0", - "@babel/plugin-syntax-do-expressions": "7.2.0" + "@babel/helper-plugin-utils": "^7.0.0", + "@babel/plugin-syntax-do-expressions": "^7.2.0" } }, "@babel/plugin-proposal-export-default-from": { @@ -416,8 +416,8 @@ "integrity": "sha512-NVfNe7F6nsasG1FnvcFxh2FN0l04ZNe75qTOAVOILWPam0tw9a63RtT/Dab8dPjedZa4fTQaQ83yMMywF9OSug==", "dev": true, "requires": { - "@babel/helper-plugin-utils": "7.0.0", - "@babel/plugin-syntax-export-default-from": "7.2.0" + "@babel/helper-plugin-utils": "^7.0.0", + "@babel/plugin-syntax-export-default-from": "^7.2.0" } }, "@babel/plugin-proposal-export-namespace-from": { @@ -426,8 +426,8 @@ "integrity": "sha512-DZUxbHYxQ5fUFIkMEnh75ogEdBLPfL+mQUqrO2hNY2LGm+tqFnxE924+mhAcCOh/8za8AaZsWHbq6bBoS3TAzA==", "dev": true, "requires": { - "@babel/helper-plugin-utils": "7.0.0", - "@babel/plugin-syntax-export-namespace-from": "7.2.0" + "@babel/helper-plugin-utils": "^7.0.0", + "@babel/plugin-syntax-export-namespace-from": "^7.2.0" } }, "@babel/plugin-proposal-function-bind": { @@ -436,8 +436,8 @@ "integrity": "sha512-qOFJ/eX1Is78sywwTxDcsntLOdb5ZlHVVqUz5xznq8ldAfOVIyZzp1JE2rzHnaksZIhrqMrwIpQL/qcEprnVbw==", "dev": true, "requires": { - "@babel/helper-plugin-utils": "7.0.0", - "@babel/plugin-syntax-function-bind": "7.2.0" + "@babel/helper-plugin-utils": "^7.0.0", + "@babel/plugin-syntax-function-bind": "^7.2.0" } }, "@babel/plugin-proposal-function-sent": { @@ -446,9 +446,9 @@ "integrity": "sha512-qQBDKRSCu1wGJi3jbngs18vrujVQA4F+OkSuIQYRhE6y19jcPzeEIGOc683mCQXDUR3BQCz8JyCupIwv+IRFmA==", "dev": true, "requires": { - "@babel/helper-plugin-utils": "7.0.0", - "@babel/helper-wrap-function": "7.2.0", - "@babel/plugin-syntax-function-sent": "7.2.0" + "@babel/helper-plugin-utils": "^7.0.0", + "@babel/helper-wrap-function": "^7.2.0", + "@babel/plugin-syntax-function-sent": "^7.2.0" } }, "@babel/plugin-proposal-json-strings": { @@ -457,8 +457,8 @@ "integrity": "sha512-MAFV1CA/YVmYwZG0fBQyXhmj0BHCB5egZHCKWIFVv/XCxAeVGIHfos3SwDck4LvCllENIAg7xMKOG5kH0dzyUg==", "dev": true, "requires": { - "@babel/helper-plugin-utils": "7.0.0", - "@babel/plugin-syntax-json-strings": "7.2.0" + "@babel/helper-plugin-utils": "^7.0.0", + "@babel/plugin-syntax-json-strings": "^7.2.0" } }, "@babel/plugin-proposal-logical-assignment-operators": { @@ -467,8 +467,8 @@ "integrity": "sha512-0w797xwdPXKk0m3Js74hDi0mCTZplIu93MOSfb1ZLd/XFe3abWypx1QknVk0J+ohnsjYpvjH4Gwfo2i3RicB6Q==", "dev": true, "requires": { - "@babel/helper-plugin-utils": "7.0.0", - "@babel/plugin-syntax-logical-assignment-operators": "7.2.0" + "@babel/helper-plugin-utils": "^7.0.0", + "@babel/plugin-syntax-logical-assignment-operators": "^7.2.0" } }, "@babel/plugin-proposal-nullish-coalescing-operator": { @@ -477,8 +477,8 @@ "integrity": "sha512-QXj/YjFuFJd68oDvoc1e8aqLr2wz7Kofzvp6Ekd/o7MWZl+nZ0/cpStxND+hlZ7DpRWAp7OmuyT2areZ2V3YUA==", "dev": true, "requires": { - "@babel/helper-plugin-utils": "7.0.0", - "@babel/plugin-syntax-nullish-coalescing-operator": "7.2.0" + "@babel/helper-plugin-utils": "^7.0.0", + "@babel/plugin-syntax-nullish-coalescing-operator": "^7.2.0" } }, "@babel/plugin-proposal-numeric-separator": { @@ -487,8 +487,8 @@ "integrity": "sha512-DohMOGDrZiMKS7LthjUZNNcWl8TAf5BZDwZAH4wpm55FuJTHgfqPGdibg7rZDmont/8Yg0zA03IgT6XLeP+4sg==", "dev": true, "requires": { - "@babel/helper-plugin-utils": "7.0.0", - "@babel/plugin-syntax-numeric-separator": "7.2.0" + "@babel/helper-plugin-utils": "^7.0.0", + "@babel/plugin-syntax-numeric-separator": "^7.2.0" } }, "@babel/plugin-proposal-object-rest-spread": { @@ -497,8 +497,8 @@ "integrity": "sha512-1L5mWLSvR76XYUQJXkd/EEQgjq8HHRP6lQuZTTg0VA4tTGPpGemmCdAfQIz1rzEuWAm+ecP8PyyEm30jC1eQCg==", "dev": true, "requires": { - "@babel/helper-plugin-utils": "7.0.0", - "@babel/plugin-syntax-object-rest-spread": "7.2.0" + "@babel/helper-plugin-utils": "^7.0.0", + "@babel/plugin-syntax-object-rest-spread": "^7.2.0" } }, "@babel/plugin-proposal-optional-catch-binding": { @@ -507,8 +507,8 @@ "integrity": "sha512-mgYj3jCcxug6KUcX4OBoOJz3CMrwRfQELPQ5560F70YQUBZB7uac9fqaWamKR1iWUzGiK2t0ygzjTScZnVz75g==", "dev": true, "requires": { - "@babel/helper-plugin-utils": "7.0.0", - "@babel/plugin-syntax-optional-catch-binding": "7.2.0" + "@babel/helper-plugin-utils": "^7.0.0", + "@babel/plugin-syntax-optional-catch-binding": "^7.2.0" } }, "@babel/plugin-proposal-optional-chaining": { @@ -517,8 +517,8 @@ "integrity": "sha512-ea3Q6edZC/55wEBVZAEz42v528VulyO0eir+7uky/sT4XRcdkWJcFi1aPtitTlwUzGnECWJNExWww1SStt+yWw==", "dev": true, "requires": { - "@babel/helper-plugin-utils": "7.0.0", - "@babel/plugin-syntax-optional-chaining": "7.2.0" + "@babel/helper-plugin-utils": "^7.0.0", + "@babel/plugin-syntax-optional-chaining": "^7.2.0" } }, "@babel/plugin-proposal-pipeline-operator": { @@ -527,8 +527,8 @@ "integrity": "sha512-CkMwpQJlLB3lIa5Td1pQfXUMpt/Hmam+dgWa6A1FOt6wyh9IIq/JlvU9WZkrcDuHUfNmj2uloqYqhIl6So1NUg==", "dev": true, "requires": { - "@babel/helper-plugin-utils": "7.0.0", - "@babel/plugin-syntax-pipeline-operator": "7.2.0" + "@babel/helper-plugin-utils": "^7.0.0", + "@babel/plugin-syntax-pipeline-operator": "^7.2.0" } }, "@babel/plugin-proposal-throw-expressions": { @@ -537,8 +537,8 @@ "integrity": "sha512-adsydM8DQF4i5DLNO4ySAU5VtHTPewOtNBV3u7F4lNMPADFF9bWQ+iDtUUe8+033cYCUz+bFlQdXQJmJOwoLpw==", "dev": true, "requires": { - "@babel/helper-plugin-utils": "7.0.0", - "@babel/plugin-syntax-throw-expressions": "7.2.0" + "@babel/helper-plugin-utils": "^7.0.0", + "@babel/plugin-syntax-throw-expressions": "^7.2.0" } }, "@babel/plugin-proposal-unicode-property-regex": { @@ -547,9 +547,9 @@ "integrity": "sha512-LvRVYb7kikuOtIoUeWTkOxQEV1kYvL5B6U3iWEGCzPNRus1MzJweFqORTj+0jkxozkTSYNJozPOddxmqdqsRpw==", "dev": true, "requires": { - "@babel/helper-plugin-utils": "7.0.0", - "@babel/helper-regex": "7.0.0", - "regexpu-core": "4.4.0" + "@babel/helper-plugin-utils": "^7.0.0", + "@babel/helper-regex": "^7.0.0", + "regexpu-core": "^4.2.0" }, "dependencies": { "jsesc": { @@ -570,12 +570,12 @@ "integrity": "sha512-eDDWElbwwI3K0Lo6CqbQbA6FwgtCz4kYTarrri1okfkRLZAqstU+B3voZBCjg8Fl6iq0gXrJG6MvRgLthfvgOA==", "dev": true, "requires": { - "regenerate": "1.4.0", - "regenerate-unicode-properties": "7.0.0", - "regjsgen": "0.5.0", - "regjsparser": "0.6.0", - "unicode-match-property-ecmascript": "1.0.4", - "unicode-match-property-value-ecmascript": "1.0.2" + "regenerate": "^1.4.0", + "regenerate-unicode-properties": "^7.0.0", + "regjsgen": "^0.5.0", + "regjsparser": "^0.6.0", + "unicode-match-property-ecmascript": "^1.0.4", + "unicode-match-property-value-ecmascript": "^1.0.2" } }, "regjsgen": { @@ -590,7 +590,7 @@ "integrity": "sha512-RQ7YyokLiQBomUJuUG8iGVvkgOLxwyZM8k6d3q5SAXpg4r5TZJZigKFvC6PpD+qQ98bCDC5YelPeA3EucDoNeQ==", "dev": true, "requires": { - "jsesc": "0.5.0" + "jsesc": "~0.5.0" } } } @@ -601,7 +601,7 @@ "integrity": "sha512-1ZrIRBv2t0GSlcwVoQ6VgSLpLgiN/FVQUzt9znxo7v2Ov4jJrs8RY8tv0wvDmFN3qIdMKWrmMMW6yZ0G19MfGg==", "dev": true, "requires": { - "@babel/helper-plugin-utils": "7.0.0" + "@babel/helper-plugin-utils": "^7.0.0" } }, "@babel/plugin-syntax-decorators": { @@ -610,7 +610,7 @@ "integrity": "sha512-38QdqVoXdHUQfTpZo3rQwqQdWtCn5tMv4uV6r2RMfTqNBuv4ZBhz79SfaQWKTVmxHjeFv/DnXVC/+agHCklYWA==", "dev": true, "requires": { - "@babel/helper-plugin-utils": "7.0.0" + "@babel/helper-plugin-utils": "^7.0.0" } }, "@babel/plugin-syntax-do-expressions": { @@ -619,7 +619,7 @@ "integrity": "sha512-/u4rJ+XEmZkIhspVuKRS+7WLvm7Dky9j9TvGK5IgId8B3FKir9MG+nQxDZ9xLn10QMBvW58dZ6ABe2juSmARjg==", "dev": true, "requires": { - "@babel/helper-plugin-utils": "7.0.0" + "@babel/helper-plugin-utils": "^7.0.0" } }, "@babel/plugin-syntax-dynamic-import": { @@ -628,7 +628,7 @@ "integrity": "sha512-mVxuJ0YroI/h/tbFTPGZR8cv6ai+STMKNBq0f8hFxsxWjl94qqhsb+wXbpNMDPU3cfR1TIsVFzU3nXyZMqyK4w==", "dev": true, "requires": { - "@babel/helper-plugin-utils": "7.0.0" + "@babel/helper-plugin-utils": "^7.0.0" } }, "@babel/plugin-syntax-export-default-from": { @@ -637,7 +637,7 @@ "integrity": "sha512-c7nqUnNST97BWPtoe+Ssi+fJukc9P9/JMZ71IOMNQWza2E+Psrd46N6AEvtw6pqK+gt7ChjXyrw4SPDO79f3Lw==", "dev": true, "requires": { - "@babel/helper-plugin-utils": "7.0.0" + "@babel/helper-plugin-utils": "^7.0.0" } }, "@babel/plugin-syntax-export-namespace-from": { @@ -646,7 +646,7 @@ "integrity": "sha512-1zGA3UNch6A+A11nIzBVEaE3DDJbjfB+eLIcf0GGOh/BJr/8NxL3546MGhV/r0RhH4xADFIEso39TKCfEMlsGA==", "dev": true, "requires": { - "@babel/helper-plugin-utils": "7.0.0" + "@babel/helper-plugin-utils": "^7.0.0" } }, "@babel/plugin-syntax-flow": { @@ -655,7 +655,7 @@ "integrity": "sha512-r6YMuZDWLtLlu0kqIim5o/3TNRAlWb073HwT3e2nKf9I8IIvOggPrnILYPsrrKilmn/mYEMCf/Z07w3yQJF6dg==", "dev": true, "requires": { - "@babel/helper-plugin-utils": "7.0.0" + "@babel/helper-plugin-utils": "^7.0.0" } }, "@babel/plugin-syntax-function-bind": { @@ -664,7 +664,7 @@ "integrity": "sha512-/WzU1lLU2l0wDfB42Wkg6tahrmtBbiD8C4H6EGSX0M4GAjzN6JiOpq/Uh8G6GSoR6lPMvhjM0MNiV6znj6y/zg==", "dev": true, "requires": { - "@babel/helper-plugin-utils": "7.0.0" + "@babel/helper-plugin-utils": "^7.0.0" } }, "@babel/plugin-syntax-function-sent": { @@ -673,7 +673,7 @@ "integrity": "sha512-2MOVuJ6IMAifp2cf0RFkHQaOvHpbBYyWCvgtF/WVqXhTd7Bgtov8iXVCadLXp2FN1BrI2EFl+JXuwXy0qr3KoQ==", "dev": true, "requires": { - "@babel/helper-plugin-utils": "7.0.0" + "@babel/helper-plugin-utils": "^7.0.0" } }, "@babel/plugin-syntax-import-meta": { @@ -682,7 +682,7 @@ "integrity": "sha512-Hq6kFSZD7+PHkmBN8bCpHR6J8QEoCuEV/B38AIQscYjgMZkGlXB7cHNFzP5jR4RCh5545yP1ujHdmO7hAgKtBA==", "dev": true, "requires": { - "@babel/helper-plugin-utils": "7.0.0" + "@babel/helper-plugin-utils": "^7.0.0" } }, "@babel/plugin-syntax-json-strings": { @@ -691,7 +691,7 @@ "integrity": "sha512-5UGYnMSLRE1dqqZwug+1LISpA403HzlSfsg6P9VXU6TBjcSHeNlw4DxDx7LgpF+iKZoOG/+uzqoRHTdcUpiZNg==", "dev": true, "requires": { - "@babel/helper-plugin-utils": "7.0.0" + "@babel/helper-plugin-utils": "^7.0.0" } }, "@babel/plugin-syntax-jsx": { @@ -700,7 +700,7 @@ "integrity": "sha512-VyN4QANJkRW6lDBmENzRszvZf3/4AXaj9YR7GwrWeeN9tEBPuXbmDYVU9bYBN0D70zCWVwUy0HWq2553VCb6Hw==", "dev": true, "requires": { - "@babel/helper-plugin-utils": "7.0.0" + "@babel/helper-plugin-utils": "^7.0.0" } }, "@babel/plugin-syntax-logical-assignment-operators": { @@ -709,7 +709,7 @@ "integrity": "sha512-l/NKSlrnvd73/EL540t9hZhcSo4TULBrIPs9Palju8Oc/A8DXDO+xQf04whfeuZLpi8AuIvCAdpKmmubLN4EfQ==", "dev": true, "requires": { - "@babel/helper-plugin-utils": "7.0.0" + "@babel/helper-plugin-utils": "^7.0.0" } }, "@babel/plugin-syntax-nullish-coalescing-operator": { @@ -718,7 +718,7 @@ "integrity": "sha512-lRCEaKE+LTxDQtgbYajI04ddt6WW0WJq57xqkAZ+s11h4YgfRHhVA/Y2VhfPzzFD4qeLHWg32DMp9HooY4Kqlg==", "dev": true, "requires": { - "@babel/helper-plugin-utils": "7.0.0" + "@babel/helper-plugin-utils": "^7.0.0" } }, "@babel/plugin-syntax-numeric-separator": { @@ -727,7 +727,7 @@ "integrity": "sha512-DroeVNkO/BnGpL2R7+ZNZqW+E24aR/4YWxP3Qb15d6lPU8KDzF8HlIUIRCOJRn4X77/oyW4mJY+7FHfY82NLtQ==", "dev": true, "requires": { - "@babel/helper-plugin-utils": "7.0.0" + "@babel/helper-plugin-utils": "^7.0.0" } }, "@babel/plugin-syntax-object-rest-spread": { @@ -736,7 +736,7 @@ "integrity": "sha512-t0JKGgqk2We+9may3t0xDdmneaXmyxq0xieYcKHxIsrJO64n1OiMWNUtc5gQK1PA0NpdCRrtZp4z+IUaKugrSA==", "dev": true, "requires": { - "@babel/helper-plugin-utils": "7.0.0" + "@babel/helper-plugin-utils": "^7.0.0" } }, "@babel/plugin-syntax-optional-catch-binding": { @@ -745,7 +745,7 @@ "integrity": "sha512-bDe4xKNhb0LI7IvZHiA13kff0KEfaGX/Hv4lMA9+7TEc63hMNvfKo6ZFpXhKuEp+II/q35Gc4NoMeDZyaUbj9w==", "dev": true, "requires": { - "@babel/helper-plugin-utils": "7.0.0" + "@babel/helper-plugin-utils": "^7.0.0" } }, "@babel/plugin-syntax-optional-chaining": { @@ -754,7 +754,7 @@ "integrity": "sha512-HtGCtvp5Uq/jH/WNUPkK6b7rufnCPLLlDAFN7cmACoIjaOOiXxUt3SswU5loHqrhtqTsa/WoLQ1OQ1AGuZqaWA==", "dev": true, "requires": { - "@babel/helper-plugin-utils": "7.0.0" + "@babel/helper-plugin-utils": "^7.0.0" } }, "@babel/plugin-syntax-pipeline-operator": { @@ -763,7 +763,7 @@ "integrity": "sha512-cMjegj67vi0Hs5sYEe7WIu+sYoAwXQXwQD4YTDaowylFxPbX7dRmwnkq20aFkkQGSlOF6wDjKzno7thYAibYzg==", "dev": true, "requires": { - "@babel/helper-plugin-utils": "7.0.0" + "@babel/helper-plugin-utils": "^7.0.0" } }, "@babel/plugin-syntax-throw-expressions": { @@ -772,7 +772,7 @@ "integrity": "sha512-ngwynuqu1Rx0JUS9zxSDuPgW1K8TyVZCi2hHehrL4vyjqE7RGoNHWlZsS7KQT2vw9Yjk4YLa0+KldBXTRdPLRg==", "dev": true, "requires": { - "@babel/helper-plugin-utils": "7.0.0" + "@babel/helper-plugin-utils": "^7.0.0" } }, "@babel/plugin-transform-arrow-functions": { @@ -781,7 +781,7 @@ "integrity": "sha512-ER77Cax1+8/8jCB9fo4Ud161OZzWN5qawi4GusDuRLcDbDG+bIGYY20zb2dfAFdTRGzrfq2xZPvF0R64EHnimg==", "dev": true, "requires": { - "@babel/helper-plugin-utils": "7.0.0" + "@babel/helper-plugin-utils": "^7.0.0" } }, "@babel/plugin-transform-async-to-generator": { @@ -790,9 +790,9 @@ "integrity": "sha512-CEHzg4g5UraReozI9D4fblBYABs7IM6UerAVG7EJVrTLC5keh00aEuLUT+O40+mJCEzaXkYfTCUKIyeDfMOFFQ==", "dev": true, "requires": { - "@babel/helper-module-imports": "7.0.0", - "@babel/helper-plugin-utils": "7.0.0", - "@babel/helper-remap-async-to-generator": "7.1.0" + "@babel/helper-module-imports": "^7.0.0", + "@babel/helper-plugin-utils": "^7.0.0", + "@babel/helper-remap-async-to-generator": "^7.1.0" } }, "@babel/plugin-transform-block-scoped-functions": { @@ -801,7 +801,7 @@ "integrity": "sha512-ntQPR6q1/NKuphly49+QiQiTN0O63uOwjdD6dhIjSWBI5xlrbUFh720TIpzBhpnrLfv2tNH/BXvLIab1+BAI0w==", "dev": true, "requires": { - "@babel/helper-plugin-utils": "7.0.0" + "@babel/helper-plugin-utils": "^7.0.0" } }, "@babel/plugin-transform-block-scoping": { @@ -810,8 +810,8 @@ "integrity": "sha512-vDTgf19ZEV6mx35yiPJe4fS02mPQUUcBNwWQSZFXSzTSbsJFQvHt7DqyS3LK8oOWALFOsJ+8bbqBgkirZteD5Q==", "dev": true, "requires": { - "@babel/helper-plugin-utils": "7.0.0", - "lodash": "4.17.11" + "@babel/helper-plugin-utils": "^7.0.0", + "lodash": "^4.17.10" } }, "@babel/plugin-transform-classes": { @@ -820,14 +820,14 @@ "integrity": "sha512-gEZvgTy1VtcDOaQty1l10T3jQmJKlNVxLDCs+3rCVPr6nMkODLELxViq5X9l+rfxbie3XrfrMCYYY6eX3aOcOQ==", "dev": true, "requires": { - "@babel/helper-annotate-as-pure": "7.0.0", - "@babel/helper-define-map": "7.1.0", - "@babel/helper-function-name": "7.1.0", - "@babel/helper-optimise-call-expression": "7.0.0", - "@babel/helper-plugin-utils": "7.0.0", - "@babel/helper-replace-supers": "7.2.3", - "@babel/helper-split-export-declaration": "7.0.0", - "globals": "11.10.0" + "@babel/helper-annotate-as-pure": "^7.0.0", + "@babel/helper-define-map": "^7.1.0", + "@babel/helper-function-name": "^7.1.0", + "@babel/helper-optimise-call-expression": "^7.0.0", + "@babel/helper-plugin-utils": "^7.0.0", + "@babel/helper-replace-supers": "^7.1.0", + "@babel/helper-split-export-declaration": "^7.0.0", + "globals": "^11.1.0" }, "dependencies": { "globals": { @@ -844,7 +844,7 @@ "integrity": "sha512-kP/drqTxY6Xt3NNpKiMomfgkNn4o7+vKxK2DDKcBG9sHj51vHqMBGy8wbDS/J4lMxnqs153/T3+DmCEAkC5cpA==", "dev": true, "requires": { - "@babel/helper-plugin-utils": "7.0.0" + "@babel/helper-plugin-utils": "^7.0.0" } }, "@babel/plugin-transform-destructuring": { @@ -853,7 +853,7 @@ "integrity": "sha512-coVO2Ayv7g0qdDbrNiadE4bU7lvCd9H539m2gMknyVjjMdwF/iCOM7R+E8PkntoqLkltO0rk+3axhpp/0v68VQ==", "dev": true, "requires": { - "@babel/helper-plugin-utils": "7.0.0" + "@babel/helper-plugin-utils": "^7.0.0" } }, "@babel/plugin-transform-dotall-regex": { @@ -862,9 +862,9 @@ "integrity": "sha512-sKxnyHfizweTgKZf7XsXu/CNupKhzijptfTM+bozonIuyVrLWVUvYjE2bhuSBML8VQeMxq4Mm63Q9qvcvUcciQ==", "dev": true, "requires": { - "@babel/helper-plugin-utils": "7.0.0", - "@babel/helper-regex": "7.0.0", - "regexpu-core": "4.4.0" + "@babel/helper-plugin-utils": "^7.0.0", + "@babel/helper-regex": "^7.0.0", + "regexpu-core": "^4.1.3" }, "dependencies": { "jsesc": { @@ -885,12 +885,12 @@ "integrity": "sha512-eDDWElbwwI3K0Lo6CqbQbA6FwgtCz4kYTarrri1okfkRLZAqstU+B3voZBCjg8Fl6iq0gXrJG6MvRgLthfvgOA==", "dev": true, "requires": { - "regenerate": "1.4.0", - "regenerate-unicode-properties": "7.0.0", - "regjsgen": "0.5.0", - "regjsparser": "0.6.0", - "unicode-match-property-ecmascript": "1.0.4", - "unicode-match-property-value-ecmascript": "1.0.2" + "regenerate": "^1.4.0", + "regenerate-unicode-properties": "^7.0.0", + "regjsgen": "^0.5.0", + "regjsparser": "^0.6.0", + "unicode-match-property-ecmascript": "^1.0.4", + "unicode-match-property-value-ecmascript": "^1.0.2" } }, "regjsgen": { @@ -905,7 +905,7 @@ "integrity": "sha512-RQ7YyokLiQBomUJuUG8iGVvkgOLxwyZM8k6d3q5SAXpg4r5TZJZigKFvC6PpD+qQ98bCDC5YelPeA3EucDoNeQ==", "dev": true, "requires": { - "jsesc": "0.5.0" + "jsesc": "~0.5.0" } } } @@ -916,7 +916,7 @@ "integrity": "sha512-q+yuxW4DsTjNceUiTzK0L+AfQ0zD9rWaTLiUqHA8p0gxx7lu1EylenfzjeIWNkPy6e/0VG/Wjw9uf9LueQwLOw==", "dev": true, "requires": { - "@babel/helper-plugin-utils": "7.0.0" + "@babel/helper-plugin-utils": "^7.0.0" } }, "@babel/plugin-transform-exponentiation-operator": { @@ -925,8 +925,8 @@ "integrity": "sha512-umh4hR6N7mu4Elq9GG8TOu9M0bakvlsREEC+ialrQN6ABS4oDQ69qJv1VtR3uxlKMCQMCvzk7vr17RHKcjx68A==", "dev": true, "requires": { - "@babel/helper-builder-binary-assignment-operator-visitor": "7.1.0", - "@babel/helper-plugin-utils": "7.0.0" + "@babel/helper-builder-binary-assignment-operator-visitor": "^7.1.0", + "@babel/helper-plugin-utils": "^7.0.0" } }, "@babel/plugin-transform-flow-strip-types": { @@ -935,8 +935,8 @@ "integrity": "sha512-xnt7UIk9GYZRitqCnsVMjQK1O2eKZwFB3CvvHjf5SGx6K6vr/MScCKQDnf1DxRaj501e3pXjti+inbSXX2ZUoQ==", "dev": true, "requires": { - "@babel/helper-plugin-utils": "7.0.0", - "@babel/plugin-syntax-flow": "7.2.0" + "@babel/helper-plugin-utils": "^7.0.0", + "@babel/plugin-syntax-flow": "^7.2.0" } }, "@babel/plugin-transform-for-of": { @@ -945,7 +945,7 @@ "integrity": "sha512-Kz7Mt0SsV2tQk6jG5bBv5phVbkd0gd27SgYD4hH1aLMJRchM0dzHaXvrWhVZ+WxAlDoAKZ7Uy3jVTW2mKXQ1WQ==", "dev": true, "requires": { - "@babel/helper-plugin-utils": "7.0.0" + "@babel/helper-plugin-utils": "^7.0.0" } }, "@babel/plugin-transform-function-name": { @@ -954,8 +954,8 @@ "integrity": "sha512-kWgksow9lHdvBC2Z4mxTsvc7YdY7w/V6B2vy9cTIPtLEE9NhwoWivaxdNM/S37elu5bqlLP/qOY906LukO9lkQ==", "dev": true, "requires": { - "@babel/helper-function-name": "7.1.0", - "@babel/helper-plugin-utils": "7.0.0" + "@babel/helper-function-name": "^7.1.0", + "@babel/helper-plugin-utils": "^7.0.0" } }, "@babel/plugin-transform-literals": { @@ -964,7 +964,7 @@ "integrity": "sha512-2ThDhm4lI4oV7fVQ6pNNK+sx+c/GM5/SaML0w/r4ZB7sAneD/piDJtwdKlNckXeyGK7wlwg2E2w33C/Hh+VFCg==", "dev": true, "requires": { - "@babel/helper-plugin-utils": "7.0.0" + "@babel/helper-plugin-utils": "^7.0.0" } }, "@babel/plugin-transform-modules-amd": { @@ -973,8 +973,8 @@ "integrity": "sha512-mK2A8ucqz1qhrdqjS9VMIDfIvvT2thrEsIQzbaTdc5QFzhDjQv2CkJJ5f6BXIkgbmaoax3zBr2RyvV/8zeoUZw==", "dev": true, "requires": { - "@babel/helper-module-transforms": "7.2.2", - "@babel/helper-plugin-utils": "7.0.0" + "@babel/helper-module-transforms": "^7.1.0", + "@babel/helper-plugin-utils": "^7.0.0" } }, "@babel/plugin-transform-modules-commonjs": { @@ -983,9 +983,9 @@ "integrity": "sha512-V6y0uaUQrQPXUrmj+hgnks8va2L0zcZymeU7TtWEgdRLNkceafKXEduv7QzgQAE4lT+suwooG9dC7LFhdRAbVQ==", "dev": true, "requires": { - "@babel/helper-module-transforms": "7.2.2", - "@babel/helper-plugin-utils": "7.0.0", - "@babel/helper-simple-access": "7.1.0" + "@babel/helper-module-transforms": "^7.1.0", + "@babel/helper-plugin-utils": "^7.0.0", + "@babel/helper-simple-access": "^7.1.0" } }, "@babel/plugin-transform-modules-systemjs": { @@ -994,8 +994,8 @@ "integrity": "sha512-aYJwpAhoK9a+1+O625WIjvMY11wkB/ok0WClVwmeo3mCjcNRjt+/8gHWrB5i+00mUju0gWsBkQnPpdvQ7PImmQ==", "dev": true, "requires": { - "@babel/helper-hoist-variables": "7.0.0", - "@babel/helper-plugin-utils": "7.0.0" + "@babel/helper-hoist-variables": "^7.0.0", + "@babel/helper-plugin-utils": "^7.0.0" } }, "@babel/plugin-transform-modules-umd": { @@ -1004,8 +1004,8 @@ "integrity": "sha512-BV3bw6MyUH1iIsGhXlOK6sXhmSarZjtJ/vMiD9dNmpY8QXFFQTj+6v92pcfy1iqa8DeAfJFwoxcrS/TUZda6sw==", "dev": true, "requires": { - "@babel/helper-module-transforms": "7.2.2", - "@babel/helper-plugin-utils": "7.0.0" + "@babel/helper-module-transforms": "^7.1.0", + "@babel/helper-plugin-utils": "^7.0.0" } }, "@babel/plugin-transform-new-target": { @@ -1014,7 +1014,7 @@ "integrity": "sha512-yin069FYjah+LbqfGeTfzIBODex/e++Yfa0rH0fpfam9uTbuEeEOx5GLGr210ggOV77mVRNoeqSYqeuaqSzVSw==", "dev": true, "requires": { - "@babel/helper-plugin-utils": "7.0.0" + "@babel/helper-plugin-utils": "^7.0.0" } }, "@babel/plugin-transform-object-super": { @@ -1023,8 +1023,8 @@ "integrity": "sha512-VMyhPYZISFZAqAPVkiYb7dUe2AsVi2/wCT5+wZdsNO31FojQJa9ns40hzZ6U9f50Jlq4w6qwzdBB2uwqZ00ebg==", "dev": true, "requires": { - "@babel/helper-plugin-utils": "7.0.0", - "@babel/helper-replace-supers": "7.2.3" + "@babel/helper-plugin-utils": "^7.0.0", + "@babel/helper-replace-supers": "^7.1.0" } }, "@babel/plugin-transform-parameters": { @@ -1033,9 +1033,9 @@ "integrity": "sha512-kB9+hhUidIgUoBQ0MsxMewhzr8i60nMa2KgeJKQWYrqQpqcBYtnpR+JgkadZVZoaEZ/eKu9mclFaVwhRpLNSzA==", "dev": true, "requires": { - "@babel/helper-call-delegate": "7.1.0", - "@babel/helper-get-function-arity": "7.0.0", - "@babel/helper-plugin-utils": "7.0.0" + "@babel/helper-call-delegate": "^7.1.0", + "@babel/helper-get-function-arity": "^7.0.0", + "@babel/helper-plugin-utils": "^7.0.0" } }, "@babel/plugin-transform-react-display-name": { @@ -1044,7 +1044,7 @@ "integrity": "sha512-Htf/tPa5haZvRMiNSQSFifK12gtr/8vwfr+A9y69uF0QcU77AVu4K7MiHEkTxF7lQoHOL0F9ErqgfNEAKgXj7A==", "dev": true, "requires": { - "@babel/helper-plugin-utils": "7.0.0" + "@babel/helper-plugin-utils": "^7.0.0" } }, "@babel/plugin-transform-react-jsx": { @@ -1053,9 +1053,9 @@ "integrity": "sha512-h/fZRel5wAfCqcKgq3OhbmYaReo7KkoJBpt8XnvpS7wqaNMqtw5xhxutzcm35iMUWucfAdT/nvGTsWln0JTg2Q==", "dev": true, "requires": { - "@babel/helper-builder-react-jsx": "7.0.0", - "@babel/helper-plugin-utils": "7.0.0", - "@babel/plugin-syntax-jsx": "7.2.0" + "@babel/helper-builder-react-jsx": "^7.0.0", + "@babel/helper-plugin-utils": "^7.0.0", + "@babel/plugin-syntax-jsx": "^7.2.0" } }, "@babel/plugin-transform-react-jsx-self": { @@ -1064,8 +1064,8 @@ "integrity": "sha512-v6S5L/myicZEy+jr6ielB0OR8h+EH/1QFx/YJ7c7Ua+7lqsjj/vW6fD5FR9hB/6y7mGbfT4vAURn3xqBxsUcdg==", "dev": true, "requires": { - "@babel/helper-plugin-utils": "7.0.0", - "@babel/plugin-syntax-jsx": "7.2.0" + "@babel/helper-plugin-utils": "^7.0.0", + "@babel/plugin-syntax-jsx": "^7.2.0" } }, "@babel/plugin-transform-react-jsx-source": { @@ -1074,8 +1074,8 @@ "integrity": "sha512-A32OkKTp4i5U6aE88GwwcuV4HAprUgHcTq0sSafLxjr6AW0QahrCRCjxogkbbcdtpbXkuTOlgpjophCxb6sh5g==", "dev": true, "requires": { - "@babel/helper-plugin-utils": "7.0.0", - "@babel/plugin-syntax-jsx": "7.2.0" + "@babel/helper-plugin-utils": "^7.0.0", + "@babel/plugin-syntax-jsx": "^7.2.0" } }, "@babel/plugin-transform-regenerator": { @@ -1084,7 +1084,7 @@ "integrity": "sha512-sj2qzsEx8KDVv1QuJc/dEfilkg3RRPvPYx/VnKLtItVQRWt1Wqf5eVCOLZm29CiGFfYYsA3VPjfizTCV0S0Dlw==", "dev": true, "requires": { - "regenerator-transform": "0.13.3" + "regenerator-transform": "^0.13.3" }, "dependencies": { "regenerator-transform": { @@ -1093,7 +1093,7 @@ "integrity": "sha512-5ipTrZFSq5vU2YoGoww4uaRVAK4wyYC4TSICibbfEPOruUu8FFP7ErV0BjmbIOEpn3O/k9na9UEdYR/3m7N6uA==", "dev": true, "requires": { - "private": "0.1.8" + "private": "^0.1.6" } } } @@ -1104,10 +1104,10 @@ "integrity": "sha512-jIgkljDdq4RYDnJyQsiWbdvGeei/0MOTtSHKO/rfbd/mXBxNpdlulMx49L0HQ4pug1fXannxoqCI+fYSle9eSw==", "dev": true, "requires": { - "@babel/helper-module-imports": "7.0.0", - "@babel/helper-plugin-utils": "7.0.0", - "resolve": "1.9.0", - "semver": "5.6.0" + "@babel/helper-module-imports": "^7.0.0", + "@babel/helper-plugin-utils": "^7.0.0", + "resolve": "^1.8.1", + "semver": "^5.5.1" }, "dependencies": { "path-parse": { @@ -1122,7 +1122,7 @@ "integrity": "sha512-TZNye00tI67lwYvzxCxHGjwTNlUV70io54/Ed4j6PscB8xVfuBJpRenI/o6dVk0cY0PYTY27AgCoGGxRnYuItQ==", "dev": true, "requires": { - "path-parse": "1.0.6" + "path-parse": "^1.0.6" } }, "semver": { @@ -1139,7 +1139,7 @@ "integrity": "sha512-QP4eUM83ha9zmYtpbnyjTLAGKQritA5XW/iG9cjtuOI8s1RuL/3V6a3DeSHfKutJQ+ayUfeZJPcnCYEQzaPQqg==", "dev": true, "requires": { - "@babel/helper-plugin-utils": "7.0.0" + "@babel/helper-plugin-utils": "^7.0.0" } }, "@babel/plugin-transform-spread": { @@ -1148,7 +1148,7 @@ "integrity": "sha512-KWfky/58vubwtS0hLqEnrWJjsMGaOeSBn90Ezn5Jeg9Z8KKHmELbP1yGylMlm5N6TPKeY9A2+UaSYLdxahg01w==", "dev": true, "requires": { - "@babel/helper-plugin-utils": "7.0.0" + "@babel/helper-plugin-utils": "^7.0.0" } }, "@babel/plugin-transform-sticky-regex": { @@ -1157,8 +1157,8 @@ "integrity": "sha512-KKYCoGaRAf+ckH8gEL3JHUaFVyNHKe3ASNsZ+AlktgHevvxGigoIttrEJb8iKN03Q7Eazlv1s6cx2B2cQ3Jabw==", "dev": true, "requires": { - "@babel/helper-plugin-utils": "7.0.0", - "@babel/helper-regex": "7.0.0" + "@babel/helper-plugin-utils": "^7.0.0", + "@babel/helper-regex": "^7.0.0" } }, "@babel/plugin-transform-template-literals": { @@ -1167,8 +1167,8 @@ "integrity": "sha512-FkPix00J9A/XWXv4VoKJBMeSkyY9x/TqIh76wzcdfl57RJJcf8CehQ08uwfhCDNtRQYtHQKBTwKZDEyjE13Lwg==", "dev": true, "requires": { - "@babel/helper-annotate-as-pure": "7.0.0", - "@babel/helper-plugin-utils": "7.0.0" + "@babel/helper-annotate-as-pure": "^7.0.0", + "@babel/helper-plugin-utils": "^7.0.0" } }, "@babel/plugin-transform-typeof-symbol": { @@ -1177,7 +1177,7 @@ "integrity": "sha512-2LNhETWYxiYysBtrBTqL8+La0jIoQQnIScUJc74OYvUGRmkskNY4EzLCnjHBzdmb38wqtTaixpo1NctEcvMDZw==", "dev": true, "requires": { - "@babel/helper-plugin-utils": "7.0.0" + "@babel/helper-plugin-utils": "^7.0.0" } }, "@babel/plugin-transform-unicode-regex": { @@ -1186,9 +1186,9 @@ "integrity": "sha512-m48Y0lMhrbXEJnVUaYly29jRXbQ3ksxPrS1Tg8t+MHqzXhtBYAvI51euOBaoAlZLPHsieY9XPVMf80a5x0cPcA==", "dev": true, "requires": { - "@babel/helper-plugin-utils": "7.0.0", - "@babel/helper-regex": "7.0.0", - "regexpu-core": "4.4.0" + "@babel/helper-plugin-utils": "^7.0.0", + "@babel/helper-regex": "^7.0.0", + "regexpu-core": "^4.1.3" }, "dependencies": { "jsesc": { @@ -1209,12 +1209,12 @@ "integrity": "sha512-eDDWElbwwI3K0Lo6CqbQbA6FwgtCz4kYTarrri1okfkRLZAqstU+B3voZBCjg8Fl6iq0gXrJG6MvRgLthfvgOA==", "dev": true, "requires": { - "regenerate": "1.4.0", - "regenerate-unicode-properties": "7.0.0", - "regjsgen": "0.5.0", - "regjsparser": "0.6.0", - "unicode-match-property-ecmascript": "1.0.4", - "unicode-match-property-value-ecmascript": "1.0.2" + "regenerate": "^1.4.0", + "regenerate-unicode-properties": "^7.0.0", + "regjsgen": "^0.5.0", + "regjsparser": "^0.6.0", + "unicode-match-property-ecmascript": "^1.0.4", + "unicode-match-property-value-ecmascript": "^1.0.2" } }, "regjsgen": { @@ -1229,7 +1229,7 @@ "integrity": "sha512-RQ7YyokLiQBomUJuUG8iGVvkgOLxwyZM8k6d3q5SAXpg4r5TZJZigKFvC6PpD+qQ98bCDC5YelPeA3EucDoNeQ==", "dev": true, "requires": { - "jsesc": "0.5.0" + "jsesc": "~0.5.0" } } } @@ -1240,8 +1240,8 @@ "integrity": "sha512-8Y/t3MWThtMLYr0YNC/Q76tqN1w30+b0uQMeFUYauG2UGTR19zyUtFrAzT23zNtBxPp+LbE5E/nwV/q/r3y6ug==", "dev": true, "requires": { - "core-js": "2.6.2", - "regenerator-runtime": "0.12.1" + "core-js": "^2.5.7", + "regenerator-runtime": "^0.12.0" }, "dependencies": { "core-js": { @@ -1264,47 +1264,47 @@ "integrity": "sha512-AuHzW7a9rbv5WXmvGaPX7wADxFkZIqKlbBh1dmZUQp4iwiPpkE/Qnrji6SC4UQCQzvWY/cpHET29eUhXS9cLPw==", "dev": true, "requires": { - "@babel/helper-module-imports": "7.0.0", - "@babel/helper-plugin-utils": "7.0.0", - "@babel/plugin-proposal-async-generator-functions": "7.2.0", - "@babel/plugin-proposal-json-strings": "7.2.0", - "@babel/plugin-proposal-object-rest-spread": "7.2.0", - "@babel/plugin-proposal-optional-catch-binding": "7.2.0", - "@babel/plugin-proposal-unicode-property-regex": "7.2.0", - "@babel/plugin-syntax-async-generators": "7.2.0", - "@babel/plugin-syntax-object-rest-spread": "7.2.0", - "@babel/plugin-syntax-optional-catch-binding": "7.2.0", - "@babel/plugin-transform-arrow-functions": "7.2.0", - "@babel/plugin-transform-async-to-generator": "7.2.0", - "@babel/plugin-transform-block-scoped-functions": "7.2.0", - "@babel/plugin-transform-block-scoping": "7.2.0", - "@babel/plugin-transform-classes": "7.2.2", - "@babel/plugin-transform-computed-properties": "7.2.0", - "@babel/plugin-transform-destructuring": "7.2.0", - "@babel/plugin-transform-dotall-regex": "7.2.0", - "@babel/plugin-transform-duplicate-keys": "7.2.0", - "@babel/plugin-transform-exponentiation-operator": "7.2.0", - "@babel/plugin-transform-for-of": "7.2.0", - "@babel/plugin-transform-function-name": "7.2.0", - "@babel/plugin-transform-literals": "7.2.0", - "@babel/plugin-transform-modules-amd": "7.2.0", - "@babel/plugin-transform-modules-commonjs": "7.2.0", - "@babel/plugin-transform-modules-systemjs": "7.2.0", - "@babel/plugin-transform-modules-umd": "7.2.0", - "@babel/plugin-transform-new-target": "7.0.0", - "@babel/plugin-transform-object-super": "7.2.0", - "@babel/plugin-transform-parameters": "7.2.0", - "@babel/plugin-transform-regenerator": "7.0.0", - "@babel/plugin-transform-shorthand-properties": "7.2.0", - "@babel/plugin-transform-spread": "7.2.2", - "@babel/plugin-transform-sticky-regex": "7.2.0", - "@babel/plugin-transform-template-literals": "7.2.0", - "@babel/plugin-transform-typeof-symbol": "7.2.0", - "@babel/plugin-transform-unicode-regex": "7.2.0", - "browserslist": "4.4.1", - "invariant": "2.2.3", - "js-levenshtein": "1.1.6", - "semver": "5.5.0" + "@babel/helper-module-imports": "^7.0.0", + "@babel/helper-plugin-utils": "^7.0.0", + "@babel/plugin-proposal-async-generator-functions": "^7.2.0", + "@babel/plugin-proposal-json-strings": "^7.2.0", + "@babel/plugin-proposal-object-rest-spread": "^7.2.0", + "@babel/plugin-proposal-optional-catch-binding": "^7.2.0", + "@babel/plugin-proposal-unicode-property-regex": "^7.2.0", + "@babel/plugin-syntax-async-generators": "^7.2.0", + "@babel/plugin-syntax-object-rest-spread": "^7.2.0", + "@babel/plugin-syntax-optional-catch-binding": "^7.2.0", + "@babel/plugin-transform-arrow-functions": "^7.2.0", + "@babel/plugin-transform-async-to-generator": "^7.2.0", + "@babel/plugin-transform-block-scoped-functions": "^7.2.0", + "@babel/plugin-transform-block-scoping": "^7.2.0", + "@babel/plugin-transform-classes": "^7.2.0", + "@babel/plugin-transform-computed-properties": "^7.2.0", + "@babel/plugin-transform-destructuring": "^7.2.0", + "@babel/plugin-transform-dotall-regex": "^7.2.0", + "@babel/plugin-transform-duplicate-keys": "^7.2.0", + "@babel/plugin-transform-exponentiation-operator": "^7.2.0", + "@babel/plugin-transform-for-of": "^7.2.0", + "@babel/plugin-transform-function-name": "^7.2.0", + "@babel/plugin-transform-literals": "^7.2.0", + "@babel/plugin-transform-modules-amd": "^7.2.0", + "@babel/plugin-transform-modules-commonjs": "^7.2.0", + "@babel/plugin-transform-modules-systemjs": "^7.2.0", + "@babel/plugin-transform-modules-umd": "^7.2.0", + "@babel/plugin-transform-new-target": "^7.0.0", + "@babel/plugin-transform-object-super": "^7.2.0", + "@babel/plugin-transform-parameters": "^7.2.0", + "@babel/plugin-transform-regenerator": "^7.0.0", + "@babel/plugin-transform-shorthand-properties": "^7.2.0", + "@babel/plugin-transform-spread": "^7.2.0", + "@babel/plugin-transform-sticky-regex": "^7.2.0", + "@babel/plugin-transform-template-literals": "^7.2.0", + "@babel/plugin-transform-typeof-symbol": "^7.2.0", + "@babel/plugin-transform-unicode-regex": "^7.2.0", + "browserslist": "^4.3.4", + "invariant": "^2.2.2", + "js-levenshtein": "^1.1.3", + "semver": "^5.3.0" } }, "@babel/preset-flow": { @@ -1313,8 +1313,8 @@ "integrity": "sha512-bJOHrYOPqJZCkPVbG1Lot2r5OSsB+iUOaxiHdlOeB1yPWS6evswVHwvkDLZ54WTaTRIk89ds0iHmGZSnxlPejQ==", "dev": true, "requires": { - "@babel/helper-plugin-utils": "7.0.0", - "@babel/plugin-transform-flow-strip-types": "7.2.3" + "@babel/helper-plugin-utils": "^7.0.0", + "@babel/plugin-transform-flow-strip-types": "^7.0.0" } }, "@babel/preset-react": { @@ -1323,11 +1323,11 @@ "integrity": "sha512-oayxyPS4Zj+hF6Et11BwuBkmpgT/zMxyuZgFrMeZID6Hdh3dGlk4sHCAhdBCpuCKW2ppBfl2uCCetlrUIJRY3w==", "dev": true, "requires": { - "@babel/helper-plugin-utils": "7.0.0", - "@babel/plugin-transform-react-display-name": "7.2.0", - "@babel/plugin-transform-react-jsx": "7.2.0", - "@babel/plugin-transform-react-jsx-self": "7.2.0", - "@babel/plugin-transform-react-jsx-source": "7.2.0" + "@babel/helper-plugin-utils": "^7.0.0", + "@babel/plugin-transform-react-display-name": "^7.0.0", + "@babel/plugin-transform-react-jsx": "^7.0.0", + "@babel/plugin-transform-react-jsx-self": "^7.0.0", + "@babel/plugin-transform-react-jsx-source": "^7.0.0" } }, "@babel/runtime": { @@ -1335,7 +1335,7 @@ "resolved": "https://registry.npmjs.org/@babel/runtime/-/runtime-7.2.0.tgz", "integrity": "sha512-oouEibCbHMVdZSDlJBO6bZmID/zA/G/Qx3H1d3rSNPTD+L8UNKvCat7aKWSJ74zYbm5zWGh0GQN0hKj8zYFTCg==", "requires": { - "regenerator-runtime": "0.12.1" + "regenerator-runtime": "^0.12.0" } }, "@babel/template": { @@ -1344,9 +1344,9 @@ "integrity": "sha512-zRL0IMM02AUDwghf5LMSSDEz7sBCO2YnNmpg3uWTZj/v1rcG2BmQUvaGU8GhU8BvfMh1k2KIAYZ7Ji9KXPUg7g==", "dev": true, "requires": { - "@babel/code-frame": "7.0.0", - "@babel/parser": "7.2.3", - "@babel/types": "7.2.2" + "@babel/code-frame": "^7.0.0", + "@babel/parser": "^7.2.2", + "@babel/types": "^7.2.2" } }, "@babel/traverse": { @@ -1355,15 +1355,15 @@ "integrity": "sha512-Z31oUD/fJvEWVR0lNZtfgvVt512ForCTNKYcJBGbPb1QZfve4WGH8Wsy7+Mev33/45fhP/hwQtvgusNdcCMgSw==", "dev": true, "requires": { - "@babel/code-frame": "7.0.0", - "@babel/generator": "7.2.2", - "@babel/helper-function-name": "7.1.0", - "@babel/helper-split-export-declaration": "7.0.0", - "@babel/parser": "7.2.3", - "@babel/types": "7.2.2", - "debug": "4.1.1", - "globals": "11.10.0", - "lodash": "4.17.11" + "@babel/code-frame": "^7.0.0", + "@babel/generator": "^7.2.2", + "@babel/helper-function-name": "^7.1.0", + "@babel/helper-split-export-declaration": "^7.0.0", + "@babel/parser": "^7.2.3", + "@babel/types": "^7.2.2", + "debug": "^4.1.0", + "globals": "^11.1.0", + "lodash": "^4.17.10" }, "dependencies": { "debug": { @@ -1372,7 +1372,7 @@ "integrity": "sha512-pYAIzeRo8J6KPEaJ0VWOh5Pzkbw/RetuzehGM7QRRX5he4fPHx2rdKMB256ehJCkX+XRQm16eZLqLNS8RSZXZw==", "dev": true, "requires": { - "ms": "2.1.1" + "ms": "^2.1.1" } }, "globals": { @@ -1395,9 +1395,9 @@ "integrity": "sha512-fKCuD6UFUMkR541eDWL+2ih/xFZBXPOg/7EQFeTluMDebfqR4jrpaCjLhkWlQS4hT6nRa2PMEgXKbRB5/H2fpg==", "dev": true, "requires": { - "esutils": "2.0.2", - "lodash": "4.17.11", - "to-fast-properties": "2.0.0" + "esutils": "^2.0.2", + "lodash": "^4.17.10", + "to-fast-properties": "^2.0.0" }, "dependencies": { "to-fast-properties": { @@ -1408,176 +1408,253 @@ } } }, + "@fortawesome/fontawesome-common-types": { + "version": "0.2.19", + "resolved": "https://registry.npmjs.org/@fortawesome/fontawesome-common-types/-/fontawesome-common-types-0.2.19.tgz", + "integrity": "sha512-nd2Ul/CUs8U9sjofQYAALzOGpgkVJQgEhIJnOHaoyVR/LeC3x2mVg4eB910a4kS6WgLPebAY0M2fApEI497raQ==" + }, + "@fortawesome/fontawesome-svg-core": { + "version": "1.2.19", + "resolved": "https://registry.npmjs.org/@fortawesome/fontawesome-svg-core/-/fontawesome-svg-core-1.2.19.tgz", + "integrity": "sha512-D4ICXg9oU08eF9o7Or392gPpjmwwgJu8ecCFusthbID95CLVXOgIyd4mOKD9Nud5Ckz+Ty59pqkNtThDKR0erA==", + "requires": { + "@fortawesome/fontawesome-common-types": "^0.2.19" + } + }, + "@fortawesome/free-solid-svg-icons": { + "version": "5.9.0", + "resolved": "https://registry.npmjs.org/@fortawesome/free-solid-svg-icons/-/free-solid-svg-icons-5.9.0.tgz", + "integrity": "sha512-U8YXPfWcSozsCW0psCtlRGKjjRs5+Am5JJwLOUmVHFZbIEWzaz4YbP84EoPwUsVmSAKrisu3QeNcVOtmGml0Xw==", + "requires": { + "@fortawesome/fontawesome-common-types": "^0.2.19" + } + }, + "@fortawesome/react-fontawesome": { + "version": "0.1.4", + "resolved": "https://registry.npmjs.org/@fortawesome/react-fontawesome/-/react-fontawesome-0.1.4.tgz", + "integrity": "sha512-GwmxQ+TK7PEdfSwvxtGnMCqrfEm0/HbRHArbUudsYiy9KzVCwndxa2KMcfyTQ8El0vROrq8gOOff09RF1oQe8g==", + "requires": { + "humps": "^2.0.1", + "prop-types": "^15.5.10" + } + }, + "@types/events": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/@types/events/-/events-3.0.0.tgz", + "integrity": "sha512-EaObqwIvayI5a8dCzhFrjKzVwKLxjoG9T6Ppd5CEo07LRKfQ8Yokw54r5+Wq7FaBQ+yXRvQAYPrHwya1/UFt9g==", + "dev": true + }, + "@types/glob": { + "version": "7.1.1", + "resolved": "https://registry.npmjs.org/@types/glob/-/glob-7.1.1.tgz", + "integrity": "sha512-1Bh06cbWJUHMC97acuD6UMG29nMt0Aqz1vF3guLfG+kHHJhy3AyohZFFxYk2f7Q1SQIrNwvncxAE0N/9s70F2w==", + "dev": true, + "requires": { + "@types/events": "*", + "@types/minimatch": "*", + "@types/node": "*" + } + }, + "@types/minimatch": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/@types/minimatch/-/minimatch-3.0.3.tgz", + "integrity": "sha512-tHq6qdbT9U1IRSGf14CL0pUlULksvY9OZ+5eEgl1N7t+OA3tGvNpxJCzuKQlsNgCVwbAs670L1vcVQi8j9HjnA==", + "dev": true + }, + "@types/node": { + "version": "12.12.14", + "resolved": "https://registry.npmjs.org/@types/node/-/node-12.12.14.tgz", + "integrity": "sha512-u/SJDyXwuihpwjXy7hOOghagLEV1KdAST6syfnOk6QZAMzZuWZqXy5aYYZbh8Jdpd4escVFP0MvftHNDb9pruA==", + "dev": true + }, + "@types/prop-types": { + "version": "15.7.1", + "resolved": "https://registry.npmjs.org/@types/prop-types/-/prop-types-15.7.1.tgz", + "integrity": "sha512-CFzn9idOEpHrgdw8JsoTkaDDyRWk1jrzIV8djzcgpq0y9tG4B4lFT+Nxh52DVpDXV+n4+NPNv7M1Dj5uMp6XFg==" + }, + "@types/react": { + "version": "16.8.23", + "resolved": "https://registry.npmjs.org/@types/react/-/react-16.8.23.tgz", + "integrity": "sha512-abkEOIeljniUN9qB5onp++g0EY38h7atnDHxwKUFz1r3VH1+yG1OKi2sNPTyObL40goBmfKFpdii2lEzwLX1cA==", + "requires": { + "@types/prop-types": "*", + "csstype": "^2.2.0" + } + }, "@webassemblyjs/ast": { - "version": "1.7.11", - "resolved": "https://registry.npmjs.org/@webassemblyjs/ast/-/ast-1.7.11.tgz", - "integrity": "sha512-ZEzy4vjvTzScC+SH8RBssQUawpaInUdMTYwYYLh54/s8TuT0gBLuyUnppKsVyZEi876VmmStKsUs28UxPgdvrA==", + "version": "1.8.5", + "resolved": "https://registry.npmjs.org/@webassemblyjs/ast/-/ast-1.8.5.tgz", + "integrity": "sha512-aJMfngIZ65+t71C3y2nBBg5FFG0Okt9m0XEgWZ7Ywgn1oMAT8cNwx00Uv1cQyHtidq0Xn94R4TAywO+LCQ+ZAQ==", "dev": true, "requires": { - "@webassemblyjs/helper-module-context": "1.7.11", - "@webassemblyjs/helper-wasm-bytecode": "1.7.11", - "@webassemblyjs/wast-parser": "1.7.11" + "@webassemblyjs/helper-module-context": "1.8.5", + "@webassemblyjs/helper-wasm-bytecode": "1.8.5", + "@webassemblyjs/wast-parser": "1.8.5" } }, "@webassemblyjs/floating-point-hex-parser": { - "version": "1.7.11", - "resolved": "https://registry.npmjs.org/@webassemblyjs/floating-point-hex-parser/-/floating-point-hex-parser-1.7.11.tgz", - "integrity": "sha512-zY8dSNyYcgzNRNT666/zOoAyImshm3ycKdoLsyDw/Bwo6+/uktb7p4xyApuef1dwEBo/U/SYQzbGBvV+nru2Xg==", + "version": "1.8.5", + "resolved": "https://registry.npmjs.org/@webassemblyjs/floating-point-hex-parser/-/floating-point-hex-parser-1.8.5.tgz", + "integrity": "sha512-9p+79WHru1oqBh9ewP9zW95E3XAo+90oth7S5Re3eQnECGq59ly1Ri5tsIipKGpiStHsUYmY3zMLqtk3gTcOtQ==", "dev": true }, "@webassemblyjs/helper-api-error": { - "version": "1.7.11", - "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-api-error/-/helper-api-error-1.7.11.tgz", - "integrity": "sha512-7r1qXLmiglC+wPNkGuXCvkmalyEstKVwcueZRP2GNC2PAvxbLYwLLPr14rcdJaE4UtHxQKfFkuDFuv91ipqvXg==", + "version": "1.8.5", + "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-api-error/-/helper-api-error-1.8.5.tgz", + "integrity": "sha512-Za/tnzsvnqdaSPOUXHyKJ2XI7PDX64kWtURyGiJJZKVEdFOsdKUCPTNEVFZq3zJ2R0G5wc2PZ5gvdTRFgm81zA==", "dev": true }, "@webassemblyjs/helper-buffer": { - "version": "1.7.11", - "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-buffer/-/helper-buffer-1.7.11.tgz", - "integrity": "sha512-MynuervdylPPh3ix+mKZloTcL06P8tenNH3sx6s0qE8SLR6DdwnfgA7Hc9NSYeob2jrW5Vql6GVlsQzKQCa13w==", + "version": "1.8.5", + "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-buffer/-/helper-buffer-1.8.5.tgz", + "integrity": "sha512-Ri2R8nOS0U6G49Q86goFIPNgjyl6+oE1abW1pS84BuhP1Qcr5JqMwRFT3Ah3ADDDYGEgGs1iyb1DGX+kAi/c/Q==", "dev": true }, "@webassemblyjs/helper-code-frame": { - "version": "1.7.11", - "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-code-frame/-/helper-code-frame-1.7.11.tgz", - "integrity": "sha512-T8ESC9KMXFTXA5urJcyor5cn6qWeZ4/zLPyWeEXZ03hj/x9weSokGNkVCdnhSabKGYWxElSdgJ+sFa9G/RdHNw==", + "version": "1.8.5", + "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-code-frame/-/helper-code-frame-1.8.5.tgz", + "integrity": "sha512-VQAadSubZIhNpH46IR3yWO4kZZjMxN1opDrzePLdVKAZ+DFjkGD/rf4v1jap744uPVU6yjL/smZbRIIJTOUnKQ==", "dev": true, "requires": { - "@webassemblyjs/wast-printer": "1.7.11" + "@webassemblyjs/wast-printer": "1.8.5" } }, "@webassemblyjs/helper-fsm": { - "version": "1.7.11", - "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-fsm/-/helper-fsm-1.7.11.tgz", - "integrity": "sha512-nsAQWNP1+8Z6tkzdYlXT0kxfa2Z1tRTARd8wYnc/e3Zv3VydVVnaeePgqUzFrpkGUyhUUxOl5ML7f1NuT+gC0A==", + "version": "1.8.5", + "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-fsm/-/helper-fsm-1.8.5.tgz", + "integrity": "sha512-kRuX/saORcg8se/ft6Q2UbRpZwP4y7YrWsLXPbbmtepKr22i8Z4O3V5QE9DbZK908dh5Xya4Un57SDIKwB9eow==", "dev": true }, "@webassemblyjs/helper-module-context": { - "version": "1.7.11", - "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-module-context/-/helper-module-context-1.7.11.tgz", - "integrity": "sha512-JxfD5DX8Ygq4PvXDucq0M+sbUFA7BJAv/GGl9ITovqE+idGX+J3QSzJYz+LwQmL7fC3Rs+utvWoJxDb6pmC0qg==", - "dev": true + "version": "1.8.5", + "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-module-context/-/helper-module-context-1.8.5.tgz", + "integrity": "sha512-/O1B236mN7UNEU4t9X7Pj38i4VoU8CcMHyy3l2cV/kIF4U5KoHXDVqcDuOs1ltkac90IM4vZdHc52t1x8Yfs3g==", + "dev": true, + "requires": { + "@webassemblyjs/ast": "1.8.5", + "mamacro": "^0.0.3" + } }, "@webassemblyjs/helper-wasm-bytecode": { - "version": "1.7.11", - "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-wasm-bytecode/-/helper-wasm-bytecode-1.7.11.tgz", - "integrity": "sha512-cMXeVS9rhoXsI9LLL4tJxBgVD/KMOKXuFqYb5oCJ/opScWpkCMEz9EJtkonaNcnLv2R3K5jIeS4TRj/drde1JQ==", + "version": "1.8.5", + "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-wasm-bytecode/-/helper-wasm-bytecode-1.8.5.tgz", + "integrity": "sha512-Cu4YMYG3Ddl72CbmpjU/wbP6SACcOPVbHN1dI4VJNJVgFwaKf1ppeFJrwydOG3NDHxVGuCfPlLZNyEdIYlQ6QQ==", "dev": true }, "@webassemblyjs/helper-wasm-section": { - "version": "1.7.11", - "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-wasm-section/-/helper-wasm-section-1.7.11.tgz", - "integrity": "sha512-8ZRY5iZbZdtNFE5UFunB8mmBEAbSI3guwbrsCl4fWdfRiAcvqQpeqd5KHhSWLL5wuxo53zcaGZDBU64qgn4I4Q==", + "version": "1.8.5", + "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-wasm-section/-/helper-wasm-section-1.8.5.tgz", + "integrity": "sha512-VV083zwR+VTrIWWtgIUpqfvVdK4ff38loRmrdDBgBT8ADXYsEZ5mPQ4Nde90N3UYatHdYoDIFb7oHzMncI02tA==", "dev": true, "requires": { - "@webassemblyjs/ast": "1.7.11", - "@webassemblyjs/helper-buffer": "1.7.11", - "@webassemblyjs/helper-wasm-bytecode": "1.7.11", - "@webassemblyjs/wasm-gen": "1.7.11" + "@webassemblyjs/ast": "1.8.5", + "@webassemblyjs/helper-buffer": "1.8.5", + "@webassemblyjs/helper-wasm-bytecode": "1.8.5", + "@webassemblyjs/wasm-gen": "1.8.5" } }, "@webassemblyjs/ieee754": { - "version": "1.7.11", - "resolved": "https://registry.npmjs.org/@webassemblyjs/ieee754/-/ieee754-1.7.11.tgz", - "integrity": "sha512-Mmqx/cS68K1tSrvRLtaV/Lp3NZWzXtOHUW2IvDvl2sihAwJh4ACE0eL6A8FvMyDG9abes3saB6dMimLOs+HMoQ==", + "version": "1.8.5", + "resolved": "https://registry.npmjs.org/@webassemblyjs/ieee754/-/ieee754-1.8.5.tgz", + "integrity": "sha512-aaCvQYrvKbY/n6wKHb/ylAJr27GglahUO89CcGXMItrOBqRarUMxWLJgxm9PJNuKULwN5n1csT9bYoMeZOGF3g==", "dev": true, "requires": { - "@xtuc/ieee754": "1.2.0" + "@xtuc/ieee754": "^1.2.0" } }, "@webassemblyjs/leb128": { - "version": "1.7.11", - "resolved": "https://registry.npmjs.org/@webassemblyjs/leb128/-/leb128-1.7.11.tgz", - "integrity": "sha512-vuGmgZjjp3zjcerQg+JA+tGOncOnJLWVkt8Aze5eWQLwTQGNgVLcyOTqgSCxWTR4J42ijHbBxnuRaL1Rv7XMdw==", + "version": "1.8.5", + "resolved": "https://registry.npmjs.org/@webassemblyjs/leb128/-/leb128-1.8.5.tgz", + "integrity": "sha512-plYUuUwleLIziknvlP8VpTgO4kqNaH57Y3JnNa6DLpu/sGcP6hbVdfdX5aHAV716pQBKrfuU26BJK29qY37J7A==", "dev": true, "requires": { - "@xtuc/long": "4.2.1" + "@xtuc/long": "4.2.2" } }, "@webassemblyjs/utf8": { - "version": "1.7.11", - "resolved": "https://registry.npmjs.org/@webassemblyjs/utf8/-/utf8-1.7.11.tgz", - "integrity": "sha512-C6GFkc7aErQIAH+BMrIdVSmW+6HSe20wg57HEC1uqJP8E/xpMjXqQUxkQw07MhNDSDcGpxI9G5JSNOQCqJk4sA==", + "version": "1.8.5", + "resolved": "https://registry.npmjs.org/@webassemblyjs/utf8/-/utf8-1.8.5.tgz", + "integrity": "sha512-U7zgftmQriw37tfD934UNInokz6yTmn29inT2cAetAsaU9YeVCveWEwhKL1Mg4yS7q//NGdzy79nlXh3bT8Kjw==", "dev": true }, "@webassemblyjs/wasm-edit": { - "version": "1.7.11", - "resolved": "https://registry.npmjs.org/@webassemblyjs/wasm-edit/-/wasm-edit-1.7.11.tgz", - "integrity": "sha512-FUd97guNGsCZQgeTPKdgxJhBXkUbMTY6hFPf2Y4OedXd48H97J+sOY2Ltaq6WGVpIH8o/TGOVNiVz/SbpEMJGg==", + "version": "1.8.5", + "resolved": "https://registry.npmjs.org/@webassemblyjs/wasm-edit/-/wasm-edit-1.8.5.tgz", + "integrity": "sha512-A41EMy8MWw5yvqj7MQzkDjU29K7UJq1VrX2vWLzfpRHt3ISftOXqrtojn7nlPsZ9Ijhp5NwuODuycSvfAO/26Q==", "dev": true, "requires": { - "@webassemblyjs/ast": "1.7.11", - "@webassemblyjs/helper-buffer": "1.7.11", - "@webassemblyjs/helper-wasm-bytecode": "1.7.11", - "@webassemblyjs/helper-wasm-section": "1.7.11", - "@webassemblyjs/wasm-gen": "1.7.11", - "@webassemblyjs/wasm-opt": "1.7.11", - "@webassemblyjs/wasm-parser": "1.7.11", - "@webassemblyjs/wast-printer": "1.7.11" + "@webassemblyjs/ast": "1.8.5", + "@webassemblyjs/helper-buffer": "1.8.5", + "@webassemblyjs/helper-wasm-bytecode": "1.8.5", + "@webassemblyjs/helper-wasm-section": "1.8.5", + "@webassemblyjs/wasm-gen": "1.8.5", + "@webassemblyjs/wasm-opt": "1.8.5", + "@webassemblyjs/wasm-parser": "1.8.5", + "@webassemblyjs/wast-printer": "1.8.5" } }, "@webassemblyjs/wasm-gen": { - "version": "1.7.11", - "resolved": "https://registry.npmjs.org/@webassemblyjs/wasm-gen/-/wasm-gen-1.7.11.tgz", - "integrity": "sha512-U/KDYp7fgAZX5KPfq4NOupK/BmhDc5Kjy2GIqstMhvvdJRcER/kUsMThpWeRP8BMn4LXaKhSTggIJPOeYHwISA==", + "version": "1.8.5", + "resolved": "https://registry.npmjs.org/@webassemblyjs/wasm-gen/-/wasm-gen-1.8.5.tgz", + "integrity": "sha512-BCZBT0LURC0CXDzj5FXSc2FPTsxwp3nWcqXQdOZE4U7h7i8FqtFK5Egia6f9raQLpEKT1VL7zr4r3+QX6zArWg==", "dev": true, "requires": { - "@webassemblyjs/ast": "1.7.11", - "@webassemblyjs/helper-wasm-bytecode": "1.7.11", - "@webassemblyjs/ieee754": "1.7.11", - "@webassemblyjs/leb128": "1.7.11", - "@webassemblyjs/utf8": "1.7.11" + "@webassemblyjs/ast": "1.8.5", + "@webassemblyjs/helper-wasm-bytecode": "1.8.5", + "@webassemblyjs/ieee754": "1.8.5", + "@webassemblyjs/leb128": "1.8.5", + "@webassemblyjs/utf8": "1.8.5" } }, "@webassemblyjs/wasm-opt": { - "version": "1.7.11", - "resolved": "https://registry.npmjs.org/@webassemblyjs/wasm-opt/-/wasm-opt-1.7.11.tgz", - "integrity": "sha512-XynkOwQyiRidh0GLua7SkeHvAPXQV/RxsUeERILmAInZegApOUAIJfRuPYe2F7RcjOC9tW3Cb9juPvAC/sCqvg==", + "version": "1.8.5", + "resolved": "https://registry.npmjs.org/@webassemblyjs/wasm-opt/-/wasm-opt-1.8.5.tgz", + "integrity": "sha512-HKo2mO/Uh9A6ojzu7cjslGaHaUU14LdLbGEKqTR7PBKwT6LdPtLLh9fPY33rmr5wcOMrsWDbbdCHq4hQUdd37Q==", "dev": true, "requires": { - "@webassemblyjs/ast": "1.7.11", - "@webassemblyjs/helper-buffer": "1.7.11", - "@webassemblyjs/wasm-gen": "1.7.11", - "@webassemblyjs/wasm-parser": "1.7.11" + "@webassemblyjs/ast": "1.8.5", + "@webassemblyjs/helper-buffer": "1.8.5", + "@webassemblyjs/wasm-gen": "1.8.5", + "@webassemblyjs/wasm-parser": "1.8.5" } }, "@webassemblyjs/wasm-parser": { - "version": "1.7.11", - "resolved": "https://registry.npmjs.org/@webassemblyjs/wasm-parser/-/wasm-parser-1.7.11.tgz", - "integrity": "sha512-6lmXRTrrZjYD8Ng8xRyvyXQJYUQKYSXhJqXOBLw24rdiXsHAOlvw5PhesjdcaMadU/pyPQOJ5dHreMjBxwnQKg==", + "version": "1.8.5", + "resolved": "https://registry.npmjs.org/@webassemblyjs/wasm-parser/-/wasm-parser-1.8.5.tgz", + "integrity": "sha512-pi0SYE9T6tfcMkthwcgCpL0cM9nRYr6/6fjgDtL6q/ZqKHdMWvxitRi5JcZ7RI4SNJJYnYNaWy5UUrHQy998lw==", "dev": true, "requires": { - "@webassemblyjs/ast": "1.7.11", - "@webassemblyjs/helper-api-error": "1.7.11", - "@webassemblyjs/helper-wasm-bytecode": "1.7.11", - "@webassemblyjs/ieee754": "1.7.11", - "@webassemblyjs/leb128": "1.7.11", - "@webassemblyjs/utf8": "1.7.11" + "@webassemblyjs/ast": "1.8.5", + "@webassemblyjs/helper-api-error": "1.8.5", + "@webassemblyjs/helper-wasm-bytecode": "1.8.5", + "@webassemblyjs/ieee754": "1.8.5", + "@webassemblyjs/leb128": "1.8.5", + "@webassemblyjs/utf8": "1.8.5" } }, "@webassemblyjs/wast-parser": { - "version": "1.7.11", - "resolved": "https://registry.npmjs.org/@webassemblyjs/wast-parser/-/wast-parser-1.7.11.tgz", - "integrity": "sha512-lEyVCg2np15tS+dm7+JJTNhNWq9yTZvi3qEhAIIOaofcYlUp0UR5/tVqOwa/gXYr3gjwSZqw+/lS9dscyLelbQ==", + "version": "1.8.5", + "resolved": "https://registry.npmjs.org/@webassemblyjs/wast-parser/-/wast-parser-1.8.5.tgz", + "integrity": "sha512-daXC1FyKWHF1i11obK086QRlsMsY4+tIOKgBqI1lxAnkp9xe9YMcgOxm9kLe+ttjs5aWV2KKE1TWJCN57/Btsg==", "dev": true, "requires": { - "@webassemblyjs/ast": "1.7.11", - "@webassemblyjs/floating-point-hex-parser": "1.7.11", - "@webassemblyjs/helper-api-error": "1.7.11", - "@webassemblyjs/helper-code-frame": "1.7.11", - "@webassemblyjs/helper-fsm": "1.7.11", - "@xtuc/long": "4.2.1" + "@webassemblyjs/ast": "1.8.5", + "@webassemblyjs/floating-point-hex-parser": "1.8.5", + "@webassemblyjs/helper-api-error": "1.8.5", + "@webassemblyjs/helper-code-frame": "1.8.5", + "@webassemblyjs/helper-fsm": "1.8.5", + "@xtuc/long": "4.2.2" } }, "@webassemblyjs/wast-printer": { - "version": "1.7.11", - "resolved": "https://registry.npmjs.org/@webassemblyjs/wast-printer/-/wast-printer-1.7.11.tgz", - "integrity": "sha512-m5vkAsuJ32QpkdkDOUPGSltrg8Cuk3KBx4YrmAGQwCZPRdUHXxG4phIOuuycLemHFr74sWL9Wthqss4fzdzSwg==", + "version": "1.8.5", + "resolved": "https://registry.npmjs.org/@webassemblyjs/wast-printer/-/wast-printer-1.8.5.tgz", + "integrity": "sha512-w0U0pD4EhlnvRyeJzBqaVSJAo9w/ce7/WPogeXLzGkO6hzhr4GnQIZ4W4uUt5b9ooAaXPtnXlj0gzsXEOUNYMg==", "dev": true, "requires": { - "@webassemblyjs/ast": "1.7.11", - "@webassemblyjs/wast-parser": "1.7.11", - "@xtuc/long": "4.2.1" + "@webassemblyjs/ast": "1.8.5", + "@webassemblyjs/wast-parser": "1.8.5", + "@xtuc/long": "4.2.2" } }, "@xtuc/ieee754": { @@ -1587,40 +1664,49 @@ "dev": true }, "@xtuc/long": { - "version": "4.2.1", - "resolved": "https://registry.npmjs.org/@xtuc/long/-/long-4.2.1.tgz", - "integrity": "sha512-FZdkNBDqBRHKQ2MEbSC17xnPFOhZxeJ2YGSfr2BKf3sujG49Qe3bB+rGCwQfIaA7WHnGeGkSijX4FuBCdrzW/g==", + "version": "4.2.2", + "resolved": "https://registry.npmjs.org/@xtuc/long/-/long-4.2.2.tgz", + "integrity": "sha512-NuHqBY1PB/D8xU6s/thBgOAiAP7HOYDQ32+BFZILJ8ivkUkAHQnWfn6WhL79Owj1qmUnoN/YPhktdIoucipkAQ==", "dev": true }, "abbrev": { "version": "1.1.1", "resolved": "https://registry.npmjs.org/abbrev/-/abbrev-1.1.1.tgz", - "integrity": "sha1-+PLIh60Qv2f2NPAFtph/7TF5qsg=", + "integrity": "sha512-nne9/IiQ/hzIhY6pdDnbBtz7DjPTKrY00P/zvPSm5pOFkl6xuGrGnXn/VtTNNfNtAfZ9/1RtehkszU9qcTii0Q==", "dev": true }, "accepts": { - "version": "1.3.5", - "resolved": "https://registry.npmjs.org/accepts/-/accepts-1.3.5.tgz", - "integrity": "sha1-63d99gEXI6OxTopywIBcjoZ0a9I=", + "version": "1.3.7", + "resolved": "https://registry.npmjs.org/accepts/-/accepts-1.3.7.tgz", + "integrity": "sha512-Il80Qs2WjYlJIBNzNkK6KYqlVMTbZLXgHx2oT0pU/fjRHyEp+PEfEPY0R3WCwAGVOtauxh1hOxNgIf5bv7dQpA==", "dev": true, "requires": { - "mime-types": "2.1.18", - "negotiator": "0.6.1" + "mime-types": "~2.1.24", + "negotiator": "0.6.2" + }, + "dependencies": { + "mime-db": { + "version": "1.42.0", + "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.42.0.tgz", + "integrity": "sha512-UbfJCR4UAVRNgMpfImz05smAXK7+c+ZntjaA26ANtkXLlOe947Aag5zdIcKQULAiF9Cq4WxBi9jUs5zkA84bYQ==", + "dev": true + }, + "mime-types": { + "version": "2.1.25", + "resolved": "https://registry.npmjs.org/mime-types/-/mime-types-2.1.25.tgz", + "integrity": "sha512-5KhStqB5xpTAeGqKBAMgwaYMnQik7teQN4IAzC7npDv6kzeU6prfkR67bc87J1kWMPGkoaZSq1npmexMgkmEVg==", + "dev": true, + "requires": { + "mime-db": "1.42.0" + } + } } }, "acorn": { - "version": "5.5.3", - "resolved": "https://registry.npmjs.org/acorn/-/acorn-5.5.3.tgz", - "integrity": "sha1-9HPdR+AnegjijpvsWu6wR1HwuMk=" - }, - "acorn-dynamic-import": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/acorn-dynamic-import/-/acorn-dynamic-import-3.0.0.tgz", - "integrity": "sha512-zVWV8Z8lislJoOKKqdNMOB+s6+XV5WERty8MnKBeFgwA+19XJjJHs2RP5dzM57FftIs+jQnRToLiWazKr6sSWg==", - "dev": true, - "requires": { - "acorn": "5.5.3" - } + "version": "6.1.1", + "resolved": "https://registry.npmjs.org/acorn/-/acorn-6.1.1.tgz", + "integrity": "sha512-jPTiwtOxaHNaAPg/dmrJ/beuzLRnXtB0kQPQ8JpotKJgTB6rX6c8mlf315941pyjBSaPg8NHXS9fhP4u17DpGA==", + "dev": true }, "acorn-jsx": { "version": "5.0.1", @@ -1634,13 +1720,13 @@ "integrity": "sha512-958oaHHVEXMvsY7v7cC5gEkNIcoaAVIhZ4mBReYVZJOTP9IgKmzLjIOhTtzpLMu+qriXvLsVjJ155EeInp45IQ==", "dev": true, "requires": { - "assert": "1.4.1", - "camelcase": "1.2.1", - "loader-utils": "1.2.3", - "lodash.assign": "4.2.0", - "lodash.defaults": "3.1.2", - "object-path": "0.9.2", - "regex-parser": "2.2.10" + "assert": "^1.3.0", + "camelcase": "^1.2.1", + "loader-utils": "^1.1.0", + "lodash.assign": "^4.0.1", + "lodash.defaults": "^3.1.2", + "object-path": "^0.9.2", + "regex-parser": "^2.2.9" }, "dependencies": { "big.js": { @@ -1661,7 +1747,7 @@ "integrity": "sha512-aKS4WQjPenRxiQsC93MNfjx+nbF4PAdYzmd/1JIj8HYzqfbu86beTuNgXDzPknWk0n0uARlyewZo4s++ES36Ow==", "dev": true, "requires": { - "minimist": "1.2.0" + "minimist": "^1.2.0" } }, "loader-utils": { @@ -1670,9 +1756,9 @@ "integrity": "sha512-fkpz8ejdnEMG3s37wGL07iSBDg99O9D5yflE9RGNH3hRdx9SOwYfnGYdZOUIZitN8E+E2vkq3MUMYMvPYl5ZZA==", "dev": true, "requires": { - "big.js": "5.2.2", - "emojis-list": "2.1.0", - "json5": "1.0.1" + "big.js": "^5.2.2", + "emojis-list": "^2.0.0", + "json5": "^1.0.1" } }, "lodash.defaults": { @@ -1681,8 +1767,8 @@ "integrity": "sha1-xzCLGNv4vJNy1wGnNJPGEZK9Liw=", "dev": true, "requires": { - "lodash.assign": "3.2.0", - "lodash.restparam": "3.6.1" + "lodash.assign": "^3.0.0", + "lodash.restparam": "^3.0.0" }, "dependencies": { "lodash.assign": { @@ -1691,9 +1777,9 @@ "integrity": "sha1-POnwI0tLIiPilrj6CsH+6OvKZPo=", "dev": true, "requires": { - "lodash._baseassign": "3.2.0", - "lodash._createassigner": "3.1.1", - "lodash.keys": "3.1.2" + "lodash._baseassign": "^3.0.0", + "lodash._createassigner": "^3.0.0", + "lodash.keys": "^3.0.0" } } } @@ -1711,10 +1797,10 @@ "resolved": "https://registry.npmjs.org/ajv/-/ajv-5.5.2.tgz", "integrity": "sha1-c7Xuyj+rZT49P5Qis0GtQiBdyWU=", "requires": { - "co": "4.6.0", - "fast-deep-equal": "1.1.0", - "fast-json-stable-stringify": "2.0.0", - "json-schema-traverse": "0.3.1" + "co": "^4.6.0", + "fast-deep-equal": "^1.0.0", + "fast-json-stable-stringify": "^2.0.0", + "json-schema-traverse": "^0.3.0" } }, "ajv-errors": { @@ -1735,9 +1821,9 @@ "dev": true }, "ansi-colors": { - "version": "3.2.3", - "resolved": "https://registry.npmjs.org/ansi-colors/-/ansi-colors-3.2.3.tgz", - "integrity": "sha512-LEHHyuhlPY3TmuUYMh2oz89lTShfvgbmzaBcxve9t/9Wuy7Dwf4yoAKcND7KFT1HAQfqZ12qtc+DUrBMeKF9nw==", + "version": "3.2.4", + "resolved": "https://registry.npmjs.org/ansi-colors/-/ansi-colors-3.2.4.tgz", + "integrity": "sha512-hHUXGagefjN2iRrID63xckIvotOXOojhQKWIPUZ4mNUZ9nLZW+7FMNoE1lOkEhNWYsx/7ysGIuJYCiMAA9FnrA==", "dev": true }, "ansi-escapes": { @@ -1767,8 +1853,19 @@ "integrity": "sha512-5teOsQWABXHHBFP9y3skS5P3d/WfWXpv3FUpy+LorMrNYaT9pI4oLMQX7jzQ2KklNpGpWHzdCXTDT2Y3XGlZBw==", "dev": true, "requires": { - "micromatch": "3.1.10", - "normalize-path": "2.1.1" + "micromatch": "^3.1.4", + "normalize-path": "^2.1.1" + }, + "dependencies": { + "normalize-path": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/normalize-path/-/normalize-path-2.1.1.tgz", + "integrity": "sha1-GrKLVW4Zg2Oowab35vogE3/mrtk=", + "dev": true, + "requires": { + "remove-trailing-separator": "^1.0.1" + } + } } }, "aproba": { @@ -1783,8 +1880,8 @@ "integrity": "sha512-5hYdAkZlcG8tOLujVDTgCT+uPX0VnpAH28gWsLfzpXYm7wP6mp5Q/gYyR7YQ0cKVJcXJnl3j2kpBan13PtQf6w==", "dev": true, "requires": { - "delegates": "1.0.0", - "readable-stream": "2.3.5" + "delegates": "^1.0.0", + "readable-stream": "^2.0.6" } }, "argparse": { @@ -1792,7 +1889,7 @@ "resolved": "https://registry.npmjs.org/argparse/-/argparse-1.0.10.tgz", "integrity": "sha512-o5Roy6tNG4SL/FOkCAN6RzjiakZS25RLYFrcMttJqbdd8BWrnA+fGz57iN5Pb06pvBGvl5gQ0B48dJlslXvoTg==", "requires": { - "sprintf-js": "1.0.3" + "sprintf-js": "~1.0.2" } }, "arr-diff": { @@ -1830,8 +1927,8 @@ "resolved": "https://registry.npmjs.org/array-includes/-/array-includes-3.0.3.tgz", "integrity": "sha1-GEtI9i2S10UrsxsyMWXH+L0CJm0=", "requires": { - "define-properties": "1.1.2", - "es-abstract": "1.10.0" + "define-properties": "^1.1.2", + "es-abstract": "^1.7.0" } }, "array-union": { @@ -1839,7 +1936,7 @@ "resolved": "https://registry.npmjs.org/array-union/-/array-union-1.0.2.tgz", "integrity": "sha1-mjRBDk9OPaI96jdb5b5w8kd47Dk=", "requires": { - "array-uniq": "1.0.3" + "array-uniq": "^1.0.1" } }, "array-uniq": { @@ -1875,9 +1972,9 @@ "integrity": "sha512-p32cOF5q0Zqs9uBiONKYLm6BClCoBCM5O9JfeUSlnQLBTxYdTK+pW+nXflm8UkKd2UYlEbYz5qEi0JuZR9ckSw==", "dev": true, "requires": { - "bn.js": "4.11.8", - "inherits": "2.0.1", - "minimalistic-assert": "1.0.1" + "bn.js": "^4.0.0", + "inherits": "^2.0.1", + "minimalistic-assert": "^1.0.0" } }, "assert": { @@ -1908,15 +2005,26 @@ "dev": true }, "async": { - "version": "1.5.2", - "resolved": "https://registry.npmjs.org/async/-/async-1.5.2.tgz", - "integrity": "sha1-7GphrlZIDAw8skHJVhjiCJL5Zyo=", - "dev": true + "version": "2.6.3", + "resolved": "https://registry.npmjs.org/async/-/async-2.6.3.tgz", + "integrity": "sha512-zflvls11DCy+dQWzTW2dzuilv8Z5X/pjfmZOWba6TNIVDm+2UDaJmXSOXlasHKfNBs8oo3M0aT50fDEWfKZjXg==", + "dev": true, + "requires": { + "lodash": "^4.17.14" + }, + "dependencies": { + "lodash": { + "version": "4.17.15", + "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.15.tgz", + "integrity": "sha512-8xOcRHvCjnocdS5cpwXQXVzmmh5e5+saE2QGoeQmbKmRS6J3VQppPOIt0MnmE+4xlZoumy0GPG0D0MVIQbNA1A==", + "dev": true + } + } }, "async-each": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/async-each/-/async-each-1.0.1.tgz", - "integrity": "sha1-GdOGodntxufByF04iu28xW0zYC0=", + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/async-each/-/async-each-1.0.3.tgz", + "integrity": "sha512-z/WhQ5FPySLdvREByI2vZiTWwCnF0moMJ1hK9YQwDTHKh6I7/uSckMetoRGb5UBZPC1z0jlw+n/XCgjeH7y1AQ==", "dev": true }, "async-foreach": { @@ -1925,6 +2033,12 @@ "integrity": "sha1-NhIfhFwFeBct5Bmpfb6x0W7DRUI=", "dev": true }, + "async-limiter": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/async-limiter/-/async-limiter-1.0.1.tgz", + "integrity": "sha512-csOlWGAcRFJaI6m+F2WKdnMKr4HhdhFVBk0H/QbJFMCr+uO2kwohwXQPxw/9OCxp05r5ghVBFSyioixx3gfkNQ==", + "dev": true + }, "asynckit": { "version": "0.4.0", "resolved": "https://registry.npmjs.org/asynckit/-/asynckit-0.4.0.tgz", @@ -1955,9 +2069,9 @@ "resolved": "https://registry.npmjs.org/babel-code-frame/-/babel-code-frame-6.26.0.tgz", "integrity": "sha1-Y/1D99weO7fONZR9uP42mj9Yx0s=", "requires": { - "chalk": "1.1.3", - "esutils": "2.0.2", - "js-tokens": "3.0.2" + "chalk": "^1.1.3", + "esutils": "^2.0.2", + "js-tokens": "^3.0.2" } }, "babel-eslint": { @@ -1966,12 +2080,12 @@ "integrity": "sha512-z7OT1iNV+TjOwHNLLyJk+HN+YVWX+CLE6fPD2SymJZOZQBs+QIexFjhm4keGTm8MW9xr4EC9Q0PbaLB24V5GoQ==", "dev": true, "requires": { - "@babel/code-frame": "7.0.0", - "@babel/parser": "7.2.3", - "@babel/traverse": "7.2.3", - "@babel/types": "7.2.2", + "@babel/code-frame": "^7.0.0", + "@babel/parser": "^7.0.0", + "@babel/traverse": "^7.0.0", + "@babel/types": "^7.0.0", "eslint-scope": "3.7.1", - "eslint-visitor-keys": "1.0.0" + "eslint-visitor-keys": "^1.0.0" } }, "babel-loader": { @@ -1980,10 +2094,10 @@ "integrity": "sha512-NTnHnVRd2JnRqPC0vW+iOQWU5pchDbYXsG2E6DMXEpMfUcQKclF9gmf3G3ZMhzG7IG9ji4coL0cm+FxeWxDpnw==", "dev": true, "requires": { - "find-cache-dir": "2.0.0", - "loader-utils": "1.2.3", - "mkdirp": "0.5.1", - "util.promisify": "1.0.0" + "find-cache-dir": "^2.0.0", + "loader-utils": "^1.0.2", + "mkdirp": "^0.5.1", + "util.promisify": "^1.0.0" }, "dependencies": { "big.js": { @@ -1998,7 +2112,7 @@ "integrity": "sha512-aKS4WQjPenRxiQsC93MNfjx+nbF4PAdYzmd/1JIj8HYzqfbu86beTuNgXDzPknWk0n0uARlyewZo4s++ES36Ow==", "dev": true, "requires": { - "minimist": "1.2.0" + "minimist": "^1.2.0" } }, "loader-utils": { @@ -2007,9 +2121,9 @@ "integrity": "sha512-fkpz8ejdnEMG3s37wGL07iSBDg99O9D5yflE9RGNH3hRdx9SOwYfnGYdZOUIZitN8E+E2vkq3MUMYMvPYl5ZZA==", "dev": true, "requires": { - "big.js": "5.2.2", - "emojis-list": "2.1.0", - "json5": "1.0.1" + "big.js": "^5.2.2", + "emojis-list": "^2.0.0", + "json5": "^1.0.1" } }, "minimist": { @@ -2031,13 +2145,13 @@ "integrity": "sha512-5T6P4xPgpp0YDFvSWwEZ4NoE3aM4QBQXDzmVbraCkFj8zHM+mba8SyqB5DbZWyR7mYHo6Y7BdQo3MoA4m0TeQg==", "dev": true, "requires": { - "cache-base": "1.0.1", - "class-utils": "0.3.6", - "component-emitter": "1.2.1", - "define-property": "1.0.0", - "isobject": "3.0.1", - "mixin-deep": "1.3.1", - "pascalcase": "0.1.1" + "cache-base": "^1.0.1", + "class-utils": "^0.3.5", + "component-emitter": "^1.2.1", + "define-property": "^1.0.0", + "isobject": "^3.0.1", + "mixin-deep": "^1.2.0", + "pascalcase": "^0.1.1" }, "dependencies": { "define-property": { @@ -2046,7 +2160,7 @@ "integrity": "sha1-dp66rz9KY6rTr56NMEybvnm/sOY=", "dev": true, "requires": { - "is-descriptor": "1.0.2" + "is-descriptor": "^1.0.0" } }, "is-accessor-descriptor": { @@ -2055,7 +2169,7 @@ "integrity": "sha512-m5hnHTkcVsPfqx3AKlyttIPb7J+XykHvJP2B9bZDjlhLIoEq4XoK64Vg7boZlVWYK6LUY94dYPEE7Lh0ZkZKcQ==", "dev": true, "requires": { - "kind-of": "6.0.2" + "kind-of": "^6.0.0" } }, "is-data-descriptor": { @@ -2064,7 +2178,7 @@ "integrity": "sha512-jbRXy1FmtAoCjQkVmIVYwuuqDFUbaOeDjmed1tOGPrsMhtJA4rD9tkgA0F1qJ3gRFRXcHYVkdeaP50Q5rE/jLQ==", "dev": true, "requires": { - "kind-of": "6.0.2" + "kind-of": "^6.0.0" } }, "is-descriptor": { @@ -2073,9 +2187,9 @@ "integrity": "sha512-2eis5WqQGV7peooDyLmNEPUrps9+SXX5c9pL3xEB+4e9HnGuDa7mB7kHxHw4CbqS9k1T2hOH3miL8n8WtiYVtg==", "dev": true, "requires": { - "is-accessor-descriptor": "1.0.0", - "is-data-descriptor": "1.0.0", - "kind-of": "6.0.2" + "is-accessor-descriptor": "^1.0.0", + "is-data-descriptor": "^1.0.0", + "kind-of": "^6.0.2" } } } @@ -2098,7 +2212,7 @@ "dev": true, "optional": true, "requires": { - "tweetnacl": "0.14.5" + "tweetnacl": "^0.14.3" } }, "big.js": { @@ -2108,9 +2222,9 @@ "dev": true }, "binary-extensions": { - "version": "1.12.0", - "resolved": "https://registry.npmjs.org/binary-extensions/-/binary-extensions-1.12.0.tgz", - "integrity": "sha512-DYWGk01lDcxeS/K9IHPGWfT8PsJmbXRtRd2Sx72Tnb8pcYZQFF1oSDb8hJtS1vhp212q1Rzi5dUf9+nq0o9UIg==", + "version": "1.13.1", + "resolved": "https://registry.npmjs.org/binary-extensions/-/binary-extensions-1.13.1.tgz", + "integrity": "sha512-Un7MIEDdUC5gNpcGDV97op1Ywk748MpHcFTHoYs6qnj1Z3j7I53VG3nwZhKzoBZmbdRNnb6WRdFlwl7tSDuZGw==", "dev": true }, "block-stream": { @@ -2119,9 +2233,15 @@ "integrity": "sha1-E+v+d4oDIFz+A3UUgeu0szAMEmo=", "dev": true, "requires": { - "inherits": "2.0.1" + "inherits": "~2.0.0" } }, + "bluebird": { + "version": "3.7.2", + "resolved": "https://registry.npmjs.org/bluebird/-/bluebird-3.7.2.tgz", + "integrity": "sha512-XpNj6GDQzdfW+r2Wnn7xiSAd7TM3jzkxGXBGTtWKuSXv1xUV+azxAm8jdWZN06QTQk+2N2XB9jRDkvbmQmcRtg==", + "dev": true + }, "bn.js": { "version": "4.11.8", "resolved": "https://registry.npmjs.org/bn.js/-/bn.js-4.11.8.tgz", @@ -2129,36 +2249,42 @@ "dev": true }, "body-parser": { - "version": "1.18.3", - "resolved": "https://registry.npmjs.org/body-parser/-/body-parser-1.18.3.tgz", - "integrity": "sha1-WykhmP/dVTs6DyDe0FkrlWlVyLQ=", + "version": "1.19.0", + "resolved": "https://registry.npmjs.org/body-parser/-/body-parser-1.19.0.tgz", + "integrity": "sha512-dhEPs72UPbDnAQJ9ZKMNTP6ptJaionhP5cBb541nXPlW60Jepo9RV/a4fX4XWW9CuFNK22krhrj1+rgzifNCsw==", "dev": true, "requires": { - "bytes": "3.0.0", - "content-type": "1.0.4", + "bytes": "3.1.0", + "content-type": "~1.0.4", "debug": "2.6.9", - "depd": "1.1.2", - "http-errors": "1.6.3", - "iconv-lite": "0.4.23", - "on-finished": "2.3.0", - "qs": "6.5.2", - "raw-body": "2.3.3", - "type-is": "1.6.16" + "depd": "~1.1.2", + "http-errors": "1.7.2", + "iconv-lite": "0.4.24", + "on-finished": "~2.3.0", + "qs": "6.7.0", + "raw-body": "2.4.0", + "type-is": "~1.6.17" }, "dependencies": { + "bytes": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/bytes/-/bytes-3.1.0.tgz", + "integrity": "sha512-zauLjrfCG+xvoyaqLoV8bLVXXNGC4JqlxFCutSDWA6fJrTo2ZuvLYTqZ7aHBLZSMOopbzwv8f+wZcVzfVTI2Dg==", + "dev": true + }, "iconv-lite": { - "version": "0.4.23", - "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.4.23.tgz", - "integrity": "sha512-neyTUVFtahjf0mB3dZT77u+8O0QB89jFdnBkd5P1JgYPbPaia3gXXOVL2fq8VyU2gMMD7SaN7QukTB/pmXYvDA==", + "version": "0.4.24", + "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.4.24.tgz", + "integrity": "sha512-v3MXnZAcvnywkTUEZomIActle7RXXeedOR31wwl7VlyoXO4Qi9arvSenNQWne1TcRwhCL1HwLI21bEqdpj8/rA==", "dev": true, "requires": { - "safer-buffer": "2.1.2" + "safer-buffer": ">= 2.1.2 < 3" } }, "qs": { - "version": "6.5.2", - "resolved": "https://registry.npmjs.org/qs/-/qs-6.5.2.tgz", - "integrity": "sha512-N5ZAX4/LxJmF+7wN74pUD6qAh9/wnvdQcjq9TZjevvXzSUo7bfmw91saqMjzGS2xq91/odN2dW/WOl7qQHNDGA==", + "version": "6.7.0", + "resolved": "https://registry.npmjs.org/qs/-/qs-6.7.0.tgz", + "integrity": "sha512-VCdBRNFTX1fyE7Nb6FYoURo/SPe62QCaAyzJvUjwRaIsc+NePBEniHlvxFmmX56+HZphIGtV0XeCirBtpDrTyQ==", "dev": true } } @@ -2169,12 +2295,12 @@ "integrity": "sha1-jokKGD2O6aI5OzhExpGkK897yfU=", "dev": true, "requires": { - "array-flatten": "2.1.2", - "deep-equal": "1.0.1", - "dns-equal": "1.0.0", - "dns-txt": "2.0.2", - "multicast-dns": "6.2.3", - "multicast-dns-service-types": "1.1.0" + "array-flatten": "^2.1.0", + "deep-equal": "^1.0.1", + "dns-equal": "^1.0.0", + "dns-txt": "^2.0.2", + "multicast-dns": "^6.0.1", + "multicast-dns-service-types": "^1.1.0" } }, "boolbase": { @@ -2190,13 +2316,13 @@ "dev": true, "optional": true, "requires": { - "hoek": "4.2.1" + "hoek": "4.x.x" } }, "bootstrap": { - "version": "4.1.2", - "resolved": "https://registry.npmjs.org/bootstrap/-/bootstrap-4.1.2.tgz", - "integrity": "sha512-3bP609EdMc/8EwgGp8KgpN8HwnR4V4lZ9CTi5pImMrXNxpkw7dK1B05aMwQWpG1ZWmTLlBSN/uzkuz5GsmQNFA==" + "version": "4.3.1", + "resolved": "https://registry.npmjs.org/bootstrap/-/bootstrap-4.3.1.tgz", + "integrity": "sha512-rXqOmH1VilAt2DyPzluTi2blhk17bO7ef+zLLPlWvG494pDxcM234pJ8wTc/6R40UWizAIIMgxjvxZg5kmsbag==" }, "bootstrap-loader": { "version": "3.0.2", @@ -2211,7 +2337,7 @@ "loader-utils": "1.1.0", "resolve": "1.7.1", "semver": "5.5.0", - "strip-json-comments": "2.0.1" + "strip-json-comments": "^2.0.1" }, "dependencies": { "ansi-styles": { @@ -2220,7 +2346,7 @@ "integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==", "dev": true, "requires": { - "color-convert": "1.9.1" + "color-convert": "^1.9.0" } }, "chalk": { @@ -2229,9 +2355,9 @@ "integrity": "sha512-ObN6h1v2fTJSmUXoS3nMQ92LbDK9be4TV+6G+omQlGJFdcUX5heKi1LZ1YnRMIgwTLEj3E24bT6tYni50rlCfQ==", "dev": true, "requires": { - "ansi-styles": "3.2.1", - "escape-string-regexp": "1.0.5", - "supports-color": "5.5.0" + "ansi-styles": "^3.2.1", + "escape-string-regexp": "^1.0.5", + "supports-color": "^5.3.0" } }, "esprima": { @@ -2246,8 +2372,8 @@ "integrity": "sha512-saJstZWv7oNeOyBh3+Dx1qWzhW0+e6/8eDzo7p5rDFqxntSztloLtuKu+Ejhtq82jsilwOIZYsCz+lIjthg1Hw==", "dev": true, "requires": { - "argparse": "1.0.10", - "esprima": "4.0.1" + "argparse": "^1.0.7", + "esprima": "^4.0.0" } }, "loader-utils": { @@ -2256,9 +2382,9 @@ "integrity": "sha1-yYrvSIvM7aL/teLeZG1qdUQp9c0=", "dev": true, "requires": { - "big.js": "3.2.0", - "emojis-list": "2.1.0", - "json5": "0.5.1" + "big.js": "^3.1.3", + "emojis-list": "^2.0.0", + "json5": "^0.5.0" } }, "resolve": { @@ -2267,7 +2393,7 @@ "integrity": "sha512-c7rwLofp8g1U+h1KNyHL/jicrKg1Ek4q+Lr33AL65uZTinUZHe30D5HlyN5V9NW0JX1D5dXQ4jqW5l7Sy/kGfw==", "dev": true, "requires": { - "path-parse": "1.0.5" + "path-parse": "^1.0.5" } }, "supports-color": { @@ -2276,15 +2402,15 @@ "integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==", "dev": true, "requires": { - "has-flag": "3.0.0" + "has-flag": "^3.0.0" } } } }, "bootstrap-sass": { - "version": "3.4.0", - "resolved": "https://registry.npmjs.org/bootstrap-sass/-/bootstrap-sass-3.4.0.tgz", - "integrity": "sha512-qdUyw4KmNNPSIdBadn+eyuuQFH0LsZlRCs6tor1zN8sQas7mnY5JNfemauraOdNPiFQd2gFeeo3gZjZZCuohZg==", + "version": "3.4.1", + "resolved": "https://registry.npmjs.org/bootstrap-sass/-/bootstrap-sass-3.4.1.tgz", + "integrity": "sha512-p5rxsK/IyEDQm2CwiHxxUi0MZZtvVFbhWmyMOt4lLkA4bujDA1TGoKT0i1FKIWiugAdP+kK8T5KMDFIKQCLYIA==", "dev": true }, "brace": { @@ -2300,7 +2426,7 @@ "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz", "integrity": "sha1-PH/L9SnYcibz0vUrlm/1Jx60Qd0=", "requires": { - "balanced-match": "1.0.0", + "balanced-match": "^1.0.0", "concat-map": "0.0.1" } }, @@ -2310,16 +2436,16 @@ "integrity": "sha512-aNdbnj9P8PjdXU4ybaWLK2IF3jc/EoDYbC7AazW6to3TRsfXxscC9UXOB5iDiEQrkyIbWp2SLQda4+QAa7nc3w==", "dev": true, "requires": { - "arr-flatten": "1.1.0", - "array-unique": "0.3.2", - "extend-shallow": "2.0.1", - "fill-range": "4.0.0", - "isobject": "3.0.1", - "repeat-element": "1.1.3", - "snapdragon": "0.8.2", - "snapdragon-node": "2.1.1", - "split-string": "3.1.0", - "to-regex": "3.0.2" + "arr-flatten": "^1.1.0", + "array-unique": "^0.3.2", + "extend-shallow": "^2.0.1", + "fill-range": "^4.0.0", + "isobject": "^3.0.1", + "repeat-element": "^1.1.2", + "snapdragon": "^0.8.1", + "snapdragon-node": "^2.0.1", + "split-string": "^3.0.2", + "to-regex": "^3.0.1" }, "dependencies": { "extend-shallow": { @@ -2328,7 +2454,7 @@ "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=", "dev": true, "requires": { - "is-extendable": "0.1.1" + "is-extendable": "^0.1.0" } } } @@ -2345,12 +2471,12 @@ "integrity": "sha512-+7CHXqGuspUn/Sl5aO7Ea0xWGAtETPXNSAjHo48JfLdPWcMng33Xe4znFvQweqc/uzk5zSOI3H52CYnjCfb5hA==", "dev": true, "requires": { - "buffer-xor": "1.0.3", - "cipher-base": "1.0.4", - "create-hash": "1.2.0", - "evp_bytestokey": "1.0.3", - "inherits": "2.0.1", - "safe-buffer": "5.1.1" + "buffer-xor": "^1.0.3", + "cipher-base": "^1.0.0", + "create-hash": "^1.1.0", + "evp_bytestokey": "^1.0.3", + "inherits": "^2.0.1", + "safe-buffer": "^5.0.1" } }, "browserify-cipher": { @@ -2359,9 +2485,9 @@ "integrity": "sha512-sPhkz0ARKbf4rRQt2hTpAHqn47X3llLkUGn+xEJzLjwY8LRs2p0v7ljvI5EyoRO/mexrNunNECisZs+gw2zz1w==", "dev": true, "requires": { - "browserify-aes": "1.2.0", - "browserify-des": "1.0.2", - "evp_bytestokey": "1.0.3" + "browserify-aes": "^1.0.4", + "browserify-des": "^1.0.0", + "evp_bytestokey": "^1.0.0" } }, "browserify-des": { @@ -2370,16 +2496,16 @@ "integrity": "sha512-BioO1xf3hFwz4kc6iBhI3ieDFompMhrMlnDFC4/0/vd5MokpuAc3R+LYbwTA9A5Yc9pq9UYPqffKpW2ObuwX5A==", "dev": true, "requires": { - "cipher-base": "1.0.4", - "des.js": "1.0.0", - "inherits": "2.0.1", - "safe-buffer": "5.1.2" + "cipher-base": "^1.0.1", + "des.js": "^1.0.0", + "inherits": "^2.0.1", + "safe-buffer": "^5.1.2" }, "dependencies": { "safe-buffer": { - "version": "5.1.2", - "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz", - "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==", + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.2.0.tgz", + "integrity": "sha512-fZEwUGbVl7kouZs1jCdMLdt95hdIv0ZeHg6L7qPeciMZhZ+/gdesW4wgTARkrFWEpspjEATAzUGPG8N2jJiwbg==", "dev": true } } @@ -2390,8 +2516,8 @@ "integrity": "sha1-IeCr+vbyApzy+vsTNWenAdQTVSQ=", "dev": true, "requires": { - "bn.js": "4.11.8", - "randombytes": "2.0.6" + "bn.js": "^4.1.0", + "randombytes": "^2.0.1" } }, "browserify-sign": { @@ -2400,13 +2526,22 @@ "integrity": "sha1-qk62jl17ZYuqa/alfmMMvXqT0pg=", "dev": true, "requires": { - "bn.js": "4.11.8", - "browserify-rsa": "4.0.1", - "create-hash": "1.2.0", - "create-hmac": "1.1.7", - "elliptic": "6.4.1", - "inherits": "2.0.1", - "parse-asn1": "5.1.3" + "bn.js": "^4.1.1", + "browserify-rsa": "^4.0.0", + "create-hash": "^1.1.0", + "create-hmac": "^1.1.2", + "elliptic": "^6.0.0", + "inherits": "^2.0.1", + "parse-asn1": "^5.0.0" + } + }, + "browserify-zlib": { + "version": "0.2.0", + "resolved": "https://registry.npmjs.org/browserify-zlib/-/browserify-zlib-0.2.0.tgz", + "integrity": "sha512-Z942RysHXmJrhqk88FmKBVq/v5tqmSkDz7p54G/MGyjMnCFFnC79XWNbg+Vta8W6Wb2qtSZTSxIGkJrRpCFEiA==", + "dev": true, + "requires": { + "pako": "~1.0.5" } }, "browserslist": { @@ -2415,9 +2550,9 @@ "integrity": "sha512-pEBxEXg7JwaakBXjATYw/D1YZh4QUSCX/Mnd/wnqSRPPSi1U39iDhDoKGoBUcraKdxDlrYqJxSI5nNvD+dWP2A==", "dev": true, "requires": { - "caniuse-lite": "1.0.30000929", - "electron-to-chromium": "1.3.103", - "node-releases": "1.1.3" + "caniuse-lite": "^1.0.30000929", + "electron-to-chromium": "^1.3.103", + "node-releases": "^1.1.3" } }, "buffer": { @@ -2425,8 +2560,8 @@ "resolved": "https://registry.npmjs.org/buffer/-/buffer-5.0.5.tgz", "integrity": "sha1-Nck5MkSpCv+DWBBj0W8Igs7MlBg=", "requires": { - "base64-js": "1.2.3", - "ieee754": "1.1.8" + "base64-js": "^1.0.2", + "ieee754": "^1.1.4" } }, "buffer-from": { @@ -2465,51 +2600,46 @@ "dev": true }, "cacache": { - "version": "11.3.2", - "resolved": "https://registry.npmjs.org/cacache/-/cacache-11.3.2.tgz", - "integrity": "sha512-E0zP4EPGDOaT2chM08Als91eYnf8Z+eH1awwwVsngUmgppfM5jjJ8l3z5vO5p5w/I3LsiXawb1sW0VY65pQABg==", - "dev": true, - "requires": { - "bluebird": "3.5.3", - "chownr": "1.1.1", - "figgy-pudding": "3.5.1", - "glob": "7.1.3", - "graceful-fs": "4.1.15", - "lru-cache": "5.1.1", - "mississippi": "3.0.0", - "mkdirp": "0.5.1", - "move-concurrently": "1.0.1", - "promise-inflight": "1.0.1", - "rimraf": "2.6.2", - "ssri": "6.0.1", - "unique-filename": "1.1.1", - "y18n": "4.0.0" + "version": "12.0.3", + "resolved": "https://registry.npmjs.org/cacache/-/cacache-12.0.3.tgz", + "integrity": "sha512-kqdmfXEGFepesTuROHMs3MpFLWrPkSSpRqOw80RCflZXy/khxaArvFrQ7uJxSUduzAufc6G0g1VUCOZXxWavPw==", + "dev": true, + "requires": { + "bluebird": "^3.5.5", + "chownr": "^1.1.1", + "figgy-pudding": "^3.5.1", + "glob": "^7.1.4", + "graceful-fs": "^4.1.15", + "infer-owner": "^1.0.3", + "lru-cache": "^5.1.1", + "mississippi": "^3.0.0", + "mkdirp": "^0.5.1", + "move-concurrently": "^1.0.1", + "promise-inflight": "^1.0.1", + "rimraf": "^2.6.3", + "ssri": "^6.0.1", + "unique-filename": "^1.1.1", + "y18n": "^4.0.0" }, "dependencies": { - "bluebird": { - "version": "3.5.3", - "resolved": "https://registry.npmjs.org/bluebird/-/bluebird-3.5.3.tgz", - "integrity": "sha512-/qKPUQlaW1OyR51WeCPBvRnAlnZFUJkCSG5HzGnuIqhgyJtF+T94lFnn33eiazjRm2LAHVy2guNnaq48X9SJuw==", - "dev": true - }, "glob": { - "version": "7.1.3", - "resolved": "https://registry.npmjs.org/glob/-/glob-7.1.3.tgz", - "integrity": "sha512-vcfuiIxogLV4DlGBHIUOwI0IbrJ8HWPc4MU7HzviGeNho/UJDfi6B5p3sHeWIQ0KGIU0Jpxi5ZHxemQfLkkAwQ==", + "version": "7.1.6", + "resolved": "https://registry.npmjs.org/glob/-/glob-7.1.6.tgz", + "integrity": "sha512-LwaxwyZ72Lk7vZINtNNrywX0ZuLyStrdDtabefZKAY5ZGJhVtgdznluResxNmPitE0SAO+O26sWTHeKSI2wMBA==", "dev": true, "requires": { - "fs.realpath": "1.0.0", - "inflight": "1.0.6", - "inherits": "2.0.1", - "minimatch": "3.0.4", - "once": "1.4.0", - "path-is-absolute": "1.0.1" + "fs.realpath": "^1.0.0", + "inflight": "^1.0.4", + "inherits": "2", + "minimatch": "^3.0.4", + "once": "^1.3.0", + "path-is-absolute": "^1.0.0" } }, "graceful-fs": { - "version": "4.1.15", - "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.1.15.tgz", - "integrity": "sha512-6uHUhOPEBgQ24HM+r6b/QwWfZq+yiFcipKFrOFiBEnWdy5sdzYoi+pJeQaPI5qOLRFqWmAXUPQNsielzdLoecA==", + "version": "4.2.3", + "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.3.tgz", + "integrity": "sha512-a30VEBm4PEdx1dRB7MFK7BejejvCvBronbLjht+sHuGYj8PHs7M/5Z+rt5lw551vZ7yfTCj4Vuyy3mSJytDWRQ==", "dev": true }, "lru-cache": { @@ -2518,7 +2648,16 @@ "integrity": "sha512-KpNARQA3Iwv+jTA0utUVVbrh+Jlrr1Fv0e56GGzAFOXN7dk/FviaDW8LHmK52DlcH4WP2n6gI8vN1aesBFgo9w==", "dev": true, "requires": { - "yallist": "3.0.3" + "yallist": "^3.0.2" + } + }, + "rimraf": { + "version": "2.7.1", + "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-2.7.1.tgz", + "integrity": "sha512-uWjbaKIK3T1OSVptzX7Nl6PvQ3qAGtKEtVRjRuazjfL3Bx5eI409VZSqgND+4UNnmzLVdPj9FqFJNPqBZFve4w==", + "dev": true, + "requires": { + "glob": "^7.1.3" } }, "y18n": { @@ -2528,9 +2667,9 @@ "dev": true }, "yallist": { - "version": "3.0.3", - "resolved": "https://registry.npmjs.org/yallist/-/yallist-3.0.3.tgz", - "integrity": "sha512-S+Zk8DEWE6oKpV+vI3qWkaK+jSbIK86pCwe2IF/xwIpQ8jEuxpw9NyaGjmp9+BoJv5FV2piqCDcoCtStppiq2A==", + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/yallist/-/yallist-3.1.1.tgz", + "integrity": "sha512-a4UGQaWPH59mOXUYnAG2ewncQS4i4F43Tv3JoAM+s2VDAmS9NsK8GpDMLrCHPksFT7h3K6TOoUNn2pb7RoXx4g==", "dev": true } } @@ -2541,15 +2680,15 @@ "integrity": "sha512-AKcdTnFSWATd5/GCPRxr2ChwIJ85CeyrEyjRHlKxQ56d4XJMGym0uAiKn0xbLOGOl3+yRpOTi484dVCEc5AUzQ==", "dev": true, "requires": { - "collection-visit": "1.0.0", - "component-emitter": "1.2.1", - "get-value": "2.0.6", - "has-value": "1.0.0", - "isobject": "3.0.1", - "set-value": "2.0.0", - "to-object-path": "0.3.0", - "union-value": "1.0.0", - "unset-value": "1.0.0" + "collection-visit": "^1.0.0", + "component-emitter": "^1.2.1", + "get-value": "^2.0.6", + "has-value": "^1.0.0", + "isobject": "^3.0.1", + "set-value": "^2.0.0", + "to-object-path": "^0.3.0", + "union-value": "^1.0.0", + "unset-value": "^1.0.0" } }, "caller-path": { @@ -2557,7 +2696,7 @@ "resolved": "https://registry.npmjs.org/caller-path/-/caller-path-0.1.0.tgz", "integrity": "sha1-lAhe9jWB7NPaqSREqP6U6CV3dR8=", "requires": { - "callsites": "0.2.0" + "callsites": "^0.2.0" } }, "callsites": { @@ -2571,8 +2710,8 @@ "integrity": "sha1-yjw2iKTpzzpM2nd9xNy8cTJJz3M=", "dev": true, "requires": { - "no-case": "2.3.2", - "upper-case": "1.1.3" + "no-case": "^2.2.0", + "upper-case": "^1.1.1" } }, "camelcase": { @@ -2587,8 +2726,8 @@ "integrity": "sha1-MIvur/3ygRkFHvodkyITyRuPkuc=", "dev": true, "requires": { - "camelcase": "2.1.1", - "map-obj": "1.0.1" + "camelcase": "^2.0.0", + "map-obj": "^1.0.0" } }, "caniuse-lite": { @@ -2608,11 +2747,11 @@ "resolved": "https://registry.npmjs.org/chalk/-/chalk-1.1.3.tgz", "integrity": "sha1-qBFcVeSnAv5NFQq9OHKCKn4J/Jg=", "requires": { - "ansi-styles": "2.2.1", - "escape-string-regexp": "1.0.5", - "has-ansi": "2.0.0", - "strip-ansi": "3.0.1", - "supports-color": "2.0.0" + "ansi-styles": "^2.2.1", + "escape-string-regexp": "^1.0.2", + "has-ansi": "^2.0.0", + "strip-ansi": "^3.0.0", + "supports-color": "^2.0.0" } }, "chardet": { @@ -2621,39 +2760,46 @@ "integrity": "sha1-tUc7M9yXxCTl2Y3IfVXU2KKci/I=" }, "chokidar": { - "version": "2.0.4", - "resolved": "https://registry.npmjs.org/chokidar/-/chokidar-2.0.4.tgz", - "integrity": "sha512-z9n7yt9rOvIJrMhvDtDictKrkFHeihkNl6uWMmZlmL6tJtX9Cs+87oK+teBx+JIgzvbX3yZHT3eF8vpbDxHJXQ==", + "version": "2.1.8", + "resolved": "https://registry.npmjs.org/chokidar/-/chokidar-2.1.8.tgz", + "integrity": "sha512-ZmZUazfOzf0Nve7duiCKD23PFSCs4JPoYyccjUFF3aQkQadqBhfzhjkwBH2mNOG9cTBwhamM37EIsIkZw3nRgg==", "dev": true, "requires": { - "anymatch": "2.0.0", - "async-each": "1.0.1", - "braces": "2.3.2", - "fsevents": "1.2.4", - "glob-parent": "3.1.0", - "inherits": "2.0.1", - "is-binary-path": "1.0.1", - "is-glob": "4.0.0", - "lodash.debounce": "4.0.8", - "normalize-path": "2.1.1", - "path-is-absolute": "1.0.1", - "readdirp": "2.2.1", - "upath": "1.1.0" + "anymatch": "^2.0.0", + "async-each": "^1.0.1", + "braces": "^2.3.2", + "fsevents": "^1.2.7", + "glob-parent": "^3.1.0", + "inherits": "^2.0.3", + "is-binary-path": "^1.0.0", + "is-glob": "^4.0.0", + "normalize-path": "^3.0.0", + "path-is-absolute": "^1.0.0", + "readdirp": "^2.2.1", + "upath": "^1.1.1" + }, + "dependencies": { + "inherits": { + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.4.tgz", + "integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==", + "dev": true + } } }, "chownr": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/chownr/-/chownr-1.1.1.tgz", - "integrity": "sha512-j38EvO5+LHX84jlo6h4UzmOwi0UgW61WRyPtJz4qaadK5eY3BTS5TY/S1Stc3Uk2lIM6TPevAlULiEJwie860g==", + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/chownr/-/chownr-1.1.3.tgz", + "integrity": "sha512-i70fVHhmV3DtTl6nqvZOnIjbY0Pe4kAUjwHj8z0zAdgBtYrJyYwLKCCuRBQ5ppkyL0AkN7HKRnETdmdp1zqNXw==", "dev": true }, "chrome-trace-event": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/chrome-trace-event/-/chrome-trace-event-1.0.0.tgz", - "integrity": "sha512-xDbVgyfDTT2piup/h8dK/y4QZfJRSa73bw1WZ8b4XM1o7fsFubUVGYcE+1ANtOzJJELGpYoG2961z0Z6OAld9A==", + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/chrome-trace-event/-/chrome-trace-event-1.0.2.tgz", + "integrity": "sha512-9e/zx1jw7B4CO+c/RXoCsfg/x1AfUBioy4owYH0bJprEYAx5hRFLRhWBqHAG57D0ZM4H7vxbP7bPe0VwhQRYDQ==", "dev": true, "requires": { - "tslib": "1.9.3" + "tslib": "^1.9.0" } }, "cipher-base": { @@ -2662,8 +2808,8 @@ "integrity": "sha512-Kkht5ye6ZGmwv40uUDZztayT2ThLQGfnj/T71N/XzeZeo3nf8foyW7zGTsPYkEya3m5f3cAypH+qe7YOrM1U2Q==", "dev": true, "requires": { - "inherits": "2.0.1", - "safe-buffer": "5.1.1" + "inherits": "^2.0.1", + "safe-buffer": "^5.0.1" } }, "circular-json": { @@ -2677,10 +2823,10 @@ "integrity": "sha512-qOhPa/Fj7s6TY8H8esGu5QNpMMQxz79h+urzrNYN6mn+9BnxlDGf5QZ+XeCDsxSjPqsSR56XOZOJmpeurnLMeg==", "dev": true, "requires": { - "arr-union": "3.1.0", - "define-property": "0.2.5", - "isobject": "3.0.1", - "static-extend": "0.1.2" + "arr-union": "^3.1.0", + "define-property": "^0.2.5", + "isobject": "^3.0.0", + "static-extend": "^0.1.1" }, "dependencies": { "define-property": { @@ -2689,7 +2835,7 @@ "integrity": "sha1-w1se+RjsPJkPmlvFe+BKrOxcgRY=", "dev": true, "requires": { - "is-descriptor": "0.1.6" + "is-descriptor": "^0.1.0" } } } @@ -2700,7 +2846,7 @@ "integrity": "sha512-4ZxI6dy4lrY6FHzfiy1aEOXgu4LIsW2MhwG0VBKdcoGoH/XLFgaHSdLTGr4O8Be6A8r3MOphEiI8Gc1n0ecf3g==", "dev": true, "requires": { - "source-map": "0.6.1" + "source-map": "~0.6.0" }, "dependencies": { "source-map": { @@ -2716,7 +2862,7 @@ "resolved": "https://registry.npmjs.org/cli-cursor/-/cli-cursor-2.1.0.tgz", "integrity": "sha1-s12sN2R5+sw+lHR9QdDQ9SOP/LU=", "requires": { - "restore-cursor": "2.0.0" + "restore-cursor": "^2.0.0" } }, "cli-width": { @@ -2730,9 +2876,9 @@ "integrity": "sha1-EgYBU3qRbSmUD5NNo7SNWFo5IT0=", "dev": true, "requires": { - "string-width": "1.0.2", - "strip-ansi": "3.0.1", - "wrap-ansi": "2.1.0" + "string-width": "^1.0.1", + "strip-ansi": "^3.0.1", + "wrap-ansi": "^2.0.0" }, "dependencies": { "is-fullwidth-code-point": { @@ -2741,7 +2887,7 @@ "integrity": "sha1-754xOG8DGn8NZDr4L95QxFfvAMs=", "dev": true, "requires": { - "number-is-nan": "1.0.1" + "number-is-nan": "^1.0.0" } }, "string-width": { @@ -2750,9 +2896,9 @@ "integrity": "sha1-EYvfW4zcUaKn5w0hHgfisLmxB9M=", "dev": true, "requires": { - "code-point-at": "1.1.0", - "is-fullwidth-code-point": "1.0.0", - "strip-ansi": "3.0.1" + "code-point-at": "^1.0.0", + "is-fullwidth-code-point": "^1.0.0", + "strip-ansi": "^3.0.0" } } } @@ -2763,10 +2909,10 @@ "integrity": "sha1-ANs6Hhc2VnMNEYjD1qztbX6pdxM=", "dev": true, "requires": { - "for-own": "1.0.0", - "is-plain-object": "2.0.4", - "kind-of": "6.0.2", - "shallow-clone": "1.0.0" + "for-own": "^1.0.0", + "is-plain-object": "^2.0.4", + "kind-of": "^6.0.0", + "shallow-clone": "^1.0.0" } }, "co": { @@ -2786,8 +2932,8 @@ "integrity": "sha1-S8A3PBZLwykbTTaMgpzxqApZ3KA=", "dev": true, "requires": { - "map-visit": "1.0.0", - "object-visit": "1.0.1" + "map-visit": "^1.0.0", + "object-visit": "^1.0.0" } }, "color-convert": { @@ -2795,7 +2941,7 @@ "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-1.9.1.tgz", "integrity": "sha1-wSYRB66y8pTr/+ye2eytUppgl+0=", "requires": { - "color-name": "1.1.3" + "color-name": "^1.1.1" } }, "color-name": { @@ -2809,7 +2955,7 @@ "integrity": "sha1-cj599ugBrFYTETp+RFqbactjKBg=", "dev": true, "requires": { - "delayed-stream": "1.0.0" + "delayed-stream": "~1.0.0" } }, "commander": { @@ -2825,41 +2971,41 @@ "dev": true }, "component-emitter": { - "version": "1.2.1", - "resolved": "https://registry.npmjs.org/component-emitter/-/component-emitter-1.2.1.tgz", - "integrity": "sha1-E3kY1teCg/ffemt8WmPhQOaUJeY=", + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/component-emitter/-/component-emitter-1.3.0.tgz", + "integrity": "sha512-Rd3se6QB+sO1TwqZjscQrurpEPIfO0/yYnSin6Q/rD3mOutHvUrCAhJub3r90uNb+SESBuE0QYoB90YdfatsRg==", "dev": true }, "compressible": { - "version": "2.0.15", - "resolved": "https://registry.npmjs.org/compressible/-/compressible-2.0.15.tgz", - "integrity": "sha512-4aE67DL33dSW9gw4CI2H/yTxqHLNcxp0yS6jB+4h+wr3e43+1z7vm0HU9qXOH8j+qjKuL8+UtkOxYQSMq60Ylw==", + "version": "2.0.17", + "resolved": "https://registry.npmjs.org/compressible/-/compressible-2.0.17.tgz", + "integrity": "sha512-BGHeLCK1GV7j1bSmQQAi26X+GgWcTjLr/0tzSvMCl3LH1w1IJ4PFSPoV5316b30cneTziC+B1a+3OjoSUcQYmw==", "dev": true, "requires": { - "mime-db": "1.37.0" + "mime-db": ">= 1.40.0 < 2" }, "dependencies": { "mime-db": { - "version": "1.37.0", - "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.37.0.tgz", - "integrity": "sha512-R3C4db6bgQhlIhPU48fUtdVmKnflq+hRdad7IyKhtFj06VPNVdk2RhiYL3UjQIlso8L+YxAtFkobT0VK+S/ybg==", + "version": "1.42.0", + "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.42.0.tgz", + "integrity": "sha512-UbfJCR4UAVRNgMpfImz05smAXK7+c+ZntjaA26ANtkXLlOe947Aag5zdIcKQULAiF9Cq4WxBi9jUs5zkA84bYQ==", "dev": true } } }, "compression": { - "version": "1.7.3", - "resolved": "https://registry.npmjs.org/compression/-/compression-1.7.3.tgz", - "integrity": "sha512-HSjyBG5N1Nnz7tF2+O7A9XUhyjru71/fwgNb7oIsEVHR0WShfs2tIS/EySLgiTe98aOK18YDlMXpzjCXY/n9mg==", + "version": "1.7.4", + "resolved": "https://registry.npmjs.org/compression/-/compression-1.7.4.tgz", + "integrity": "sha512-jaSIDzP9pZVS4ZfQ+TzvtiWhdpFhE2RDHz8QJkpX9SIpLq88VueF5jJw6t+6CUQcAoA6t+x89MLrWAqpfDE8iQ==", "dev": true, "requires": { - "accepts": "1.3.5", + "accepts": "~1.3.5", "bytes": "3.0.0", - "compressible": "2.0.15", + "compressible": "~2.0.16", "debug": "2.6.9", - "on-headers": "1.0.1", + "on-headers": "~1.0.2", "safe-buffer": "5.1.2", - "vary": "1.1.2" + "vary": "~1.1.2" }, "dependencies": { "safe-buffer": { @@ -2880,9 +3026,9 @@ "resolved": "https://registry.npmjs.org/concat-stream/-/concat-stream-1.6.1.tgz", "integrity": "sha1-JhuPUYMB8dg042NCuf6gldJiCiY=", "requires": { - "inherits": "2.0.3", - "readable-stream": "2.3.5", - "typedarray": "0.0.6" + "inherits": "^2.0.3", + "readable-stream": "^2.2.2", + "typedarray": "^0.0.6" }, "dependencies": { "inherits": { @@ -2899,13 +3045,10 @@ "dev": true }, "console-browserify": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/console-browserify/-/console-browserify-1.1.0.tgz", - "integrity": "sha1-8CQcRXMKn8YyOyBtvzjtx0HQuxA=", - "dev": true, - "requires": { - "date-now": "0.1.4" - } + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/console-browserify/-/console-browserify-1.2.0.tgz", + "integrity": "sha512-ZMkYO/LkF17QvCPqM0gxw8yUzigAOZOSWSHg91FH6orS7vcEj5dVZTidN2fQ14yBSdg97RqhSNwLUXInd52OTA==", + "dev": true }, "console-control-strings": { "version": "1.1.0", @@ -2913,21 +3056,38 @@ "integrity": "sha1-PXz0Rk22RG6mRL9LOVB/mFEAjo4=", "dev": true }, + "constants-browserify": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/constants-browserify/-/constants-browserify-1.0.0.tgz", + "integrity": "sha1-wguW2MYXdIqvHBYCF2DNJ/y4y3U=", + "dev": true + }, "contains-path": { "version": "0.1.0", "resolved": "https://registry.npmjs.org/contains-path/-/contains-path-0.1.0.tgz", "integrity": "sha1-/ozxhP9mcLa67wGp1IYaXL7EEgo=" }, "content-disposition": { - "version": "0.5.2", - "resolved": "https://registry.npmjs.org/content-disposition/-/content-disposition-0.5.2.tgz", - "integrity": "sha1-DPaLud318r55YcOoUXjLhdunjLQ=", - "dev": true + "version": "0.5.3", + "resolved": "https://registry.npmjs.org/content-disposition/-/content-disposition-0.5.3.tgz", + "integrity": "sha512-ExO0774ikEObIAEV9kDo50o+79VCUdEB6n6lzKgGwupcVeRlhrj3qGAfwq8G6uBJjkqLrhT0qEYFcWng8z1z0g==", + "dev": true, + "requires": { + "safe-buffer": "5.1.2" + }, + "dependencies": { + "safe-buffer": { + "version": "5.1.2", + "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz", + "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==", + "dev": true + } + } }, "content-type": { "version": "1.0.4", "resolved": "https://registry.npmjs.org/content-type/-/content-type-1.0.4.tgz", - "integrity": "sha1-4TjMdeBAxyexlm/l5fjJruJW/js=", + "integrity": "sha512-hIP3EEPs8tB9AT1L+NUqtwOAps4mk2Zob89MWXMHjHWg9milF/j4osnnQLXBCBFBk/tvIG/tUc9mOUJiPBhPXA==", "dev": true }, "convert-source-map": { @@ -2937,9 +3097,9 @@ "dev": true }, "cookie": { - "version": "0.3.1", - "resolved": "https://registry.npmjs.org/cookie/-/cookie-0.3.1.tgz", - "integrity": "sha1-5+Ch+e9DtMi6klxcWpboBtFoc7s=", + "version": "0.4.0", + "resolved": "https://registry.npmjs.org/cookie/-/cookie-0.4.0.tgz", + "integrity": "sha512-+Hp8fLp57wnUSt0tY0tHEXh4voZRDnoIrZPqlo3DPiI4y9lwg/jqx+1Om94/W6ZaPDOUbnjOt/99w66zk+l1Xg==", "dev": true }, "cookie-signature": { @@ -2954,12 +3114,12 @@ "integrity": "sha512-f2domd9fsVDFtaFcbaRZuYXwtdmnzqbADSwhSWYxYB/Q8zsdUUFMXVRwXGDMWmbEzAn1kdRrtI1T/KTFOL4X2A==", "dev": true, "requires": { - "aproba": "1.2.0", - "fs-write-stream-atomic": "1.0.10", - "iferr": "0.1.5", - "mkdirp": "0.5.1", - "rimraf": "2.6.2", - "run-queue": "1.0.3" + "aproba": "^1.1.1", + "fs-write-stream-atomic": "^1.0.8", + "iferr": "^0.1.5", + "mkdirp": "^0.5.1", + "rimraf": "^2.5.4", + "run-queue": "^1.0.0" } }, "copy-descriptor": { @@ -2979,8 +3139,8 @@ "integrity": "sha512-GbEHQPMOswGpKXM9kCWVrremUcBmjteUaQ01T9rkKCPDXfUHX0IoP9LpHYo2NPFampa4e+/pFDc3jQdxrxQLaw==", "dev": true, "requires": { - "bn.js": "4.11.8", - "elliptic": "6.4.1" + "bn.js": "^4.1.0", + "elliptic": "^6.0.0" } }, "create-hash": { @@ -2989,33 +3149,11 @@ "integrity": "sha512-z00bCGNHDG8mHAkP7CtT1qVu+bFQUPjYq/4Iv3C3kWjTFV10zIjfSoeqXo9Asws8gwSHDGj/hl2u4OGIjapeCg==", "dev": true, "requires": { - "cipher-base": "1.0.4", - "inherits": "2.0.1", - "md5.js": "1.3.5", - "ripemd160": "2.0.2", - "sha.js": "2.4.11" - }, - "dependencies": { - "ripemd160": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/ripemd160/-/ripemd160-2.0.2.tgz", - "integrity": "sha512-ii4iagi25WusVoiC4B4lq7pbXfAp3D9v5CwfkY33vffw2+pkDjY1D8GaN7spsxvCSx8dkPqOZCEZyfxcmJG2IA==", - "dev": true, - "requires": { - "hash-base": "3.0.4", - "inherits": "2.0.1" - } - }, - "sha.js": { - "version": "2.4.11", - "resolved": "https://registry.npmjs.org/sha.js/-/sha.js-2.4.11.tgz", - "integrity": "sha512-QMEp5B7cftE7APOjk5Y6xgrbWu+WkLVQwk8JNjZ8nKRciZaByEW6MubieAiToS7+dwvrjGhH8jRXz3MVd0AYqQ==", - "dev": true, - "requires": { - "inherits": "2.0.1", - "safe-buffer": "5.1.1" - } - } + "cipher-base": "^1.0.1", + "inherits": "^2.0.1", + "md5.js": "^1.3.4", + "ripemd160": "^2.0.1", + "sha.js": "^2.4.0" } }, "create-hmac": { @@ -3024,54 +3162,74 @@ "integrity": "sha512-MJG9liiZ+ogc4TzUwuvbER1JRdgvUFSB5+VR/g5h82fGaIRWMWddtKBHi7/sVhfjQZ6SehlyhvQYrcYkaUIpLg==", "dev": true, "requires": { - "cipher-base": "1.0.4", - "create-hash": "1.2.0", - "inherits": "2.0.1", - "ripemd160": "2.0.2", - "safe-buffer": "5.1.1", - "sha.js": "2.4.11" + "cipher-base": "^1.0.3", + "create-hash": "^1.1.0", + "inherits": "^2.0.1", + "ripemd160": "^2.0.0", + "safe-buffer": "^5.0.1", + "sha.js": "^2.4.8" + } + }, + "cross-env": { + "version": "6.0.3", + "resolved": "https://registry.npmjs.org/cross-env/-/cross-env-6.0.3.tgz", + "integrity": "sha512-+KqxF6LCvfhWvADcDPqo64yVIB31gv/jQulX2NGzKS/g3GEVz6/pt4wjHFtFWsHMddebWD/sDthJemzM4MaAag==", + "dev": true, + "requires": { + "cross-spawn": "^7.0.0" }, "dependencies": { - "ripemd160": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/ripemd160/-/ripemd160-2.0.2.tgz", - "integrity": "sha512-ii4iagi25WusVoiC4B4lq7pbXfAp3D9v5CwfkY33vffw2+pkDjY1D8GaN7spsxvCSx8dkPqOZCEZyfxcmJG2IA==", + "cross-spawn": { + "version": "7.0.1", + "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-7.0.1.tgz", + "integrity": "sha512-u7v4o84SwFpD32Z8IIcPZ6z1/ie24O6RU3RbtL5Y316l3KuHVPx9ItBgWQ6VlfAFnRnTtMUrsQ9MUUTuEZjogg==", + "dev": true, + "requires": { + "path-key": "^3.1.0", + "shebang-command": "^2.0.0", + "which": "^2.0.1" + } + }, + "path-key": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/path-key/-/path-key-3.1.1.tgz", + "integrity": "sha512-ojmeN0qd+y0jszEtoY48r0Peq5dwMEkIlCOu6Q5f41lfkswXuKtYrhgoTpLnyIcHm24Uhqx+5Tqm2InSwLhE6Q==", + "dev": true + }, + "shebang-command": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/shebang-command/-/shebang-command-2.0.0.tgz", + "integrity": "sha512-kHxr2zZpYtdmrN1qDjrrX/Z1rR1kG8Dx+gkpK1G4eXmvXswmcE1hTWBWYUzlraYw1/yZp6YuDY77YtvbN0dmDA==", "dev": true, "requires": { - "hash-base": "3.0.4", - "inherits": "2.0.1" + "shebang-regex": "^3.0.0" } }, - "sha.js": { - "version": "2.4.11", - "resolved": "https://registry.npmjs.org/sha.js/-/sha.js-2.4.11.tgz", - "integrity": "sha512-QMEp5B7cftE7APOjk5Y6xgrbWu+WkLVQwk8JNjZ8nKRciZaByEW6MubieAiToS7+dwvrjGhH8jRXz3MVd0AYqQ==", + "shebang-regex": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/shebang-regex/-/shebang-regex-3.0.0.tgz", + "integrity": "sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A==", + "dev": true + }, + "which": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/which/-/which-2.0.2.tgz", + "integrity": "sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA==", "dev": true, "requires": { - "inherits": "2.0.1", - "safe-buffer": "5.1.1" + "isexe": "^2.0.0" } } } }, - "cross-env": { - "version": "3.2.4", - "resolved": "https://registry.npmjs.org/cross-env/-/cross-env-3.2.4.tgz", - "integrity": "sha1-ngWF8neGTtQhznVvgamA/w1piro=", - "dev": true, - "requires": { - "cross-spawn": "5.1.0", - "is-windows": "1.0.2" - } - }, "cross-spawn": { "version": "5.1.0", "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-5.1.0.tgz", "integrity": "sha1-6L0O/uWPz/b4+UUQoKVUu/ojVEk=", "requires": { - "lru-cache": "4.0.2", - "shebang-command": "1.2.0", - "which": "1.3.0" + "lru-cache": "^4.0.1", + "shebang-command": "^1.2.0", + "which": "^1.2.9" } }, "cryptiles": { @@ -3079,7 +3237,7 @@ "resolved": "https://registry.npmjs.org/cryptiles/-/cryptiles-4.1.2.tgz", "integrity": "sha512-U2ALcoAHvA1oO2xOreyHvtkQ+IELqDG2WVWRI1GH/XEmmfGIOalnM5MU5Dd2ITyWfr3m6kNqXiy8XuYyd4wKJw==", "requires": { - "boom": "7.2.0" + "boom": "7.x.x" }, "dependencies": { "boom": { @@ -3087,7 +3245,7 @@ "resolved": "https://registry.npmjs.org/boom/-/boom-7.2.0.tgz", "integrity": "sha1-K/8kpVVldn/ehp7ICDF+sQxI6WY=", "requires": { - "hoek": "5.0.4" + "hoek": "5.x.x" } }, "hoek": { @@ -3097,16 +3255,35 @@ } } }, + "crypto-browserify": { + "version": "3.12.0", + "resolved": "https://registry.npmjs.org/crypto-browserify/-/crypto-browserify-3.12.0.tgz", + "integrity": "sha512-fz4spIh+znjO2VjL+IdhEpRJ3YN6sMzITSBijk6FK2UvTqruSQW+/cCZTSNsMiZNvUeq0CqurF+dAbyiGOY6Wg==", + "dev": true, + "requires": { + "browserify-cipher": "^1.0.0", + "browserify-sign": "^4.0.0", + "create-ecdh": "^4.0.0", + "create-hash": "^1.1.0", + "create-hmac": "^1.1.0", + "diffie-hellman": "^5.0.0", + "inherits": "^2.0.1", + "pbkdf2": "^3.0.3", + "public-encrypt": "^4.0.0", + "randombytes": "^2.0.0", + "randomfill": "^1.0.3" + } + }, "css": { "version": "2.2.4", "resolved": "https://registry.npmjs.org/css/-/css-2.2.4.tgz", "integrity": "sha512-oUnjmWpy0niI3x/mPL8dVEI1l7MnG3+HHyRPHf+YFSbK+svOhXpmSOcDURUh2aOCgl2grzrOPt1nHLuCVFULLw==", "dev": true, "requires": { - "inherits": "2.0.3", - "source-map": "0.6.1", - "source-map-resolve": "0.5.2", - "urix": "0.1.0" + "inherits": "^2.0.3", + "source-map": "^0.6.1", + "source-map-resolve": "^0.5.2", + "urix": "^0.1.0" }, "dependencies": { "inherits": { @@ -3129,16 +3306,16 @@ "integrity": "sha512-MoOu+CStsGrSt5K2OeZ89q3Snf+IkxRfAIt9aAKg4piioTrhtP1iEFPu+OVn3Ohz24FO6L+rw9UJxBILiSBw5Q==", "dev": true, "requires": { - "icss-utils": "4.0.0", - "loader-utils": "1.2.3", - "lodash": "4.17.11", - "postcss": "7.0.13", - "postcss-modules-extract-imports": "2.0.0", - "postcss-modules-local-by-default": "2.0.4", - "postcss-modules-scope": "2.0.1", - "postcss-modules-values": "2.0.0", - "postcss-value-parser": "3.3.1", - "schema-utils": "1.0.0" + "icss-utils": "^4.0.0", + "loader-utils": "^1.2.1", + "lodash": "^4.17.11", + "postcss": "^7.0.6", + "postcss-modules-extract-imports": "^2.0.0", + "postcss-modules-local-by-default": "^2.0.3", + "postcss-modules-scope": "^2.0.0", + "postcss-modules-values": "^2.0.0", + "postcss-value-parser": "^3.3.0", + "schema-utils": "^1.0.0" }, "dependencies": { "ajv": { @@ -3147,10 +3324,10 @@ "integrity": "sha512-RZXPviBTtfmtka9n9sy1N5M5b82CbxWIR6HIis4s3WQTXDJamc/0gpCWNGz6EWdWp4DOfjzJfhz/AS9zVPjjWg==", "dev": true, "requires": { - "fast-deep-equal": "2.0.1", - "fast-json-stable-stringify": "2.0.0", - "json-schema-traverse": "0.4.1", - "uri-js": "4.2.2" + "fast-deep-equal": "^2.0.1", + "fast-json-stable-stringify": "^2.0.0", + "json-schema-traverse": "^0.4.1", + "uri-js": "^4.2.2" } }, "ajv-keywords": { @@ -3183,7 +3360,7 @@ "integrity": "sha512-aKS4WQjPenRxiQsC93MNfjx+nbF4PAdYzmd/1JIj8HYzqfbu86beTuNgXDzPknWk0n0uARlyewZo4s++ES36Ow==", "dev": true, "requires": { - "minimist": "1.2.0" + "minimist": "^1.2.0" } }, "loader-utils": { @@ -3192,9 +3369,9 @@ "integrity": "sha512-fkpz8ejdnEMG3s37wGL07iSBDg99O9D5yflE9RGNH3hRdx9SOwYfnGYdZOUIZitN8E+E2vkq3MUMYMvPYl5ZZA==", "dev": true, "requires": { - "big.js": "5.2.2", - "emojis-list": "2.1.0", - "json5": "1.0.1" + "big.js": "^5.2.2", + "emojis-list": "^2.0.0", + "json5": "^1.0.1" } }, "minimist": { @@ -3209,9 +3386,9 @@ "integrity": "sha512-i27Mic4KovM/lnGsy8whRCHhc7VicJajAjTrYg11K9zfZXnYIt4k5F+kZkwjnrhKzLic/HLU4j11mjsz2G/75g==", "dev": true, "requires": { - "ajv": "6.7.0", - "ajv-errors": "1.0.1", - "ajv-keywords": "3.2.0" + "ajv": "^6.1.0", + "ajv-errors": "^1.0.0", + "ajv-keywords": "^3.1.0" } } } @@ -3222,10 +3399,10 @@ "integrity": "sha1-KzoRBTnFNV8c2NMUYj6HCxIeyFg=", "dev": true, "requires": { - "boolbase": "1.0.0", - "css-what": "2.1.2", + "boolbase": "~1.0.0", + "css-what": "2.1", "domutils": "1.5.1", - "nth-check": "1.0.2" + "nth-check": "~1.0.1" } }, "css-selector-tokenizer": { @@ -3234,9 +3411,9 @@ "integrity": "sha512-xYL0AMZJ4gFzJQsHUKa5jiWWi2vH77WVNg7JYRyewwj6oPh4yb/y6Y9ZCw9dsj/9UauMhtuxR+ogQd//EdEVNA==", "dev": true, "requires": { - "cssesc": "0.1.0", - "fastparse": "1.1.2", - "regexpu-core": "1.0.0" + "cssesc": "^0.1.0", + "fastparse": "^1.1.1", + "regexpu-core": "^1.0.0" }, "dependencies": { "regexpu-core": { @@ -3245,9 +3422,9 @@ "integrity": "sha1-hqdj9Y7k18L2sQLkdkBQ3n7ZDGs=", "dev": true, "requires": { - "regenerate": "1.3.3", - "regjsgen": "0.2.0", - "regjsparser": "0.1.5" + "regenerate": "^1.2.1", + "regjsgen": "^0.2.0", + "regjsparser": "^0.1.4" } } } @@ -3264,19 +3441,24 @@ "integrity": "sha1-yBSQPkViM3GgR3tAEJqq++6t27Q=", "dev": true }, + "csstype": { + "version": "2.6.6", + "resolved": "https://registry.npmjs.org/csstype/-/csstype-2.6.6.tgz", + "integrity": "sha512-RpFbQGUE74iyPgvr46U9t1xoQBM8T4BL8SxrN66Le2xYAPSaDJJKeztV3awugusb3g3G9iL8StmkBBXhcbbXhg==" + }, "currently-unhandled": { "version": "0.4.1", "resolved": "https://registry.npmjs.org/currently-unhandled/-/currently-unhandled-0.4.1.tgz", "integrity": "sha1-mI3zP+qxke95mmE2nddsF635V+o=", "dev": true, "requires": { - "array-find-index": "1.0.2" + "array-find-index": "^1.0.1" } }, "cyclist": { - "version": "0.2.2", - "resolved": "https://registry.npmjs.org/cyclist/-/cyclist-0.2.2.tgz", - "integrity": "sha1-GzN5LhHpFKL9bW7WRHRkRE5fpkA=", + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/cyclist/-/cyclist-1.0.1.tgz", + "integrity": "sha1-WW6WmP0MgOEgOMK4LW6xs1tiJNk=", "dev": true }, "d": { @@ -3284,7 +3466,7 @@ "resolved": "https://registry.npmjs.org/d/-/d-1.0.0.tgz", "integrity": "sha1-dUu1v+VUUdpppYuU1F9MWwRi1Y8=", "requires": { - "es5-ext": "0.10.40" + "es5-ext": "^0.10.9" } }, "dashdash": { @@ -3293,15 +3475,9 @@ "integrity": "sha1-hTz6D3y+L+1d4gMmuN1YEDX24vA=", "dev": true, "requires": { - "assert-plus": "1.0.0" + "assert-plus": "^1.0.0" } }, - "date-now": { - "version": "0.1.4", - "resolved": "https://registry.npmjs.org/date-now/-/date-now-0.1.4.tgz", - "integrity": "sha1-6vQ5/U1ISK105cx9vvIAZyueNFs=", - "dev": true - }, "debug": { "version": "2.6.9", "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", @@ -3328,9 +3504,26 @@ "dev": true }, "deep-equal": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/deep-equal/-/deep-equal-1.0.1.tgz", - "integrity": "sha1-9dJgKStmDghO/0zbyfCK0yR0SLU=" + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/deep-equal/-/deep-equal-1.1.1.tgz", + "integrity": "sha512-yd9c5AdiqVcR+JjcwUQb9DkhJc8ngNr0MahEBGvDiJw8puWab2yZlh+nkasOnZP+EGTAP6rRp2JzJhJZzvNF8g==", + "dev": true, + "requires": { + "is-arguments": "^1.0.4", + "is-date-object": "^1.0.1", + "is-regex": "^1.0.4", + "object-is": "^1.0.1", + "object-keys": "^1.1.1", + "regexp.prototype.flags": "^1.2.0" + }, + "dependencies": { + "object-keys": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/object-keys/-/object-keys-1.1.1.tgz", + "integrity": "sha512-NuAESUOUMrlIXOfHKzD6bpPu3tYt3xvjNdRIQ+FeT0lNb4K8WR70CaDxhuNguS2XG+GjkyMwOzsN5ZktImfhLA==", + "dev": true + } + } }, "deep-is": { "version": "0.1.3", @@ -3338,13 +3531,13 @@ "integrity": "sha1-s2nW+128E+7PUk+RsHD+7cNXzzQ=" }, "default-gateway": { - "version": "2.7.2", - "resolved": "https://registry.npmjs.org/default-gateway/-/default-gateway-2.7.2.tgz", - "integrity": "sha512-lAc4i9QJR0YHSDFdzeBQKfZ1SRDG3hsJNEkrpcZa8QhBfidLAilT60BDEIVUUGqosFp425KOgB3uYqcnQrWafQ==", + "version": "4.2.0", + "resolved": "https://registry.npmjs.org/default-gateway/-/default-gateway-4.2.0.tgz", + "integrity": "sha512-h6sMrVB1VMWVrW13mSc6ia/DwYYw5MN6+exNu1OaJeFac5aSAvwM7lZ0NVfTABuSkQelr4h5oebg3KB1XPdjgA==", "dev": true, "requires": { - "execa": "0.10.0", - "ip-regex": "2.1.0" + "execa": "^1.0.0", + "ip-regex": "^2.1.0" } }, "define-properties": { @@ -3352,8 +3545,8 @@ "resolved": "https://registry.npmjs.org/define-properties/-/define-properties-1.1.2.tgz", "integrity": "sha1-g6c/L+pWmJj7c3GTyPhzyvbUXJQ=", "requires": { - "foreach": "2.0.5", - "object-keys": "1.0.11" + "foreach": "^2.0.5", + "object-keys": "^1.0.8" } }, "define-property": { @@ -3362,8 +3555,8 @@ "integrity": "sha512-jwK2UV4cnPpbcG7+VRARKTZPUWowwXA8bzH5NP6ud0oeAxyYPuGZUAC7hMugpCdz4BeSZl2Dl9k66CHJ/46ZYQ==", "dev": true, "requires": { - "is-descriptor": "1.0.2", - "isobject": "3.0.1" + "is-descriptor": "^1.0.2", + "isobject": "^3.0.1" }, "dependencies": { "is-accessor-descriptor": { @@ -3372,7 +3565,7 @@ "integrity": "sha512-m5hnHTkcVsPfqx3AKlyttIPb7J+XykHvJP2B9bZDjlhLIoEq4XoK64Vg7boZlVWYK6LUY94dYPEE7Lh0ZkZKcQ==", "dev": true, "requires": { - "kind-of": "6.0.2" + "kind-of": "^6.0.0" } }, "is-data-descriptor": { @@ -3381,7 +3574,7 @@ "integrity": "sha512-jbRXy1FmtAoCjQkVmIVYwuuqDFUbaOeDjmed1tOGPrsMhtJA4rD9tkgA0F1qJ3gRFRXcHYVkdeaP50Q5rE/jLQ==", "dev": true, "requires": { - "kind-of": "6.0.2" + "kind-of": "^6.0.0" } }, "is-descriptor": { @@ -3390,9 +3583,9 @@ "integrity": "sha512-2eis5WqQGV7peooDyLmNEPUrps9+SXX5c9pL3xEB+4e9HnGuDa7mB7kHxHw4CbqS9k1T2hOH3miL8n8WtiYVtg==", "dev": true, "requires": { - "is-accessor-descriptor": "1.0.0", - "is-data-descriptor": "1.0.0", - "kind-of": "6.0.2" + "is-accessor-descriptor": "^1.0.0", + "is-data-descriptor": "^1.0.0", + "kind-of": "^6.0.2" } } } @@ -3402,12 +3595,12 @@ "resolved": "https://registry.npmjs.org/deglob/-/deglob-2.1.0.tgz", "integrity": "sha1-TUSr4W7zLHebSXK9FBqAMlApoUo=", "requires": { - "find-root": "1.1.0", - "glob": "7.1.2", - "ignore": "3.3.7", - "pkg-config": "1.1.1", - "run-parallel": "1.1.7", - "uniq": "1.0.1" + "find-root": "^1.0.0", + "glob": "^7.0.5", + "ignore": "^3.0.9", + "pkg-config": "^1.1.0", + "run-parallel": "^1.1.2", + "uniq": "^1.0.1" } }, "del": { @@ -3415,13 +3608,13 @@ "resolved": "https://registry.npmjs.org/del/-/del-2.2.2.tgz", "integrity": "sha1-wSyYHQZ4RshLyvhiz/kw2Qf/0ag=", "requires": { - "globby": "5.0.0", - "is-path-cwd": "1.0.0", - "is-path-in-cwd": "1.0.0", - "object-assign": "4.1.1", - "pify": "2.3.0", - "pinkie-promise": "2.0.1", - "rimraf": "2.6.2" + "globby": "^5.0.0", + "is-path-cwd": "^1.0.0", + "is-path-in-cwd": "^1.0.0", + "object-assign": "^4.0.1", + "pify": "^2.0.0", + "pinkie-promise": "^2.0.0", + "rimraf": "^2.2.8" } }, "delayed-stream": { @@ -3443,13 +3636,13 @@ "dev": true }, "des.js": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/des.js/-/des.js-1.0.0.tgz", - "integrity": "sha1-wHTS4qpqipoH29YfmhXCzYPsjsw=", + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/des.js/-/des.js-1.0.1.tgz", + "integrity": "sha512-Q0I4pfFrv2VPd34/vfLrFOoRmlYj3OV50i7fskps1jZWK1kApMWWT9G6RRUeYedLcBDIhnSDaUvJMb3AhUlaEA==", "dev": true, "requires": { - "inherits": "2.0.1", - "minimalistic-assert": "1.0.1" + "inherits": "^2.0.1", + "minimalistic-assert": "^1.0.0" } }, "destroy": { @@ -3476,9 +3669,9 @@ "integrity": "sha512-kqag/Nl+f3GwyK25fhUMYj81BUOrZ9IuJsjIcDE5icNM9FJHAVm3VcUDxdLPoQtTuUylWm6ZIknYJwwaPxsUzg==", "dev": true, "requires": { - "bn.js": "4.11.8", - "miller-rabin": "4.0.1", - "randombytes": "2.0.6" + "bn.js": "^4.1.0", + "miller-rabin": "^4.0.0", + "randombytes": "^2.0.0" } }, "dns-equal": { @@ -3493,8 +3686,8 @@ "integrity": "sha512-0UxfQkMhYAUaZI+xrNZOz/as5KgDU0M/fQ9b6SpkyLbk3GEswDi6PADJVaYJradtRVsRIlF1zLyOodbcTCDzUg==", "dev": true, "requires": { - "ip": "1.1.5", - "safe-buffer": "5.1.1" + "ip": "^1.1.0", + "safe-buffer": "^5.0.1" } }, "dns-txt": { @@ -3503,7 +3696,7 @@ "integrity": "sha1-uR2Ab10nGI5Ks+fRB9iBocxGQrY=", "dev": true, "requires": { - "buffer-indexof": "1.1.1" + "buffer-indexof": "^1.0.0" } }, "doctrine": { @@ -3511,7 +3704,7 @@ "resolved": "https://registry.npmjs.org/doctrine/-/doctrine-2.1.0.tgz", "integrity": "sha1-XNAfwQFiG0LEzX9dGmYkNxbT850=", "requires": { - "esutils": "2.0.2" + "esutils": "^2.0.2" } }, "dom-converter": { @@ -3520,7 +3713,7 @@ "integrity": "sha512-gd3ypIPfOMr9h5jIKq8E3sHOTCjeirnl0WK5ZdS1AW0Odt0b1PaWaHdJ4Qk4klv+YB9aJBS7mESXjFoDQPu6DA==", "dev": true, "requires": { - "utila": "0.4.0" + "utila": "~0.4" } }, "dom-serializer": { @@ -3529,8 +3722,8 @@ "integrity": "sha1-BzxpdUbOB4DOI75KKOKT5AvDDII=", "dev": true, "requires": { - "domelementtype": "1.1.3", - "entities": "1.1.2" + "domelementtype": "~1.1.1", + "entities": "~1.1.1" }, "dependencies": { "domelementtype": { @@ -3559,7 +3752,7 @@ "integrity": "sha1-0mRvXlf2w7qxHPbLBdPArPdBJZQ=", "dev": true, "requires": { - "domelementtype": "1.3.1" + "domelementtype": "1" } }, "domutils": { @@ -3568,20 +3761,20 @@ "integrity": "sha1-3NhIiib1Y9YQeeSMn3t+Mjc2gs8=", "dev": true, "requires": { - "dom-serializer": "0.1.0", - "domelementtype": "1.3.1" + "dom-serializer": "0", + "domelementtype": "1" } }, "duplexify": { - "version": "3.6.1", - "resolved": "https://registry.npmjs.org/duplexify/-/duplexify-3.6.1.tgz", - "integrity": "sha512-vM58DwdnKmty+FSPzT14K9JXb90H+j5emaR4KYbr2KTIz00WHGbWOe5ghQTx233ZCLZtrGDALzKwcjEtSt35mA==", + "version": "3.7.1", + "resolved": "https://registry.npmjs.org/duplexify/-/duplexify-3.7.1.tgz", + "integrity": "sha512-07z8uv2wMyS51kKhD1KsdXJg5WQ6t93RneqRxUHnskXVtlYYkLqM0gqStQZ3pj073g687jPCHrqNfCzawLYh5g==", "dev": true, "requires": { - "end-of-stream": "1.4.1", - "inherits": "2.0.1", - "readable-stream": "2.3.5", - "stream-shift": "1.0.0" + "end-of-stream": "^1.0.0", + "inherits": "^2.0.1", + "readable-stream": "^2.0.0", + "stream-shift": "^1.0.0" } }, "duration": { @@ -3589,8 +3782,8 @@ "resolved": "https://registry.npmjs.org/duration/-/duration-0.2.1.tgz", "integrity": "sha512-gP9Uzm/3kBnHOMrWeymFPjYbG96fQtHtsvUcWI7sP9TXoaRJ602y9SpB7dXgbvcjqQ2p1K6S+yzJccm2wr9PsQ==", "requires": { - "d": "1.0.0", - "es5-ext": "0.10.40" + "d": "1", + "es5-ext": "~0.10.23" } }, "ecc-jsbn": { @@ -3600,7 +3793,7 @@ "dev": true, "optional": true, "requires": { - "jsbn": "0.1.1" + "jsbn": "~0.1.0" } }, "ee-first": { @@ -3616,20 +3809,26 @@ "dev": true }, "elliptic": { - "version": "6.4.1", - "resolved": "https://registry.npmjs.org/elliptic/-/elliptic-6.4.1.tgz", - "integrity": "sha512-BsXLz5sqX8OHcsh7CqBMztyXARmGQ3LWPtGjJi6DiJHq5C/qvi9P3OqgswKSDftbu8+IoI/QDTAm2fFnQ9SZSQ==", + "version": "6.5.2", + "resolved": "https://registry.npmjs.org/elliptic/-/elliptic-6.5.2.tgz", + "integrity": "sha512-f4x70okzZbIQl/NSRLkI/+tteV/9WqL98zx+SQ69KbXxmVrmjwsNUPn/gYJJ0sHvEak24cZgHIPegRePAtA/xw==", "dev": true, "requires": { - "bn.js": "4.11.8", - "brorand": "1.1.0", - "hash.js": "1.1.7", - "hmac-drbg": "1.0.1", - "inherits": "2.0.1", - "minimalistic-assert": "1.0.1", - "minimalistic-crypto-utils": "1.0.1" + "bn.js": "^4.4.0", + "brorand": "^1.0.1", + "hash.js": "^1.0.0", + "hmac-drbg": "^1.0.0", + "inherits": "^2.0.1", + "minimalistic-assert": "^1.0.0", + "minimalistic-crypto-utils": "^1.0.0" } }, + "emoji-regex": { + "version": "7.0.3", + "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-7.0.3.tgz", + "integrity": "sha512-CwBLREIQ7LvYFB0WyRvwhq5N5qPhc6PMjD6bYggFlI5YyDgl+0vxq5VHbMOFqLg7hfWzmu8T5Z1QofhmTIhItA==", + "dev": true + }, "emojis-list": { "version": "2.1.0", "resolved": "https://registry.npmjs.org/emojis-list/-/emojis-list-2.1.0.tgz", @@ -3647,27 +3846,39 @@ "resolved": "https://registry.npmjs.org/encoding/-/encoding-0.1.12.tgz", "integrity": "sha1-U4tm8+5izRq1HsMjgp0flIDHS+s=", "requires": { - "iconv-lite": "0.4.19" + "iconv-lite": "~0.4.13" } }, "end-of-stream": { - "version": "1.4.1", - "resolved": "https://registry.npmjs.org/end-of-stream/-/end-of-stream-1.4.1.tgz", - "integrity": "sha512-1MkrZNvWTKCaigbn+W15elq2BB/L22nqrSY5DKlo3X6+vclJm8Bb5djXJBmEX6fS3+zCh/F4VBK5Z2KxJt4s2Q==", + "version": "1.4.4", + "resolved": "https://registry.npmjs.org/end-of-stream/-/end-of-stream-1.4.4.tgz", + "integrity": "sha512-+uw1inIHVPQoaVuHzRyXd21icM+cnt4CzD5rW+NC1wjOUSTOs+Te7FOv7AhN7vS9x/oIyhLP5PR1H+phQAHu5Q==", "dev": true, "requires": { - "once": "1.4.0" + "once": "^1.4.0" } }, "enhanced-resolve": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/enhanced-resolve/-/enhanced-resolve-4.1.0.tgz", - "integrity": "sha512-F/7vkyTtyc/llOIn8oWclcB25KdRaiPBpZYDgJHgh/UHtpgT2p2eldQgtQnLtUvfMKPKxbRaQM/hHkvLHt1Vng==", + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/enhanced-resolve/-/enhanced-resolve-4.1.1.tgz", + "integrity": "sha512-98p2zE+rL7/g/DzMHMTF4zZlCgeVdJ7yr6xzEpJRYwFYrGi9ANdn5DnJURg6RpBkyk60XYDnWIv51VfIhfNGuA==", "dev": true, "requires": { - "graceful-fs": "4.1.11", - "memory-fs": "0.4.1", - "tapable": "1.1.1" + "graceful-fs": "^4.1.2", + "memory-fs": "^0.5.0", + "tapable": "^1.0.0" + }, + "dependencies": { + "memory-fs": { + "version": "0.5.0", + "resolved": "https://registry.npmjs.org/memory-fs/-/memory-fs-0.5.0.tgz", + "integrity": "sha512-jA0rdU5KoQMC0e6ppoNRtpp6vjFq6+NY7r8hywnC7V+1Xj/MtHwGIbB1QaK/dunyjWteJzmkpd7ooeWg10T7GA==", + "dev": true, + "requires": { + "errno": "^0.1.3", + "readable-stream": "^2.0.1" + } + } } }, "entities": { @@ -3682,7 +3893,7 @@ "integrity": "sha1-RoTXF3mtOa8Xfj8AeZb3xnyFJhg=", "dev": true, "requires": { - "prr": "1.0.1" + "prr": "~1.0.1" } }, "error-ex": { @@ -3690,7 +3901,7 @@ "resolved": "https://registry.npmjs.org/error-ex/-/error-ex-1.3.1.tgz", "integrity": "sha1-+FWobOYa3E6GIcPNoh56dhLDqNw=", "requires": { - "is-arrayish": "0.2.1" + "is-arrayish": "^0.2.1" } }, "es-abstract": { @@ -3698,11 +3909,11 @@ "resolved": "https://registry.npmjs.org/es-abstract/-/es-abstract-1.10.0.tgz", "integrity": "sha1-Hss2wZeEKgDY7kwt/YZGu5fWCGQ=", "requires": { - "es-to-primitive": "1.1.1", - "function-bind": "1.1.1", - "has": "1.0.1", - "is-callable": "1.1.3", - "is-regex": "1.0.4" + "es-to-primitive": "^1.1.1", + "function-bind": "^1.1.1", + "has": "^1.0.1", + "is-callable": "^1.1.3", + "is-regex": "^1.0.4" } }, "es-to-primitive": { @@ -3710,9 +3921,9 @@ "resolved": "https://registry.npmjs.org/es-to-primitive/-/es-to-primitive-1.1.1.tgz", "integrity": "sha1-RTVSSKiJeQNLZ5Lhm7gfK3l13Q0=", "requires": { - "is-callable": "1.1.3", - "is-date-object": "1.0.1", - "is-symbol": "1.0.1" + "is-callable": "^1.1.1", + "is-date-object": "^1.0.1", + "is-symbol": "^1.0.1" } }, "es5-ext": { @@ -3720,8 +3931,8 @@ "resolved": "https://registry.npmjs.org/es5-ext/-/es5-ext-0.10.40.tgz", "integrity": "sha1-qz0heblDAIxenvJBvrJe9BQkx3Q=", "requires": { - "es6-iterator": "2.0.3", - "es6-symbol": "3.1.1" + "es6-iterator": "~2.0.3", + "es6-symbol": "~3.1.1" } }, "es6-iterator": { @@ -3729,9 +3940,9 @@ "resolved": "https://registry.npmjs.org/es6-iterator/-/es6-iterator-2.0.3.tgz", "integrity": "sha1-p96IkUGgWpSwhUQDstCg+/qY87c=", "requires": { - "d": "1.0.0", - "es5-ext": "0.10.40", - "es6-symbol": "3.1.1" + "d": "1", + "es5-ext": "^0.10.35", + "es6-symbol": "^3.1.1" }, "dependencies": { "d": { @@ -3739,7 +3950,7 @@ "resolved": "https://registry.npmjs.org/d/-/d-1.0.0.tgz", "integrity": "sha1-dUu1v+VUUdpppYuU1F9MWwRi1Y8=", "requires": { - "es5-ext": "0.10.40" + "es5-ext": "^0.10.9" } } } @@ -3749,8 +3960,8 @@ "resolved": "https://registry.npmjs.org/es6-symbol/-/es6-symbol-3.1.1.tgz", "integrity": "sha1-vwDvT9q2uhtG7Le2KbTH7VcVzHc=", "requires": { - "d": "1.0.0", - "es5-ext": "0.10.40" + "d": "1", + "es5-ext": "~0.10.14" }, "dependencies": { "d": { @@ -3758,7 +3969,7 @@ "resolved": "https://registry.npmjs.org/d/-/d-1.0.0.tgz", "integrity": "sha1-dUu1v+VUUdpppYuU1F9MWwRi1Y8=", "requires": { - "es5-ext": "0.10.40" + "es5-ext": "^0.10.9" } } } @@ -3786,43 +3997,43 @@ "integrity": "sha512-54NV+JkTpTu0d8+UYSA8mMKAG4XAsaOrozA9rCW7tgneg1mevcL7wIotPC+fZ0SkWwdhNqoXoxnQCTBp7UvTsg==", "dev": true, "requires": { - "@babel/code-frame": "7.0.0", - "ajv": "6.7.0", - "chalk": "2.4.2", - "cross-spawn": "6.0.5", - "debug": "4.1.1", - "doctrine": "2.1.0", - "eslint-scope": "4.0.0", - "eslint-utils": "1.3.1", - "eslint-visitor-keys": "1.0.0", - "espree": "5.0.0", - "esquery": "1.0.1", - "esutils": "2.0.2", - "file-entry-cache": "2.0.0", - "functional-red-black-tree": "1.0.1", - "glob": "7.1.2", - "globals": "11.10.0", - "ignore": "4.0.6", - "import-fresh": "3.0.0", - "imurmurhash": "0.1.4", - "inquirer": "6.2.1", - "js-yaml": "3.12.1", - "json-stable-stringify-without-jsonify": "1.0.1", - "levn": "0.3.0", - "lodash": "4.17.11", - "minimatch": "3.0.4", - "mkdirp": "0.5.1", - "natural-compare": "1.4.0", - "optionator": "0.8.2", - "path-is-inside": "1.0.2", - "pluralize": "7.0.0", - "progress": "2.0.0", - "regexpp": "2.0.1", - "semver": "5.6.0", - "strip-ansi": "4.0.0", - "strip-json-comments": "2.0.1", - "table": "5.2.1", - "text-table": "0.2.0" + "@babel/code-frame": "^7.0.0", + "ajv": "^6.5.3", + "chalk": "^2.1.0", + "cross-spawn": "^6.0.5", + "debug": "^4.0.1", + "doctrine": "^2.1.0", + "eslint-scope": "^4.0.0", + "eslint-utils": "^1.3.1", + "eslint-visitor-keys": "^1.0.0", + "espree": "^5.0.0", + "esquery": "^1.0.1", + "esutils": "^2.0.2", + "file-entry-cache": "^2.0.0", + "functional-red-black-tree": "^1.0.1", + "glob": "^7.1.2", + "globals": "^11.7.0", + "ignore": "^4.0.6", + "import-fresh": "^3.0.0", + "imurmurhash": "^0.1.4", + "inquirer": "^6.1.0", + "js-yaml": "^3.12.0", + "json-stable-stringify-without-jsonify": "^1.0.1", + "levn": "^0.3.0", + "lodash": "^4.17.5", + "minimatch": "^3.0.4", + "mkdirp": "^0.5.1", + "natural-compare": "^1.4.0", + "optionator": "^0.8.2", + "path-is-inside": "^1.0.2", + "pluralize": "^7.0.0", + "progress": "^2.0.0", + "regexpp": "^2.0.1", + "semver": "^5.5.1", + "strip-ansi": "^4.0.0", + "strip-json-comments": "^2.0.1", + "table": "^5.0.2", + "text-table": "^0.2.0" }, "dependencies": { "ajv": { @@ -3831,10 +4042,10 @@ "integrity": "sha512-RZXPviBTtfmtka9n9sy1N5M5b82CbxWIR6HIis4s3WQTXDJamc/0gpCWNGz6EWdWp4DOfjzJfhz/AS9zVPjjWg==", "dev": true, "requires": { - "fast-deep-equal": "2.0.1", - "fast-json-stable-stringify": "2.0.0", - "json-schema-traverse": "0.4.1", - "uri-js": "4.2.2" + "fast-deep-equal": "^2.0.1", + "fast-json-stable-stringify": "^2.0.0", + "json-schema-traverse": "^0.4.1", + "uri-js": "^4.2.2" } }, "ansi-regex": { @@ -3849,7 +4060,7 @@ "integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==", "dev": true, "requires": { - "color-convert": "1.9.1" + "color-convert": "^1.9.0" } }, "chalk": { @@ -3858,9 +4069,9 @@ "integrity": "sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==", "dev": true, "requires": { - "ansi-styles": "3.2.1", - "escape-string-regexp": "1.0.5", - "supports-color": "5.5.0" + "ansi-styles": "^3.2.1", + "escape-string-regexp": "^1.0.5", + "supports-color": "^5.3.0" } }, "cross-spawn": { @@ -3869,11 +4080,11 @@ "integrity": "sha512-eTVLrBSt7fjbDygz805pMnstIs2VTBNkRm0qxZd+M7A5XDdxVRWO5MxGBXZhjY4cqLYLdtrGqRf8mBPmzwSpWQ==", "dev": true, "requires": { - "nice-try": "1.0.5", - "path-key": "2.0.1", - "semver": "5.6.0", - "shebang-command": "1.2.0", - "which": "1.3.0" + "nice-try": "^1.0.4", + "path-key": "^2.0.1", + "semver": "^5.5.0", + "shebang-command": "^1.2.0", + "which": "^1.2.9" } }, "debug": { @@ -3882,7 +4093,7 @@ "integrity": "sha512-pYAIzeRo8J6KPEaJ0VWOh5Pzkbw/RetuzehGM7QRRX5he4fPHx2rdKMB256ehJCkX+XRQm16eZLqLNS8RSZXZw==", "dev": true, "requires": { - "ms": "2.1.1" + "ms": "^2.1.1" } }, "eslint-scope": { @@ -3891,8 +4102,8 @@ "integrity": "sha512-1G6UTDi7Jc1ELFwnR58HV4fK9OQK4S6N985f166xqXxpjU6plxFISJa2Ba9KCQuFa8RCnj/lSFJbHo7UFDBnUA==", "dev": true, "requires": { - "esrecurse": "4.2.1", - "estraverse": "4.2.0" + "esrecurse": "^4.1.0", + "estraverse": "^4.1.1" } }, "esprima": { @@ -3919,8 +4130,8 @@ "integrity": "sha512-um46hB9wNOKlwkHgiuyEVAybXBjwFUV0Z/RaHJblRd9DXltue9FTYvzCr9ErQrK9Adz5MU4gHWVaNUfdmrC8qA==", "dev": true, "requires": { - "argparse": "1.0.10", - "esprima": "4.0.1" + "argparse": "^1.0.7", + "esprima": "^4.0.0" } }, "json-schema-traverse": { @@ -3947,7 +4158,7 @@ "integrity": "sha1-qEeQIusaw2iocTibY1JixQXuNo8=", "dev": true, "requires": { - "ansi-regex": "3.0.0" + "ansi-regex": "^3.0.0" } }, "supports-color": { @@ -3956,7 +4167,7 @@ "integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==", "dev": true, "requires": { - "has-flag": "3.0.0" + "has-flag": "^3.0.0" } } } @@ -3976,17 +4187,35 @@ "resolved": "https://registry.npmjs.org/eslint-import-resolver-node/-/eslint-import-resolver-node-0.3.2.tgz", "integrity": "sha1-WPFfuDm40FdsqYBBNHaqskcttmo=", "requires": { - "debug": "2.6.9", - "resolve": "1.5.0" + "debug": "^2.6.9", + "resolve": "^1.5.0" } }, "eslint-module-utils": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/eslint-module-utils/-/eslint-module-utils-2.1.1.tgz", - "integrity": "sha1-q67IJBd2E7ipWymWOeG2+s9HNEk=", + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/eslint-module-utils/-/eslint-module-utils-2.3.0.tgz", + "integrity": "sha512-lmDJgeOOjk8hObTysjqH7wyMi+nsHwwvfBykwfhjR1LNdd7C2uFJBvx4OpWYpXOw4df1yE1cDEVd1yLHitk34w==", "requires": { - "debug": "2.6.9", - "pkg-dir": "1.0.0" + "debug": "^2.6.8", + "pkg-dir": "^2.0.0" + }, + "dependencies": { + "find-up": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/find-up/-/find-up-2.1.0.tgz", + "integrity": "sha1-RdG35QbHF93UgndaK3eSCjwMV6c=", + "requires": { + "locate-path": "^2.0.0" + } + }, + "pkg-dir": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/pkg-dir/-/pkg-dir-2.0.0.tgz", + "integrity": "sha1-9tXREJ4Z1j7fQo4L1X4Sd3YVM0s=", + "requires": { + "find-up": "^2.1.0" + } + } } }, "eslint-plugin-es": { @@ -3995,34 +4224,60 @@ "integrity": "sha512-XfFmgFdIUDgvaRAlaXUkxrRg5JSADoRC8IkKLc/cISeR3yHVMefFHQZpcyXXEUUPHfy5DwviBcrfqlyqEwlQVw==", "dev": true, "requires": { - "eslint-utils": "1.3.1", - "regexpp": "2.0.1" + "eslint-utils": "^1.3.0", + "regexpp": "^2.0.1" } }, "eslint-plugin-import": { - "version": "2.8.0", - "resolved": "https://registry.npmjs.org/eslint-plugin-import/-/eslint-plugin-import-2.8.0.tgz", - "integrity": "sha1-+htu8x/LPFAcCYWcG4bx/FuYaJQ=", + "version": "2.16.0", + "resolved": "https://registry.npmjs.org/eslint-plugin-import/-/eslint-plugin-import-2.16.0.tgz", + "integrity": "sha512-z6oqWlf1x5GkHIFgrSvtmudnqM6Q60KM4KvpWi5ubonMjycLjndvd5+8VAZIsTlHC03djdgJuyKG6XO577px6A==", + "dev": true, "requires": { - "builtin-modules": "1.1.1", - "contains-path": "0.1.0", - "debug": "2.6.9", + "contains-path": "^0.1.0", + "debug": "^2.6.9", "doctrine": "1.5.0", - "eslint-import-resolver-node": "0.3.2", - "eslint-module-utils": "2.1.1", - "has": "1.0.1", - "lodash.cond": "4.5.2", - "minimatch": "3.0.4", - "read-pkg-up": "2.0.0" + "eslint-import-resolver-node": "^0.3.2", + "eslint-module-utils": "^2.3.0", + "has": "^1.0.3", + "lodash": "^4.17.11", + "minimatch": "^3.0.4", + "read-pkg-up": "^2.0.0", + "resolve": "^1.9.0" }, "dependencies": { "doctrine": { "version": "1.5.0", "resolved": "https://registry.npmjs.org/doctrine/-/doctrine-1.5.0.tgz", "integrity": "sha1-N53Ocw9hZvds76TmcHoVmwLFpvo=", + "dev": true, "requires": { - "esutils": "2.0.2", - "isarray": "1.0.0" + "esutils": "^2.0.2", + "isarray": "^1.0.0" + } + }, + "has": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/has/-/has-1.0.3.tgz", + "integrity": "sha512-f2dvO0VU6Oej7RkWJGrehjbzMAjFp5/VKPp5tTpWIV4JHHZK1/BxbFRtf/siA2SWTe09caDmVtYYzWEIbBS4zw==", + "dev": true, + "requires": { + "function-bind": "^1.1.1" + } + }, + "path-parse": { + "version": "1.0.6", + "resolved": "https://registry.npmjs.org/path-parse/-/path-parse-1.0.6.tgz", + "integrity": "sha512-GSmOT2EbHrINBf9SR7CDELwlJ8AENk3Qn7OikK4nFYAu3Ote2+JYNVvkpAEQm3/TLNEJFD/xZJjzyxg3KBWOzw==", + "dev": true + }, + "resolve": { + "version": "1.10.0", + "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.10.0.tgz", + "integrity": "sha512-3sUr9aq5OfSg2S9pNtPA9hL1FVEAjvfOC4leW0SNf/mpnaakz2a9femSd6LqAww2RaFctwyf1lCqnTHuF1rxDg==", + "dev": true, + "requires": { + "path-parse": "^1.0.6" } } } @@ -4032,10 +4287,10 @@ "resolved": "https://registry.npmjs.org/eslint-plugin-node/-/eslint-plugin-node-6.0.1.tgz", "integrity": "sha1-vxlkIpgGQ3kxXXpLKnWTc3b6BeQ=", "requires": { - "ignore": "3.3.7", - "minimatch": "3.0.4", - "resolve": "1.5.0", - "semver": "5.5.0" + "ignore": "^3.3.6", + "minimatch": "^3.0.4", + "resolve": "^1.3.3", + "semver": "^5.4.1" } }, "eslint-plugin-promise": { @@ -4044,14 +4299,64 @@ "integrity": "sha1-VLdljI9FSBPcKocK/4FS7ElpunU=" }, "eslint-plugin-react": { - "version": "7.6.1", - "resolved": "https://registry.npmjs.org/eslint-plugin-react/-/eslint-plugin-react-7.6.1.tgz", - "integrity": "sha1-XQ6Qi+WZ8MAvv07vDH7W8p3/djM=", + "version": "7.12.4", + "resolved": "https://registry.npmjs.org/eslint-plugin-react/-/eslint-plugin-react-7.12.4.tgz", + "integrity": "sha512-1puHJkXJY+oS1t467MjbqjvX53uQ05HXwjqDgdbGBqf5j9eeydI54G3KwiJmWciQ0HTBacIKw2jgwSBSH3yfgQ==", + "dev": true, "requires": { - "doctrine": "2.1.0", - "has": "1.0.1", - "jsx-ast-utils": "2.0.1", - "prop-types": "15.6.1" + "array-includes": "^3.0.3", + "doctrine": "^2.1.0", + "has": "^1.0.3", + "jsx-ast-utils": "^2.0.1", + "object.fromentries": "^2.0.0", + "prop-types": "^15.6.2", + "resolve": "^1.9.0" + }, + "dependencies": { + "has": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/has/-/has-1.0.3.tgz", + "integrity": "sha512-f2dvO0VU6Oej7RkWJGrehjbzMAjFp5/VKPp5tTpWIV4JHHZK1/BxbFRtf/siA2SWTe09caDmVtYYzWEIbBS4zw==", + "dev": true, + "requires": { + "function-bind": "^1.1.1" + } + }, + "loose-envify": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/loose-envify/-/loose-envify-1.4.0.tgz", + "integrity": "sha512-lyuxPGr/Wfhrlem2CL/UcnUc1zcqKAImBDzukY7Y5F/yQiNdko6+fRLevlw1HgMySw7f611UIY408EtxRSoK3Q==", + "dev": true, + "requires": { + "js-tokens": "^3.0.0 || ^4.0.0" + } + }, + "path-parse": { + "version": "1.0.6", + "resolved": "https://registry.npmjs.org/path-parse/-/path-parse-1.0.6.tgz", + "integrity": "sha512-GSmOT2EbHrINBf9SR7CDELwlJ8AENk3Qn7OikK4nFYAu3Ote2+JYNVvkpAEQm3/TLNEJFD/xZJjzyxg3KBWOzw==", + "dev": true + }, + "prop-types": { + "version": "15.7.2", + "resolved": "https://registry.npmjs.org/prop-types/-/prop-types-15.7.2.tgz", + "integrity": "sha512-8QQikdH7//R2vurIJSutZ1smHYTcLpRWEOlHnzcWHmBYrOGUysKwSsrC89BCiFj3CbrfJ/nXFdJepOVrY1GCHQ==", + "dev": true, + "requires": { + "loose-envify": "^1.4.0", + "object-assign": "^4.1.1", + "react-is": "^16.8.1" + } + }, + "resolve": { + "version": "1.11.1", + "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.11.1.tgz", + "integrity": "sha512-vIpgF6wfuJOZI7KKKSP+HmiKggadPQAdsp5HiC1mvqnfp0gF1vdwgBWZIdrVft9pgqoMFQN+R7BSWZiBxx+BBw==", + "dev": true, + "requires": { + "path-parse": "^1.0.6" + } + } } }, "eslint-plugin-standard": { @@ -4064,15 +4369,18 @@ "resolved": "https://registry.npmjs.org/eslint-scope/-/eslint-scope-3.7.1.tgz", "integrity": "sha1-PWPD7f2gLgbgGkUq2IyqzHzctug=", "requires": { - "esrecurse": "4.2.1", - "estraverse": "4.2.0" + "esrecurse": "^4.1.0", + "estraverse": "^4.1.1" } }, "eslint-utils": { - "version": "1.3.1", - "resolved": "https://registry.npmjs.org/eslint-utils/-/eslint-utils-1.3.1.tgz", - "integrity": "sha512-Z7YjnIldX+2XMcjr7ZkgEsOj/bREONV60qYeB/bjMAqqqZ4zxKyWX+BOUkdmRmA9riiIPVvo5x86m5elviOk0Q==", - "dev": true + "version": "1.4.2", + "resolved": "https://registry.npmjs.org/eslint-utils/-/eslint-utils-1.4.2.tgz", + "integrity": "sha512-eAZS2sEUMlIeCjBeubdj45dmBHQwPHWyBcT1VSYB7o9x9WRRqKxyUoiXlRjyAwzN7YEzHJlYg0NmzDRWx6GP4Q==", + "dev": true, + "requires": { + "eslint-visitor-keys": "^1.0.0" + } }, "eslint-visitor-keys": { "version": "1.0.0", @@ -4085,9 +4393,9 @@ "integrity": "sha512-1MpUfwsdS9MMoN7ZXqAr9e9UKdVHDcvrJpyx7mm1WuQlx/ygErEQBzgi5Nh5qBHIoYweprhtMkTCb9GhcAIcsA==", "dev": true, "requires": { - "acorn": "6.0.5", - "acorn-jsx": "5.0.1", - "eslint-visitor-keys": "1.0.0" + "acorn": "^6.0.2", + "acorn-jsx": "^5.0.0", + "eslint-visitor-keys": "^1.0.0" }, "dependencies": { "acorn": { @@ -4099,16 +4407,16 @@ } }, "esprima": { - "version": "3.1.3", - "resolved": "https://registry.npmjs.org/esprima/-/esprima-3.1.3.tgz", - "integrity": "sha1-/cpRzuYTOJXjyI1TXOSdv/YqRjM=" + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/esprima/-/esprima-4.0.1.tgz", + "integrity": "sha512-eGuFFw7Upda+g4p+QHvnW0RyTX/SVeJBDM/gCtMARO0cLuT2HcEKnTPvhjV6aGeqrCB/sbNop0Kszm0jsaWU4A==" }, "esquery": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/esquery/-/esquery-1.0.1.tgz", "integrity": "sha512-SmiyZ5zIWH9VM+SRUReLS5Q8a7GxtRdxEBVZpm98rJM7Sb+A9DVCndXfkeFUd3byderg+EbDkfnevfCwynWaNA==", "requires": { - "estraverse": "4.2.0" + "estraverse": "^4.0.0" } }, "esrecurse": { @@ -4116,7 +4424,7 @@ "resolved": "https://registry.npmjs.org/esrecurse/-/esrecurse-4.2.1.tgz", "integrity": "sha1-AHo7n9vCs7uH5IeeoZyS/b05Qs8=", "requires": { - "estraverse": "4.2.0" + "estraverse": "^4.1.0" } }, "estraverse": { @@ -4136,9 +4444,15 @@ "dev": true }, "eventemitter3": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/eventemitter3/-/eventemitter3-3.1.0.tgz", - "integrity": "sha512-ivIvhpq/Y0uSjcHDcOIccjmYjGLcP09MFGE7ysAwkAvkXfpZlC985pH2/ui64DKazbTW/4kN3yqozUxlXzI6cA==", + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/eventemitter3/-/eventemitter3-4.0.0.tgz", + "integrity": "sha512-qerSRB0p+UDEssxTtm6EDKcE7W4OaoisfIMl4CngyEhjpYglocpNg6UEqCvemdGhosAsg4sO2dXJOdyBifPGCg==", + "dev": true + }, + "events": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/events/-/events-3.0.0.tgz", + "integrity": "sha512-Dc381HFWJzEOhQ+d8pkNon++bk9h6cdAoAj4iE6Q4y6xgTzySWXlKn05/TVNpjnfRqi/X0EpJEJohPjNI3zpVA==", "dev": true }, "eventsource": { @@ -4147,7 +4461,7 @@ "integrity": "sha512-4Ln17+vVT0k8aWq+t/bF5arcS3EpT9gYtW66EPacdj/mAFevznsnyoHLPy2BA8gbIQeIHoPsvwmfBftfcG//BQ==", "dev": true, "requires": { - "original": "1.0.2" + "original": "^1.0.0" } }, "evp_bytestokey": { @@ -4156,23 +4470,23 @@ "integrity": "sha512-/f2Go4TognH/KvCISP7OUsHn85hT9nUkxxA9BEWxFn+Oj9o8ZNLm/40hdlgSLyuOimsrTKLUMEorQexp/aPQeA==", "dev": true, "requires": { - "md5.js": "1.3.5", - "safe-buffer": "5.1.1" + "md5.js": "^1.3.4", + "safe-buffer": "^5.1.1" } }, "execa": { - "version": "0.10.0", - "resolved": "https://registry.npmjs.org/execa/-/execa-0.10.0.tgz", - "integrity": "sha512-7XOMnz8Ynx1gGo/3hyV9loYNPWM94jG3+3T3Y8tsfSstFmETmENCMU/A/zj8Lyaj1lkgEepKepvd6240tBRvlw==", + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/execa/-/execa-1.0.0.tgz", + "integrity": "sha512-adbxcyWV46qiHyvSp50TKt05tB4tK3HcmF7/nxfAdhnox83seTDbwnaqKO4sXRy7roHAIFqJP/Rw/AuEbX61LA==", "dev": true, "requires": { - "cross-spawn": "6.0.5", - "get-stream": "3.0.0", - "is-stream": "1.1.0", - "npm-run-path": "2.0.2", - "p-finally": "1.0.0", - "signal-exit": "3.0.2", - "strip-eof": "1.0.0" + "cross-spawn": "^6.0.0", + "get-stream": "^4.0.0", + "is-stream": "^1.1.0", + "npm-run-path": "^2.0.0", + "p-finally": "^1.0.0", + "signal-exit": "^3.0.0", + "strip-eof": "^1.0.0" }, "dependencies": { "cross-spawn": { @@ -4181,11 +4495,11 @@ "integrity": "sha512-eTVLrBSt7fjbDygz805pMnstIs2VTBNkRm0qxZd+M7A5XDdxVRWO5MxGBXZhjY4cqLYLdtrGqRf8mBPmzwSpWQ==", "dev": true, "requires": { - "nice-try": "1.0.5", - "path-key": "2.0.1", - "semver": "5.5.0", - "shebang-command": "1.2.0", - "which": "1.3.0" + "nice-try": "^1.0.4", + "path-key": "^2.0.1", + "semver": "^5.5.0", + "shebang-command": "^1.2.0", + "which": "^1.2.9" } } } @@ -4196,13 +4510,13 @@ "integrity": "sha1-t3c14xXOMPa27/D4OwQVGiJEliI=", "dev": true, "requires": { - "debug": "2.6.9", - "define-property": "0.2.5", - "extend-shallow": "2.0.1", - "posix-character-classes": "0.1.1", - "regex-not": "1.0.2", - "snapdragon": "0.8.2", - "to-regex": "3.0.2" + "debug": "^2.3.3", + "define-property": "^0.2.5", + "extend-shallow": "^2.0.1", + "posix-character-classes": "^0.1.0", + "regex-not": "^1.0.0", + "snapdragon": "^0.8.1", + "to-regex": "^3.0.1" }, "dependencies": { "define-property": { @@ -4211,7 +4525,7 @@ "integrity": "sha1-w1se+RjsPJkPmlvFe+BKrOxcgRY=", "dev": true, "requires": { - "is-descriptor": "0.1.6" + "is-descriptor": "^0.1.0" } }, "extend-shallow": { @@ -4220,7 +4534,7 @@ "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=", "dev": true, "requires": { - "is-extendable": "0.1.1" + "is-extendable": "^0.1.0" } } } @@ -4231,7 +4545,7 @@ "integrity": "sha1-l+gBqgUt8CRU3kawK/YhZCzchQI=", "dev": true, "requires": { - "homedir-polyfill": "1.0.1" + "homedir-polyfill": "^1.0.1" } }, "exports-loader": { @@ -4240,7 +4554,7 @@ "integrity": "sha512-RKwCrO4A6IiKm0pG3c9V46JxIHcDplwwGJn6+JJ1RcVnh/WSGJa0xkmk5cRVtgOPzCAtTMGj2F7nluh9L0vpSA==", "dev": true, "requires": { - "loader-utils": "1.2.3", + "loader-utils": "^1.1.0", "source-map": "0.5.0" }, "dependencies": { @@ -4256,7 +4570,7 @@ "integrity": "sha512-aKS4WQjPenRxiQsC93MNfjx+nbF4PAdYzmd/1JIj8HYzqfbu86beTuNgXDzPknWk0n0uARlyewZo4s++ES36Ow==", "dev": true, "requires": { - "minimist": "1.2.0" + "minimist": "^1.2.0" } }, "loader-utils": { @@ -4265,9 +4579,9 @@ "integrity": "sha512-fkpz8ejdnEMG3s37wGL07iSBDg99O9D5yflE9RGNH3hRdx9SOwYfnGYdZOUIZitN8E+E2vkq3MUMYMvPYl5ZZA==", "dev": true, "requires": { - "big.js": "5.2.2", - "emojis-list": "2.1.0", - "json5": "1.0.1" + "big.js": "^5.2.2", + "emojis-list": "^2.0.0", + "json5": "^1.0.1" } }, "minimist": { @@ -4285,41 +4599,41 @@ } }, "express": { - "version": "4.16.4", - "resolved": "https://registry.npmjs.org/express/-/express-4.16.4.tgz", - "integrity": "sha512-j12Uuyb4FMrd/qQAm6uCHAkPtO8FDTRJZBDd5D2KOL2eLaz1yUNdUB/NOIyq0iU4q4cFarsUCrnFDPBcnksuOg==", + "version": "4.17.1", + "resolved": "https://registry.npmjs.org/express/-/express-4.17.1.tgz", + "integrity": "sha512-mHJ9O79RqluphRrcw2X/GTh3k9tVv8YcoyY4Kkh4WDMUYKRZUq0h1o0w2rrrxBqM7VoeUVqgb27xlEMXTnYt4g==", "dev": true, "requires": { - "accepts": "1.3.5", + "accepts": "~1.3.7", "array-flatten": "1.1.1", - "body-parser": "1.18.3", - "content-disposition": "0.5.2", - "content-type": "1.0.4", - "cookie": "0.3.1", + "body-parser": "1.19.0", + "content-disposition": "0.5.3", + "content-type": "~1.0.4", + "cookie": "0.4.0", "cookie-signature": "1.0.6", "debug": "2.6.9", - "depd": "1.1.2", - "encodeurl": "1.0.2", - "escape-html": "1.0.3", - "etag": "1.8.1", - "finalhandler": "1.1.1", + "depd": "~1.1.2", + "encodeurl": "~1.0.2", + "escape-html": "~1.0.3", + "etag": "~1.8.1", + "finalhandler": "~1.1.2", "fresh": "0.5.2", "merge-descriptors": "1.0.1", - "methods": "1.1.2", - "on-finished": "2.3.0", - "parseurl": "1.3.2", + "methods": "~1.1.2", + "on-finished": "~2.3.0", + "parseurl": "~1.3.3", "path-to-regexp": "0.1.7", - "proxy-addr": "2.0.4", - "qs": "6.5.2", - "range-parser": "1.2.0", + "proxy-addr": "~2.0.5", + "qs": "6.7.0", + "range-parser": "~1.2.1", "safe-buffer": "5.1.2", - "send": "0.16.2", - "serve-static": "1.13.2", - "setprototypeof": "1.1.0", - "statuses": "1.4.0", - "type-is": "1.6.16", + "send": "0.17.1", + "serve-static": "1.14.1", + "setprototypeof": "1.1.1", + "statuses": "~1.5.0", + "type-is": "~1.6.18", "utils-merge": "1.0.1", - "vary": "1.1.2" + "vary": "~1.1.2" }, "dependencies": { "array-flatten": { @@ -4329,9 +4643,9 @@ "dev": true }, "qs": { - "version": "6.5.2", - "resolved": "https://registry.npmjs.org/qs/-/qs-6.5.2.tgz", - "integrity": "sha512-N5ZAX4/LxJmF+7wN74pUD6qAh9/wnvdQcjq9TZjevvXzSUo7bfmw91saqMjzGS2xq91/odN2dW/WOl7qQHNDGA==", + "version": "6.7.0", + "resolved": "https://registry.npmjs.org/qs/-/qs-6.7.0.tgz", + "integrity": "sha512-VCdBRNFTX1fyE7Nb6FYoURo/SPe62QCaAyzJvUjwRaIsc+NePBEniHlvxFmmX56+HZphIGtV0XeCirBtpDrTyQ==", "dev": true }, "safe-buffer": { @@ -4345,7 +4659,8 @@ "extend": { "version": "3.0.2", "resolved": "https://registry.npmjs.org/extend/-/extend-3.0.2.tgz", - "integrity": "sha512-fjquC59cD7CyW6urNXK0FBufkZcoiGG80wTuPujX590cB5Ttln20E2UB4S/WARVqhXffZl2LNgS+gQdPIIim/g==" + "integrity": "sha512-fjquC59cD7CyW6urNXK0FBufkZcoiGG80wTuPujX590cB5Ttln20E2UB4S/WARVqhXffZl2LNgS+gQdPIIim/g==", + "dev": true }, "extend-shallow": { "version": "3.0.2", @@ -4353,8 +4668,8 @@ "integrity": "sha1-Jqcarwc7OfshJxcnRhMcJwQCjbg=", "dev": true, "requires": { - "assign-symbols": "1.0.0", - "is-extendable": "1.0.1" + "assign-symbols": "^1.0.0", + "is-extendable": "^1.0.1" }, "dependencies": { "is-extendable": { @@ -4363,7 +4678,7 @@ "integrity": "sha512-arnXMxT1hhoKo9k1LZdmlNyJdDDfy2v0fXjFlmok4+i8ul/6WlbVge9bhM74OpNPQPMGUToDtz+KXa1PneJxOA==", "dev": true, "requires": { - "is-plain-object": "2.0.4" + "is-plain-object": "^2.0.4" } } } @@ -4373,9 +4688,9 @@ "resolved": "https://registry.npmjs.org/external-editor/-/external-editor-2.1.0.tgz", "integrity": "sha1-PQJqIbf5W1cmOH1CAKwWDTcsO0g=", "requires": { - "chardet": "0.4.2", - "iconv-lite": "0.4.19", - "tmp": "0.0.33" + "chardet": "^0.4.0", + "iconv-lite": "^0.4.17", + "tmp": "^0.0.33" } }, "extglob": { @@ -4384,14 +4699,14 @@ "integrity": "sha512-Nmb6QXkELsuBr24CJSkilo6UHHgbekK5UiZgfE6UHD3Eb27YC6oD+bhcT+tJ6cl8dmsgdQxnWlcry8ksBIBLpw==", "dev": true, "requires": { - "array-unique": "0.3.2", - "define-property": "1.0.0", - "expand-brackets": "2.1.4", - "extend-shallow": "2.0.1", - "fragment-cache": "0.2.1", - "regex-not": "1.0.2", - "snapdragon": "0.8.2", - "to-regex": "3.0.2" + "array-unique": "^0.3.2", + "define-property": "^1.0.0", + "expand-brackets": "^2.1.4", + "extend-shallow": "^2.0.1", + "fragment-cache": "^0.2.1", + "regex-not": "^1.0.0", + "snapdragon": "^0.8.1", + "to-regex": "^3.0.1" }, "dependencies": { "define-property": { @@ -4400,7 +4715,7 @@ "integrity": "sha1-dp66rz9KY6rTr56NMEybvnm/sOY=", "dev": true, "requires": { - "is-descriptor": "1.0.2" + "is-descriptor": "^1.0.0" } }, "extend-shallow": { @@ -4409,7 +4724,7 @@ "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=", "dev": true, "requires": { - "is-extendable": "0.1.1" + "is-extendable": "^0.1.0" } }, "is-accessor-descriptor": { @@ -4418,7 +4733,7 @@ "integrity": "sha512-m5hnHTkcVsPfqx3AKlyttIPb7J+XykHvJP2B9bZDjlhLIoEq4XoK64Vg7boZlVWYK6LUY94dYPEE7Lh0ZkZKcQ==", "dev": true, "requires": { - "kind-of": "6.0.2" + "kind-of": "^6.0.0" } }, "is-data-descriptor": { @@ -4427,7 +4742,7 @@ "integrity": "sha512-jbRXy1FmtAoCjQkVmIVYwuuqDFUbaOeDjmed1tOGPrsMhtJA4rD9tkgA0F1qJ3gRFRXcHYVkdeaP50Q5rE/jLQ==", "dev": true, "requires": { - "kind-of": "6.0.2" + "kind-of": "^6.0.0" } }, "is-descriptor": { @@ -4436,9 +4751,9 @@ "integrity": "sha512-2eis5WqQGV7peooDyLmNEPUrps9+SXX5c9pL3xEB+4e9HnGuDa7mB7kHxHw4CbqS9k1T2hOH3miL8n8WtiYVtg==", "dev": true, "requires": { - "is-accessor-descriptor": "1.0.0", - "is-data-descriptor": "1.0.0", - "kind-of": "6.0.2" + "is-accessor-descriptor": "^1.0.0", + "is-data-descriptor": "^1.0.0", + "kind-of": "^6.0.2" } } } @@ -4476,7 +4791,7 @@ "integrity": "sha1-TkkvjQTftviQA1B/btvy1QHnxvQ=", "dev": true, "requires": { - "websocket-driver": "0.7.0" + "websocket-driver": ">=0.5.1" } }, "fbjs": { @@ -4484,13 +4799,13 @@ "resolved": "https://registry.npmjs.org/fbjs/-/fbjs-0.8.16.tgz", "integrity": "sha1-XmdDL1UNxBtXK/VYR7ispk5TN9s=", "requires": { - "core-js": "1.2.7", - "isomorphic-fetch": "2.2.1", - "loose-envify": "1.3.1", - "object-assign": "4.1.1", - "promise": "7.3.1", - "setimmediate": "1.0.5", - "ua-parser-js": "0.7.17" + "core-js": "^1.0.0", + "isomorphic-fetch": "^2.1.1", + "loose-envify": "^1.0.0", + "object-assign": "^4.1.0", + "promise": "^7.1.1", + "setimmediate": "^1.0.5", + "ua-parser-js": "^0.7.9" }, "dependencies": { "core-js": { @@ -4511,7 +4826,7 @@ "resolved": "https://registry.npmjs.org/figures/-/figures-2.0.0.tgz", "integrity": "sha1-OrGi0qYsi/tDGgyUy3l6L84nyWI=", "requires": { - "escape-string-regexp": "1.0.5" + "escape-string-regexp": "^1.0.5" } }, "file-entry-cache": { @@ -4519,8 +4834,8 @@ "resolved": "https://registry.npmjs.org/file-entry-cache/-/file-entry-cache-2.0.0.tgz", "integrity": "sha1-w5KZDD5oR4PYOLjISkXYoEhFg2E=", "requires": { - "flat-cache": "1.3.0", - "object-assign": "4.1.1" + "flat-cache": "^1.2.1", + "object-assign": "^4.0.1" } }, "file-loader": { @@ -4529,8 +4844,8 @@ "integrity": "sha512-4sNIOXgtH/9WZq4NvlfU3Opn5ynUsqBwSLyM+I7UOwdGigTBYfVVQEwe/msZNX/j4pCJTIM14Fsw66Svo1oVrw==", "dev": true, "requires": { - "loader-utils": "1.2.3", - "schema-utils": "1.0.0" + "loader-utils": "^1.0.2", + "schema-utils": "^1.0.0" }, "dependencies": { "ajv": { @@ -4539,10 +4854,10 @@ "integrity": "sha512-RZXPviBTtfmtka9n9sy1N5M5b82CbxWIR6HIis4s3WQTXDJamc/0gpCWNGz6EWdWp4DOfjzJfhz/AS9zVPjjWg==", "dev": true, "requires": { - "fast-deep-equal": "2.0.1", - "fast-json-stable-stringify": "2.0.0", - "json-schema-traverse": "0.4.1", - "uri-js": "4.2.2" + "fast-deep-equal": "^2.0.1", + "fast-json-stable-stringify": "^2.0.0", + "json-schema-traverse": "^0.4.1", + "uri-js": "^4.2.2" } }, "ajv-keywords": { @@ -4575,7 +4890,7 @@ "integrity": "sha512-aKS4WQjPenRxiQsC93MNfjx+nbF4PAdYzmd/1JIj8HYzqfbu86beTuNgXDzPknWk0n0uARlyewZo4s++ES36Ow==", "dev": true, "requires": { - "minimist": "1.2.0" + "minimist": "^1.2.0" } }, "loader-utils": { @@ -4584,9 +4899,9 @@ "integrity": "sha512-fkpz8ejdnEMG3s37wGL07iSBDg99O9D5yflE9RGNH3hRdx9SOwYfnGYdZOUIZitN8E+E2vkq3MUMYMvPYl5ZZA==", "dev": true, "requires": { - "big.js": "5.2.2", - "emojis-list": "2.1.0", - "json5": "1.0.1" + "big.js": "^5.2.2", + "emojis-list": "^2.0.0", + "json5": "^1.0.1" } }, "minimist": { @@ -4601,9 +4916,9 @@ "integrity": "sha512-i27Mic4KovM/lnGsy8whRCHhc7VicJajAjTrYg11K9zfZXnYIt4k5F+kZkwjnrhKzLic/HLU4j11mjsz2G/75g==", "dev": true, "requires": { - "ajv": "6.7.0", - "ajv-errors": "1.0.1", - "ajv-keywords": "3.2.0" + "ajv": "^6.1.0", + "ajv-errors": "^1.0.0", + "ajv-keywords": "^3.1.0" } } } @@ -4614,10 +4929,10 @@ "integrity": "sha1-1USBHUKPmOsGpj3EAtJAPDKMOPc=", "dev": true, "requires": { - "extend-shallow": "2.0.1", - "is-number": "3.0.0", - "repeat-string": "1.6.1", - "to-regex-range": "2.1.1" + "extend-shallow": "^2.0.1", + "is-number": "^3.0.0", + "repeat-string": "^1.6.1", + "to-regex-range": "^2.1.0" }, "dependencies": { "extend-shallow": { @@ -4626,24 +4941,24 @@ "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=", "dev": true, "requires": { - "is-extendable": "0.1.1" + "is-extendable": "^0.1.0" } } } }, "finalhandler": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/finalhandler/-/finalhandler-1.1.1.tgz", - "integrity": "sha1-7r9O2EAHnIP0JJA4ydcDAIMBsQU=", + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/finalhandler/-/finalhandler-1.1.2.tgz", + "integrity": "sha512-aAWcW57uxVNrQZqFXjITpW3sIUQmHGG3qSb9mUah9MgMC4NeWhNOlNjXEYq3HjRAvL6arUviZGGJsBg6z0zsWA==", "dev": true, "requires": { "debug": "2.6.9", - "encodeurl": "1.0.2", - "escape-html": "1.0.3", - "on-finished": "2.3.0", - "parseurl": "1.3.2", - "statuses": "1.4.0", - "unpipe": "1.0.0" + "encodeurl": "~1.0.2", + "escape-html": "~1.0.3", + "on-finished": "~2.3.0", + "parseurl": "~1.3.3", + "statuses": "~1.5.0", + "unpipe": "~1.0.0" } }, "find-cache-dir": { @@ -4652,9 +4967,9 @@ "integrity": "sha512-LDUY6V1Xs5eFskUVYtIwatojt6+9xC9Chnlk/jYOOvn3FAFfSaWddxahDGyNHh0b2dMXa6YW2m0tk8TdVaXHlA==", "dev": true, "requires": { - "commondir": "1.0.1", - "make-dir": "1.3.0", - "pkg-dir": "3.0.0" + "commondir": "^1.0.1", + "make-dir": "^1.0.0", + "pkg-dir": "^3.0.0" }, "dependencies": { "find-up": { @@ -4663,7 +4978,7 @@ "integrity": "sha512-1yD6RmLI1XBfxugvORwlck6f75tYL+iR0jqwsOrOxMZyGYqUuDhJ0l4AXdO1iX/FTs9cBAMEk1gWSEx1kSbylg==", "dev": true, "requires": { - "locate-path": "3.0.0" + "locate-path": "^3.0.0" } }, "locate-path": { @@ -4672,8 +4987,8 @@ "integrity": "sha512-7AO748wWnIhNqAuaty2ZWHkQHRSNfPVIsPIfwEOWO22AmaoVrWavlOcMR5nzTLNYvp36X220/maaRsrec1G65A==", "dev": true, "requires": { - "p-locate": "3.0.0", - "path-exists": "3.0.0" + "p-locate": "^3.0.0", + "path-exists": "^3.0.0" } }, "p-limit": { @@ -4682,7 +4997,7 @@ "integrity": "sha512-NhURkNcrVB+8hNfLuysU8enY5xn2KXphsHBaC2YmRNTZRc7RWusw6apSpdEj3jo4CMb6W9nrF6tTnsJsJeyu6g==", "dev": true, "requires": { - "p-try": "2.0.0" + "p-try": "^2.0.0" } }, "p-locate": { @@ -4691,7 +5006,7 @@ "integrity": "sha512-x+12w/To+4GFfgJhBEpiDcLozRJGegY+Ei7/z0tSLkMmxGZNybVMSfWj9aJn8Z5Fc7dBUNJOOVgPv2H7IwulSQ==", "dev": true, "requires": { - "p-limit": "2.1.0" + "p-limit": "^2.0.0" } }, "p-try": { @@ -4712,7 +5027,7 @@ "integrity": "sha512-/E57AYkoeQ25qkxMj5PBOVgF8Kiu/h7cYS30Z5+R7WaiCCBfLq58ZI/dSeaEKb9WVJV5n/03QwrN3IeWIFllvw==", "dev": true, "requires": { - "find-up": "3.0.0" + "find-up": "^3.0.0" } } } @@ -4726,32 +5041,22 @@ "version": "1.1.2", "resolved": "https://registry.npmjs.org/find-up/-/find-up-1.1.2.tgz", "integrity": "sha1-ay6YIrGizgpgq2TWEOzK1TyyTQ8=", + "dev": true, "requires": { - "path-exists": "2.1.0", - "pinkie-promise": "2.0.1" + "path-exists": "^2.0.0", + "pinkie-promise": "^2.0.0" } }, "findup-sync": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/findup-sync/-/findup-sync-2.0.0.tgz", - "integrity": "sha1-kyaxSIwi0aYIhlCoaQGy2akKLLw=", + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/findup-sync/-/findup-sync-3.0.0.tgz", + "integrity": "sha512-YbffarhcicEhOrm4CtrwdKBdCuz576RLdhJDsIfvNtxUuhdRet1qZcsMjqbePtAseKdAnDyM/IyXbu7PRPRLYg==", "dev": true, "requires": { - "detect-file": "1.0.0", - "is-glob": "3.1.0", - "micromatch": "3.1.10", - "resolve-dir": "1.0.1" - }, - "dependencies": { - "is-glob": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-3.1.0.tgz", - "integrity": "sha1-e6WuJCF4BKxwcHuWkiVnSGzD6Eo=", - "dev": true, - "requires": { - "is-extglob": "2.1.1" - } - } + "detect-file": "^1.0.0", + "is-glob": "^4.0.0", + "micromatch": "^3.0.4", + "resolve-dir": "^1.0.1" } }, "flat-cache": { @@ -4759,10 +5064,10 @@ "resolved": "https://registry.npmjs.org/flat-cache/-/flat-cache-1.3.0.tgz", "integrity": "sha1-0wMLMrOBVPTjt+nHCfSQ9++XxIE=", "requires": { - "circular-json": "0.3.3", - "del": "2.2.2", - "graceful-fs": "4.1.11", - "write": "0.2.1" + "circular-json": "^0.3.1", + "del": "^2.0.2", + "graceful-fs": "^4.1.2", + "write": "^0.2.1" } }, "flow-bin": { @@ -4777,36 +5082,74 @@ "integrity": "sha1-Qlps3zdjqK7vPf8gPlEnuRm9EEo=", "dev": true, "requires": { - "shelljs": "0.6.1" + "shelljs": "^0.6.0" } }, "flush-write-stream": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/flush-write-stream/-/flush-write-stream-1.0.3.tgz", - "integrity": "sha512-calZMC10u0FMUqoiunI2AiGIIUtUIvifNwkHhNupZH4cbNnW1Itkoh/Nf5HFYmDrwWPjrUxpkZT0KhuCq0jmGw==", + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/flush-write-stream/-/flush-write-stream-1.1.1.tgz", + "integrity": "sha512-3Z4XhFZ3992uIq0XOqb9AreonueSYphE6oYbpt5+3u06JWklbsPkNv3ZKkP9Bz/r+1MWCaMoSQ28P85+1Yc77w==", "dev": true, "requires": { - "inherits": "2.0.1", - "readable-stream": "2.3.5" + "inherits": "^2.0.3", + "readable-stream": "^2.3.6" + }, + "dependencies": { + "inherits": { + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.4.tgz", + "integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==", + "dev": true + }, + "readable-stream": { + "version": "2.3.6", + "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.6.tgz", + "integrity": "sha512-tQtKA9WIAhBF3+VLAseyMqZeBjW0AHJoxOtYqSUZNJxauErmLbVm2FW1y+J/YA9dUrAC39ITejlZWhVIwawkKw==", + "dev": true, + "requires": { + "core-util-is": "~1.0.0", + "inherits": "~2.0.3", + "isarray": "~1.0.0", + "process-nextick-args": "~2.0.0", + "safe-buffer": "~5.1.1", + "string_decoder": "~1.1.1", + "util-deprecate": "~1.0.1" + } + }, + "string_decoder": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz", + "integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==", + "dev": true, + "requires": { + "safe-buffer": "~5.1.0" + } + } } }, "follow-redirects": { - "version": "1.6.1", - "resolved": "https://registry.npmjs.org/follow-redirects/-/follow-redirects-1.6.1.tgz", - "integrity": "sha512-t2JCjbzxQpWvbhts3l6SH1DKzSrx8a+SsaVf4h6bG4kOXUuPYS/kg2Lr4gQSb7eemaHqJkOThF1BGyjlUkO1GQ==", + "version": "1.9.0", + "resolved": "https://registry.npmjs.org/follow-redirects/-/follow-redirects-1.9.0.tgz", + "integrity": "sha512-CRcPzsSIbXyVDl0QI01muNDu69S8trU4jArW9LpOt2WtC6LyUJetcIrmfHsRBx7/Jb6GHJUiuqyYxPooFfNt6A==", "dev": true, "requires": { - "debug": "3.1.0" + "debug": "^3.0.0" }, "dependencies": { "debug": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/debug/-/debug-3.1.0.tgz", - "integrity": "sha512-OX8XqP7/1a9cqkxYw2yXss15f26NKWBpDXQd0/uK/KPqdQhxbPa994hnzjcE2VqQpDslf55723cKPUOGSmMY3g==", + "version": "3.2.6", + "resolved": "https://registry.npmjs.org/debug/-/debug-3.2.6.tgz", + "integrity": "sha512-mel+jf7nrtEl5Pn1Qx46zARXKDpBbvzezse7p7LqINmdoIk8PYP5SySaxEmYv6TZ0JyEKA1hsCId6DIhgITtWQ==", "dev": true, "requires": { - "ms": "2.0.0" + "ms": "^2.1.1" } + }, + "ms": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", + "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==", + "dev": true } } }, @@ -4822,7 +5165,7 @@ "integrity": "sha1-xjMy9BXO3EsE2/5wz4NklMU8tEs=", "dev": true, "requires": { - "for-in": "1.0.2" + "for-in": "^1.0.1" } }, "foreach": { @@ -4842,9 +5185,9 @@ "integrity": "sha1-SXBJi+YEwgwAXU9cI67NIda0kJk=", "dev": true, "requires": { - "asynckit": "0.4.0", + "asynckit": "^0.4.0", "combined-stream": "1.0.6", - "mime-types": "2.1.18" + "mime-types": "^2.1.12" } }, "forwarded": { @@ -4859,7 +5202,7 @@ "integrity": "sha1-QpD60n8T6Jvn8zeZxrxaCr//DRk=", "dev": true, "requires": { - "map-cache": "0.2.2" + "map-cache": "^0.2.2" } }, "fresh": { @@ -4874,8 +5217,36 @@ "integrity": "sha1-i/tVAr3kpNNs/e6gB/zKIdfjgq8=", "dev": true, "requires": { - "inherits": "2.0.1", - "readable-stream": "2.3.5" + "inherits": "^2.0.1", + "readable-stream": "^2.0.0" + } + }, + "fs-extra": { + "version": "8.1.0", + "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-8.1.0.tgz", + "integrity": "sha512-yhlQgA6mnOJUKOsRUFsgJdQCvkKhcz8tlZG5HBQfReYZy46OwLcY+Zia0mtdHsOo9y/hP+CxMN0TU9QxoOtG4g==", + "dev": true, + "requires": { + "graceful-fs": "^4.2.0", + "jsonfile": "^4.0.0", + "universalify": "^0.1.0" + }, + "dependencies": { + "graceful-fs": { + "version": "4.2.3", + "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.3.tgz", + "integrity": "sha512-a30VEBm4PEdx1dRB7MFK7BejejvCvBronbLjht+sHuGYj8PHs7M/5Z+rt5lw551vZ7yfTCj4Vuyy3mSJytDWRQ==", + "dev": true + }, + "jsonfile": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/jsonfile/-/jsonfile-4.0.0.tgz", + "integrity": "sha1-h3Gq4HmbZAdrdmQPygWPnBDjPss=", + "dev": true, + "requires": { + "graceful-fs": "^4.1.6" + } + } } }, "fs-write-stream-atomic": { @@ -4884,10 +5255,10 @@ "integrity": "sha1-tH31NJPvkR33VzHnCp3tAYnbQMk=", "dev": true, "requires": { - "graceful-fs": "4.1.11", - "iferr": "0.1.5", - "imurmurhash": "0.1.4", - "readable-stream": "2.3.5" + "graceful-fs": "^4.1.2", + "iferr": "^0.1.5", + "imurmurhash": "^0.1.4", + "readable-stream": "1 || 2" } }, "fs.realpath": { @@ -4896,14 +5267,14 @@ "integrity": "sha1-FQStJSMVjKpA20onh8sBQRmU6k8=" }, "fsevents": { - "version": "1.2.4", - "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-1.2.4.tgz", - "integrity": "sha512-z8H8/diyk76B7q5wg+Ud0+CqzcAF3mBBI/bA5ne5zrRUUIvNkJY//D3BqyH571KuAC4Nr7Rw7CjWX4r0y9DvNg==", + "version": "1.2.9", + "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-1.2.9.tgz", + "integrity": "sha512-oeyj2H3EjjonWcFjD5NvZNE9Rqe4UW+nQBU2HNeKw0koVLEFIhtyETyAakeAM3de7Z/SW5kcA+fZUait9EApnw==", "dev": true, "optional": true, "requires": { - "nan": "2.9.2", - "node-pre-gyp": "0.10.0" + "nan": "^2.12.1", + "node-pre-gyp": "^0.12.0" }, "dependencies": { "abbrev": { @@ -4915,7 +5286,8 @@ "ansi-regex": { "version": "2.1.1", "bundled": true, - "dev": true + "dev": true, + "optional": true }, "aproba": { "version": "1.2.0", @@ -4924,31 +5296,33 @@ "optional": true }, "are-we-there-yet": { - "version": "1.1.4", + "version": "1.1.5", "bundled": true, "dev": true, "optional": true, "requires": { - "delegates": "1.0.0", - "readable-stream": "2.3.6" + "delegates": "^1.0.0", + "readable-stream": "^2.0.6" } }, "balanced-match": { "version": "1.0.0", "bundled": true, - "dev": true + "dev": true, + "optional": true }, "brace-expansion": { "version": "1.1.11", "bundled": true, "dev": true, + "optional": true, "requires": { - "balanced-match": "1.0.0", + "balanced-match": "^1.0.0", "concat-map": "0.0.1" } }, "chownr": { - "version": "1.0.1", + "version": "1.1.1", "bundled": true, "dev": true, "optional": true @@ -4956,17 +5330,20 @@ "code-point-at": { "version": "1.1.0", "bundled": true, - "dev": true + "dev": true, + "optional": true }, "concat-map": { "version": "0.0.1", "bundled": true, - "dev": true + "dev": true, + "optional": true }, "console-control-strings": { "version": "1.1.0", "bundled": true, - "dev": true + "dev": true, + "optional": true }, "core-util-is": { "version": "1.0.2", @@ -4975,16 +5352,16 @@ "optional": true }, "debug": { - "version": "2.6.9", + "version": "4.1.1", "bundled": true, "dev": true, "optional": true, "requires": { - "ms": "2.0.0" + "ms": "^2.1.1" } }, "deep-extend": { - "version": "0.5.1", + "version": "0.6.0", "bundled": true, "dev": true, "optional": true @@ -5007,7 +5384,7 @@ "dev": true, "optional": true, "requires": { - "minipass": "2.2.4" + "minipass": "^2.2.1" } }, "fs.realpath": { @@ -5022,28 +5399,28 @@ "dev": true, "optional": true, "requires": { - "aproba": "1.2.0", - "console-control-strings": "1.1.0", - "has-unicode": "2.0.1", - "object-assign": "4.1.1", - "signal-exit": "3.0.2", - "string-width": "1.0.2", - "strip-ansi": "3.0.1", - "wide-align": "1.1.2" + "aproba": "^1.0.3", + "console-control-strings": "^1.0.0", + "has-unicode": "^2.0.0", + "object-assign": "^4.1.0", + "signal-exit": "^3.0.0", + "string-width": "^1.0.1", + "strip-ansi": "^3.0.1", + "wide-align": "^1.1.0" } }, "glob": { - "version": "7.1.2", + "version": "7.1.3", "bundled": true, "dev": true, "optional": true, "requires": { - "fs.realpath": "1.0.0", - "inflight": "1.0.6", - "inherits": "2.0.3", - "minimatch": "3.0.4", - "once": "1.4.0", - "path-is-absolute": "1.0.1" + "fs.realpath": "^1.0.0", + "inflight": "^1.0.4", + "inherits": "2", + "minimatch": "^3.0.4", + "once": "^1.3.0", + "path-is-absolute": "^1.0.0" } }, "has-unicode": { @@ -5053,12 +5430,12 @@ "optional": true }, "iconv-lite": { - "version": "0.4.21", + "version": "0.4.24", "bundled": true, "dev": true, "optional": true, "requires": { - "safer-buffer": "2.1.2" + "safer-buffer": ">= 2.1.2 < 3" } }, "ignore-walk": { @@ -5067,7 +5444,7 @@ "dev": true, "optional": true, "requires": { - "minimatch": "3.0.4" + "minimatch": "^3.0.4" } }, "inflight": { @@ -5076,14 +5453,15 @@ "dev": true, "optional": true, "requires": { - "once": "1.4.0", - "wrappy": "1.0.2" + "once": "^1.3.0", + "wrappy": "1" } }, "inherits": { "version": "2.0.3", "bundled": true, - "dev": true + "dev": true, + "optional": true }, "ini": { "version": "1.3.5", @@ -5095,8 +5473,9 @@ "version": "1.0.0", "bundled": true, "dev": true, + "optional": true, "requires": { - "number-is-nan": "1.0.1" + "number-is-nan": "^1.0.0" } }, "isarray": { @@ -5109,74 +5488,78 @@ "version": "3.0.4", "bundled": true, "dev": true, + "optional": true, "requires": { - "brace-expansion": "1.1.11" + "brace-expansion": "^1.1.7" } }, "minimist": { "version": "0.0.8", "bundled": true, - "dev": true + "dev": true, + "optional": true }, "minipass": { - "version": "2.2.4", + "version": "2.3.5", "bundled": true, "dev": true, + "optional": true, "requires": { - "safe-buffer": "5.1.1", - "yallist": "3.0.2" + "safe-buffer": "^5.1.2", + "yallist": "^3.0.0" } }, "minizlib": { - "version": "1.1.0", + "version": "1.2.1", "bundled": true, "dev": true, "optional": true, "requires": { - "minipass": "2.2.4" + "minipass": "^2.2.1" } }, "mkdirp": { "version": "0.5.1", "bundled": true, "dev": true, + "optional": true, "requires": { "minimist": "0.0.8" } }, "ms": { - "version": "2.0.0", + "version": "2.1.1", "bundled": true, "dev": true, "optional": true }, "needle": { - "version": "2.2.0", + "version": "2.3.0", "bundled": true, "dev": true, "optional": true, "requires": { - "debug": "2.6.9", - "iconv-lite": "0.4.21", - "sax": "1.2.4" + "debug": "^4.1.0", + "iconv-lite": "^0.4.4", + "sax": "^1.2.4" } }, "node-pre-gyp": { - "version": "0.10.0", + "version": "0.12.0", "bundled": true, "dev": true, "optional": true, "requires": { - "detect-libc": "1.0.3", - "mkdirp": "0.5.1", - "needle": "2.2.0", - "nopt": "4.0.1", - "npm-packlist": "1.1.10", - "npmlog": "4.1.2", - "rc": "1.2.7", - "rimraf": "2.6.2", - "semver": "5.5.0", - "tar": "4.4.1" + "detect-libc": "^1.0.2", + "mkdirp": "^0.5.1", + "needle": "^2.2.1", + "nopt": "^4.0.1", + "npm-packlist": "^1.1.6", + "npmlog": "^4.0.2", + "rc": "^1.2.7", + "rimraf": "^2.6.1", + "semver": "^5.3.0", + "tar": "^4" } }, "nopt": { @@ -5185,24 +5568,24 @@ "dev": true, "optional": true, "requires": { - "abbrev": "1.1.1", - "osenv": "0.1.5" + "abbrev": "1", + "osenv": "^0.1.4" } }, "npm-bundled": { - "version": "1.0.3", + "version": "1.0.6", "bundled": true, "dev": true, "optional": true }, "npm-packlist": { - "version": "1.1.10", + "version": "1.4.1", "bundled": true, "dev": true, "optional": true, "requires": { - "ignore-walk": "3.0.1", - "npm-bundled": "1.0.3" + "ignore-walk": "^3.0.1", + "npm-bundled": "^1.0.1" } }, "npmlog": { @@ -5211,16 +5594,17 @@ "dev": true, "optional": true, "requires": { - "are-we-there-yet": "1.1.4", - "console-control-strings": "1.1.0", - "gauge": "2.7.4", - "set-blocking": "2.0.0" + "are-we-there-yet": "~1.1.2", + "console-control-strings": "~1.1.0", + "gauge": "~2.7.3", + "set-blocking": "~2.0.0" } }, "number-is-nan": { "version": "1.0.1", "bundled": true, - "dev": true + "dev": true, + "optional": true }, "object-assign": { "version": "4.1.1", @@ -5232,8 +5616,9 @@ "version": "1.4.0", "bundled": true, "dev": true, + "optional": true, "requires": { - "wrappy": "1.0.2" + "wrappy": "1" } }, "os-homedir": { @@ -5254,8 +5639,8 @@ "dev": true, "optional": true, "requires": { - "os-homedir": "1.0.2", - "os-tmpdir": "1.0.2" + "os-homedir": "^1.0.0", + "os-tmpdir": "^1.0.0" } }, "path-is-absolute": { @@ -5271,15 +5656,15 @@ "optional": true }, "rc": { - "version": "1.2.7", + "version": "1.2.8", "bundled": true, "dev": true, "optional": true, "requires": { - "deep-extend": "0.5.1", - "ini": "1.3.5", - "minimist": "1.2.0", - "strip-json-comments": "2.0.1" + "deep-extend": "^0.6.0", + "ini": "~1.3.0", + "minimist": "^1.2.0", + "strip-json-comments": "~2.0.1" }, "dependencies": { "minimist": { @@ -5296,28 +5681,29 @@ "dev": true, "optional": true, "requires": { - "core-util-is": "1.0.2", - "inherits": "2.0.3", - "isarray": "1.0.0", - "process-nextick-args": "2.0.0", - "safe-buffer": "5.1.1", - "string_decoder": "1.1.1", - "util-deprecate": "1.0.2" + "core-util-is": "~1.0.0", + "inherits": "~2.0.3", + "isarray": "~1.0.0", + "process-nextick-args": "~2.0.0", + "safe-buffer": "~5.1.1", + "string_decoder": "~1.1.1", + "util-deprecate": "~1.0.1" } }, "rimraf": { - "version": "2.6.2", + "version": "2.6.3", "bundled": true, "dev": true, "optional": true, "requires": { - "glob": "7.1.2" + "glob": "^7.1.3" } }, "safe-buffer": { - "version": "5.1.1", + "version": "5.1.2", "bundled": true, - "dev": true + "dev": true, + "optional": true }, "safer-buffer": { "version": "2.1.2", @@ -5332,7 +5718,7 @@ "optional": true }, "semver": { - "version": "5.5.0", + "version": "5.7.0", "bundled": true, "dev": true, "optional": true @@ -5353,10 +5739,11 @@ "version": "1.0.2", "bundled": true, "dev": true, + "optional": true, "requires": { - "code-point-at": "1.1.0", - "is-fullwidth-code-point": "1.0.0", - "strip-ansi": "3.0.1" + "code-point-at": "^1.0.0", + "is-fullwidth-code-point": "^1.0.0", + "strip-ansi": "^3.0.0" } }, "string_decoder": { @@ -5365,15 +5752,16 @@ "dev": true, "optional": true, "requires": { - "safe-buffer": "5.1.1" + "safe-buffer": "~5.1.0" } }, "strip-ansi": { "version": "3.0.1", "bundled": true, "dev": true, + "optional": true, "requires": { - "ansi-regex": "2.1.1" + "ansi-regex": "^2.0.0" } }, "strip-json-comments": { @@ -5383,18 +5771,18 @@ "optional": true }, "tar": { - "version": "4.4.1", + "version": "4.4.8", "bundled": true, "dev": true, "optional": true, "requires": { - "chownr": "1.0.1", - "fs-minipass": "1.2.5", - "minipass": "2.2.4", - "minizlib": "1.1.0", - "mkdirp": "0.5.1", - "safe-buffer": "5.1.1", - "yallist": "3.0.2" + "chownr": "^1.1.1", + "fs-minipass": "^1.2.5", + "minipass": "^2.3.4", + "minizlib": "^1.1.1", + "mkdirp": "^0.5.0", + "safe-buffer": "^5.1.2", + "yallist": "^3.0.2" } }, "util-deprecate": { @@ -5404,36 +5792,38 @@ "optional": true }, "wide-align": { - "version": "1.1.2", + "version": "1.1.3", "bundled": true, "dev": true, "optional": true, "requires": { - "string-width": "1.0.2" + "string-width": "^1.0.2 || 2" } }, "wrappy": { "version": "1.0.2", "bundled": true, - "dev": true + "dev": true, + "optional": true }, "yallist": { - "version": "3.0.2", + "version": "3.0.3", "bundled": true, - "dev": true + "dev": true, + "optional": true } } }, "fstream": { - "version": "1.0.11", - "resolved": "https://registry.npmjs.org/fstream/-/fstream-1.0.11.tgz", - "integrity": "sha1-XB+x8RdHcRTwYyoOtLcbPLD9MXE=", + "version": "1.0.12", + "resolved": "https://registry.npmjs.org/fstream/-/fstream-1.0.12.tgz", + "integrity": "sha512-WvJ193OHa0GHPEL+AycEJgxvBEwyfRkN1vhjca23OaPVMCaLCXTd5qAu82AjTcgP1UJmytkOKb63Ypde7raDIg==", "dev": true, "requires": { - "graceful-fs": "4.1.11", - "inherits": "2.0.1", - "mkdirp": "0.5.1", - "rimraf": "2.6.2" + "graceful-fs": "^4.1.2", + "inherits": "~2.0.0", + "mkdirp": ">=0.5 0", + "rimraf": "2" } }, "function-bind": { @@ -5452,14 +5842,14 @@ "integrity": "sha1-LANAXHU4w51+s3sxcCLjJfsBi/c=", "dev": true, "requires": { - "aproba": "1.2.0", - "console-control-strings": "1.1.0", - "has-unicode": "2.0.1", - "object-assign": "4.1.1", - "signal-exit": "3.0.2", - "string-width": "1.0.2", - "strip-ansi": "3.0.1", - "wide-align": "1.1.3" + "aproba": "^1.0.3", + "console-control-strings": "^1.0.0", + "has-unicode": "^2.0.0", + "object-assign": "^4.1.0", + "signal-exit": "^3.0.0", + "string-width": "^1.0.1", + "strip-ansi": "^3.0.1", + "wide-align": "^1.1.0" }, "dependencies": { "is-fullwidth-code-point": { @@ -5468,7 +5858,7 @@ "integrity": "sha1-754xOG8DGn8NZDr4L95QxFfvAMs=", "dev": true, "requires": { - "number-is-nan": "1.0.1" + "number-is-nan": "^1.0.0" } }, "string-width": { @@ -5477,9 +5867,9 @@ "integrity": "sha1-EYvfW4zcUaKn5w0hHgfisLmxB9M=", "dev": true, "requires": { - "code-point-at": "1.1.0", - "is-fullwidth-code-point": "1.0.0", - "strip-ansi": "3.0.1" + "code-point-at": "^1.0.0", + "is-fullwidth-code-point": "^1.0.0", + "strip-ansi": "^3.0.0" } } } @@ -5490,7 +5880,7 @@ "integrity": "sha512-BRdNm8hbWzFzWHERTrejLqwHDfS4GibPoq5wjTPIoJHoBtKGPg3xAFfxmM+9ztbXelxcf2hwQcaz1PtmFeue8g==", "dev": true, "requires": { - "globule": "1.2.1" + "globule": "^1.0.0" } }, "get-caller-file": { @@ -5510,10 +5900,13 @@ "integrity": "sha1-ngm/cSs2CrkiXoEgSPcf3pyJZXs=" }, "get-stream": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/get-stream/-/get-stream-3.0.0.tgz", - "integrity": "sha1-jpQ9E1jcN1VQVOy+LtsFqhdO3hQ=", - "dev": true + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/get-stream/-/get-stream-4.1.0.tgz", + "integrity": "sha512-GMat4EJ5161kIy2HevLlr4luNjBgvmj413KaQA7jt4V8B4RDsfpHk7WQ9GVqfYyyx8OS/L66Kox+rJRNklLK7w==", + "dev": true, + "requires": { + "pump": "^3.0.0" + } }, "get-value": { "version": "2.0.6", @@ -5527,7 +5920,7 @@ "integrity": "sha1-Xv+OPmhNVprkyysSgmBOi6YhSfo=", "dev": true, "requires": { - "assert-plus": "1.0.0" + "assert-plus": "^1.0.0" } }, "glob": { @@ -5535,12 +5928,12 @@ "resolved": "https://registry.npmjs.org/glob/-/glob-7.1.2.tgz", "integrity": "sha1-wZyd+aAocC1nhhI4SmVSQExjbRU=", "requires": { - "fs.realpath": "1.0.0", - "inflight": "1.0.6", - "inherits": "2.0.1", - "minimatch": "3.0.4", - "once": "1.4.0", - "path-is-absolute": "1.0.1" + "fs.realpath": "^1.0.0", + "inflight": "^1.0.4", + "inherits": "2", + "minimatch": "^3.0.4", + "once": "^1.3.0", + "path-is-absolute": "^1.0.0" } }, "glob-parent": { @@ -5549,8 +5942,8 @@ "integrity": "sha1-nmr2KZ2NO9K9QEMIMr0RPfkGxa4=", "dev": true, "requires": { - "is-glob": "3.1.0", - "path-dirname": "1.0.2" + "is-glob": "^3.1.0", + "path-dirname": "^1.0.0" }, "dependencies": { "is-glob": { @@ -5559,39 +5952,53 @@ "integrity": "sha1-e6WuJCF4BKxwcHuWkiVnSGzD6Eo=", "dev": true, "requires": { - "is-extglob": "2.1.1" + "is-extglob": "^2.1.0" } } } }, "global-modules": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/global-modules/-/global-modules-1.0.0.tgz", - "integrity": "sha512-sKzpEkf11GpOFuw0Zzjzmt4B4UZwjOcG757PPvrfhxcLFbq0wpsgpOqxpxtxFiCG4DtG93M6XRVbF2oGdev7bg==", + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/global-modules/-/global-modules-2.0.0.tgz", + "integrity": "sha512-NGbfmJBp9x8IxyJSd1P+otYK8vonoJactOogrVfFRIAEY1ukil8RSKDz2Yo7wh1oihl51l/r6W4epkeKJHqL8A==", "dev": true, "requires": { - "global-prefix": "1.0.2", - "is-windows": "1.0.2", - "resolve-dir": "1.0.1" + "global-prefix": "^3.0.0" + }, + "dependencies": { + "global-prefix": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/global-prefix/-/global-prefix-3.0.0.tgz", + "integrity": "sha512-awConJSVCHVGND6x3tmMaKcQvwXLhjdkmomy2W+Goaui8YPgYgXJZewhg3fWC+DlfqqQuWg8AwqjGTD2nAPVWg==", + "dev": true, + "requires": { + "ini": "^1.3.5", + "kind-of": "^6.0.2", + "which": "^1.3.1" + } + }, + "which": { + "version": "1.3.1", + "resolved": "https://registry.npmjs.org/which/-/which-1.3.1.tgz", + "integrity": "sha512-HxJdYWq1MTIQbJ3nw0cqssHoTNU267KlrDuGZ1WYlxDStUtKUhOaJmh112/TZmHxxUfuJqPXSOm7tDyas0OSIQ==", + "dev": true, + "requires": { + "isexe": "^2.0.0" + } + } } }, - "global-modules-path": { - "version": "2.3.1", - "resolved": "https://registry.npmjs.org/global-modules-path/-/global-modules-path-2.3.1.tgz", - "integrity": "sha512-y+shkf4InI7mPRHSo2b/k6ix6+NLDtyccYv86whhxrSGX9wjPX1VMITmrDbE1eh7zkzhiWtW2sHklJYoQ62Cxg==", - "dev": true - }, "global-prefix": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/global-prefix/-/global-prefix-1.0.2.tgz", "integrity": "sha1-2/dDxsFJklk8ZVVoy2btMsASLr4=", "dev": true, "requires": { - "expand-tilde": "2.0.2", - "homedir-polyfill": "1.0.1", - "ini": "1.3.5", - "is-windows": "1.0.2", - "which": "1.3.0" + "expand-tilde": "^2.0.2", + "homedir-polyfill": "^1.0.1", + "ini": "^1.3.4", + "is-windows": "^1.0.1", + "which": "^1.2.14" } }, "globals": { @@ -5604,12 +6011,12 @@ "resolved": "https://registry.npmjs.org/globby/-/globby-5.0.0.tgz", "integrity": "sha1-69hGZ8oNuzMLmbz8aOrCvFQ3Dg0=", "requires": { - "array-union": "1.0.2", - "arrify": "1.0.1", - "glob": "7.1.2", - "object-assign": "4.1.1", - "pify": "2.3.0", - "pinkie-promise": "2.0.1" + "array-union": "^1.0.1", + "arrify": "^1.0.0", + "glob": "^7.0.3", + "object-assign": "^4.0.1", + "pify": "^2.0.0", + "pinkie-promise": "^2.0.0" } }, "globule": { @@ -5618,9 +6025,9 @@ "integrity": "sha512-g7QtgWF4uYSL5/dn71WxubOrS7JVGCnFPEnoeChJmBnyR9Mw8nGoEwOgJL/RC2Te0WhbsEUCejfH8SZNJ+adYQ==", "dev": true, "requires": { - "glob": "7.1.2", - "lodash": "4.17.11", - "minimatch": "3.0.4" + "glob": "~7.1.1", + "lodash": "~4.17.10", + "minimatch": "~3.0.2" } }, "graceful-fs": { @@ -5628,6 +6035,11 @@ "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.1.11.tgz", "integrity": "sha1-Dovf5NHduIVNZOBOp8AOKgJuVlg=" }, + "gud": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/gud/-/gud-1.0.0.tgz", + "integrity": "sha512-zGEOVKFM5sVPPrYs7J5/hYEw2Pof8KCyOwyhG8sAF26mCAeUFAcYPu1mwB7hhpIP29zOIBaDqwuHdLp0jvZXjw==" + }, "handle-thing": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/handle-thing/-/handle-thing-2.0.0.tgz", @@ -5647,8 +6059,8 @@ "dev": true, "optional": true, "requires": { - "ajv": "5.5.2", - "har-schema": "2.0.0" + "ajv": "^5.1.0", + "har-schema": "^2.0.0" } }, "has": { @@ -5656,7 +6068,7 @@ "resolved": "https://registry.npmjs.org/has/-/has-1.0.1.tgz", "integrity": "sha1-hGFzP1OLCDfJNh45qauelwTcLyg=", "requires": { - "function-bind": "1.1.1" + "function-bind": "^1.0.2" } }, "has-ansi": { @@ -5664,7 +6076,7 @@ "resolved": "https://registry.npmjs.org/has-ansi/-/has-ansi-2.0.0.tgz", "integrity": "sha1-NPUEnOHs3ysGSa8+8k5F7TVBbZE=", "requires": { - "ansi-regex": "2.1.1" + "ansi-regex": "^2.0.0" } }, "has-flag": { @@ -5672,6 +6084,12 @@ "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz", "integrity": "sha1-tdRU3CGZriJWmfNGfloH87lVuv0=" }, + "has-symbols": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/has-symbols/-/has-symbols-1.0.0.tgz", + "integrity": "sha1-uhqPGvKg/DllD1yFA2dwQSIGO0Q=", + "dev": true + }, "has-unicode": { "version": "2.0.1", "resolved": "https://registry.npmjs.org/has-unicode/-/has-unicode-2.0.1.tgz", @@ -5684,9 +6102,9 @@ "integrity": "sha1-GLKB2lhbHFxR3vJMkw7SmgvmsXc=", "dev": true, "requires": { - "get-value": "2.0.6", - "has-values": "1.0.0", - "isobject": "3.0.1" + "get-value": "^2.0.6", + "has-values": "^1.0.0", + "isobject": "^3.0.0" } }, "has-values": { @@ -5695,37 +6113,17 @@ "integrity": "sha1-lbC2P+whRmGab+V/51Yo1aOe/k8=", "dev": true, "requires": { - "is-number": "3.0.0", - "kind-of": "4.0.0" + "is-number": "^3.0.0", + "kind-of": "^4.0.0" }, "dependencies": { - "is-number": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/is-number/-/is-number-3.0.0.tgz", - "integrity": "sha1-JP1iAaR4LPUFYcgQJ2r8fRLXEZU=", - "dev": true, - "requires": { - "kind-of": "3.2.2" - }, - "dependencies": { - "kind-of": { - "version": "3.2.2", - "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", - "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=", - "dev": true, - "requires": { - "is-buffer": "1.1.6" - } - } - } - }, "kind-of": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-4.0.0.tgz", "integrity": "sha1-IIE989cSkosgc3hpGkUGb65y3Vc=", "dev": true, "requires": { - "is-buffer": "1.1.6" + "is-buffer": "^1.1.5" } } } @@ -5736,8 +6134,8 @@ "integrity": "sha1-X8hoaEfs1zSZQDMZprCj8/auSRg=", "dev": true, "requires": { - "inherits": "2.0.1", - "safe-buffer": "5.1.1" + "inherits": "^2.0.1", + "safe-buffer": "^5.0.1" } }, "hash.js": { @@ -5746,14 +6144,14 @@ "integrity": "sha512-taOaskGt4z4SOANNseOviYDvjEJinIkRgmp7LbKP2YTTmVxWBl87s/uzK9r+44BclBSp2X7K1hqeNfz9JbBeXA==", "dev": true, "requires": { - "inherits": "2.0.3", - "minimalistic-assert": "1.0.1" + "inherits": "^2.0.3", + "minimalistic-assert": "^1.0.1" }, "dependencies": { "inherits": { - "version": "2.0.3", - "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.3.tgz", - "integrity": "sha1-Yzwsg+PaQqUC9SRmAiSA9CCCYd4=", + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.4.tgz", + "integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==", "dev": true } } @@ -5765,10 +6163,10 @@ "dev": true, "optional": true, "requires": { - "boom": "4.3.1", - "cryptiles": "3.1.2", - "hoek": "4.2.1", - "sntp": "2.1.0" + "boom": "4.x.x", + "cryptiles": "3.x.x", + "hoek": "4.x.x", + "sntp": "2.x.x" }, "dependencies": { "cryptiles": { @@ -5778,7 +6176,7 @@ "dev": true, "optional": true, "requires": { - "boom": "5.2.0" + "boom": "5.x.x" }, "dependencies": { "boom": { @@ -5788,7 +6186,7 @@ "dev": true, "optional": true, "requires": { - "hoek": "4.2.1" + "hoek": "4.x.x" } } } @@ -5802,14 +6200,16 @@ "dev": true }, "history": { - "version": "2.1.2", - "resolved": "https://registry.npmjs.org/history/-/history-2.1.2.tgz", - "integrity": "sha1-SqLeiXoOSGfkU5hDvm7Nsphr/ew=", + "version": "4.9.0", + "resolved": "https://registry.npmjs.org/history/-/history-4.9.0.tgz", + "integrity": "sha512-H2DkjCjXf0Op9OAr6nJ56fcRkTSNrUiv41vNJ6IswJjif6wlpZK0BTfFbi7qK9dXLSYZxkq5lBsj3vUjlYBYZA==", "requires": { - "deep-equal": "1.0.1", - "invariant": "2.2.3", - "query-string": "3.0.3", - "warning": "2.1.0" + "@babel/runtime": "^7.1.2", + "loose-envify": "^1.2.0", + "resolve-pathname": "^2.2.0", + "tiny-invariant": "^1.0.2", + "tiny-warning": "^1.0.0", + "value-equal": "^0.4.0" } }, "hmac-drbg": { @@ -5818,29 +6218,33 @@ "integrity": "sha1-0nRXAQJabHdabFRXk+1QL8DGSaE=", "dev": true, "requires": { - "hash.js": "1.1.7", - "minimalistic-assert": "1.0.1", - "minimalistic-crypto-utils": "1.0.1" + "hash.js": "^1.0.3", + "minimalistic-assert": "^1.0.0", + "minimalistic-crypto-utils": "^1.0.1" } }, "hoek": { "version": "4.2.1", "resolved": "https://registry.npmjs.org/hoek/-/hoek-4.2.1.tgz", "integrity": "sha1-ljRQKqEsRF3Vp8VzS1cruHOKrLs=", - "dev": true + "dev": true, + "optional": true }, "hoist-non-react-statics": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/hoist-non-react-statics/-/hoist-non-react-statics-1.2.0.tgz", - "integrity": "sha1-qkSM8JhtVcxAdzsXF0t90GbLfPs=" + "version": "3.3.0", + "resolved": "https://registry.npmjs.org/hoist-non-react-statics/-/hoist-non-react-statics-3.3.0.tgz", + "integrity": "sha512-0XsbTXxgiaCDYDIWFcwkmerZPSwywfUqYmwT4jzewKTQSWoE6FCMoUVOeBJWK3E/CrWbxRG3m5GzY4lnIwGRBA==", + "requires": { + "react-is": "^16.7.0" + } }, "homedir-polyfill": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/homedir-polyfill/-/homedir-polyfill-1.0.1.tgz", - "integrity": "sha1-TCu8inWJmP7r9e1oWA921GdotLw=", + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/homedir-polyfill/-/homedir-polyfill-1.0.3.tgz", + "integrity": "sha512-eSmmWE5bZTK2Nou4g0AI3zZ9rswp7GRKoKXS1BLUkvPviOqs4YTN1djQIqrXy9k5gEtdLPy86JjRwsNM9tnDcA==", "dev": true, "requires": { - "parse-passwd": "1.0.0" + "parse-passwd": "^1.0.0" } }, "hosted-git-info": { @@ -5854,10 +6258,10 @@ "integrity": "sha1-h3dMCUnlE/QuhFdbPEVoH63ioLI=", "dev": true, "requires": { - "inherits": "2.0.1", - "obuf": "1.1.2", - "readable-stream": "2.3.5", - "wbuf": "1.7.3" + "inherits": "^2.0.1", + "obuf": "^1.0.0", + "readable-stream": "^2.0.1", + "wbuf": "^1.1.0" } }, "html-entities": { @@ -5872,13 +6276,13 @@ "integrity": "sha512-LKUKwuJDhxNa3uf/LPR/KVjm/l3rBqtYeCOAekvG8F1vItxMUpueGd94i/asDDr8/1u7InxzFA5EeGjhhG5mMA==", "dev": true, "requires": { - "camel-case": "3.0.0", - "clean-css": "4.2.1", - "commander": "2.17.1", - "he": "1.2.0", - "param-case": "2.1.1", - "relateurl": "0.2.7", - "uglify-js": "3.4.9" + "camel-case": "3.0.x", + "clean-css": "4.2.x", + "commander": "2.17.x", + "he": "1.2.x", + "param-case": "2.1.x", + "relateurl": "0.2.x", + "uglify-js": "3.4.x" } }, "html-webpack-plugin": { @@ -5887,12 +6291,12 @@ "integrity": "sha1-sBq71yOsqqeze2r0SS69oD2d03s=", "dev": true, "requires": { - "html-minifier": "3.5.21", - "loader-utils": "0.2.17", - "lodash": "4.17.11", - "pretty-error": "2.1.1", - "tapable": "1.1.1", - "toposort": "1.0.7", + "html-minifier": "^3.2.3", + "loader-utils": "^0.2.16", + "lodash": "^4.17.3", + "pretty-error": "^2.0.2", + "tapable": "^1.0.0", + "toposort": "^1.0.0", "util.promisify": "1.0.0" } }, @@ -5902,10 +6306,10 @@ "integrity": "sha1-zHDQWln2VC5D8OaFyYLhTJJKnv4=", "dev": true, "requires": { - "domelementtype": "1.3.1", - "domhandler": "2.1.0", - "domutils": "1.1.6", - "readable-stream": "1.0.34" + "domelementtype": "1", + "domhandler": "2.1", + "domutils": "1.1", + "readable-stream": "1.0" }, "dependencies": { "domutils": { @@ -5914,7 +6318,7 @@ "integrity": "sha1-vdw94Jm5ou+sxRxiPyj0FuzFdIU=", "dev": true, "requires": { - "domelementtype": "1.3.1" + "domelementtype": "1" } }, "isarray": { @@ -5929,10 +6333,10 @@ "integrity": "sha1-Elgg40vIQtLyqq+v5MKRbuMsFXw=", "dev": true, "requires": { - "core-util-is": "1.0.2", - "inherits": "2.0.1", + "core-util-is": "~1.0.0", + "inherits": "~2.0.1", "isarray": "0.0.1", - "string_decoder": "0.10.31" + "string_decoder": "~0.10.x" } }, "string_decoder": { @@ -5950,15 +6354,16 @@ "dev": true }, "http-errors": { - "version": "1.6.3", - "resolved": "https://registry.npmjs.org/http-errors/-/http-errors-1.6.3.tgz", - "integrity": "sha1-i1VoC7S+KDoLW/TqLjhYC+HZMg0=", + "version": "1.7.2", + "resolved": "https://registry.npmjs.org/http-errors/-/http-errors-1.7.2.tgz", + "integrity": "sha512-uUQBt3H/cSIVfch6i1EuPNy/YsRSOUBXTVfZ+yR7Zjez3qjBz6i9+i4zjNaoqcoFVI4lQJ5plg63TvGfRSDCRg==", "dev": true, "requires": { - "depd": "1.1.2", + "depd": "~1.1.2", "inherits": "2.0.3", - "setprototypeof": "1.1.0", - "statuses": "1.4.0" + "setprototypeof": "1.1.1", + "statuses": ">= 1.5.0 < 2", + "toidentifier": "1.0.0" }, "dependencies": { "inherits": { @@ -5970,32 +6375,32 @@ } }, "http-parser-js": { - "version": "0.5.0", - "resolved": "https://registry.npmjs.org/http-parser-js/-/http-parser-js-0.5.0.tgz", - "integrity": "sha512-cZdEF7r4gfRIq7ezX9J0T+kQmJNOub71dWbgAXVHDct80TKP4MCETtZQ31xyv38UwgzkWPYF/Xc0ge55dW9Z9w==", + "version": "0.4.10", + "resolved": "https://registry.npmjs.org/http-parser-js/-/http-parser-js-0.4.10.tgz", + "integrity": "sha1-ksnBN0w1CF912zWexWzCV8u5P6Q=", "dev": true }, "http-proxy": { - "version": "1.17.0", - "resolved": "https://registry.npmjs.org/http-proxy/-/http-proxy-1.17.0.tgz", - "integrity": "sha512-Taqn+3nNvYRfJ3bGvKfBSRwy1v6eePlm3oc/aWVxZp57DQr5Eq3xhKJi7Z4hZpS8PC3H4qI+Yly5EmFacGuA/g==", + "version": "1.18.0", + "resolved": "https://registry.npmjs.org/http-proxy/-/http-proxy-1.18.0.tgz", + "integrity": "sha512-84I2iJM/n1d4Hdgc6y2+qY5mDaz2PUVjlg9znE9byl+q0uC3DeByqBGReQu5tpLK0TAqTIXScRUV+dg7+bUPpQ==", "dev": true, "requires": { - "eventemitter3": "3.1.0", - "follow-redirects": "1.6.1", - "requires-port": "1.0.0" + "eventemitter3": "^4.0.0", + "follow-redirects": "^1.0.0", + "requires-port": "^1.0.0" } }, "http-proxy-middleware": { - "version": "0.18.0", - "resolved": "https://registry.npmjs.org/http-proxy-middleware/-/http-proxy-middleware-0.18.0.tgz", - "integrity": "sha512-Fs25KVMPAIIcgjMZkVHJoKg9VcXcC1C8yb9JUgeDvVXY0S/zgVIhMb+qVswDIgtJe2DfckMSY2d6TuTEutlk6Q==", + "version": "0.19.1", + "resolved": "https://registry.npmjs.org/http-proxy-middleware/-/http-proxy-middleware-0.19.1.tgz", + "integrity": "sha512-yHYTgWMQO8VvwNS22eLLloAkvungsKdKTLO8AJlftYIKNfJr3GK3zK0ZCfzDDGUBttdGc8xFy1mCitvNKQtC3Q==", "dev": true, "requires": { - "http-proxy": "1.17.0", - "is-glob": "4.0.0", - "lodash": "4.17.11", - "micromatch": "3.1.10" + "http-proxy": "^1.17.0", + "is-glob": "^4.0.0", + "lodash": "^4.17.11", + "micromatch": "^3.1.10" } }, "http-signature": { @@ -6004,14 +6409,25 @@ "integrity": "sha1-muzZJRFHcvPZW2WmCruPfBj7rOE=", "dev": true, "requires": { - "assert-plus": "1.0.0", - "jsprim": "1.4.1", - "sshpk": "1.14.1" + "assert-plus": "^1.0.0", + "jsprim": "^1.2.2", + "sshpk": "^1.7.0" } }, - "iconv-lite": { - "version": "0.4.19", - "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.4.19.tgz", + "https-browserify": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/https-browserify/-/https-browserify-1.0.0.tgz", + "integrity": "sha1-7AbBDgo0wPL68Zn3/X/Hj//QPHM=", + "dev": true + }, + "humps": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/humps/-/humps-2.0.1.tgz", + "integrity": "sha1-3QLqYIG9BWjcXQcxhEY5V7qe+ao=" + }, + "iconv-lite": { + "version": "0.4.19", + "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.4.19.tgz", "integrity": "sha1-90aPYBNfXl2tM5nAqBvpoWA6CCs=" }, "icss-replace-symbols": { @@ -6026,7 +6442,7 @@ "integrity": "sha512-bA/xGiwWM17qjllIs9X/y0EjsB7e0AV08F3OL8UPsoNkNRibIuu8f1eKTnQ8QO1DteKKTxTUAn+IEWUToIwGOA==", "dev": true, "requires": { - "postcss": "7.0.13" + "postcss": "^7.0.5" } }, "ieee754": { @@ -6058,8 +6474,8 @@ "integrity": "sha512-pOnA9tfM3Uwics+SaBLCNyZZZbK+4PTu0OPZtLlMIrv17EdBoC15S9Kn8ckJ9TZTyKb3ywNE5y1yeDxxGA7nTQ==", "dev": true, "requires": { - "parent-module": "1.0.0", - "resolve-from": "4.0.0" + "parent-module": "^1.0.0", + "resolve-from": "^4.0.0" }, "dependencies": { "resolve-from": { @@ -6076,8 +6492,8 @@ "integrity": "sha512-b6s04m3O+s3CGSbqDIyP4R6aAwAeYlVq9+WUWep6iHa8ETRf9yei1U48C5MmfJmV9AiLYYBKPMq/W+/WRpQmCQ==", "dev": true, "requires": { - "pkg-dir": "3.0.0", - "resolve-cwd": "2.0.0" + "pkg-dir": "^3.0.0", + "resolve-cwd": "^2.0.0" }, "dependencies": { "find-up": { @@ -6086,7 +6502,7 @@ "integrity": "sha512-1yD6RmLI1XBfxugvORwlck6f75tYL+iR0jqwsOrOxMZyGYqUuDhJ0l4AXdO1iX/FTs9cBAMEk1gWSEx1kSbylg==", "dev": true, "requires": { - "locate-path": "3.0.0" + "locate-path": "^3.0.0" } }, "locate-path": { @@ -6095,17 +6511,17 @@ "integrity": "sha512-7AO748wWnIhNqAuaty2ZWHkQHRSNfPVIsPIfwEOWO22AmaoVrWavlOcMR5nzTLNYvp36X220/maaRsrec1G65A==", "dev": true, "requires": { - "p-locate": "3.0.0", - "path-exists": "3.0.0" + "p-locate": "^3.0.0", + "path-exists": "^3.0.0" } }, "p-limit": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-2.1.0.tgz", - "integrity": "sha512-NhURkNcrVB+8hNfLuysU8enY5xn2KXphsHBaC2YmRNTZRc7RWusw6apSpdEj3jo4CMb6W9nrF6tTnsJsJeyu6g==", + "version": "2.2.1", + "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-2.2.1.tgz", + "integrity": "sha512-85Tk+90UCVWvbDavCLKPOLC9vvY8OwEX/RtKF+/1OADJMVlFfEHOiMTPVyxg7mk/dKa+ipdHm0OUkTvCpMTuwg==", "dev": true, "requires": { - "p-try": "2.0.0" + "p-try": "^2.0.0" } }, "p-locate": { @@ -6114,13 +6530,13 @@ "integrity": "sha512-x+12w/To+4GFfgJhBEpiDcLozRJGegY+Ei7/z0tSLkMmxGZNybVMSfWj9aJn8Z5Fc7dBUNJOOVgPv2H7IwulSQ==", "dev": true, "requires": { - "p-limit": "2.1.0" + "p-limit": "^2.0.0" } }, "p-try": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/p-try/-/p-try-2.0.0.tgz", - "integrity": "sha512-hMp0onDKIajHfIkdRk3P4CdCmErkYAxxDtP3Wx/4nZ3aGlau2VKh3mZpcuFkH27WQkL/3WBCPOktzA9ZOAnMQQ==", + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/p-try/-/p-try-2.2.0.tgz", + "integrity": "sha512-R4nPAVTAU0B9D35/Gk3uJf/7XYbQcyohSKdvAxIRSNghFl4e71hVoGnBNQz9cWaXxO2I10KTC+3jMdvvoKw6dQ==", "dev": true }, "path-exists": { @@ -6135,7 +6551,7 @@ "integrity": "sha512-/E57AYkoeQ25qkxMj5PBOVgF8Kiu/h7cYS30Z5+R7WaiCCBfLq58ZI/dSeaEKb9WVJV5n/03QwrN3IeWIFllvw==", "dev": true, "requires": { - "find-up": "3.0.0" + "find-up": "^3.0.0" } } } @@ -6146,8 +6562,8 @@ "integrity": "sha512-kXWL7Scp8KQ4552ZcdVTeaQCZSLW+e6nJfp3cwUMB673T7Hr98Xjx5JK+ql7ADlJUvj1JS5O01RLbKoutN5QDQ==", "dev": true, "requires": { - "loader-utils": "1.2.3", - "source-map": "0.6.1" + "loader-utils": "^1.0.2", + "source-map": "^0.6.1" }, "dependencies": { "big.js": { @@ -6162,7 +6578,7 @@ "integrity": "sha512-aKS4WQjPenRxiQsC93MNfjx+nbF4PAdYzmd/1JIj8HYzqfbu86beTuNgXDzPknWk0n0uARlyewZo4s++ES36Ow==", "dev": true, "requires": { - "minimist": "1.2.0" + "minimist": "^1.2.0" } }, "loader-utils": { @@ -6171,9 +6587,9 @@ "integrity": "sha512-fkpz8ejdnEMG3s37wGL07iSBDg99O9D5yflE9RGNH3hRdx9SOwYfnGYdZOUIZitN8E+E2vkq3MUMYMvPYl5ZZA==", "dev": true, "requires": { - "big.js": "5.2.2", - "emojis-list": "2.1.0", - "json5": "1.0.1" + "big.js": "^5.2.2", + "emojis-list": "^2.0.0", + "json5": "^1.0.1" } }, "minimist": { @@ -6207,13 +6623,13 @@ "integrity": "sha1-ji1INIdCEhtKghi3oTfppSBJ3IA=", "dev": true, "requires": { - "repeating": "2.0.1" + "repeating": "^2.0.0" } }, - "indexof": { - "version": "0.0.1", - "resolved": "https://registry.npmjs.org/indexof/-/indexof-0.0.1.tgz", - "integrity": "sha1-gtwzbSMrkGIXnQWrMpOmYFn9Q10=", + "infer-owner": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/infer-owner/-/infer-owner-1.0.4.tgz", + "integrity": "sha512-IClj+Xz94+d7irH5qRyfJonOdfTzuDaifE6ZPWfx0N0+/ATZCbuTPq2prFl526urkQd90WyUKIh1DfBQ2hMz9A==", "dev": true }, "inflight": { @@ -6221,8 +6637,8 @@ "resolved": "https://registry.npmjs.org/inflight/-/inflight-1.0.6.tgz", "integrity": "sha1-Sb1jMdfQLQwJvJEKEHW6gWW1bfk=", "requires": { - "once": "1.4.0", - "wrappy": "1.0.2" + "once": "^1.3.0", + "wrappy": "1" } }, "inherits": { @@ -6242,19 +6658,19 @@ "integrity": "sha512-088kl3DRT2dLU5riVMKKr1DlImd6X7smDhpXUCkJDCKvTEJeRiXh0G132HG9u5a+6Ylw9plFRY7RuTnwohYSpg==", "dev": true, "requires": { - "ansi-escapes": "3.0.0", - "chalk": "2.4.2", - "cli-cursor": "2.1.0", - "cli-width": "2.2.0", - "external-editor": "3.0.3", - "figures": "2.0.0", - "lodash": "4.17.11", + "ansi-escapes": "^3.0.0", + "chalk": "^2.0.0", + "cli-cursor": "^2.1.0", + "cli-width": "^2.0.0", + "external-editor": "^3.0.0", + "figures": "^2.0.0", + "lodash": "^4.17.10", "mute-stream": "0.0.7", - "run-async": "2.3.0", - "rxjs": "6.3.3", - "string-width": "2.1.1", - "strip-ansi": "5.0.0", - "through": "2.3.8" + "run-async": "^2.2.0", + "rxjs": "^6.1.0", + "string-width": "^2.1.0", + "strip-ansi": "^5.0.0", + "through": "^2.3.6" }, "dependencies": { "ansi-regex": { @@ -6269,7 +6685,7 @@ "integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==", "dev": true, "requires": { - "color-convert": "1.9.1" + "color-convert": "^1.9.0" } }, "chalk": { @@ -6278,9 +6694,9 @@ "integrity": "sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==", "dev": true, "requires": { - "ansi-styles": "3.2.1", - "escape-string-regexp": "1.0.5", - "supports-color": "5.5.0" + "ansi-styles": "^3.2.1", + "escape-string-regexp": "^1.0.5", + "supports-color": "^5.3.0" } }, "chardet": { @@ -6295,9 +6711,9 @@ "integrity": "sha512-bn71H9+qWoOQKyZDo25mOMVpSmXROAsTJVVVYzrrtol3d4y+AsKjf4Iwl2Q+IuT0kFSQ1qo166UuIwqYq7mGnA==", "dev": true, "requires": { - "chardet": "0.7.0", - "iconv-lite": "0.4.24", - "tmp": "0.0.33" + "chardet": "^0.7.0", + "iconv-lite": "^0.4.24", + "tmp": "^0.0.33" } }, "iconv-lite": { @@ -6306,7 +6722,7 @@ "integrity": "sha512-v3MXnZAcvnywkTUEZomIActle7RXXeedOR31wwl7VlyoXO4Qi9arvSenNQWne1TcRwhCL1HwLI21bEqdpj8/rA==", "dev": true, "requires": { - "safer-buffer": "2.1.2" + "safer-buffer": ">= 2.1.2 < 3" } }, "rxjs": { @@ -6315,7 +6731,7 @@ "integrity": "sha512-JTWmoY9tWCs7zvIk/CvRjhjGaOd+OVBM987mxFo+OW66cGpdKjZcpmc74ES1sB//7Kl/PAe8+wEakuhG4pcgOw==", "dev": true, "requires": { - "tslib": "1.9.3" + "tslib": "^1.9.0" } }, "strip-ansi": { @@ -6324,7 +6740,7 @@ "integrity": "sha512-Uu7gQyZI7J7gn5qLn1Np3G9vcYGTVqB+lFTytnDJv83dd8T22aGH451P3jueT2/QemInJDfxHB5Tde5OzgG1Ow==", "dev": true, "requires": { - "ansi-regex": "4.0.0" + "ansi-regex": "^4.0.0" } }, "supports-color": { @@ -6333,33 +6749,34 @@ "integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==", "dev": true, "requires": { - "has-flag": "3.0.0" + "has-flag": "^3.0.0" } } } }, "internal-ip": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/internal-ip/-/internal-ip-3.0.1.tgz", - "integrity": "sha512-NXXgESC2nNVtU+pqmC9e6R8B1GpKxzsAQhffvh5AL79qKnodd+L7tnEQmTiUAVngqLalPbSqRA7XGIEL5nCd0Q==", + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/internal-ip/-/internal-ip-4.3.0.tgz", + "integrity": "sha512-S1zBo1D6zcsyuC6PMmY5+55YMILQ9av8lotMx447Bq6SAgo/sDK6y6uUKmuYhW7eacnIhFfsPmCNYdDzsnnDCg==", "dev": true, "requires": { - "default-gateway": "2.7.2", - "ipaddr.js": "1.8.0" + "default-gateway": "^4.2.0", + "ipaddr.js": "^1.9.0" } }, "interpret": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/interpret/-/interpret-1.1.0.tgz", - "integrity": "sha1-ftGxQQxqDg94z5XTuEQMY/eLhhQ=", + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/interpret/-/interpret-1.2.0.tgz", + "integrity": "sha512-mT34yGKMNceBQUoVn7iCDKDntA7SC6gycMAWzGx1z/CMCTV7b2AAtXlo3nRyHZ1FelRkQbQjprHSYGwzLtkVbw==", "dev": true }, "invariant": { "version": "2.2.3", "resolved": "https://registry.npmjs.org/invariant/-/invariant-2.2.3.tgz", "integrity": "sha1-GoJ9/efcvXwyPwyoJr6Pp8Xp1og=", + "dev": true, "requires": { - "loose-envify": "1.3.1" + "loose-envify": "^1.0.0" } }, "invert-kv": { @@ -6381,9 +6798,15 @@ "dev": true }, "ipaddr.js": { - "version": "1.8.0", - "resolved": "https://registry.npmjs.org/ipaddr.js/-/ipaddr.js-1.8.0.tgz", - "integrity": "sha1-6qM9bd16zo9/b+DJygRA5wZzix4=", + "version": "1.9.0", + "resolved": "https://registry.npmjs.org/ipaddr.js/-/ipaddr.js-1.9.0.tgz", + "integrity": "sha512-M4Sjn6N/+O6/IXSJseKqHoFc+5FdGJ22sXqnjTpdZweHK64MzEPAyQZyEU3R/KRv2GLoa7nNtg/C2Ev6m7z+eA==", + "dev": true + }, + "is-absolute-url": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/is-absolute-url/-/is-absolute-url-3.0.3.tgz", + "integrity": "sha512-opmNIX7uFnS96NtPmhWQgQx6/NYFgsUXYMllcfzwWKUMwfo8kku1TvE6hkNcH+Q1ts5cMVrsY7j0bxXQDciu9Q==", "dev": true }, "is-accessor-descriptor": { @@ -6392,7 +6815,7 @@ "integrity": "sha1-qeEss66Nh2cn7u84Q/igiXtcmNY=", "dev": true, "requires": { - "kind-of": "3.2.2" + "kind-of": "^3.0.2" }, "dependencies": { "kind-of": { @@ -6401,11 +6824,17 @@ "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=", "dev": true, "requires": { - "is-buffer": "1.1.6" + "is-buffer": "^1.1.5" } } } }, + "is-arguments": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/is-arguments/-/is-arguments-1.0.4.tgz", + "integrity": "sha512-xPh0Rmt8NE65sNzvyUmWgI1tz3mKq74lGA0mL8LYZcoIzKOzDh6HmrYm3d18k60nHerC8A9Km8kYu87zfSFnLA==", + "dev": true + }, "is-arrayish": { "version": "0.2.1", "resolved": "https://registry.npmjs.org/is-arrayish/-/is-arrayish-0.2.1.tgz", @@ -6417,7 +6846,7 @@ "integrity": "sha1-dfFmQrSA8YenEcgUFh/TpKdlWJg=", "dev": true, "requires": { - "binary-extensions": "1.12.0" + "binary-extensions": "^1.0.0" } }, "is-buffer": { @@ -6431,7 +6860,7 @@ "resolved": "https://registry.npmjs.org/is-builtin-module/-/is-builtin-module-1.0.0.tgz", "integrity": "sha1-VAVy0096wxGfj3bDDLwbHgN6/74=", "requires": { - "builtin-modules": "1.1.1" + "builtin-modules": "^1.0.0" } }, "is-callable": { @@ -6445,7 +6874,7 @@ "integrity": "sha1-C17mSDiOLIYCgueT8YVv7D8wG1Y=", "dev": true, "requires": { - "kind-of": "3.2.2" + "kind-of": "^3.0.2" }, "dependencies": { "kind-of": { @@ -6454,7 +6883,7 @@ "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=", "dev": true, "requires": { - "is-buffer": "1.1.6" + "is-buffer": "^1.1.5" } } } @@ -6470,9 +6899,9 @@ "integrity": "sha512-avDYr0SB3DwO9zsMov0gKCESFYqCnE4hq/4z3TdUlukEy5t9C0YRq7HLrsN52NAcqXKaepeCD0n+B0arnVG3Hg==", "dev": true, "requires": { - "is-accessor-descriptor": "0.1.6", - "is-data-descriptor": "0.1.4", - "kind-of": "5.1.0" + "is-accessor-descriptor": "^0.1.6", + "is-data-descriptor": "^0.1.4", + "kind-of": "^5.0.0" }, "dependencies": { "kind-of": { @@ -6501,7 +6930,7 @@ "integrity": "sha1-zGZ3aVYCvlUO8R6LSqYwU0K20Ko=", "dev": true, "requires": { - "number-is-nan": "1.0.1" + "number-is-nan": "^1.0.0" } }, "is-fullwidth-code-point": { @@ -6510,12 +6939,12 @@ "integrity": "sha1-o7MKXE8ZkYMWeqq5O+764937ZU8=" }, "is-glob": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-4.0.0.tgz", - "integrity": "sha1-lSHHaEXMJhCoUgPd8ICpWML/q8A=", + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-4.0.1.tgz", + "integrity": "sha512-5G0tKtBTFImOqDnLB2hG6Bp2qcKEFduo4tZu9MT/H6NQv/ghhy30o55ufafxJ/LdH79LLs2Kfrn85TLKyA7BUg==", "dev": true, "requires": { - "is-extglob": "2.1.1" + "is-extglob": "^2.1.1" } }, "is-number": { @@ -6524,7 +6953,7 @@ "integrity": "sha1-JP1iAaR4LPUFYcgQJ2r8fRLXEZU=", "dev": true, "requires": { - "kind-of": "3.2.2" + "kind-of": "^3.0.2" }, "dependencies": { "kind-of": { @@ -6533,7 +6962,7 @@ "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=", "dev": true, "requires": { - "is-buffer": "1.1.6" + "is-buffer": "^1.1.5" } } } @@ -6548,7 +6977,7 @@ "resolved": "https://registry.npmjs.org/is-path-in-cwd/-/is-path-in-cwd-1.0.0.tgz", "integrity": "sha1-ZHdYK4IU1gI0YJRWcAO+ip6sBNw=", "requires": { - "is-path-inside": "1.0.1" + "is-path-inside": "^1.0.0" } }, "is-path-inside": { @@ -6556,7 +6985,7 @@ "resolved": "https://registry.npmjs.org/is-path-inside/-/is-path-inside-1.0.1.tgz", "integrity": "sha1-jvW33lBDej/cprToZe96pVy0gDY=", "requires": { - "path-is-inside": "1.0.2" + "path-is-inside": "^1.0.1" } }, "is-plain-object": { @@ -6565,7 +6994,7 @@ "integrity": "sha1-LBY7P6+xtgbZ0Xko8FwqHDjgdnc=", "dev": true, "requires": { - "isobject": "3.0.1" + "isobject": "^3.0.1" } }, "is-promise": { @@ -6578,7 +7007,7 @@ "resolved": "https://registry.npmjs.org/is-regex/-/is-regex-1.0.4.tgz", "integrity": "sha1-VRdIm1RwkbCTDglWVM7SXul+lJE=", "requires": { - "has": "1.0.1" + "has": "^1.0.1" } }, "is-resolvable": { @@ -6611,7 +7040,7 @@ "is-windows": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/is-windows/-/is-windows-1.0.2.tgz", - "integrity": "sha1-0YUOuXkezRjmGCzhKjDzlmNLsZ0=", + "integrity": "sha512-eXK1UInq2bPmjyX6e3VHIzMLobc4J94i4AWn+Hpq3OU5KkrRC96OAcR3PRJ/pGu6m8TRnBHP9dkXQVsT/COVIA==", "dev": true }, "is-wsl": { @@ -6641,8 +7070,8 @@ "resolved": "https://registry.npmjs.org/isomorphic-fetch/-/isomorphic-fetch-2.2.1.tgz", "integrity": "sha1-YRrhrPFPXoH3KVB0coGf6XM1WKk=", "requires": { - "node-fetch": "1.7.3", - "whatwg-fetch": "2.0.3" + "node-fetch": "^1.0.1", + "whatwg-fetch": ">=0.10.0" } }, "isstream": { @@ -6652,14 +7081,14 @@ "dev": true }, "jquery": { - "version": "3.2.1", - "resolved": "https://registry.npmjs.org/jquery/-/jquery-3.2.1.tgz", - "integrity": "sha1-XE2d5lKvbNCncBVKYxu6ErAVx4c=" + "version": "3.4.0", + "resolved": "https://registry.npmjs.org/jquery/-/jquery-3.4.0.tgz", + "integrity": "sha512-ggRCXln9zEqv6OqAGXFEcshF5dSBvCkzj6Gm2gzuR5fWawaX8t7cxKVkkygKODrDAzKdoYw3l/e3pm3vlT4IbQ==" }, "js-base64": { - "version": "2.5.0", - "resolved": "https://registry.npmjs.org/js-base64/-/js-base64-2.5.0.tgz", - "integrity": "sha512-wlEBIZ5LP8usDylWbDNhKPEFVFdI5hCHpnVoT/Ysvoi/PRhJENm/Rlh9TvjYB38HFfKZN7OzEbRjmjvLkFw11g==", + "version": "2.5.1", + "resolved": "https://registry.npmjs.org/js-base64/-/js-base64-2.5.1.tgz", + "integrity": "sha512-M7kLczedRMYX4L8Mdh4MzyAMM9O5osx+4FcOQuTvr3A9F2D9S5JXheN0ewNbrvK2UatkTRhL5ejGmGSjNMiZuw==", "dev": true }, "js-levenshtein": { @@ -6679,12 +7108,12 @@ "integrity": "sha1-BBi/T9jboZ4QRaVHix7ZA2rldl0=" }, "js-yaml": { - "version": "3.8.2", - "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-3.8.2.tgz", - "integrity": "sha1-AtPiwPa+qyAkjUEsNSIDgn14ZyE=", + "version": "3.13.1", + "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-3.13.1.tgz", + "integrity": "sha512-YfbcO7jXDdyj0DGxYVSlSeQNHbD7XPWvrVWeVUujrQEoZzWJIRrCPoyk6kL6IAjAG2IolMK4T0hNUe0HOUs5Jw==", "requires": { - "argparse": "1.0.10", - "esprima": "3.1.3" + "argparse": "^1.0.7", + "esprima": "^4.0.0" } }, "jsbn": { @@ -6722,9 +7151,9 @@ "dev": true }, "json3": { - "version": "3.3.2", - "resolved": "https://registry.npmjs.org/json3/-/json3-3.3.2.tgz", - "integrity": "sha1-PAQ0dD35Pi9cQq7nsZvLSDV19OE=", + "version": "3.3.3", + "resolved": "https://registry.npmjs.org/json3/-/json3-3.3.3.tgz", + "integrity": "sha512-c7/8mbUsKigAbLkD5B010BK4D9LZm7A1pNItkEwiUZRpIN66exu/e7YQWysGun+TRKaJp8MhemM+VkfWv42aCA==", "dev": true }, "json5": { @@ -6733,12 +7162,6 @@ "integrity": "sha1-Hq3nrMASA0rYTiOWdn6tn6VJWCE=", "dev": true }, - "jsonfile": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/jsonfile/-/jsonfile-1.1.1.tgz", - "integrity": "sha1-2k/WrXfxolUgPqY8e8Mtwx72RDM=", - "dev": true - }, "jsprim": { "version": "1.4.1", "resolved": "https://registry.npmjs.org/jsprim/-/jsprim-1.4.1.tgz", @@ -6756,7 +7179,7 @@ "resolved": "https://registry.npmjs.org/jsx-ast-utils/-/jsx-ast-utils-2.0.1.tgz", "integrity": "sha1-6AGxs5mF4g//yHtA43SAgOLcrH8=", "requires": { - "array-includes": "3.0.3" + "array-includes": "^3.0.3" } }, "killable": { @@ -6777,7 +7200,7 @@ "integrity": "sha1-MIrMr6C8SDo4Z7S28rlQYlHRuDU=", "dev": true, "requires": { - "invert-kv": "1.0.0" + "invert-kv": "^1.0.0" } }, "less": { @@ -6786,14 +7209,14 @@ "integrity": "sha1-No1sxz4fsDmBGDKAkYdDxdz5s98=", "dev": true, "requires": { - "errno": "0.1.7", - "graceful-fs": "4.1.11", - "image-size": "0.5.5", - "mime": "1.6.0", - "mkdirp": "0.5.1", - "promise": "7.3.1", - "request": "2.85.0", - "source-map": "0.5.7" + "errno": "^0.1.1", + "graceful-fs": "^4.1.2", + "image-size": "~0.5.0", + "mime": "^1.2.11", + "mkdirp": "^0.5.0", + "promise": "^7.1.1", + "request": "^2.72.0", + "source-map": "^0.5.3" } }, "less-loader": { @@ -6802,9 +7225,9 @@ "integrity": "sha512-KNTsgCE9tMOM70+ddxp9yyt9iHqgmSs0yTZc5XH5Wo+g80RWRIYNqE58QJKm/yMud5wZEvz50ugRDuzVIkyahg==", "dev": true, "requires": { - "clone": "2.1.2", - "loader-utils": "1.2.3", - "pify": "3.0.0" + "clone": "^2.1.1", + "loader-utils": "^1.1.0", + "pify": "^3.0.0" }, "dependencies": { "big.js": { @@ -6825,7 +7248,7 @@ "integrity": "sha512-aKS4WQjPenRxiQsC93MNfjx+nbF4PAdYzmd/1JIj8HYzqfbu86beTuNgXDzPknWk0n0uARlyewZo4s++ES36Ow==", "dev": true, "requires": { - "minimist": "1.2.0" + "minimist": "^1.2.0" } }, "loader-utils": { @@ -6834,9 +7257,9 @@ "integrity": "sha512-fkpz8ejdnEMG3s37wGL07iSBDg99O9D5yflE9RGNH3hRdx9SOwYfnGYdZOUIZitN8E+E2vkq3MUMYMvPYl5ZZA==", "dev": true, "requires": { - "big.js": "5.2.2", - "emojis-list": "2.1.0", - "json5": "1.0.1" + "big.js": "^5.2.2", + "emojis-list": "^2.0.0", + "json5": "^1.0.1" } }, "minimist": { @@ -6858,25 +7281,19 @@ "resolved": "https://registry.npmjs.org/levn/-/levn-0.3.0.tgz", "integrity": "sha1-OwmSTt+fCDwEkP3UwLxEIeBHZO4=", "requires": { - "prelude-ls": "1.1.2", - "type-check": "0.3.2" + "prelude-ls": "~1.1.2", + "type-check": "~0.3.2" } }, - "lightercollective": { - "version": "0.1.0", - "resolved": "https://registry.npmjs.org/lightercollective/-/lightercollective-0.1.0.tgz", - "integrity": "sha512-J9tg5uraYoQKaWbmrzDDexbG6hHnMcWS1qLYgJSWE+mpA3U5OCSeMUhb+K55otgZJ34oFdR0ECvdIb3xuO5JOQ==", - "dev": true - }, "load-json-file": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/load-json-file/-/load-json-file-2.0.0.tgz", "integrity": "sha1-eUfkIUmvgNaWy/eXvKq8/h/inKg=", "requires": { - "graceful-fs": "4.1.11", - "parse-json": "2.2.0", - "pify": "2.3.0", - "strip-bom": "3.0.0" + "graceful-fs": "^4.1.2", + "parse-json": "^2.2.0", + "pify": "^2.0.0", + "strip-bom": "^3.0.0" } }, "loader-runner": { @@ -6891,10 +7308,10 @@ "integrity": "sha1-+G5jdNQyBabmxg6RlvF8Apm/s0g=", "dev": true, "requires": { - "big.js": "3.2.0", - "emojis-list": "2.1.0", - "json5": "0.5.1", - "object-assign": "4.1.1" + "big.js": "^3.1.3", + "emojis-list": "^2.0.0", + "json5": "^0.5.0", + "object-assign": "^4.0.1" } }, "locate-path": { @@ -6902,8 +7319,8 @@ "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-2.0.0.tgz", "integrity": "sha1-K1aLJl7slExtnA3pw9u7ygNUzY4=", "requires": { - "p-locate": "2.0.0", - "path-exists": "3.0.0" + "p-locate": "^2.0.0", + "path-exists": "^3.0.0" }, "dependencies": { "path-exists": { @@ -6914,9 +7331,9 @@ } }, "lodash": { - "version": "4.17.11", - "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.11.tgz", - "integrity": "sha512-cQKh8igo5QUhZ7lg38DYWAxMvjSAKG0A8wGSVimP07SIUEK2UO+arSRKbRZWtelMtN5V0Hkwh5ryOto/SshYIg==" + "version": "4.17.13", + "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.13.tgz", + "integrity": "sha512-vm3/XWXfWtRua0FkUyEHBZy8kCPjErNBT9fJx8Zvs+U6zjqPbTUOpkaoum3O5uiA8sm+yNMHXfYkTUHFoMxFNA==" }, "lodash._baseassign": { "version": "3.2.0", @@ -6924,8 +7341,8 @@ "integrity": "sha1-jDigmVAPIVrQnlnxci/QxSv+Ck4=", "dev": true, "requires": { - "lodash._basecopy": "3.0.1", - "lodash.keys": "3.1.2" + "lodash._basecopy": "^3.0.0", + "lodash.keys": "^3.0.0" } }, "lodash._basecopy": { @@ -6946,9 +7363,9 @@ "integrity": "sha1-g4pbri/aymOsIt7o4Z+k5taXCxE=", "dev": true, "requires": { - "lodash._bindcallback": "3.0.1", - "lodash._isiterateecall": "3.0.9", - "lodash.restparam": "3.6.1" + "lodash._bindcallback": "^3.0.0", + "lodash._isiterateecall": "^3.0.0", + "lodash.restparam": "^3.0.0" } }, "lodash._getnative": { @@ -6969,23 +7386,11 @@ "integrity": "sha1-DZnzzNem0mHRm9rrkkUAXShYCOc=", "dev": true }, - "lodash.clonedeep": { - "version": "4.5.0", - "resolved": "https://registry.npmjs.org/lodash.clonedeep/-/lodash.clonedeep-4.5.0.tgz", - "integrity": "sha1-4j8/nE+Pvd6HJSnBBxhXoIblzO8=", - "dev": true - }, "lodash.cond": { "version": "4.5.2", "resolved": "https://registry.npmjs.org/lodash.cond/-/lodash.cond-4.5.2.tgz", "integrity": "sha1-9HGh2khr5g9quVXRcRVSPdHSVdU=" }, - "lodash.debounce": { - "version": "4.0.8", - "resolved": "https://registry.npmjs.org/lodash.debounce/-/lodash.debounce-4.0.8.tgz", - "integrity": "sha1-gteb/zCmfEAF/9XiUVMArZyk168=", - "dev": true - }, "lodash.defaults": { "version": "4.2.0", "resolved": "https://registry.npmjs.org/lodash.defaults/-/lodash.defaults-4.2.0.tgz", @@ -7010,17 +7415,11 @@ "integrity": "sha1-TbwEcrFWvlCgsoaFXRvQsMZWCYo=", "dev": true, "requires": { - "lodash._getnative": "3.9.1", - "lodash.isarguments": "3.1.0", - "lodash.isarray": "3.0.4" + "lodash._getnative": "^3.0.0", + "lodash.isarguments": "^3.0.0", + "lodash.isarray": "^3.0.0" } }, - "lodash.mergewith": { - "version": "4.6.1", - "resolved": "https://registry.npmjs.org/lodash.mergewith/-/lodash.mergewith-4.6.1.tgz", - "integrity": "sha512-eWw5r+PYICtEBgrBE5hhlT6aAa75f411bgDz/ZL2KZqYV03USvucsxcHUIlGTDTECs1eunpI7HOV7U+WLDvNdQ==", - "dev": true - }, "lodash.restparam": { "version": "3.6.1", "resolved": "https://registry.npmjs.org/lodash.restparam/-/lodash.restparam-3.6.1.tgz", @@ -7034,9 +7433,9 @@ "dev": true }, "loglevel": { - "version": "1.6.1", - "resolved": "https://registry.npmjs.org/loglevel/-/loglevel-1.6.1.tgz", - "integrity": "sha1-4PyVEztu8nbNyIh82vJKpvFW+Po=", + "version": "1.6.6", + "resolved": "https://registry.npmjs.org/loglevel/-/loglevel-1.6.6.tgz", + "integrity": "sha512-Sgr5lbboAUBo3eXCSPL4/KoVz3ROKquOjcctxmHIt+vol2DrqTQe3SwkKKuYhEiWB5kYa13YyopJ69deJ1irzQ==", "dev": true }, "loose-envify": { @@ -7044,7 +7443,7 @@ "resolved": "https://registry.npmjs.org/loose-envify/-/loose-envify-1.3.1.tgz", "integrity": "sha1-0aitM/qc4OcT1l/dCsi3SNR4yEg=", "requires": { - "js-tokens": "3.0.2" + "js-tokens": "^3.0.0" } }, "loud-rejection": { @@ -7053,8 +7452,8 @@ "integrity": "sha1-W0b4AUft7leIcPCG0Eghz5mOVR8=", "dev": true, "requires": { - "currently-unhandled": "0.4.1", - "signal-exit": "3.0.2" + "currently-unhandled": "^0.4.1", + "signal-exit": "^3.0.0" } }, "lower-case": { @@ -7068,8 +7467,8 @@ "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-4.0.2.tgz", "integrity": "sha1-HRdnnAac2l0ECZGgnbwsDbN35V4=", "requires": { - "pseudomap": "1.0.2", - "yallist": "2.1.2" + "pseudomap": "^1.0.1", + "yallist": "^2.0.0" } }, "macaddress": { @@ -7083,7 +7482,7 @@ "integrity": "sha512-2w31R7SJtieJJnQtGc7RVL2StM2vGYVfqUOvUDxH6bC6aJTxPxTF0GnIgCyu7tjockiUWAYQRbxa7vKn34s5sQ==", "dev": true, "requires": { - "pify": "3.0.0" + "pify": "^3.0.0" }, "dependencies": { "pify": { @@ -7094,13 +7493,19 @@ } } }, + "mamacro": { + "version": "0.0.3", + "resolved": "https://registry.npmjs.org/mamacro/-/mamacro-0.0.3.tgz", + "integrity": "sha512-qMEwh+UujcQ+kbz3T6V+wAmO2U8veoq2w+3wY8MquqwVA3jChfwY+Tk52GZKDfACEPjuZ7r2oJLejwpt8jtwTA==", + "dev": true + }, "map-age-cleaner": { "version": "0.1.3", "resolved": "https://registry.npmjs.org/map-age-cleaner/-/map-age-cleaner-0.1.3.tgz", "integrity": "sha512-bJzx6nMoP6PDLPBFmg7+xRKeFZvFboMrGlxmNj9ClvX53KrmvM5bXFXEWjbz4cz1AFn+jWJ9z/DJSz7hrs0w3w==", "dev": true, "requires": { - "p-defer": "1.0.0" + "p-defer": "^1.0.0" } }, "map-cache": { @@ -7121,7 +7526,7 @@ "integrity": "sha1-7Nyo8TFE5mDxtb1B8S80edmN+48=", "dev": true, "requires": { - "object-visit": "1.0.1" + "object-visit": "^1.0.0" } }, "md5.js": { @@ -7130,15 +7535,15 @@ "integrity": "sha512-xitP+WxNPcTTOgnTJcrhM0xvdPepipPSf3I8EIpGKeFLjt3PlJLIDG3u8EX53ZIubkb+5U2+3rELYpEhHhzdkg==", "dev": true, "requires": { - "hash-base": "3.0.4", - "inherits": "2.0.1", - "safe-buffer": "5.1.2" + "hash-base": "^3.0.0", + "inherits": "^2.0.1", + "safe-buffer": "^5.1.2" }, "dependencies": { "safe-buffer": { - "version": "5.1.2", - "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz", - "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==", + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.2.0.tgz", + "integrity": "sha512-fZEwUGbVl7kouZs1jCdMLdt95hdIv0ZeHg6L7qPeciMZhZ+/gdesW4wgTARkrFWEpspjEATAzUGPG8N2jJiwbg==", "dev": true } } @@ -7150,14 +7555,22 @@ "dev": true }, "mem": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/mem/-/mem-4.0.0.tgz", - "integrity": "sha512-WQxG/5xYc3tMbYLXoXPm81ET2WDULiU5FxbuIoNbJqLOOI8zehXFdZuiUEgfdrU2mVB1pxBZUGlYORSrpuJreA==", + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/mem/-/mem-4.3.0.tgz", + "integrity": "sha512-qX2bG48pTqYRVmDB37rn/6PT7LcR8T7oAX3bf99u1Tt1nzxYfxkgqDwUwolPlXweM0XzBOBFzSx4kfp7KP1s/w==", "dev": true, "requires": { - "map-age-cleaner": "0.1.3", - "mimic-fn": "1.2.0", - "p-is-promise": "1.1.0" + "map-age-cleaner": "^0.1.1", + "mimic-fn": "^2.0.0", + "p-is-promise": "^2.0.0" + }, + "dependencies": { + "mimic-fn": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/mimic-fn/-/mimic-fn-2.1.0.tgz", + "integrity": "sha512-OqbOk5oEQeAZ8WXWydlu9HJjz9WVdEIvamMCcXmuqUYjTknH/sqsWvhQ3vgwKFRR1HpjvNBKQ37nbJgYzGqGcg==", + "dev": true + } } }, "memory-fs": { @@ -7166,8 +7579,8 @@ "integrity": "sha1-OpoguEYlI+RHz7x+i7gO1me/xVI=", "dev": true, "requires": { - "errno": "0.1.7", - "readable-stream": "2.3.5" + "errno": "^0.1.3", + "readable-stream": "^2.0.1" } }, "meow": { @@ -7176,16 +7589,16 @@ "integrity": "sha1-cstmi0JSKCkKu/qFaJJYcwioAfs=", "dev": true, "requires": { - "camelcase-keys": "2.1.0", - "decamelize": "1.2.0", - "loud-rejection": "1.6.0", - "map-obj": "1.0.1", - "minimist": "1.2.0", - "normalize-package-data": "2.4.0", - "object-assign": "4.1.1", - "read-pkg-up": "1.0.1", - "redent": "1.0.0", - "trim-newlines": "1.0.0" + "camelcase-keys": "^2.0.0", + "decamelize": "^1.1.2", + "loud-rejection": "^1.0.0", + "map-obj": "^1.0.1", + "minimist": "^1.1.3", + "normalize-package-data": "^2.3.4", + "object-assign": "^4.0.1", + "read-pkg-up": "^1.0.1", + "redent": "^1.0.0", + "trim-newlines": "^1.0.0" }, "dependencies": { "load-json-file": { @@ -7194,11 +7607,11 @@ "integrity": "sha1-lWkFcI1YtLq0wiYbBPWfMcmTdMA=", "dev": true, "requires": { - "graceful-fs": "4.1.11", - "parse-json": "2.2.0", - "pify": "2.3.0", - "pinkie-promise": "2.0.1", - "strip-bom": "2.0.0" + "graceful-fs": "^4.1.2", + "parse-json": "^2.2.0", + "pify": "^2.0.0", + "pinkie-promise": "^2.0.0", + "strip-bom": "^2.0.0" } }, "minimist": { @@ -7213,9 +7626,9 @@ "integrity": "sha1-WcRPfuSR2nBNpBXaWkBwuk+P5EE=", "dev": true, "requires": { - "graceful-fs": "4.1.11", - "pify": "2.3.0", - "pinkie-promise": "2.0.1" + "graceful-fs": "^4.1.2", + "pify": "^2.0.0", + "pinkie-promise": "^2.0.0" } }, "read-pkg": { @@ -7224,9 +7637,9 @@ "integrity": "sha1-9f+qXs0pyzHAR0vKfXVra7KePyg=", "dev": true, "requires": { - "load-json-file": "1.1.0", - "normalize-package-data": "2.4.0", - "path-type": "1.1.0" + "load-json-file": "^1.0.0", + "normalize-package-data": "^2.3.2", + "path-type": "^1.0.0" } }, "read-pkg-up": { @@ -7235,8 +7648,8 @@ "integrity": "sha1-nWPBMnbAZZGNV/ACpX9AobZD+wI=", "dev": true, "requires": { - "find-up": "1.1.2", - "read-pkg": "1.1.0" + "find-up": "^1.0.0", + "read-pkg": "^1.0.0" } }, "strip-bom": { @@ -7245,7 +7658,7 @@ "integrity": "sha1-YhmoVhZSBJHzV4i9vxRHqZx+aw4=", "dev": true, "requires": { - "is-utf8": "0.2.1" + "is-utf8": "^0.2.0" } } } @@ -7268,19 +7681,19 @@ "integrity": "sha512-MWikgl9n9M3w+bpsY3He8L+w9eF9338xRl8IAO5viDizwSzziFEyUzo2xrrloB64ADbTf8uA8vRqqttDTOmccg==", "dev": true, "requires": { - "arr-diff": "4.0.0", - "array-unique": "0.3.2", - "braces": "2.3.2", - "define-property": "2.0.2", - "extend-shallow": "3.0.2", - "extglob": "2.0.4", - "fragment-cache": "0.2.1", - "kind-of": "6.0.2", - "nanomatch": "1.2.13", - "object.pick": "1.3.0", - "regex-not": "1.0.2", - "snapdragon": "0.8.2", - "to-regex": "3.0.2" + "arr-diff": "^4.0.0", + "array-unique": "^0.3.2", + "braces": "^2.3.1", + "define-property": "^2.0.2", + "extend-shallow": "^3.0.2", + "extglob": "^2.0.4", + "fragment-cache": "^0.2.1", + "kind-of": "^6.0.2", + "nanomatch": "^1.2.9", + "object.pick": "^1.3.0", + "regex-not": "^1.0.0", + "snapdragon": "^0.8.1", + "to-regex": "^3.0.2" } }, "miller-rabin": { @@ -7289,16 +7702,15 @@ "integrity": "sha512-115fLhvZVqWwHPbClyntxEVfVDfl9DLLTuJvq3g2O/Oxi8AiNouAHvDSzHS0viUJc+V5vm3eq91Xwqn9dp4jRA==", "dev": true, "requires": { - "bn.js": "4.11.8", - "brorand": "1.1.0" + "bn.js": "^4.0.0", + "brorand": "^1.0.1" } }, "mime": { "version": "1.6.0", "resolved": "https://registry.npmjs.org/mime/-/mime-1.6.0.tgz", "integrity": "sha1-Ms2eXGRVO9WNGaVor0Uqz/BJgbE=", - "dev": true, - "optional": true + "dev": true }, "mime-db": { "version": "1.33.0", @@ -7312,7 +7724,7 @@ "integrity": "sha1-bzI/YKg9ERRvgx/xH9ZuL+VQO7g=", "dev": true, "requires": { - "mime-db": "1.33.0" + "mime-db": "~1.33.0" } }, "mimic-fn": { @@ -7320,60 +7732,55 @@ "resolved": "https://registry.npmjs.org/mimic-fn/-/mimic-fn-1.2.0.tgz", "integrity": "sha1-ggyGo5M0ZA6ZUWkovQP8qIBX0CI=" }, + "mini-create-react-context": { + "version": "0.3.2", + "resolved": "https://registry.npmjs.org/mini-create-react-context/-/mini-create-react-context-0.3.2.tgz", + "integrity": "sha512-2v+OeetEyliMt5VHMXsBhABoJ0/M4RCe7fatd/fBy6SMiKazUSEt3gxxypfnk2SHMkdBYvorHRoQxuGoiwbzAw==", + "requires": { + "@babel/runtime": "^7.4.0", + "gud": "^1.0.0", + "tiny-warning": "^1.0.2" + }, + "dependencies": { + "@babel/runtime": { + "version": "7.5.4", + "resolved": "https://registry.npmjs.org/@babel/runtime/-/runtime-7.5.4.tgz", + "integrity": "sha512-Na84uwyImZZc3FKf4aUF1tysApzwf3p2yuFBIyBfbzT5glzKTdvYI4KVW4kcgjrzoGUjC7w3YyCHcJKaRxsr2Q==", + "requires": { + "regenerator-runtime": "^0.13.2" + } + }, + "regenerator-runtime": { + "version": "0.13.2", + "resolved": "https://registry.npmjs.org/regenerator-runtime/-/regenerator-runtime-0.13.2.tgz", + "integrity": "sha512-S/TQAZJO+D3m9xeN1WTI8dLKBBiRgXBlTJvbWjCThHWZj9EvHK70Ff50/tYj2J/fvBY6JtFVwRuazHN2E7M9BA==" + } + } + }, "mini-css-extract-plugin": { "version": "0.5.0", "resolved": "https://registry.npmjs.org/mini-css-extract-plugin/-/mini-css-extract-plugin-0.5.0.tgz", "integrity": "sha512-IuaLjruM0vMKhUUT51fQdQzBYTX49dLj8w68ALEAe2A4iYNpIC4eMac67mt3NzycvjOlf07/kYxJDc0RTl1Wqw==", "dev": true, "requires": { - "loader-utils": "1.2.3", - "schema-utils": "1.0.0", - "webpack-sources": "1.3.0" + "loader-utils": "^1.1.0", + "schema-utils": "^1.0.0", + "webpack-sources": "^1.1.0" }, "dependencies": { - "ajv": { - "version": "6.7.0", - "resolved": "https://registry.npmjs.org/ajv/-/ajv-6.7.0.tgz", - "integrity": "sha512-RZXPviBTtfmtka9n9sy1N5M5b82CbxWIR6HIis4s3WQTXDJamc/0gpCWNGz6EWdWp4DOfjzJfhz/AS9zVPjjWg==", - "dev": true, - "requires": { - "fast-deep-equal": "2.0.1", - "fast-json-stable-stringify": "2.0.0", - "json-schema-traverse": "0.4.1", - "uri-js": "4.2.2" - } - }, - "ajv-keywords": { - "version": "3.2.0", - "resolved": "https://registry.npmjs.org/ajv-keywords/-/ajv-keywords-3.2.0.tgz", - "integrity": "sha1-6GuBnGAs+IIa1jdBNpjx3sAhhHo=", - "dev": true - }, "big.js": { "version": "5.2.2", "resolved": "https://registry.npmjs.org/big.js/-/big.js-5.2.2.tgz", "integrity": "sha512-vyL2OymJxmarO8gxMr0mhChsO9QGwhynfuu4+MHTAW6czfq9humCB7rKpUjDd9YUiDPU4mzpyupFSvOClAwbmQ==", "dev": true }, - "fast-deep-equal": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/fast-deep-equal/-/fast-deep-equal-2.0.1.tgz", - "integrity": "sha1-ewUhjd+WZ79/Nwv3/bLLFf3Qqkk=", - "dev": true - }, - "json-schema-traverse": { - "version": "0.4.1", - "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-0.4.1.tgz", - "integrity": "sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg==", - "dev": true - }, "json5": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/json5/-/json5-1.0.1.tgz", "integrity": "sha512-aKS4WQjPenRxiQsC93MNfjx+nbF4PAdYzmd/1JIj8HYzqfbu86beTuNgXDzPknWk0n0uARlyewZo4s++ES36Ow==", "dev": true, "requires": { - "minimist": "1.2.0" + "minimist": "^1.2.0" } }, "loader-utils": { @@ -7382,9 +7789,9 @@ "integrity": "sha512-fkpz8ejdnEMG3s37wGL07iSBDg99O9D5yflE9RGNH3hRdx9SOwYfnGYdZOUIZitN8E+E2vkq3MUMYMvPYl5ZZA==", "dev": true, "requires": { - "big.js": "5.2.2", - "emojis-list": "2.1.0", - "json5": "1.0.1" + "big.js": "^5.2.2", + "emojis-list": "^2.0.0", + "json5": "^1.0.1" } }, "minimist": { @@ -7392,39 +7799,6 @@ "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.0.tgz", "integrity": "sha1-o1AIsg9BOD7sH7kU9M1d95omQoQ=", "dev": true - }, - "schema-utils": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/schema-utils/-/schema-utils-1.0.0.tgz", - "integrity": "sha512-i27Mic4KovM/lnGsy8whRCHhc7VicJajAjTrYg11K9zfZXnYIt4k5F+kZkwjnrhKzLic/HLU4j11mjsz2G/75g==", - "dev": true, - "requires": { - "ajv": "6.7.0", - "ajv-errors": "1.0.1", - "ajv-keywords": "3.2.0" - } - }, - "source-list-map": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/source-list-map/-/source-list-map-2.0.1.tgz", - "integrity": "sha512-qnQ7gVMxGNxsiL4lEuJwe/To8UnK7fAnmbGEEH8RpLouuKbeEm0lhbQVFIrNSuB+G7tVrAlVsZgETT5nljf+Iw==", - "dev": true - }, - "source-map": { - "version": "0.6.1", - "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", - "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", - "dev": true - }, - "webpack-sources": { - "version": "1.3.0", - "resolved": "https://registry.npmjs.org/webpack-sources/-/webpack-sources-1.3.0.tgz", - "integrity": "sha512-OiVgSrbGu7NEnEvQJJgdSFPl2qWKkWq5lHMhgiToIiN9w34EBnjYzSYs+VbL5KoYiLNtFFa7BZIKxRED3I32pA==", - "dev": true, - "requires": { - "source-list-map": "2.0.1", - "source-map": "0.6.1" - } } } }, @@ -7445,7 +7819,7 @@ "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.0.4.tgz", "integrity": "sha1-UWbihkV/AzBgZL5Ul+jbsMPTIIM=", "requires": { - "brace-expansion": "1.1.11" + "brace-expansion": "^1.1.7" } }, "minimist": { @@ -7459,26 +7833,26 @@ "integrity": "sha512-x471SsVjUtBRtcvd4BzKE9kFC+/2TeWgKCgw0bZcw1b9l2X3QX5vCWgF+KaZaYm87Ss//rHnWryupDrgLvmSkA==", "dev": true, "requires": { - "concat-stream": "1.6.1", - "duplexify": "3.6.1", - "end-of-stream": "1.4.1", - "flush-write-stream": "1.0.3", - "from2": "2.3.0", - "parallel-transform": "1.1.0", - "pump": "3.0.0", - "pumpify": "1.5.1", - "stream-each": "1.2.3", - "through2": "2.0.5" + "concat-stream": "^1.5.0", + "duplexify": "^3.4.2", + "end-of-stream": "^1.1.0", + "flush-write-stream": "^1.0.0", + "from2": "^2.1.0", + "parallel-transform": "^1.1.0", + "pump": "^3.0.0", + "pumpify": "^1.3.3", + "stream-each": "^1.1.0", + "through2": "^2.0.0" } }, "mixin-deep": { - "version": "1.3.1", - "resolved": "https://registry.npmjs.org/mixin-deep/-/mixin-deep-1.3.1.tgz", - "integrity": "sha512-8ZItLHeEgaqEvd5lYBXfm4EZSFCX29Jb9K+lAHhDKzReKBQKj3R+7NOF6tjqYi9t4oI8VUfaWITJQm86wnXGNQ==", + "version": "1.3.2", + "resolved": "https://registry.npmjs.org/mixin-deep/-/mixin-deep-1.3.2.tgz", + "integrity": "sha512-WRoDn//mXBiJ1H40rqa3vH0toePwSsGb45iInWlTySa+Uu4k3tYUSxa2v1KqAiLtvlrSzaExqS1gtk96A9zvEA==", "dev": true, "requires": { - "for-in": "1.0.2", - "is-extendable": "1.0.1" + "for-in": "^1.0.2", + "is-extendable": "^1.0.1" }, "dependencies": { "is-extendable": { @@ -7487,7 +7861,7 @@ "integrity": "sha512-arnXMxT1hhoKo9k1LZdmlNyJdDDfy2v0fXjFlmok4+i8ul/6WlbVge9bhM74OpNPQPMGUToDtz+KXa1PneJxOA==", "dev": true, "requires": { - "is-plain-object": "2.0.4" + "is-plain-object": "^2.0.4" } } } @@ -7498,8 +7872,8 @@ "integrity": "sha1-T7lJRB2rGCVA8f4DW6YOGUel5X4=", "dev": true, "requires": { - "for-in": "0.1.8", - "is-extendable": "0.1.1" + "for-in": "^0.1.3", + "is-extendable": "^0.1.1" }, "dependencies": { "for-in": { @@ -7534,12 +7908,12 @@ "integrity": "sha1-viwAX9oy4LKa8fBdfEszIUxwH5I=", "dev": true, "requires": { - "aproba": "1.2.0", - "copy-concurrently": "1.0.5", - "fs-write-stream-atomic": "1.0.10", - "mkdirp": "0.5.1", - "rimraf": "2.6.2", - "run-queue": "1.0.3" + "aproba": "^1.1.1", + "copy-concurrently": "^1.0.0", + "fs-write-stream-atomic": "^1.0.8", + "mkdirp": "^0.5.1", + "rimraf": "^2.5.4", + "run-queue": "^1.0.3" } }, "ms": { @@ -7553,8 +7927,8 @@ "integrity": "sha512-ji6J5enbMyGRHIAkAOu3WdV8nggqviKCEKtXcOqfphZZtQrmHKycfynJ2V7eVPUA4NhJ6V7Wf4TmGbTwKE9B6g==", "dev": true, "requires": { - "dns-packet": "1.3.1", - "thunky": "1.0.3" + "dns-packet": "^1.3.1", + "thunky": "^1.0.2" } }, "multicast-dns-service-types": { @@ -7569,9 +7943,9 @@ "integrity": "sha1-MHXOk7whuPq0PhvE2n6BFe0ee6s=" }, "nan": { - "version": "2.9.2", - "resolved": "https://registry.npmjs.org/nan/-/nan-2.9.2.tgz", - "integrity": "sha1-9WTXX1+PNqbZRWzKemxP5IireGY=", + "version": "2.14.0", + "resolved": "https://registry.npmjs.org/nan/-/nan-2.14.0.tgz", + "integrity": "sha512-INOFj37C7k3AfaNTtX8RhsTw7qRy7eLET14cROi9+5HAVbbHuIWUHEauBv5qT4Av2tWasiTY1Jw6puUNqRJXQg==", "dev": true, "optional": true }, @@ -7581,31 +7955,17 @@ "integrity": "sha512-fpoe2T0RbHwBTBUOftAfBPaDEi06ufaUai0mE6Yn1kacc3SnTErfb/h+X94VXzI64rKFHYImXSvdwGGCmwOqCA==", "dev": true, "requires": { - "arr-diff": "4.0.0", - "array-unique": "0.3.2", - "define-property": "2.0.2", - "extend-shallow": "3.0.2", - "fragment-cache": "0.2.1", - "is-windows": "1.0.2", - "kind-of": "6.0.2", - "object.pick": "1.3.0", - "regex-not": "1.0.2", - "snapdragon": "0.8.2", - "to-regex": "3.0.2" - }, - "dependencies": { - "arr-diff": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/arr-diff/-/arr-diff-4.0.0.tgz", - "integrity": "sha1-1kYQdP6/7HHn4VI1dhoyml3HxSA=", - "dev": true - }, - "array-unique": { - "version": "0.3.2", - "resolved": "https://registry.npmjs.org/array-unique/-/array-unique-0.3.2.tgz", - "integrity": "sha1-qJS3XUvE9s1nnvMkSp/Y9Gri1Cg=", - "dev": true - } + "arr-diff": "^4.0.0", + "array-unique": "^0.3.2", + "define-property": "^2.0.2", + "extend-shallow": "^3.0.2", + "fragment-cache": "^0.2.1", + "is-windows": "^1.0.2", + "kind-of": "^6.0.2", + "object.pick": "^1.3.0", + "regex-not": "^1.0.0", + "snapdragon": "^0.8.1", + "to-regex": "^3.0.1" } }, "natural-compare": { @@ -7613,16 +7973,10 @@ "resolved": "https://registry.npmjs.org/natural-compare/-/natural-compare-1.4.0.tgz", "integrity": "sha1-Sr6/7tdUHywnrPspvbvRXI1bpPc=" }, - "ncp": { - "version": "0.4.2", - "resolved": "https://registry.npmjs.org/ncp/-/ncp-0.4.2.tgz", - "integrity": "sha1-q8xsvT7C7Spyn/bnwfqPAXhKhXQ=", - "dev": true - }, "negotiator": { - "version": "0.6.1", - "resolved": "https://registry.npmjs.org/negotiator/-/negotiator-0.6.1.tgz", - "integrity": "sha1-KzJxhOiZIQEXeyhWP7XnECrNDKk=", + "version": "0.6.2", + "resolved": "https://registry.npmjs.org/negotiator/-/negotiator-0.6.2.tgz", + "integrity": "sha512-hZXc7K2e+PgeI1eDBe/10Ard4ekbfrrqG8Ep+8Jmf4JID2bNg7NvCPOZN+kfF574pFQI7mum2AUqDidoKqcTOw==", "dev": true }, "neo-async": { @@ -7643,7 +7997,7 @@ "integrity": "sha1-YLgTOWvjmz8SiKTB7V0efSi0ZKw=", "dev": true, "requires": { - "lower-case": "1.1.4" + "lower-case": "^1.1.1" } }, "node-fetch": { @@ -7651,84 +8005,52 @@ "resolved": "https://registry.npmjs.org/node-fetch/-/node-fetch-1.7.3.tgz", "integrity": "sha512-NhZ4CsKx7cYm2vSrBAr2PvFOe6sWDf0UYLRqA6svUYg7+/TSfVAu49jYC4BvQ4Sms9SZgdqGBgroqfDhJdTyKQ==", "requires": { - "encoding": "0.1.12", - "is-stream": "1.1.0" + "encoding": "^0.1.11", + "is-stream": "^1.0.1" } }, "node-forge": { - "version": "0.7.5", - "resolved": "https://registry.npmjs.org/node-forge/-/node-forge-0.7.5.tgz", - "integrity": "sha512-MmbQJ2MTESTjt3Gi/3yG1wGpIMhUfcIypUCGtTizFR9IiccFwxSpfp0vtIZlkFclEqERemxfnSdZEMR9VqqEFQ==", + "version": "0.9.0", + "resolved": "https://registry.npmjs.org/node-forge/-/node-forge-0.9.0.tgz", + "integrity": "sha512-7ASaDa3pD+lJ3WvXFsxekJQelBKRpne+GOVbLbtHYdd7pFspyeuJHnWfLplGf3SwKGbfs/aYl5V/JCIaHVUKKQ==", "dev": true }, - "node-fs-extra": { - "version": "0.8.2", - "resolved": "https://registry.npmjs.org/node-fs-extra/-/node-fs-extra-0.8.2.tgz", - "integrity": "sha1-CfsrYNMPfXA+Nh7LYmqRQE8XCXo=", - "dev": true, - "requires": { - "jsonfile": "1.1.1", - "mkdirp": "0.3.5", - "ncp": "0.4.2", - "rimraf": "2.2.8" - }, - "dependencies": { - "mkdirp": { - "version": "0.3.5", - "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-0.3.5.tgz", - "integrity": "sha1-3j5fiWHIjHh+4TaN+EmsRBPsqNc=", - "dev": true - }, - "rimraf": { - "version": "2.2.8", - "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-2.2.8.tgz", - "integrity": "sha1-5Dm+Kq7jJzIZUnMPmaiSnk/FBYI=", - "dev": true - } - } - }, "node-gyp": { "version": "3.8.0", "resolved": "https://registry.npmjs.org/node-gyp/-/node-gyp-3.8.0.tgz", "integrity": "sha512-3g8lYefrRRzvGeSowdJKAKyks8oUpLEd/DyPV4eMhVlhJ0aNaZqIrNUIPuEWWTAoPqyFkfGrM67MC69baqn6vA==", "dev": true, "requires": { - "fstream": "1.0.11", - "glob": "7.1.2", - "graceful-fs": "4.1.11", - "mkdirp": "0.5.1", - "nopt": "3.0.6", - "npmlog": "4.1.2", - "osenv": "0.1.5", - "request": "2.88.0", - "rimraf": "2.6.2", - "semver": "5.3.0", - "tar": "2.2.1", - "which": "1.3.0" + "fstream": "^1.0.0", + "glob": "^7.0.3", + "graceful-fs": "^4.1.2", + "mkdirp": "^0.5.0", + "nopt": "2 || 3", + "npmlog": "0 || 1 || 2 || 3 || 4", + "osenv": "0", + "request": "^2.87.0", + "rimraf": "2", + "semver": "~5.3.0", + "tar": "^2.0.0", + "which": "1" }, "dependencies": { "ajv": { - "version": "6.7.0", - "resolved": "https://registry.npmjs.org/ajv/-/ajv-6.7.0.tgz", - "integrity": "sha512-RZXPviBTtfmtka9n9sy1N5M5b82CbxWIR6HIis4s3WQTXDJamc/0gpCWNGz6EWdWp4DOfjzJfhz/AS9zVPjjWg==", + "version": "6.10.2", + "resolved": "https://registry.npmjs.org/ajv/-/ajv-6.10.2.tgz", + "integrity": "sha512-TXtUUEYHuaTEbLZWIKUr5pmBuhDLy+8KYtPYdcV8qC+pOZL+NKqYwvWSRrVXHn+ZmRRAu8vJTAznH7Oag6RVRw==", "dev": true, "requires": { - "fast-deep-equal": "2.0.1", - "fast-json-stable-stringify": "2.0.0", - "json-schema-traverse": "0.4.1", - "uri-js": "4.2.2" + "fast-deep-equal": "^2.0.1", + "fast-json-stable-stringify": "^2.0.0", + "json-schema-traverse": "^0.4.1", + "uri-js": "^4.2.2" } }, "aws4": { - "version": "1.8.0", - "resolved": "https://registry.npmjs.org/aws4/-/aws4-1.8.0.tgz", - "integrity": "sha512-ReZxvNHIOv88FlT7rxcXIIC0fPt4KZqZbOlivyWtXLt8ESx84zd3kMC6iK5jVeS2qt+g7ftS7ye4fi06X5rtRQ==", - "dev": true - }, - "extend": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/extend/-/extend-3.0.2.tgz", - "integrity": "sha512-fjquC59cD7CyW6urNXK0FBufkZcoiGG80wTuPujX590cB5Ttln20E2UB4S/WARVqhXffZl2LNgS+gQdPIIim/g==", + "version": "1.9.0", + "resolved": "https://registry.npmjs.org/aws4/-/aws4-1.9.0.tgz", + "integrity": "sha512-Uvq6hVe90D0B2WEnUqtdgY1bATGz3mw33nH9Y+dmA+w5DHvUmBgkr5rM/KCHpCsiFNRUfokW/szpPPgMK2hm4A==", "dev": true }, "fast-deep-equal": { @@ -7743,8 +8065,8 @@ "integrity": "sha512-sNvOCzEQNr/qrvJgc3UG/kD4QtlHycrzwS+6mfTrrSq97BvaYcPZZI1ZSqGSPR73Cxn4LKTD4PttRwfU7jWq5g==", "dev": true, "requires": { - "ajv": "6.7.0", - "har-schema": "2.0.0" + "ajv": "^6.5.5", + "har-schema": "^2.0.0" } }, "json-schema-traverse": { @@ -7754,18 +8076,18 @@ "dev": true }, "mime-db": { - "version": "1.37.0", - "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.37.0.tgz", - "integrity": "sha512-R3C4db6bgQhlIhPU48fUtdVmKnflq+hRdad7IyKhtFj06VPNVdk2RhiYL3UjQIlso8L+YxAtFkobT0VK+S/ybg==", + "version": "1.42.0", + "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.42.0.tgz", + "integrity": "sha512-UbfJCR4UAVRNgMpfImz05smAXK7+c+ZntjaA26ANtkXLlOe947Aag5zdIcKQULAiF9Cq4WxBi9jUs5zkA84bYQ==", "dev": true }, "mime-types": { - "version": "2.1.21", - "resolved": "https://registry.npmjs.org/mime-types/-/mime-types-2.1.21.tgz", - "integrity": "sha512-3iL6DbwpyLzjR3xHSFNFeb9Nz/M8WDkX33t1GFQnFOllWk8pOrh/LSrB5OXlnlW5P9LH73X6loW/eogc+F5lJg==", + "version": "2.1.25", + "resolved": "https://registry.npmjs.org/mime-types/-/mime-types-2.1.25.tgz", + "integrity": "sha512-5KhStqB5xpTAeGqKBAMgwaYMnQik7teQN4IAzC7npDv6kzeU6prfkR67bc87J1kWMPGkoaZSq1npmexMgkmEVg==", "dev": true, "requires": { - "mime-db": "1.37.0" + "mime-db": "1.42.0" } }, "oauth-sign": { @@ -7786,32 +8108,32 @@ "integrity": "sha512-NAqBSrijGLZdM0WZNsInLJpkJokL72XYjUpnB0iwsRgxh7dB6COrHnTBNwN0E+lHDAJzu7kLAkDeY08z2/A0hg==", "dev": true, "requires": { - "aws-sign2": "0.7.0", - "aws4": "1.8.0", - "caseless": "0.12.0", - "combined-stream": "1.0.6", - "extend": "3.0.2", - "forever-agent": "0.6.1", - "form-data": "2.3.2", - "har-validator": "5.1.3", - "http-signature": "1.2.0", - "is-typedarray": "1.0.0", - "isstream": "0.1.2", - "json-stringify-safe": "5.0.1", - "mime-types": "2.1.21", - "oauth-sign": "0.9.0", - "performance-now": "2.1.0", - "qs": "6.5.2", - "safe-buffer": "5.1.2", - "tough-cookie": "2.4.3", - "tunnel-agent": "0.6.0", - "uuid": "3.3.2" + "aws-sign2": "~0.7.0", + "aws4": "^1.8.0", + "caseless": "~0.12.0", + "combined-stream": "~1.0.6", + "extend": "~3.0.2", + "forever-agent": "~0.6.1", + "form-data": "~2.3.2", + "har-validator": "~5.1.0", + "http-signature": "~1.2.0", + "is-typedarray": "~1.0.0", + "isstream": "~0.1.2", + "json-stringify-safe": "~5.0.1", + "mime-types": "~2.1.19", + "oauth-sign": "~0.9.0", + "performance-now": "^2.1.0", + "qs": "~6.5.2", + "safe-buffer": "^5.1.2", + "tough-cookie": "~2.4.3", + "tunnel-agent": "^0.6.0", + "uuid": "^3.3.2" } }, "safe-buffer": { - "version": "5.1.2", - "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz", - "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==", + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.2.0.tgz", + "integrity": "sha512-fZEwUGbVl7kouZs1jCdMLdt95hdIv0ZeHg6L7qPeciMZhZ+/gdesW4wgTARkrFWEpspjEATAzUGPG8N2jJiwbg==", "dev": true }, "semver": { @@ -7826,8 +8148,67 @@ "integrity": "sha512-Q5srk/4vDM54WJsJio3XNn6K2sCG+CQ8G5Wz6bZhRZoAe/+TxjWB/GlFAnYEbkYVlON9FMk/fE3h2RLpPXo4lQ==", "dev": true, "requires": { - "psl": "1.1.31", - "punycode": "1.4.1" + "psl": "^1.1.24", + "punycode": "^1.4.1" + } + } + } + }, + "node-libs-browser": { + "version": "2.2.1", + "resolved": "https://registry.npmjs.org/node-libs-browser/-/node-libs-browser-2.2.1.tgz", + "integrity": "sha512-h/zcD8H9kaDZ9ALUWwlBUDo6TKF8a7qBSCSEGfjTVIYeqsioSKaAX+BN7NgiMGp6iSIXZ3PxgCu8KS3b71YK5Q==", + "dev": true, + "requires": { + "assert": "^1.1.1", + "browserify-zlib": "^0.2.0", + "buffer": "^4.3.0", + "console-browserify": "^1.1.0", + "constants-browserify": "^1.0.0", + "crypto-browserify": "^3.11.0", + "domain-browser": "^1.1.1", + "events": "^3.0.0", + "https-browserify": "^1.0.0", + "os-browserify": "^0.3.0", + "path-browserify": "0.0.1", + "process": "^0.11.10", + "punycode": "^1.2.4", + "querystring-es3": "^0.2.0", + "readable-stream": "^2.3.3", + "stream-browserify": "^2.0.1", + "stream-http": "^2.7.2", + "string_decoder": "^1.0.0", + "timers-browserify": "^2.0.4", + "tty-browserify": "0.0.0", + "url": "^0.11.0", + "util": "^0.11.0", + "vm-browserify": "^1.0.1" + }, + "dependencies": { + "buffer": { + "version": "4.9.2", + "resolved": "https://registry.npmjs.org/buffer/-/buffer-4.9.2.tgz", + "integrity": "sha512-xq+q3SRMOxGivLhBNaUdC64hDTQwejJ+H0T/NB1XMtTVEwNTrfFF3gAxiyW0Bu/xWEGhjVKgUcMhCrUy2+uCWg==", + "dev": true, + "requires": { + "base64-js": "^1.0.2", + "ieee754": "^1.1.4", + "isarray": "^1.0.0" + } + }, + "inherits": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.3.tgz", + "integrity": "sha1-Yzwsg+PaQqUC9SRmAiSA9CCCYd4=", + "dev": true + }, + "util": { + "version": "0.11.1", + "resolved": "https://registry.npmjs.org/util/-/util-0.11.1.tgz", + "integrity": "sha512-HShAsny+zS2TZfaXxD9tYj4HQGlBezXZMZuM/S5PKLLoZkShZiGk9o5CzukI1LVHZvjdvZ2Sj1aW/Ndn2NB/HQ==", + "dev": true, + "requires": { + "inherits": "2.0.3" } } } @@ -7838,52 +8219,50 @@ "integrity": "sha512-6VrvH7z6jqqNFY200kdB6HdzkgM96Oaj9v3dqGfgp6mF+cHmU4wyQKZ2/WPDRVoR0Jz9KqbamaBN0ZhdUaysUQ==", "dev": true, "requires": { - "semver": "5.5.0" + "semver": "^5.3.0" } }, "node-sass": { - "version": "4.11.0", - "resolved": "https://registry.npmjs.org/node-sass/-/node-sass-4.11.0.tgz", - "integrity": "sha512-bHUdHTphgQJZaF1LASx0kAviPH7sGlcyNhWade4eVIpFp6tsn7SV8xNMTbsQFpEV9VXpnwTTnNYlfsZXgGgmkA==", - "dev": true, - "requires": { - "async-foreach": "0.1.3", - "chalk": "1.1.3", - "cross-spawn": "3.0.1", - "gaze": "1.1.3", - "get-stdin": "4.0.1", - "glob": "7.1.2", - "in-publish": "2.0.0", - "lodash.assign": "4.2.0", - "lodash.clonedeep": "4.5.0", - "lodash.mergewith": "4.6.1", - "meow": "3.7.0", - "mkdirp": "0.5.1", - "nan": "2.12.1", - "node-gyp": "3.8.0", - "npmlog": "4.1.2", - "request": "2.88.0", - "sass-graph": "2.2.4", - "stdout-stream": "1.4.1", - "true-case-path": "1.0.3" + "version": "4.13.0", + "resolved": "https://registry.npmjs.org/node-sass/-/node-sass-4.13.0.tgz", + "integrity": "sha512-W1XBrvoJ1dy7VsvTAS5q1V45lREbTlZQqFbiHb3R3OTTCma0XBtuG6xZ6Z4506nR4lmHPTqVRwxT6KgtWC97CA==", + "dev": true, + "requires": { + "async-foreach": "^0.1.3", + "chalk": "^1.1.1", + "cross-spawn": "^3.0.0", + "gaze": "^1.0.0", + "get-stdin": "^4.0.1", + "glob": "^7.0.3", + "in-publish": "^2.0.0", + "lodash": "^4.17.15", + "meow": "^3.7.0", + "mkdirp": "^0.5.1", + "nan": "^2.13.2", + "node-gyp": "^3.8.0", + "npmlog": "^4.0.0", + "request": "^2.88.0", + "sass-graph": "^2.2.4", + "stdout-stream": "^1.4.0", + "true-case-path": "^1.0.2" }, "dependencies": { "ajv": { - "version": "6.7.0", - "resolved": "https://registry.npmjs.org/ajv/-/ajv-6.7.0.tgz", - "integrity": "sha512-RZXPviBTtfmtka9n9sy1N5M5b82CbxWIR6HIis4s3WQTXDJamc/0gpCWNGz6EWdWp4DOfjzJfhz/AS9zVPjjWg==", + "version": "6.10.2", + "resolved": "https://registry.npmjs.org/ajv/-/ajv-6.10.2.tgz", + "integrity": "sha512-TXtUUEYHuaTEbLZWIKUr5pmBuhDLy+8KYtPYdcV8qC+pOZL+NKqYwvWSRrVXHn+ZmRRAu8vJTAznH7Oag6RVRw==", "dev": true, "requires": { - "fast-deep-equal": "2.0.1", - "fast-json-stable-stringify": "2.0.0", - "json-schema-traverse": "0.4.1", - "uri-js": "4.2.2" + "fast-deep-equal": "^2.0.1", + "fast-json-stable-stringify": "^2.0.0", + "json-schema-traverse": "^0.4.1", + "uri-js": "^4.2.2" } }, "aws4": { - "version": "1.8.0", - "resolved": "https://registry.npmjs.org/aws4/-/aws4-1.8.0.tgz", - "integrity": "sha512-ReZxvNHIOv88FlT7rxcXIIC0fPt4KZqZbOlivyWtXLt8ESx84zd3kMC6iK5jVeS2qt+g7ftS7ye4fi06X5rtRQ==", + "version": "1.9.0", + "resolved": "https://registry.npmjs.org/aws4/-/aws4-1.9.0.tgz", + "integrity": "sha512-Uvq6hVe90D0B2WEnUqtdgY1bATGz3mw33nH9Y+dmA+w5DHvUmBgkr5rM/KCHpCsiFNRUfokW/szpPPgMK2hm4A==", "dev": true }, "cross-spawn": { @@ -7892,16 +8271,10 @@ "integrity": "sha1-ElYDfsufDF9549bvE14wdwGEuYI=", "dev": true, "requires": { - "lru-cache": "4.0.2", - "which": "1.3.0" + "lru-cache": "^4.0.1", + "which": "^1.2.9" } }, - "extend": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/extend/-/extend-3.0.2.tgz", - "integrity": "sha512-fjquC59cD7CyW6urNXK0FBufkZcoiGG80wTuPujX590cB5Ttln20E2UB4S/WARVqhXffZl2LNgS+gQdPIIim/g==", - "dev": true - }, "fast-deep-equal": { "version": "2.0.1", "resolved": "https://registry.npmjs.org/fast-deep-equal/-/fast-deep-equal-2.0.1.tgz", @@ -7920,8 +8293,8 @@ "integrity": "sha512-sNvOCzEQNr/qrvJgc3UG/kD4QtlHycrzwS+6mfTrrSq97BvaYcPZZI1ZSqGSPR73Cxn4LKTD4PttRwfU7jWq5g==", "dev": true, "requires": { - "ajv": "6.7.0", - "har-schema": "2.0.0" + "ajv": "^6.5.5", + "har-schema": "^2.0.0" } }, "json-schema-traverse": { @@ -7930,25 +8303,31 @@ "integrity": "sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg==", "dev": true }, + "lodash": { + "version": "4.17.15", + "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.15.tgz", + "integrity": "sha512-8xOcRHvCjnocdS5cpwXQXVzmmh5e5+saE2QGoeQmbKmRS6J3VQppPOIt0MnmE+4xlZoumy0GPG0D0MVIQbNA1A==", + "dev": true + }, "mime-db": { - "version": "1.37.0", - "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.37.0.tgz", - "integrity": "sha512-R3C4db6bgQhlIhPU48fUtdVmKnflq+hRdad7IyKhtFj06VPNVdk2RhiYL3UjQIlso8L+YxAtFkobT0VK+S/ybg==", + "version": "1.42.0", + "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.42.0.tgz", + "integrity": "sha512-UbfJCR4UAVRNgMpfImz05smAXK7+c+ZntjaA26ANtkXLlOe947Aag5zdIcKQULAiF9Cq4WxBi9jUs5zkA84bYQ==", "dev": true }, "mime-types": { - "version": "2.1.21", - "resolved": "https://registry.npmjs.org/mime-types/-/mime-types-2.1.21.tgz", - "integrity": "sha512-3iL6DbwpyLzjR3xHSFNFeb9Nz/M8WDkX33t1GFQnFOllWk8pOrh/LSrB5OXlnlW5P9LH73X6loW/eogc+F5lJg==", + "version": "2.1.25", + "resolved": "https://registry.npmjs.org/mime-types/-/mime-types-2.1.25.tgz", + "integrity": "sha512-5KhStqB5xpTAeGqKBAMgwaYMnQik7teQN4IAzC7npDv6kzeU6prfkR67bc87J1kWMPGkoaZSq1npmexMgkmEVg==", "dev": true, "requires": { - "mime-db": "1.37.0" + "mime-db": "1.42.0" } }, "nan": { - "version": "2.12.1", - "resolved": "https://registry.npmjs.org/nan/-/nan-2.12.1.tgz", - "integrity": "sha512-JY7V6lRkStKcKTvHO5NVSQRv+RV+FIL5pvDoLiAtSL9pKlC5x9PKQcZDsq7m4FO4d57mkhC6Z+QhAh3Jdk5JFw==", + "version": "2.14.0", + "resolved": "https://registry.npmjs.org/nan/-/nan-2.14.0.tgz", + "integrity": "sha512-INOFj37C7k3AfaNTtX8RhsTw7qRy7eLET14cROi9+5HAVbbHuIWUHEauBv5qT4Av2tWasiTY1Jw6puUNqRJXQg==", "dev": true }, "oauth-sign": { @@ -7969,32 +8348,32 @@ "integrity": "sha512-NAqBSrijGLZdM0WZNsInLJpkJokL72XYjUpnB0iwsRgxh7dB6COrHnTBNwN0E+lHDAJzu7kLAkDeY08z2/A0hg==", "dev": true, "requires": { - "aws-sign2": "0.7.0", - "aws4": "1.8.0", - "caseless": "0.12.0", - "combined-stream": "1.0.6", - "extend": "3.0.2", - "forever-agent": "0.6.1", - "form-data": "2.3.2", - "har-validator": "5.1.3", - "http-signature": "1.2.0", - "is-typedarray": "1.0.0", - "isstream": "0.1.2", - "json-stringify-safe": "5.0.1", - "mime-types": "2.1.21", - "oauth-sign": "0.9.0", - "performance-now": "2.1.0", - "qs": "6.5.2", - "safe-buffer": "5.1.2", - "tough-cookie": "2.4.3", - "tunnel-agent": "0.6.0", - "uuid": "3.3.2" + "aws-sign2": "~0.7.0", + "aws4": "^1.8.0", + "caseless": "~0.12.0", + "combined-stream": "~1.0.6", + "extend": "~3.0.2", + "forever-agent": "~0.6.1", + "form-data": "~2.3.2", + "har-validator": "~5.1.0", + "http-signature": "~1.2.0", + "is-typedarray": "~1.0.0", + "isstream": "~0.1.2", + "json-stringify-safe": "~5.0.1", + "mime-types": "~2.1.19", + "oauth-sign": "~0.9.0", + "performance-now": "^2.1.0", + "qs": "~6.5.2", + "safe-buffer": "^5.1.2", + "tough-cookie": "~2.4.3", + "tunnel-agent": "^0.6.0", + "uuid": "^3.3.2" } }, "safe-buffer": { - "version": "5.1.2", - "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz", - "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==", + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.2.0.tgz", + "integrity": "sha512-fZEwUGbVl7kouZs1jCdMLdt95hdIv0ZeHg6L7qPeciMZhZ+/gdesW4wgTARkrFWEpspjEATAzUGPG8N2jJiwbg==", "dev": true }, "tough-cookie": { @@ -8003,8 +8382,8 @@ "integrity": "sha512-Q5srk/4vDM54WJsJio3XNn6K2sCG+CQ8G5Wz6bZhRZoAe/+TxjWB/GlFAnYEbkYVlON9FMk/fE3h2RLpPXo4lQ==", "dev": true, "requires": { - "psl": "1.1.31", - "punycode": "1.4.1" + "psl": "^1.1.24", + "punycode": "^1.4.1" } } } @@ -8015,7 +8394,7 @@ "integrity": "sha1-xkZdvwirzU2zWTF/eaxopkayj/k=", "dev": true, "requires": { - "abbrev": "1.1.1" + "abbrev": "1" } }, "normalize-package-data": { @@ -8023,20 +8402,17 @@ "resolved": "https://registry.npmjs.org/normalize-package-data/-/normalize-package-data-2.4.0.tgz", "integrity": "sha1-EvlaMH1YNSB1oEkHuErIvpisAS8=", "requires": { - "hosted-git-info": "2.6.0", - "is-builtin-module": "1.0.0", - "semver": "5.5.0", - "validate-npm-package-license": "3.0.3" + "hosted-git-info": "^2.1.4", + "is-builtin-module": "^1.0.0", + "semver": "2 || 3 || 4 || 5", + "validate-npm-package-license": "^3.0.1" } }, "normalize-path": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/normalize-path/-/normalize-path-2.1.1.tgz", - "integrity": "sha1-GrKLVW4Zg2Oowab35vogE3/mrtk=", - "dev": true, - "requires": { - "remove-trailing-separator": "1.1.0" - } + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/normalize-path/-/normalize-path-3.0.0.tgz", + "integrity": "sha512-6eZs5Ls3WtCisHWp9S2GUy8dqkpGi4BVSz3GaqiE6ezub0512ESztXUwUB6C6IKbQkY2Pnb/mD4WYojCRwcwLA==", + "dev": true }, "npm-run-path": { "version": "2.0.2", @@ -8044,19 +8420,19 @@ "integrity": "sha1-NakjLfo11wZ7TLLd8jV7GHFTbF8=", "dev": true, "requires": { - "path-key": "2.0.1" + "path-key": "^2.0.0" } }, "npmlog": { "version": "4.1.2", "resolved": "https://registry.npmjs.org/npmlog/-/npmlog-4.1.2.tgz", - "integrity": "sha1-CKfyqL9zRgR3mp76StXMcXq7lUs=", + "integrity": "sha512-2uUqazuKlTaSI/dC8AzicUck7+IrEaOnN/e0jd3Xtt1KcGpwx30v50mL7oPyr/h9bL3E4aZccVwpwP+5W9Vjkg==", "dev": true, "requires": { - "are-we-there-yet": "1.1.5", - "console-control-strings": "1.1.0", - "gauge": "2.7.4", - "set-blocking": "2.0.0" + "are-we-there-yet": "~1.1.2", + "console-control-strings": "~1.1.0", + "gauge": "~2.7.3", + "set-blocking": "~2.0.0" } }, "nth-check": { @@ -8065,7 +8441,7 @@ "integrity": "sha512-WeBOdju8SnzPN5vTUJYxYUxLeXpCaVP5i5e0LF8fg7WORF2Wd7wFX/pk0tYZk7s8T+J7VLy0Da6J1+wCT0AtHg==", "dev": true, "requires": { - "boolbase": "1.0.0" + "boolbase": "~1.0.0" } }, "number-is-nan": { @@ -8092,9 +8468,9 @@ "integrity": "sha1-fn2Fi3gb18mRpBupde04EnVOmYw=", "dev": true, "requires": { - "copy-descriptor": "0.1.1", - "define-property": "0.2.5", - "kind-of": "3.2.2" + "copy-descriptor": "^0.1.0", + "define-property": "^0.2.5", + "kind-of": "^3.0.3" }, "dependencies": { "define-property": { @@ -8103,7 +8479,7 @@ "integrity": "sha1-w1se+RjsPJkPmlvFe+BKrOxcgRY=", "dev": true, "requires": { - "is-descriptor": "0.1.6" + "is-descriptor": "^0.1.0" } }, "kind-of": { @@ -8112,11 +8488,17 @@ "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=", "dev": true, "requires": { - "is-buffer": "1.1.6" + "is-buffer": "^1.1.5" } } } }, + "object-is": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/object-is/-/object-is-1.0.1.tgz", + "integrity": "sha1-CqYOyZiaCz7Xlc9NBvYs8a1lObY=", + "dev": true + }, "object-keys": { "version": "1.0.11", "resolved": "https://registry.npmjs.org/object-keys/-/object-keys-1.0.11.tgz", @@ -8134,7 +8516,78 @@ "integrity": "sha1-95xEk68MU3e1n+OdOV5BBC3QRbs=", "dev": true, "requires": { - "isobject": "3.0.1" + "isobject": "^3.0.0" + } + }, + "object.fromentries": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/object.fromentries/-/object.fromentries-2.0.0.tgz", + "integrity": "sha512-9iLiI6H083uiqUuvzyY6qrlmc/Gz8hLQFOcb/Ri/0xXFkSNS3ctV+CbE6yM2+AnkYfOB3dGjdzC0wrMLIhQICA==", + "dev": true, + "requires": { + "define-properties": "^1.1.2", + "es-abstract": "^1.11.0", + "function-bind": "^1.1.1", + "has": "^1.0.1" + }, + "dependencies": { + "es-abstract": { + "version": "1.13.0", + "resolved": "https://registry.npmjs.org/es-abstract/-/es-abstract-1.13.0.tgz", + "integrity": "sha512-vDZfg/ykNxQVwup/8E1BZhVzFfBxs9NqMzGcvIJrqg5k2/5Za2bWo40dK2J1pgLngZ7c+Shh8lwYtLGyrwPutg==", + "dev": true, + "requires": { + "es-to-primitive": "^1.2.0", + "function-bind": "^1.1.1", + "has": "^1.0.3", + "is-callable": "^1.1.4", + "is-regex": "^1.0.4", + "object-keys": "^1.0.12" + }, + "dependencies": { + "has": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/has/-/has-1.0.3.tgz", + "integrity": "sha512-f2dvO0VU6Oej7RkWJGrehjbzMAjFp5/VKPp5tTpWIV4JHHZK1/BxbFRtf/siA2SWTe09caDmVtYYzWEIbBS4zw==", + "dev": true, + "requires": { + "function-bind": "^1.1.1" + } + } + } + }, + "es-to-primitive": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/es-to-primitive/-/es-to-primitive-1.2.0.tgz", + "integrity": "sha512-qZryBOJjV//LaxLTV6UC//WewneB3LcXOL9NP++ozKVXsIIIpm/2c13UDiD9Jp2eThsecw9m3jPqDwTyobcdbg==", + "dev": true, + "requires": { + "is-callable": "^1.1.4", + "is-date-object": "^1.0.1", + "is-symbol": "^1.0.2" + } + }, + "is-callable": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/is-callable/-/is-callable-1.1.4.tgz", + "integrity": "sha512-r5p9sxJjYnArLjObpjA4xu5EKI3CuKHkJXMhT7kwbpUyIFD1n5PMAsoPvWnvtZiNz7LjkYDRZhd7FlI0eMijEA==", + "dev": true + }, + "is-symbol": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/is-symbol/-/is-symbol-1.0.2.tgz", + "integrity": "sha512-HS8bZ9ox60yCJLH9snBpIwv9pYUAkcuLhSA1oero1UB5y9aiQpRA8y2ex945AOtCZL1lJDeIk3G5LthswI46Lw==", + "dev": true, + "requires": { + "has-symbols": "^1.0.0" + } + }, + "object-keys": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/object-keys/-/object-keys-1.1.1.tgz", + "integrity": "sha512-NuAESUOUMrlIXOfHKzD6bpPu3tYt3xvjNdRIQ+FeT0lNb4K8WR70CaDxhuNguS2XG+GjkyMwOzsN5ZktImfhLA==", + "dev": true + } } }, "object.getownpropertydescriptors": { @@ -8143,8 +8596,8 @@ "integrity": "sha1-h1jIRvW0B62rDyNuCYbxSwUcqhY=", "dev": true, "requires": { - "define-properties": "1.1.2", - "es-abstract": "1.10.0" + "define-properties": "^1.1.2", + "es-abstract": "^1.5.1" } }, "object.pick": { @@ -8153,7 +8606,7 @@ "integrity": "sha1-h6EKxMFpS9Lhy/U1kaZhQftd10c=", "dev": true, "requires": { - "isobject": "3.0.1" + "isobject": "^3.0.1" } }, "obuf": { @@ -8172,9 +8625,9 @@ } }, "on-headers": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/on-headers/-/on-headers-1.0.1.tgz", - "integrity": "sha1-ko9dD0cNSTQmUepnlLCFfBAGk/c=", + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/on-headers/-/on-headers-1.0.2.tgz", + "integrity": "sha512-pZAE+FJLoyITytdqK0U5s+FIpjN0JP3OzFi/u8Rx+EV5/W+JTWGXG8xFzevE7AjBfDqHv/8vL8qQsIhHnqRkrA==", "dev": true }, "once": { @@ -8182,7 +8635,7 @@ "resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz", "integrity": "sha1-WDsap3WWHUsROsF9nFC6753Xa9E=", "requires": { - "wrappy": "1.0.2" + "wrappy": "1" } }, "onetime": { @@ -8190,16 +8643,16 @@ "resolved": "https://registry.npmjs.org/onetime/-/onetime-2.0.1.tgz", "integrity": "sha1-BnQoIw/WdEOyeUsiu6UotoZ5YtQ=", "requires": { - "mimic-fn": "1.2.0" + "mimic-fn": "^1.0.0" } }, "opn": { - "version": "5.4.0", - "resolved": "https://registry.npmjs.org/opn/-/opn-5.4.0.tgz", - "integrity": "sha512-YF9MNdVy/0qvJvDtunAOzFw9iasOQHpVthTCvGzxt61Il64AYSGdK+rYwld7NAfk9qJ7dt+hymBNSc9LNYS+Sw==", + "version": "5.5.0", + "resolved": "https://registry.npmjs.org/opn/-/opn-5.5.0.tgz", + "integrity": "sha512-PqHpggC9bLV0VeWcdKhkpxY+3JTzetLSqTCWL/z/tFIbI6G8JCjondXklT1JinczLz2Xib62sSp0T/gKT4KksA==", "dev": true, "requires": { - "is-wsl": "1.1.0" + "is-wsl": "^1.1.0" } }, "optionator": { @@ -8207,12 +8660,12 @@ "resolved": "https://registry.npmjs.org/optionator/-/optionator-0.8.2.tgz", "integrity": "sha1-NkxeQJ0/TWMB1sC0wFu6UBgK62Q=", "requires": { - "deep-is": "0.1.3", - "fast-levenshtein": "2.0.6", - "levn": "0.3.0", - "prelude-ls": "1.1.2", - "type-check": "0.3.2", - "wordwrap": "1.0.0" + "deep-is": "~0.1.3", + "fast-levenshtein": "~2.0.4", + "levn": "~0.3.0", + "prelude-ls": "~1.1.2", + "type-check": "~0.3.2", + "wordwrap": "~1.0.0" } }, "original": { @@ -8221,11 +8674,17 @@ "integrity": "sha512-hyBVl6iqqUOJ8FqRe+l/gS8H+kKYjrEndd5Pm1MfBtsEKA038HkkdbAl/72EAXGyonD/PFsvmVG+EvcIpliMBg==", "dev": true, "requires": { - "url-parse": "1.4.3" + "url-parse": "^1.4.3" } }, - "os-homedir": { - "version": "1.0.2", + "os-browserify": { + "version": "0.3.0", + "resolved": "https://registry.npmjs.org/os-browserify/-/os-browserify-0.3.0.tgz", + "integrity": "sha1-hUNzx/XCMVkU/Jv8a9gjj92h7Cc=", + "dev": true + }, + "os-homedir": { + "version": "1.0.2", "resolved": "https://registry.npmjs.org/os-homedir/-/os-homedir-1.0.2.tgz", "integrity": "sha1-/7xJiDNuDoM94MFox+8VISGqf7M=", "dev": true @@ -8236,7 +8695,7 @@ "integrity": "sha1-IPnxeuKe00XoveWDsT0gCYA8FNk=", "dev": true, "requires": { - "lcid": "1.0.0" + "lcid": "^1.0.0" } }, "os-tmpdir": { @@ -8247,11 +8706,11 @@ "osenv": { "version": "0.1.5", "resolved": "https://registry.npmjs.org/osenv/-/osenv-0.1.5.tgz", - "integrity": "sha1-hc36+uso6Gd/QW4odZK18/SepBA=", + "integrity": "sha512-0CWcCECdMVc2Rw3U5w9ZjqX6ga6ubk1xDVKxtBQPK7wis/0F2r9T6k4ydGYhecl7YUBxBVxhL5oisPsNxAPe2g==", "dev": true, "requires": { - "os-homedir": "1.0.2", - "os-tmpdir": "1.0.2" + "os-homedir": "^1.0.0", + "os-tmpdir": "^1.0.0" } }, "p-defer": { @@ -8267,9 +8726,9 @@ "dev": true }, "p-is-promise": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/p-is-promise/-/p-is-promise-1.1.0.tgz", - "integrity": "sha1-nJRWmJ6fZYgBewQ01WCXZ1w9oF4=", + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/p-is-promise/-/p-is-promise-2.1.0.tgz", + "integrity": "sha512-Y3W0wlRPK8ZMRbNq97l4M5otioeA5lm1z7bkNkxCka8HSPjR0xRWmpCmc9utiaLP9Jb1eD8BgeIxTW4AIF45Pg==", "dev": true }, "p-limit": { @@ -8277,7 +8736,7 @@ "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-1.2.0.tgz", "integrity": "sha1-DpK2vty1nwIsE9DxlJ3ILRWQnxw=", "requires": { - "p-try": "1.0.0" + "p-try": "^1.0.0" } }, "p-locate": { @@ -8285,15 +8744,24 @@ "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-2.0.0.tgz", "integrity": "sha1-IKAQOyIqcMj9OcwuWAaA893l7EM=", "requires": { - "p-limit": "1.2.0" + "p-limit": "^1.1.0" } }, "p-map": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/p-map/-/p-map-1.2.0.tgz", - "integrity": "sha512-r6zKACMNhjPJMTl8KcFH4li//gkrXWfbD6feV8l6doRHlzljFWGJ2AP6iKaCJXyZmAUMOPtvbW7EXkbWO/pLEA==", + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/p-map/-/p-map-2.1.0.tgz", + "integrity": "sha512-y3b8Kpd8OAN444hxfBbFfj1FY/RjtTd8tzYwhUqNYXx0fXx2iX4maP4Qr6qhIKbQXI02wTLAda4fYUbDagTUFw==", "dev": true }, + "p-retry": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/p-retry/-/p-retry-3.0.1.tgz", + "integrity": "sha512-XE6G4+YTTkT2a0UWb2kjZe8xNwf8bIbnqpc/IS/idOBVhyves0mK5OJgeocjx7q5pvX/6m23xuzVPYT1uGM73w==", + "dev": true, + "requires": { + "retry": "^0.12.0" + } + }, "p-try": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/p-try/-/p-try-1.0.0.tgz", @@ -8305,20 +8773,20 @@ "integrity": "sha1-0iBd/ludqK95fnwWPbTR+E5GALw=" }, "parallel-transform": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/parallel-transform/-/parallel-transform-1.1.0.tgz", - "integrity": "sha1-1BDwZbBdojCB/NEPKIVMKb2jOwY=", + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/parallel-transform/-/parallel-transform-1.2.0.tgz", + "integrity": "sha512-P2vSmIu38uIlvdcU7fDkyrxj33gTUy/ABO5ZUbGowxNCopBq/OoD42bP4UmMrJoPyk4Uqf0mu3mtWBhHCZD8yg==", "dev": true, "requires": { - "cyclist": "0.2.2", - "inherits": "2.0.3", - "readable-stream": "2.3.5" + "cyclist": "^1.0.1", + "inherits": "^2.0.3", + "readable-stream": "^2.1.5" }, "dependencies": { "inherits": { - "version": "2.0.3", - "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.3.tgz", - "integrity": "sha1-Yzwsg+PaQqUC9SRmAiSA9CCCYd4=", + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.4.tgz", + "integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==", "dev": true } } @@ -8329,7 +8797,7 @@ "integrity": "sha1-35T9jPZTHs915r75oIWPvHK+Ikc=", "dev": true, "requires": { - "no-case": "2.3.2" + "no-case": "^2.2.0" } }, "parent-module": { @@ -8338,7 +8806,7 @@ "integrity": "sha512-8Mf5juOMmiE4FcmzYc4IaiS9L3+9paz2KOiXzkRviCP6aDmN49Hz6EMWz0lGNp9pX80GvvAuLADtyGfW/Em3TA==", "dev": true, "requires": { - "callsites": "3.0.0" + "callsites": "^3.0.0" }, "dependencies": { "callsites": { @@ -8350,17 +8818,17 @@ } }, "parse-asn1": { - "version": "5.1.3", - "resolved": "https://registry.npmjs.org/parse-asn1/-/parse-asn1-5.1.3.tgz", - "integrity": "sha512-VrPoetlz7B/FqjBLD2f5wBVZvsZVLnRUrxVLfRYhGXCODa/NWE4p3Wp+6+aV3ZPL3KM7/OZmxDIwwijD7yuucg==", + "version": "5.1.5", + "resolved": "https://registry.npmjs.org/parse-asn1/-/parse-asn1-5.1.5.tgz", + "integrity": "sha512-jkMYn1dcJqF6d5CpU689bq7w/b5ALS9ROVSpQDPrZsqqesUJii9qutvoT5ltGedNXMO2e16YUWIghG9KxaViTQ==", "dev": true, "requires": { - "asn1.js": "4.10.1", - "browserify-aes": "1.2.0", - "create-hash": "1.2.0", - "evp_bytestokey": "1.0.3", - "pbkdf2": "3.0.17", - "safe-buffer": "5.1.1" + "asn1.js": "^4.0.0", + "browserify-aes": "^1.0.0", + "create-hash": "^1.1.0", + "evp_bytestokey": "^1.0.0", + "pbkdf2": "^3.0.3", + "safe-buffer": "^5.1.1" } }, "parse-json": { @@ -8368,7 +8836,7 @@ "resolved": "https://registry.npmjs.org/parse-json/-/parse-json-2.2.0.tgz", "integrity": "sha1-9ID0BDTvgHQfhGkJn43qGPVaTck=", "requires": { - "error-ex": "1.3.1" + "error-ex": "^1.2.0" } }, "parse-passwd": { @@ -8378,9 +8846,9 @@ "dev": true }, "parseurl": { - "version": "1.3.2", - "resolved": "https://registry.npmjs.org/parseurl/-/parseurl-1.3.2.tgz", - "integrity": "sha1-/CidTtiZMRlGDBViUyYs3I3mW/M=", + "version": "1.3.3", + "resolved": "https://registry.npmjs.org/parseurl/-/parseurl-1.3.3.tgz", + "integrity": "sha512-CiyeOxFT/JZyN5m0z9PfXw4SCBJ6Sygz1Dpl0wqjlhDEGGBP1GnsUVEL0p63hoG1fcj3fHynXi9NYO4nWOL+qQ==", "dev": true }, "pascalcase": { @@ -8394,14 +8862,14 @@ "resolved": "https://registry.npmjs.org/path/-/path-0.12.7.tgz", "integrity": "sha1-1NwqUGxM4hl+tIHr/NWzbAFAsQ8=", "requires": { - "process": "0.11.10", - "util": "0.10.3" + "process": "^0.11.1", + "util": "^0.10.3" } }, "path-browserify": { - "version": "0.0.0", - "resolved": "https://registry.npmjs.org/path-browserify/-/path-browserify-0.0.0.tgz", - "integrity": "sha1-oLhwcpquIUAFt9UDLsLLuw+0RRo=", + "version": "0.0.1", + "resolved": "https://registry.npmjs.org/path-browserify/-/path-browserify-0.0.1.tgz", + "integrity": "sha512-BapA40NHICOS+USX9SN4tyhq+A2RrN/Ws5F0Z5aMHDp98Fl86lX8Oti8B7uN93L4Ifv4fHOEA+pQw87gmMO/lQ==", "dev": true }, "path-dirname": { @@ -8414,8 +8882,9 @@ "version": "2.1.0", "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-2.1.0.tgz", "integrity": "sha1-D+tsZPD8UY2adU3V77YscCJ2H0s=", + "dev": true, "requires": { - "pinkie-promise": "2.0.1" + "pinkie-promise": "^2.0.0" } }, "path-is-absolute": { @@ -8450,7 +8919,7 @@ "resolved": "https://registry.npmjs.org/path-type/-/path-type-2.0.0.tgz", "integrity": "sha1-8BLMuEFbcJb8LaoQVMPXI4lZTHM=", "requires": { - "pify": "2.3.0" + "pify": "^2.0.0" } }, "pbkdf2": { @@ -8459,33 +8928,11 @@ "integrity": "sha512-U/il5MsrZp7mGg3mSQfn742na2T+1/vHDCG5/iTI3X9MKUuYUZVLQhyRsg06mCgDBTd57TxzgZt7P+fYfjRLtA==", "dev": true, "requires": { - "create-hash": "1.2.0", - "create-hmac": "1.1.7", - "ripemd160": "2.0.2", - "safe-buffer": "5.1.1", - "sha.js": "2.4.11" - }, - "dependencies": { - "ripemd160": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/ripemd160/-/ripemd160-2.0.2.tgz", - "integrity": "sha512-ii4iagi25WusVoiC4B4lq7pbXfAp3D9v5CwfkY33vffw2+pkDjY1D8GaN7spsxvCSx8dkPqOZCEZyfxcmJG2IA==", - "dev": true, - "requires": { - "hash-base": "3.0.4", - "inherits": "2.0.1" - } - }, - "sha.js": { - "version": "2.4.11", - "resolved": "https://registry.npmjs.org/sha.js/-/sha.js-2.4.11.tgz", - "integrity": "sha512-QMEp5B7cftE7APOjk5Y6xgrbWu+WkLVQwk8JNjZ8nKRciZaByEW6MubieAiToS7+dwvrjGhH8jRXz3MVd0AYqQ==", - "dev": true, - "requires": { - "inherits": "2.0.1", - "safe-buffer": "5.1.1" - } - } + "create-hash": "^1.1.2", + "create-hmac": "^1.1.4", + "ripemd160": "^2.0.1", + "safe-buffer": "^5.0.1", + "sha.js": "^2.4.8" } }, "performance-now": { @@ -8509,7 +8956,7 @@ "resolved": "https://registry.npmjs.org/pinkie-promise/-/pinkie-promise-2.0.1.tgz", "integrity": "sha1-ITXW36ejWMBprJsXh3YogihFD/o=", "requires": { - "pinkie": "2.0.4" + "pinkie": "^2.0.0" } }, "pkg-conf": { @@ -8517,8 +8964,8 @@ "resolved": "https://registry.npmjs.org/pkg-conf/-/pkg-conf-2.1.0.tgz", "integrity": "sha1-ISZRTKbyq/69FoWW3xi6V4Z/AFg=", "requires": { - "find-up": "2.1.0", - "load-json-file": "4.0.0" + "find-up": "^2.0.0", + "load-json-file": "^4.0.0" }, "dependencies": { "find-up": { @@ -8526,7 +8973,7 @@ "resolved": "https://registry.npmjs.org/find-up/-/find-up-2.1.0.tgz", "integrity": "sha1-RdG35QbHF93UgndaK3eSCjwMV6c=", "requires": { - "locate-path": "2.0.0" + "locate-path": "^2.0.0" } }, "load-json-file": { @@ -8534,10 +8981,10 @@ "resolved": "https://registry.npmjs.org/load-json-file/-/load-json-file-4.0.0.tgz", "integrity": "sha1-L19Fq5HjMhYjT9U62rZo607AmTs=", "requires": { - "graceful-fs": "4.1.11", - "parse-json": "4.0.0", - "pify": "3.0.0", - "strip-bom": "3.0.0" + "graceful-fs": "^4.1.2", + "parse-json": "^4.0.0", + "pify": "^3.0.0", + "strip-bom": "^3.0.0" } }, "parse-json": { @@ -8545,8 +8992,8 @@ "resolved": "https://registry.npmjs.org/parse-json/-/parse-json-4.0.0.tgz", "integrity": "sha1-vjX1Qlvh9/bHRxhPmKeIy5lHfuA=", "requires": { - "error-ex": "1.3.1", - "json-parse-better-errors": "1.0.1" + "error-ex": "^1.3.1", + "json-parse-better-errors": "^1.0.1" } }, "pify": { @@ -8561,17 +9008,18 @@ "resolved": "https://registry.npmjs.org/pkg-config/-/pkg-config-1.1.1.tgz", "integrity": "sha1-VX7yLXPaPIg3EHdmxS6tq94pj+Q=", "requires": { - "debug-log": "1.0.1", - "find-root": "1.1.0", - "xtend": "4.0.1" + "debug-log": "^1.0.0", + "find-root": "^1.0.0", + "xtend": "^4.0.1" } }, "pkg-dir": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/pkg-dir/-/pkg-dir-1.0.0.tgz", "integrity": "sha1-ektQio1bstYp1EcFb/TpyTFM89Q=", + "dev": true, "requires": { - "find-up": "1.1.2" + "find-up": "^1.0.0" } }, "pluralize": { @@ -8580,19 +9028,36 @@ "integrity": "sha1-KYuJ34uTsCIdv0Ia0rGx6iP8Z3c=" }, "popper.js": { - "version": "1.14.4", - "resolved": "https://registry.npmjs.org/popper.js/-/popper.js-1.14.4.tgz", - "integrity": "sha1-juwdj/AqWjoVLdQ0FKFce3n9abY=" + "version": "1.15.0", + "resolved": "https://registry.npmjs.org/popper.js/-/popper.js-1.15.0.tgz", + "integrity": "sha512-w010cY1oCUmI+9KwwlWki+r5jxKfTFDVoadl7MSrIujHU5MJ5OR6HTDj6Xo8aoR/QsA56x8jKjA59qGH4ELtrA==" }, "portfinder": { - "version": "1.0.20", - "resolved": "https://registry.npmjs.org/portfinder/-/portfinder-1.0.20.tgz", - "integrity": "sha512-Yxe4mTyDzTd59PZJY4ojZR8F+E5e97iq2ZOHPz3HDgSvYC5siNad2tLooQ5y5QHyQhc3xVqvyk/eNA3wuoa7Sw==", + "version": "1.0.25", + "resolved": "https://registry.npmjs.org/portfinder/-/portfinder-1.0.25.tgz", + "integrity": "sha512-6ElJnHBbxVA1XSLgBp7G1FiCkQdlqGzuF7DswL5tcea+E8UpuvPU7beVAjjRwCioTS9ZluNbu+ZyRvgTsmqEBg==", "dev": true, "requires": { - "async": "1.5.2", - "debug": "2.6.9", - "mkdirp": "0.5.1" + "async": "^2.6.2", + "debug": "^3.1.1", + "mkdirp": "^0.5.1" + }, + "dependencies": { + "debug": { + "version": "3.2.6", + "resolved": "https://registry.npmjs.org/debug/-/debug-3.2.6.tgz", + "integrity": "sha512-mel+jf7nrtEl5Pn1Qx46zARXKDpBbvzezse7p7LqINmdoIk8PYP5SySaxEmYv6TZ0JyEKA1hsCId6DIhgITtWQ==", + "dev": true, + "requires": { + "ms": "^2.1.1" + } + }, + "ms": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", + "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==", + "dev": true + } } }, "posix-character-classes": { @@ -8602,14 +9067,14 @@ "dev": true }, "postcss": { - "version": "7.0.13", - "resolved": "https://registry.npmjs.org/postcss/-/postcss-7.0.13.tgz", - "integrity": "sha512-h8SY6kQTd1wISHWjz+E6cswdhMuyBZRb16pSTv3W4zYZ3/YbyWeJdNUeOXB5IdZqE1U76OUEjjjqsC3z2f3hVg==", + "version": "7.0.16", + "resolved": "https://registry.npmjs.org/postcss/-/postcss-7.0.16.tgz", + "integrity": "sha512-MOo8zNSlIqh22Uaa3drkdIAgUGEL+AD1ESiSdmElLUmE2uVDo1QloiT/IfW9qRw8Gw+Y/w69UVMGwbufMSftxA==", "dev": true, "requires": { - "chalk": "2.4.2", - "source-map": "0.6.1", - "supports-color": "6.1.0" + "chalk": "^2.4.2", + "source-map": "^0.6.1", + "supports-color": "^6.1.0" }, "dependencies": { "ansi-styles": { @@ -8618,7 +9083,7 @@ "integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==", "dev": true, "requires": { - "color-convert": "1.9.1" + "color-convert": "^1.9.0" } }, "chalk": { @@ -8627,9 +9092,9 @@ "integrity": "sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==", "dev": true, "requires": { - "ansi-styles": "3.2.1", - "escape-string-regexp": "1.0.5", - "supports-color": "5.5.0" + "ansi-styles": "^3.2.1", + "escape-string-regexp": "^1.0.5", + "supports-color": "^5.3.0" }, "dependencies": { "supports-color": { @@ -8638,7 +9103,7 @@ "integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==", "dev": true, "requires": { - "has-flag": "3.0.0" + "has-flag": "^3.0.0" } } } @@ -8655,7 +9120,7 @@ "integrity": "sha512-qe1jfm1Mg7Nq/NSh6XE24gPXROEVsWHxC1LIx//XNlD9iw7YZQGjZNjYN7xGaEG6iKdA8EtNFW6R0gjnVXp+wQ==", "dev": true, "requires": { - "has-flag": "3.0.0" + "has-flag": "^3.0.0" } } } @@ -8666,7 +9131,7 @@ "integrity": "sha512-LaYLDNS4SG8Q5WAWqIJgdHPJrDDr/Lv775rMBFUbgjTz6j34lUznACHcdRWroPvXANP2Vj7yNK57vp9eFqzLWQ==", "dev": true, "requires": { - "postcss": "7.0.13" + "postcss": "^7.0.5" } }, "postcss-modules-local-by-default": { @@ -8675,9 +9140,9 @@ "integrity": "sha512-WvuSaTKXUqYJbnT7R3YrsNrHv/C5vRfr5VglS4bFOk0MYT4CLBfc/xgExA+x2RftlYgiBDvWmVs191Xv8S8gZQ==", "dev": true, "requires": { - "css-selector-tokenizer": "0.7.1", - "postcss": "7.0.13", - "postcss-value-parser": "3.3.1" + "css-selector-tokenizer": "^0.7.0", + "postcss": "^7.0.6", + "postcss-value-parser": "^3.3.1" } }, "postcss-modules-scope": { @@ -8686,8 +9151,8 @@ "integrity": "sha512-7+6k9c3/AuZ5c596LJx9n923A/j3nF3ormewYBF1RrIQvjvjXe1xE8V8A1KFyFwXbvnshT6FBZFX0k/F1igneg==", "dev": true, "requires": { - "css-selector-tokenizer": "0.7.1", - "postcss": "7.0.13" + "css-selector-tokenizer": "^0.7.0", + "postcss": "^7.0.6" } }, "postcss-modules-values": { @@ -8696,8 +9161,8 @@ "integrity": "sha512-Ki7JZa7ff1N3EIMlPnGTZfUMe69FFwiQPnVSXC9mnn3jozCRBYIxiZd44yJOV2AmabOo4qFf8s0dC/+lweG7+w==", "dev": true, "requires": { - "icss-replace-symbols": "1.1.0", - "postcss": "7.0.13" + "icss-replace-symbols": "^1.1.0", + "postcss": "^7.0.6" } }, "postcss-value-parser": { @@ -8717,8 +9182,8 @@ "integrity": "sha1-X0+HyPkeWuPzuoerTPXgOxoX8aM=", "dev": true, "requires": { - "renderkid": "2.0.2", - "utila": "0.4.0" + "renderkid": "^2.0.1", + "utila": "~0.4" } }, "private": { @@ -8747,7 +9212,7 @@ "resolved": "https://registry.npmjs.org/promise/-/promise-7.3.1.tgz", "integrity": "sha512-nolQXZ/4L+bP/UGlkfaIujX9BKxGwmQ9OT4mOt5yvy8iK1h3wqTEJCijzGANTCCl9nWjY41juyAn2K3Q1hLLTg==", "requires": { - "asap": "2.0.6" + "asap": "~2.0.3" } }, "promise-inflight": { @@ -8761,19 +9226,19 @@ "resolved": "https://registry.npmjs.org/prop-types/-/prop-types-15.6.1.tgz", "integrity": "sha1-NmREU1ZCVd3aORGR+zoSXL32VMo=", "requires": { - "fbjs": "0.8.16", - "loose-envify": "1.3.1", - "object-assign": "4.1.1" + "fbjs": "^0.8.16", + "loose-envify": "^1.3.1", + "object-assign": "^4.1.1" } }, "proxy-addr": { - "version": "2.0.4", - "resolved": "https://registry.npmjs.org/proxy-addr/-/proxy-addr-2.0.4.tgz", - "integrity": "sha512-5erio2h9jp5CHGwcybmxmVqHmnCBZeewlfJ0pex+UW7Qny7OOZXTtH56TGNyBizkgiOwhJtMKrVzDTeKcySZwA==", + "version": "2.0.5", + "resolved": "https://registry.npmjs.org/proxy-addr/-/proxy-addr-2.0.5.tgz", + "integrity": "sha512-t/7RxHXPH6cJtP0pRG6smSr9QJidhB+3kXu0KgXnbGYMgzEnUxRQ4/LDdfOwZEMyIh3/xHb8PX3t+lfL9z+YVQ==", "dev": true, "requires": { - "forwarded": "0.1.2", - "ipaddr.js": "1.8.0" + "forwarded": "~0.1.2", + "ipaddr.js": "1.9.0" } }, "prr": { @@ -8788,9 +9253,9 @@ "integrity": "sha1-8FKijacOYYkX7wqKw0wa5aaChrM=" }, "psl": { - "version": "1.1.31", - "resolved": "https://registry.npmjs.org/psl/-/psl-1.1.31.tgz", - "integrity": "sha512-/6pt4+C+T+wZUieKR620OpzN/LlnNKuWjy1iFLQ/UG35JqHlR/89MP1d96dUfkf6Dne3TuLQzOYEYshJ+Hx8mw==", + "version": "1.5.0", + "resolved": "https://registry.npmjs.org/psl/-/psl-1.5.0.tgz", + "integrity": "sha512-4vqUjKi2huMu1OJiLhi3jN6jeeKvMZdI1tYgi/njW5zV52jNLgSAZSdN16m9bJFe61/cT8ulmw4qFitV9QRsEA==", "dev": true }, "public-encrypt": { @@ -8799,18 +9264,18 @@ "integrity": "sha512-zVpa8oKZSz5bTMTFClc1fQOnyyEzpl5ozpi1B5YcvBrdohMjH2rfsBtyXcuNuwjsDIXmBYlF2N5FlJYhR29t8Q==", "dev": true, "requires": { - "bn.js": "4.11.8", - "browserify-rsa": "4.0.1", - "create-hash": "1.2.0", - "parse-asn1": "5.1.3", - "randombytes": "2.0.6", - "safe-buffer": "5.1.2" + "bn.js": "^4.1.0", + "browserify-rsa": "^4.0.0", + "create-hash": "^1.1.0", + "parse-asn1": "^5.0.0", + "randombytes": "^2.0.1", + "safe-buffer": "^5.1.2" }, "dependencies": { "safe-buffer": { - "version": "5.1.2", - "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz", - "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==", + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.2.0.tgz", + "integrity": "sha512-fZEwUGbVl7kouZs1jCdMLdt95hdIv0ZeHg6L7qPeciMZhZ+/gdesW4wgTARkrFWEpspjEATAzUGPG8N2jJiwbg==", "dev": true } } @@ -8821,8 +9286,8 @@ "integrity": "sha512-LwZy+p3SFs1Pytd/jYct4wpv49HiYCqd9Rlc5ZVdk0V+8Yzv6jR5Blk3TRmPL1ft69TxP0IMZGJ+WPFU2BFhww==", "dev": true, "requires": { - "end-of-stream": "1.4.1", - "once": "1.4.0" + "end-of-stream": "^1.1.0", + "once": "^1.3.1" } }, "pumpify": { @@ -8831,15 +9296,15 @@ "integrity": "sha512-oClZI37HvuUJJxSKKrC17bZ9Cu0ZYhEAGPsPUy9KlMUmv9dKX2o77RUmq7f3XjIxbwyGwYzbzQ1L2Ks8sIradQ==", "dev": true, "requires": { - "duplexify": "3.6.1", - "inherits": "2.0.3", - "pump": "2.0.1" + "duplexify": "^3.6.0", + "inherits": "^2.0.3", + "pump": "^2.0.0" }, "dependencies": { "inherits": { - "version": "2.0.3", - "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.3.tgz", - "integrity": "sha1-Yzwsg+PaQqUC9SRmAiSA9CCCYd4=", + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.4.tgz", + "integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==", "dev": true }, "pump": { @@ -8848,8 +9313,8 @@ "integrity": "sha512-ruPMNRkN3MHP1cWJc9OWr+T/xDP0jhXYCLfJcBuX54hhfIBnaQmAUMfDcG4DM5UMWByBbJY69QSphm3jtDKIkA==", "dev": true, "requires": { - "end-of-stream": "1.4.1", - "once": "1.4.0" + "end-of-stream": "^1.1.0", + "once": "^1.3.1" } } } @@ -8867,14 +9332,6 @@ "dev": true, "optional": true }, - "query-string": { - "version": "3.0.3", - "resolved": "https://registry.npmjs.org/query-string/-/query-string-3.0.3.tgz", - "integrity": "sha1-ri4UtNBQcdTpuetIc8NbDc1C5jg=", - "requires": { - "strict-uri-encode": "1.1.0" - } - }, "querystring": { "version": "0.2.0", "resolved": "https://registry.npmjs.org/querystring/-/querystring-0.2.0.tgz", @@ -8888,12 +9345,12 @@ "dev": true }, "randombytes": { - "version": "2.0.6", - "resolved": "https://registry.npmjs.org/randombytes/-/randombytes-2.0.6.tgz", - "integrity": "sha512-CIQ5OFxf4Jou6uOKe9t1AOgqpeU5fd70A8NPdHSGeYXqXsPe6peOwI0cUl88RWZ6sP1vPMV3avd/R6cZ5/sP1A==", + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/randombytes/-/randombytes-2.1.0.tgz", + "integrity": "sha512-vYl3iOX+4CKUWuxGi9Ukhie6fsqXqS9FE2Zaic4tNFD2N2QQaXOMFbuKK4QmDHC0JO6B1Zp41J0LpT0oR68amQ==", "dev": true, "requires": { - "safe-buffer": "5.1.1" + "safe-buffer": "^5.1.0" } }, "randomfill": { @@ -8902,72 +9359,132 @@ "integrity": "sha512-87lcbR8+MhcWcUiQ+9e+Rwx8MyR2P7qnt15ynUlbm3TU/fjbgz4GsvfSUDTemtCCtVCqb4ZcEFlyPNTh9bBTLw==", "dev": true, "requires": { - "randombytes": "2.0.6", - "safe-buffer": "5.1.1" + "randombytes": "^2.0.5", + "safe-buffer": "^5.1.0" } }, "range-parser": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/range-parser/-/range-parser-1.2.0.tgz", - "integrity": "sha1-9JvmtIeJTdxA3MlKMi9hEJLgDV4=", + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/range-parser/-/range-parser-1.2.1.tgz", + "integrity": "sha512-Hrgsx+orqoygnmhFbKaHE6c296J+HTAQXoxEF6gNupROmmGJRoyzfG3ccAveqCBrwr/2yxQ5BVd/GTl5agOwSg==", "dev": true }, "raw-body": { - "version": "2.3.3", - "resolved": "https://registry.npmjs.org/raw-body/-/raw-body-2.3.3.tgz", - "integrity": "sha512-9esiElv1BrZoI3rCDuOuKCBRbuApGGaDPQfjSflGxdy4oyzqghxu6klEkkVIvBje+FF0BX9coEv8KqW6X/7njw==", + "version": "2.4.0", + "resolved": "https://registry.npmjs.org/raw-body/-/raw-body-2.4.0.tgz", + "integrity": "sha512-4Oz8DUIwdvoa5qMJelxipzi/iJIi40O5cGV1wNYp5hvZP8ZN0T+jiNkL0QepXs+EsQ9XJ8ipEDoiH70ySUJP3Q==", "dev": true, "requires": { - "bytes": "3.0.0", - "http-errors": "1.6.3", - "iconv-lite": "0.4.23", + "bytes": "3.1.0", + "http-errors": "1.7.2", + "iconv-lite": "0.4.24", "unpipe": "1.0.0" }, "dependencies": { + "bytes": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/bytes/-/bytes-3.1.0.tgz", + "integrity": "sha512-zauLjrfCG+xvoyaqLoV8bLVXXNGC4JqlxFCutSDWA6fJrTo2ZuvLYTqZ7aHBLZSMOopbzwv8f+wZcVzfVTI2Dg==", + "dev": true + }, "iconv-lite": { - "version": "0.4.23", - "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.4.23.tgz", - "integrity": "sha512-neyTUVFtahjf0mB3dZT77u+8O0QB89jFdnBkd5P1JgYPbPaia3gXXOVL2fq8VyU2gMMD7SaN7QukTB/pmXYvDA==", + "version": "0.4.24", + "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.4.24.tgz", + "integrity": "sha512-v3MXnZAcvnywkTUEZomIActle7RXXeedOR31wwl7VlyoXO4Qi9arvSenNQWne1TcRwhCL1HwLI21bEqdpj8/rA==", "dev": true, "requires": { - "safer-buffer": "2.1.2" + "safer-buffer": ">= 2.1.2 < 3" } } } }, "react": { - "version": "15.4.2", - "resolved": "https://registry.npmjs.org/react/-/react-15.4.2.tgz", - "integrity": "sha1-QfeZGyYYU5K6m66WyIiefgGDl+8=", + "version": "16.8.6", + "resolved": "https://registry.npmjs.org/react/-/react-16.8.6.tgz", + "integrity": "sha512-pC0uMkhLaHm11ZSJULfOBqV4tIZkx87ZLvbbQYunNixAAvjnC+snJCg0XQXn9VIsttVsbZP/H/ewzgsd5fxKXw==", "requires": { - "fbjs": "0.8.16", - "loose-envify": "1.3.1", - "object-assign": "4.1.1" + "loose-envify": "^1.1.0", + "object-assign": "^4.1.1", + "prop-types": "^15.6.2", + "scheduler": "^0.13.6" + }, + "dependencies": { + "prop-types": { + "version": "15.7.2", + "resolved": "https://registry.npmjs.org/prop-types/-/prop-types-15.7.2.tgz", + "integrity": "sha512-8QQikdH7//R2vurIJSutZ1smHYTcLpRWEOlHnzcWHmBYrOGUysKwSsrC89BCiFj3CbrfJ/nXFdJepOVrY1GCHQ==", + "requires": { + "loose-envify": "^1.4.0", + "object-assign": "^4.1.1", + "react-is": "^16.8.1" + }, + "dependencies": { + "loose-envify": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/loose-envify/-/loose-envify-1.4.0.tgz", + "integrity": "sha512-lyuxPGr/Wfhrlem2CL/UcnUc1zcqKAImBDzukY7Y5F/yQiNdko6+fRLevlw1HgMySw7f611UIY408EtxRSoK3Q==", + "requires": { + "js-tokens": "^3.0.0 || ^4.0.0" + } + } + } + } } }, "react-addons-pure-render-mixin": { - "version": "15.4.2", - "resolved": "https://registry.npmjs.org/react-addons-pure-render-mixin/-/react-addons-pure-render-mixin-15.4.2.tgz", - "integrity": "sha1-qEM8ccReI2hQNyGSHcR72vH7q80=", + "version": "15.6.2", + "resolved": "https://registry.npmjs.org/react-addons-pure-render-mixin/-/react-addons-pure-render-mixin-15.6.2.tgz", + "integrity": "sha1-a4P0C2s27kBzXL1hJes/E84c3ck=", "requires": { - "fbjs": "0.8.16", - "object-assign": "4.1.1" + "fbjs": "^0.8.4", + "object-assign": "^4.1.0" } }, "react-dom": { - "version": "15.4.2", - "resolved": "https://registry.npmjs.org/react-dom/-/react-dom-15.4.2.tgz", - "integrity": "sha1-AVNj8FsKH9Uq6e/dOgBg2QaVII8=", + "version": "16.8.6", + "resolved": "https://registry.npmjs.org/react-dom/-/react-dom-16.8.6.tgz", + "integrity": "sha512-1nL7PIq9LTL3fthPqwkvr2zY7phIPjYrT0jp4HjyEQrEROnw4dG41VVwi/wfoCneoleqrNX7iAD+pXebJZwrwA==", "requires": { - "fbjs": "0.8.16", - "loose-envify": "1.3.1", - "object-assign": "4.1.1" + "loose-envify": "^1.1.0", + "object-assign": "^4.1.1", + "prop-types": "^15.6.2", + "scheduler": "^0.13.6" + }, + "dependencies": { + "prop-types": { + "version": "15.7.2", + "resolved": "https://registry.npmjs.org/prop-types/-/prop-types-15.7.2.tgz", + "integrity": "sha512-8QQikdH7//R2vurIJSutZ1smHYTcLpRWEOlHnzcWHmBYrOGUysKwSsrC89BCiFj3CbrfJ/nXFdJepOVrY1GCHQ==", + "requires": { + "loose-envify": "^1.4.0", + "object-assign": "^4.1.1", + "react-is": "^16.8.1" + }, + "dependencies": { + "loose-envify": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/loose-envify/-/loose-envify-1.4.0.tgz", + "integrity": "sha512-lyuxPGr/Wfhrlem2CL/UcnUc1zcqKAImBDzukY7Y5F/yQiNdko6+fRLevlw1HgMySw7f611UIY408EtxRSoK3Q==", + "requires": { + "js-tokens": "^3.0.0 || ^4.0.0" + } + } + } + } } }, "react-interval": { - "version": "1.3.3", - "resolved": "https://registry.npmjs.org/react-interval/-/react-interval-1.3.3.tgz", - "integrity": "sha1-YYngODcM7yNvrpdcYcZn0YUGDp4=" + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/react-interval/-/react-interval-2.1.0.tgz", + "integrity": "sha512-f5s/UUcA+HSPy6OHPTXGLbiX0l2iLrv6Ca5xTM/YT/+ycApAQrB9hL6ZK2kDXV/Gd8RcaDpuXq29W+8bSAbC8g==", + "requires": { + "prop-types": "^15.6.0" + } + }, + "react-is": { + "version": "16.8.6", + "resolved": "https://registry.npmjs.org/react-is/-/react-is-16.8.6.tgz", + "integrity": "sha512-aUk3bHfZ2bRSVFFbbeVS4i+lNPZr3/WM5jT2J5omUVV1zzcs1nAaf3l51ctA5FFvCRbhrH0bdAsRRQddFJZPtA==" }, "react-json-pretty": { "version": "1.5.0", @@ -8979,20 +9496,97 @@ "resolved": "https://registry.npmjs.org/react-measure/-/react-measure-1.4.7.tgz", "integrity": "sha1-odLKDc/vBJeLesJjp2XctqCTb9s=", "requires": { - "get-node-dimensions": "1.2.1", - "prop-types": "15.6.1", - "resize-observer-polyfill": "1.5.0" + "get-node-dimensions": "^1.2.0", + "prop-types": "^15.5.4", + "resize-observer-polyfill": "^1.4.1" } }, "react-router": { - "version": "2.4.1", - "resolved": "https://registry.npmjs.org/react-router/-/react-router-2.4.1.tgz", - "integrity": "sha1-uugVzXS5xRIZLZ0XoSdvVGJXR3U=", + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/react-router/-/react-router-5.0.1.tgz", + "integrity": "sha512-EM7suCPNKb1NxcTZ2LEOWFtQBQRQXecLxVpdsP4DW4PbbqYWeRiLyV/Tt1SdCrvT2jcyXAXmVTmzvSzrPR63Bg==", + "requires": { + "@babel/runtime": "^7.1.2", + "history": "^4.9.0", + "hoist-non-react-statics": "^3.1.0", + "loose-envify": "^1.3.1", + "mini-create-react-context": "^0.3.0", + "path-to-regexp": "^1.7.0", + "prop-types": "^15.6.2", + "react-is": "^16.6.0", + "tiny-invariant": "^1.0.2", + "tiny-warning": "^1.0.0" + }, + "dependencies": { + "isarray": { + "version": "0.0.1", + "resolved": "https://registry.npmjs.org/isarray/-/isarray-0.0.1.tgz", + "integrity": "sha1-ihis/Kmo9Bd+Cav8YDiTmwXR7t8=" + }, + "path-to-regexp": { + "version": "1.7.0", + "resolved": "https://registry.npmjs.org/path-to-regexp/-/path-to-regexp-1.7.0.tgz", + "integrity": "sha1-Wf3g9DW62suhA6hOnTvGTpa5k30=", + "requires": { + "isarray": "0.0.1" + } + }, + "prop-types": { + "version": "15.7.2", + "resolved": "https://registry.npmjs.org/prop-types/-/prop-types-15.7.2.tgz", + "integrity": "sha512-8QQikdH7//R2vurIJSutZ1smHYTcLpRWEOlHnzcWHmBYrOGUysKwSsrC89BCiFj3CbrfJ/nXFdJepOVrY1GCHQ==", + "requires": { + "loose-envify": "^1.4.0", + "object-assign": "^4.1.1", + "react-is": "^16.8.1" + }, + "dependencies": { + "loose-envify": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/loose-envify/-/loose-envify-1.4.0.tgz", + "integrity": "sha512-lyuxPGr/Wfhrlem2CL/UcnUc1zcqKAImBDzukY7Y5F/yQiNdko6+fRLevlw1HgMySw7f611UIY408EtxRSoK3Q==", + "requires": { + "js-tokens": "^3.0.0 || ^4.0.0" + } + } + } + } + } + }, + "react-router-dom": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/react-router-dom/-/react-router-dom-5.0.1.tgz", + "integrity": "sha512-zaVHSy7NN0G91/Bz9GD4owex5+eop+KvgbxXsP/O+iW1/Ln+BrJ8QiIR5a6xNPtrdTvLkxqlDClx13QO1uB8CA==", "requires": { - "history": "2.1.2", - "hoist-non-react-statics": "1.2.0", - "invariant": "2.2.3", - "warning": "2.1.0" + "@babel/runtime": "^7.1.2", + "history": "^4.9.0", + "loose-envify": "^1.3.1", + "prop-types": "^15.6.2", + "react-router": "5.0.1", + "tiny-invariant": "^1.0.2", + "tiny-warning": "^1.0.0" + }, + "dependencies": { + "prop-types": { + "version": "15.7.2", + "resolved": "https://registry.npmjs.org/prop-types/-/prop-types-15.7.2.tgz", + "integrity": "sha512-8QQikdH7//R2vurIJSutZ1smHYTcLpRWEOlHnzcWHmBYrOGUysKwSsrC89BCiFj3CbrfJ/nXFdJepOVrY1GCHQ==", + "requires": { + "loose-envify": "^1.4.0", + "object-assign": "^4.1.1", + "react-is": "^16.8.1" + }, + "dependencies": { + "loose-envify": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/loose-envify/-/loose-envify-1.4.0.tgz", + "integrity": "sha512-lyuxPGr/Wfhrlem2CL/UcnUc1zcqKAImBDzukY7Y5F/yQiNdko6+fRLevlw1HgMySw7f611UIY408EtxRSoK3Q==", + "requires": { + "js-tokens": "^3.0.0 || ^4.0.0" + } + } + } + } } }, "read-pkg": { @@ -9000,9 +9594,9 @@ "resolved": "https://registry.npmjs.org/read-pkg/-/read-pkg-2.0.0.tgz", "integrity": "sha1-jvHAYjxqbbDcZxPEv6xGMysjaPg=", "requires": { - "load-json-file": "2.0.0", - "normalize-package-data": "2.4.0", - "path-type": "2.0.0" + "load-json-file": "^2.0.0", + "normalize-package-data": "^2.3.2", + "path-type": "^2.0.0" } }, "read-pkg-up": { @@ -9010,8 +9604,8 @@ "resolved": "https://registry.npmjs.org/read-pkg-up/-/read-pkg-up-2.0.0.tgz", "integrity": "sha1-a3KoBImE4MQeeVEP1en6mbO1Sb4=", "requires": { - "find-up": "2.1.0", - "read-pkg": "2.0.0" + "find-up": "^2.0.0", + "read-pkg": "^2.0.0" }, "dependencies": { "find-up": { @@ -9019,7 +9613,7 @@ "resolved": "https://registry.npmjs.org/find-up/-/find-up-2.1.0.tgz", "integrity": "sha1-RdG35QbHF93UgndaK3eSCjwMV6c=", "requires": { - "locate-path": "2.0.0" + "locate-path": "^2.0.0" } } } @@ -9029,13 +9623,13 @@ "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.5.tgz", "integrity": "sha1-tPhQA6k4y7bsvOKhJPsQEr0ag40=", "requires": { - "core-util-is": "1.0.2", - "inherits": "2.0.3", - "isarray": "1.0.0", - "process-nextick-args": "2.0.0", - "safe-buffer": "5.1.1", - "string_decoder": "1.0.3", - "util-deprecate": "1.0.2" + "core-util-is": "~1.0.0", + "inherits": "~2.0.3", + "isarray": "~1.0.0", + "process-nextick-args": "~2.0.0", + "safe-buffer": "~5.1.1", + "string_decoder": "~1.0.3", + "util-deprecate": "~1.0.1" }, "dependencies": { "inherits": { @@ -9051,354 +9645,99 @@ "integrity": "sha512-1JU/8q+VgFZyxwrJ+SVIOsh+KywWGpds3NTqikiKpDMZWScmAYyKIgqkO+ARvNWJfXeXR1zxz7aHF4u4CyH6vQ==", "dev": true, "requires": { - "graceful-fs": "4.1.11", - "micromatch": "3.1.10", - "readable-stream": "2.3.5" + "graceful-fs": "^4.1.11", + "micromatch": "^3.1.10", + "readable-stream": "^2.0.2" + } + }, + "redent": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/redent/-/redent-1.0.0.tgz", + "integrity": "sha1-z5Fqsf1fHxbfsggi3W7H9zDCr94=", + "dev": true, + "requires": { + "indent-string": "^2.1.0", + "strip-indent": "^1.0.1" + } + }, + "regenerate": { + "version": "1.3.3", + "resolved": "https://registry.npmjs.org/regenerate/-/regenerate-1.3.3.tgz", + "integrity": "sha1-DDNtOYBVPXVcObWGrjsgqknIK38=", + "dev": true + }, + "regenerate-unicode-properties": { + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/regenerate-unicode-properties/-/regenerate-unicode-properties-7.0.0.tgz", + "integrity": "sha512-s5NGghCE4itSlUS+0WUj88G6cfMVMmH8boTPNvABf8od+2dhT9WDlWu8n01raQAJZMOK8Ch6jSexaRO7swd6aw==", + "dev": true, + "requires": { + "regenerate": "^1.4.0" }, "dependencies": { - "arr-diff": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/arr-diff/-/arr-diff-4.0.0.tgz", - "integrity": "sha1-1kYQdP6/7HHn4VI1dhoyml3HxSA=", + "regenerate": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/regenerate/-/regenerate-1.4.0.tgz", + "integrity": "sha512-1G6jJVDWrt0rK99kBjvEtziZNCICAuvIPkSiUFIQxVP06RCVpq3dmDo2oi6ABpYaDYaTRr67BEhL8r1wgEZZKg==", "dev": true - }, - "array-unique": { - "version": "0.3.2", - "resolved": "https://registry.npmjs.org/array-unique/-/array-unique-0.3.2.tgz", - "integrity": "sha1-qJS3XUvE9s1nnvMkSp/Y9Gri1Cg=", - "dev": true - }, - "braces": { - "version": "2.3.2", - "resolved": "https://registry.npmjs.org/braces/-/braces-2.3.2.tgz", - "integrity": "sha512-aNdbnj9P8PjdXU4ybaWLK2IF3jc/EoDYbC7AazW6to3TRsfXxscC9UXOB5iDiEQrkyIbWp2SLQda4+QAa7nc3w==", - "dev": true, - "requires": { - "arr-flatten": "1.1.0", - "array-unique": "0.3.2", - "extend-shallow": "2.0.1", - "fill-range": "4.0.0", - "isobject": "3.0.1", - "repeat-element": "1.1.3", - "snapdragon": "0.8.2", - "snapdragon-node": "2.1.1", - "split-string": "3.1.0", - "to-regex": "3.0.2" - }, - "dependencies": { - "extend-shallow": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz", - "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=", - "dev": true, - "requires": { - "is-extendable": "0.1.1" - } - } - } - }, - "expand-brackets": { - "version": "2.1.4", - "resolved": "https://registry.npmjs.org/expand-brackets/-/expand-brackets-2.1.4.tgz", - "integrity": "sha1-t3c14xXOMPa27/D4OwQVGiJEliI=", - "dev": true, - "requires": { - "debug": "2.6.9", - "define-property": "0.2.5", - "extend-shallow": "2.0.1", - "posix-character-classes": "0.1.1", - "regex-not": "1.0.2", - "snapdragon": "0.8.2", - "to-regex": "3.0.2" - }, - "dependencies": { - "define-property": { - "version": "0.2.5", - "resolved": "https://registry.npmjs.org/define-property/-/define-property-0.2.5.tgz", - "integrity": "sha1-w1se+RjsPJkPmlvFe+BKrOxcgRY=", - "dev": true, - "requires": { - "is-descriptor": "0.1.6" - } - }, - "extend-shallow": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz", - "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=", - "dev": true, - "requires": { - "is-extendable": "0.1.1" - } - }, - "is-accessor-descriptor": { - "version": "0.1.6", - "resolved": "https://registry.npmjs.org/is-accessor-descriptor/-/is-accessor-descriptor-0.1.6.tgz", - "integrity": "sha1-qeEss66Nh2cn7u84Q/igiXtcmNY=", - "dev": true, - "requires": { - "kind-of": "3.2.2" - }, - "dependencies": { - "kind-of": { - "version": "3.2.2", - "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", - "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=", - "dev": true, - "requires": { - "is-buffer": "1.1.6" - } - } - } - }, - "is-data-descriptor": { - "version": "0.1.4", - "resolved": "https://registry.npmjs.org/is-data-descriptor/-/is-data-descriptor-0.1.4.tgz", - "integrity": "sha1-C17mSDiOLIYCgueT8YVv7D8wG1Y=", - "dev": true, - "requires": { - "kind-of": "3.2.2" - }, - "dependencies": { - "kind-of": { - "version": "3.2.2", - "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", - "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=", - "dev": true, - "requires": { - "is-buffer": "1.1.6" - } - } - } - }, - "is-descriptor": { - "version": "0.1.6", - "resolved": "https://registry.npmjs.org/is-descriptor/-/is-descriptor-0.1.6.tgz", - "integrity": "sha512-avDYr0SB3DwO9zsMov0gKCESFYqCnE4hq/4z3TdUlukEy5t9C0YRq7HLrsN52NAcqXKaepeCD0n+B0arnVG3Hg==", - "dev": true, - "requires": { - "is-accessor-descriptor": "0.1.6", - "is-data-descriptor": "0.1.4", - "kind-of": "5.1.0" - } - }, - "kind-of": { - "version": "5.1.0", - "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-5.1.0.tgz", - "integrity": "sha512-NGEErnH6F2vUuXDh+OlbcKW7/wOcfdRHaZ7VWtqCztfHri/++YKmP51OdWeGPuqCOba6kk2OTe5d02VmTB80Pw==", - "dev": true - } - } - }, - "extglob": { - "version": "2.0.4", - "resolved": "https://registry.npmjs.org/extglob/-/extglob-2.0.4.tgz", - "integrity": "sha512-Nmb6QXkELsuBr24CJSkilo6UHHgbekK5UiZgfE6UHD3Eb27YC6oD+bhcT+tJ6cl8dmsgdQxnWlcry8ksBIBLpw==", - "dev": true, - "requires": { - "array-unique": "0.3.2", - "define-property": "1.0.0", - "expand-brackets": "2.1.4", - "extend-shallow": "2.0.1", - "fragment-cache": "0.2.1", - "regex-not": "1.0.2", - "snapdragon": "0.8.2", - "to-regex": "3.0.2" - }, - "dependencies": { - "define-property": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/define-property/-/define-property-1.0.0.tgz", - "integrity": "sha1-dp66rz9KY6rTr56NMEybvnm/sOY=", - "dev": true, - "requires": { - "is-descriptor": "1.0.2" - } - }, - "extend-shallow": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz", - "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=", - "dev": true, - "requires": { - "is-extendable": "0.1.1" - } - } - } - }, - "fill-range": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-4.0.0.tgz", - "integrity": "sha1-1USBHUKPmOsGpj3EAtJAPDKMOPc=", - "dev": true, - "requires": { - "extend-shallow": "2.0.1", - "is-number": "3.0.0", - "repeat-string": "1.6.1", - "to-regex-range": "2.1.1" - }, - "dependencies": { - "extend-shallow": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz", - "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=", - "dev": true, - "requires": { - "is-extendable": "0.1.1" - } - } - } - }, - "is-accessor-descriptor": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/is-accessor-descriptor/-/is-accessor-descriptor-1.0.0.tgz", - "integrity": "sha512-m5hnHTkcVsPfqx3AKlyttIPb7J+XykHvJP2B9bZDjlhLIoEq4XoK64Vg7boZlVWYK6LUY94dYPEE7Lh0ZkZKcQ==", - "dev": true, - "requires": { - "kind-of": "6.0.2" - } - }, - "is-data-descriptor": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/is-data-descriptor/-/is-data-descriptor-1.0.0.tgz", - "integrity": "sha512-jbRXy1FmtAoCjQkVmIVYwuuqDFUbaOeDjmed1tOGPrsMhtJA4rD9tkgA0F1qJ3gRFRXcHYVkdeaP50Q5rE/jLQ==", - "dev": true, - "requires": { - "kind-of": "6.0.2" - } - }, - "is-descriptor": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/is-descriptor/-/is-descriptor-1.0.2.tgz", - "integrity": "sha512-2eis5WqQGV7peooDyLmNEPUrps9+SXX5c9pL3xEB+4e9HnGuDa7mB7kHxHw4CbqS9k1T2hOH3miL8n8WtiYVtg==", - "dev": true, - "requires": { - "is-accessor-descriptor": "1.0.0", - "is-data-descriptor": "1.0.0", - "kind-of": "6.0.2" - } - }, - "is-number": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/is-number/-/is-number-3.0.0.tgz", - "integrity": "sha1-JP1iAaR4LPUFYcgQJ2r8fRLXEZU=", - "dev": true, - "requires": { - "kind-of": "3.2.2" - }, - "dependencies": { - "kind-of": { - "version": "3.2.2", - "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", - "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=", - "dev": true, - "requires": { - "is-buffer": "1.1.6" - } - } - } - }, - "micromatch": { - "version": "3.1.10", - "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-3.1.10.tgz", - "integrity": "sha512-MWikgl9n9M3w+bpsY3He8L+w9eF9338xRl8IAO5viDizwSzziFEyUzo2xrrloB64ADbTf8uA8vRqqttDTOmccg==", - "dev": true, - "requires": { - "arr-diff": "4.0.0", - "array-unique": "0.3.2", - "braces": "2.3.2", - "define-property": "2.0.2", - "extend-shallow": "3.0.2", - "extglob": "2.0.4", - "fragment-cache": "0.2.1", - "kind-of": "6.0.2", - "nanomatch": "1.2.13", - "object.pick": "1.3.0", - "regex-not": "1.0.2", - "snapdragon": "0.8.2", - "to-regex": "3.0.2" - } - } - } - }, - "redent": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/redent/-/redent-1.0.0.tgz", - "integrity": "sha1-z5Fqsf1fHxbfsggi3W7H9zDCr94=", - "dev": true, - "requires": { - "indent-string": "2.1.0", - "strip-indent": "1.0.1" - } - }, - "regenerate": { - "version": "1.3.3", - "resolved": "https://registry.npmjs.org/regenerate/-/regenerate-1.3.3.tgz", - "integrity": "sha1-DDNtOYBVPXVcObWGrjsgqknIK38=", - "dev": true - }, - "regenerate-unicode-properties": { - "version": "7.0.0", - "resolved": "https://registry.npmjs.org/regenerate-unicode-properties/-/regenerate-unicode-properties-7.0.0.tgz", - "integrity": "sha512-s5NGghCE4itSlUS+0WUj88G6cfMVMmH8boTPNvABf8od+2dhT9WDlWu8n01raQAJZMOK8Ch6jSexaRO7swd6aw==", - "dev": true, - "requires": { - "regenerate": "1.4.0" - }, - "dependencies": { - "regenerate": { - "version": "1.4.0", - "resolved": "https://registry.npmjs.org/regenerate/-/regenerate-1.4.0.tgz", - "integrity": "sha512-1G6jJVDWrt0rK99kBjvEtziZNCICAuvIPkSiUFIQxVP06RCVpq3dmDo2oi6ABpYaDYaTRr67BEhL8r1wgEZZKg==", - "dev": true - } - } - }, - "regenerator-runtime": { - "version": "0.12.1", - "resolved": "https://registry.npmjs.org/regenerator-runtime/-/regenerator-runtime-0.12.1.tgz", - "integrity": "sha512-odxIc1/vDlo4iZcfXqRYFj0vpXFNoGdKMAUieAlFYO6m/nl5e9KR/beGf41z4a1FI+aQgtjhuaSlDxQ0hmkrHg==" - }, - "regex-not": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/regex-not/-/regex-not-1.0.2.tgz", - "integrity": "sha512-J6SDjUgDxQj5NusnOtdFxDwN/+HWykR8GELwctJ7mdqhcyy1xEc4SRFHUXvxTp661YaVKAjfRLZ9cCqS6tn32A==", - "dev": true, - "requires": { - "extend-shallow": "3.0.2", - "safe-regex": "1.1.0" - } - }, - "regex-parser": { - "version": "2.2.10", - "resolved": "https://registry.npmjs.org/regex-parser/-/regex-parser-2.2.10.tgz", - "integrity": "sha512-8t6074A68gHfU8Neftl0Le6KTDwfGAj7IyjPIMSfikI2wJUTHDMaIq42bUsfVnj8mhx0R+45rdUXHGpN164avA==", - "dev": true - }, - "regexpp": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/regexpp/-/regexpp-2.0.1.tgz", - "integrity": "sha512-lv0M6+TkDVniA3aD1Eg0DVpfU/booSu7Eev3TDO/mZKHBfVjgCGTV4t4buppESEYDtkArYFOxTJWv6S5C+iaNw==", - "dev": true - }, - "regjsgen": { - "version": "0.2.0", - "resolved": "https://registry.npmjs.org/regjsgen/-/regjsgen-0.2.0.tgz", - "integrity": "sha1-bAFq3qxVT3WCP+N6wFuS1aTtsfc=", - "dev": true - }, - "regjsparser": { - "version": "0.1.5", - "resolved": "https://registry.npmjs.org/regjsparser/-/regjsparser-0.1.5.tgz", - "integrity": "sha1-fuj4Tcb6eS0/0K4ijSS9lJ6tIFw=", - "dev": true, - "requires": { - "jsesc": "0.5.0" - }, - "dependencies": { - "jsesc": { - "version": "0.5.0", - "resolved": "https://registry.npmjs.org/jsesc/-/jsesc-0.5.0.tgz", - "integrity": "sha1-597mbjXW/Bb3EP6R1c9p9w8IkR0=", + } + } + }, + "regenerator-runtime": { + "version": "0.12.1", + "resolved": "https://registry.npmjs.org/regenerator-runtime/-/regenerator-runtime-0.12.1.tgz", + "integrity": "sha512-odxIc1/vDlo4iZcfXqRYFj0vpXFNoGdKMAUieAlFYO6m/nl5e9KR/beGf41z4a1FI+aQgtjhuaSlDxQ0hmkrHg==" + }, + "regex-not": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/regex-not/-/regex-not-1.0.2.tgz", + "integrity": "sha512-J6SDjUgDxQj5NusnOtdFxDwN/+HWykR8GELwctJ7mdqhcyy1xEc4SRFHUXvxTp661YaVKAjfRLZ9cCqS6tn32A==", + "dev": true, + "requires": { + "extend-shallow": "^3.0.2", + "safe-regex": "^1.1.0" + } + }, + "regex-parser": { + "version": "2.2.10", + "resolved": "https://registry.npmjs.org/regex-parser/-/regex-parser-2.2.10.tgz", + "integrity": "sha512-8t6074A68gHfU8Neftl0Le6KTDwfGAj7IyjPIMSfikI2wJUTHDMaIq42bUsfVnj8mhx0R+45rdUXHGpN164avA==", + "dev": true + }, + "regexp.prototype.flags": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/regexp.prototype.flags/-/regexp.prototype.flags-1.2.0.tgz", + "integrity": "sha512-ztaw4M1VqgMwl9HlPpOuiYgItcHlunW0He2fE6eNfT6E/CF2FtYi9ofOYe4mKntstYk0Fyh/rDRBdS3AnxjlrA==", + "dev": true, + "requires": { + "define-properties": "^1.1.2" + } + }, + "regexpp": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/regexpp/-/regexpp-2.0.1.tgz", + "integrity": "sha512-lv0M6+TkDVniA3aD1Eg0DVpfU/booSu7Eev3TDO/mZKHBfVjgCGTV4t4buppESEYDtkArYFOxTJWv6S5C+iaNw==", + "dev": true + }, + "regjsgen": { + "version": "0.2.0", + "resolved": "https://registry.npmjs.org/regjsgen/-/regjsgen-0.2.0.tgz", + "integrity": "sha1-bAFq3qxVT3WCP+N6wFuS1aTtsfc=", + "dev": true + }, + "regjsparser": { + "version": "0.1.5", + "resolved": "https://registry.npmjs.org/regjsparser/-/regjsparser-0.1.5.tgz", + "integrity": "sha1-fuj4Tcb6eS0/0K4ijSS9lJ6tIFw=", + "dev": true, + "requires": { + "jsesc": "~0.5.0" + }, + "dependencies": { + "jsesc": { + "version": "0.5.0", + "resolved": "https://registry.npmjs.org/jsesc/-/jsesc-0.5.0.tgz", + "integrity": "sha1-597mbjXW/Bb3EP6R1c9p9w8IkR0=", "dev": true } } @@ -9421,11 +9760,11 @@ "integrity": "sha512-FsygIxevi1jSiPY9h7vZmBFUbAOcbYm9UwyiLNdVsLRs/5We9Ob5NMPbGYUTWiLq5L+ezlVdE0A8bbME5CWTpg==", "dev": true, "requires": { - "css-select": "1.2.0", - "dom-converter": "0.2.0", - "htmlparser2": "3.3.0", - "strip-ansi": "3.0.1", - "utila": "0.4.0" + "css-select": "^1.1.0", + "dom-converter": "~0.2", + "htmlparser2": "~3.3.0", + "strip-ansi": "^3.0.0", + "utila": "^0.4.0" } }, "repeat-element": { @@ -9446,7 +9785,7 @@ "integrity": "sha1-UhTFOpJtNVJwdSf7q0FdvAjQbdo=", "dev": true, "requires": { - "is-finite": "1.0.2" + "is-finite": "^1.0.0" } }, "request": { @@ -9456,28 +9795,28 @@ "dev": true, "optional": true, "requires": { - "aws-sign2": "0.7.0", - "aws4": "1.6.0", - "caseless": "0.12.0", - "combined-stream": "1.0.6", - "extend": "3.0.2", - "forever-agent": "0.6.1", - "form-data": "2.3.2", - "har-validator": "5.0.3", - "hawk": "6.0.2", - "http-signature": "1.2.0", - "is-typedarray": "1.0.0", - "isstream": "0.1.2", - "json-stringify-safe": "5.0.1", - "mime-types": "2.1.18", - "oauth-sign": "0.8.2", - "performance-now": "2.1.0", - "qs": "6.5.1", - "safe-buffer": "5.1.1", - "stringstream": "0.0.5", - "tough-cookie": "2.3.4", - "tunnel-agent": "0.6.0", - "uuid": "3.2.1" + "aws-sign2": "~0.7.0", + "aws4": "^1.6.0", + "caseless": "~0.12.0", + "combined-stream": "~1.0.5", + "extend": "~3.0.1", + "forever-agent": "~0.6.1", + "form-data": "~2.3.1", + "har-validator": "~5.0.3", + "hawk": "~6.0.2", + "http-signature": "~1.2.0", + "is-typedarray": "~1.0.0", + "isstream": "~0.1.2", + "json-stringify-safe": "~5.0.1", + "mime-types": "~2.1.17", + "oauth-sign": "~0.8.2", + "performance-now": "^2.1.0", + "qs": "~6.5.1", + "safe-buffer": "^5.1.1", + "stringstream": "~0.0.5", + "tough-cookie": "~2.3.3", + "tunnel-agent": "^0.6.0", + "uuid": "^3.1.0" }, "dependencies": { "uuid": { @@ -9506,8 +9845,8 @@ "resolved": "https://registry.npmjs.org/require-uncached/-/require-uncached-1.0.3.tgz", "integrity": "sha1-Tg1W1slmL9MeQwEcS5WqSZVUIdM=", "requires": { - "caller-path": "0.1.0", - "resolve-from": "1.0.1" + "caller-path": "^0.1.0", + "resolve-from": "^1.0.0" } }, "requires-port": { @@ -9525,7 +9864,7 @@ "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.5.0.tgz", "integrity": "sha1-HwmsznlsmnYlefMbLBzEw83fnzY=", "requires": { - "path-parse": "1.0.5" + "path-parse": "^1.0.5" } }, "resolve-cwd": { @@ -9534,7 +9873,7 @@ "integrity": "sha1-AKn3OHVW4nA46uIyyqNypqWbZlo=", "dev": true, "requires": { - "resolve-from": "3.0.0" + "resolve-from": "^3.0.0" }, "dependencies": { "resolve-from": { @@ -9551,8 +9890,21 @@ "integrity": "sha1-eaQGRMNivoLybv/nOcm7U4IEb0M=", "dev": true, "requires": { - "expand-tilde": "2.0.2", - "global-modules": "1.0.0" + "expand-tilde": "^2.0.0", + "global-modules": "^1.0.0" + }, + "dependencies": { + "global-modules": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/global-modules/-/global-modules-1.0.0.tgz", + "integrity": "sha512-sKzpEkf11GpOFuw0Zzjzmt4B4UZwjOcG757PPvrfhxcLFbq0wpsgpOqxpxtxFiCG4DtG93M6XRVbF2oGdev7bg==", + "dev": true, + "requires": { + "global-prefix": "^1.0.1", + "is-windows": "^1.0.1", + "resolve-dir": "^1.0.0" + } + } } }, "resolve-from": { @@ -9560,6 +9912,11 @@ "resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-1.0.1.tgz", "integrity": "sha1-Jsv+k10a7uq7Kbw/5a6wHpPUQiY=" }, + "resolve-pathname": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/resolve-pathname/-/resolve-pathname-2.2.0.tgz", + "integrity": "sha512-bAFz9ld18RzJfddgrO2e/0S2O81710++chRMUxHjXOYKF6jTAMrUNZrEZ1PvV0zlhfjidm08iRPdTLPno1FuRg==" + }, "resolve-url": { "version": "0.2.1", "resolved": "https://registry.npmjs.org/resolve-url/-/resolve-url-0.2.1.tgz", @@ -9572,15 +9929,15 @@ "integrity": "sha512-tpt4A/tOT8jxRDa91RbBV4c22AGj+WllOxT8rYSYhT2XDdL33Nca9HudwVx4mvP9PLokz+wpCu44tWUGVMYYLA==", "dev": true, "requires": { - "adjust-sourcemap-loader": "1.2.0", - "camelcase": "4.1.0", - "convert-source-map": "1.5.1", - "loader-utils": "1.2.3", - "lodash.defaults": "4.2.0", - "rework": "1.0.1", - "rework-visit": "1.0.0", - "source-map": "0.5.7", - "urix": "0.1.0" + "adjust-sourcemap-loader": "^1.1.0", + "camelcase": "^4.1.0", + "convert-source-map": "^1.5.1", + "loader-utils": "^1.1.0", + "lodash.defaults": "^4.0.0", + "rework": "^1.0.1", + "rework-visit": "^1.0.0", + "source-map": "^0.5.7", + "urix": "^0.1.0" }, "dependencies": { "big.js": { @@ -9601,7 +9958,7 @@ "integrity": "sha512-aKS4WQjPenRxiQsC93MNfjx+nbF4PAdYzmd/1JIj8HYzqfbu86beTuNgXDzPknWk0n0uARlyewZo4s++ES36Ow==", "dev": true, "requires": { - "minimist": "1.2.0" + "minimist": "^1.2.0" } }, "loader-utils": { @@ -9610,9 +9967,9 @@ "integrity": "sha512-fkpz8ejdnEMG3s37wGL07iSBDg99O9D5yflE9RGNH3hRdx9SOwYfnGYdZOUIZitN8E+E2vkq3MUMYMvPYl5ZZA==", "dev": true, "requires": { - "big.js": "5.2.2", - "emojis-list": "2.1.0", - "json5": "1.0.1" + "big.js": "^5.2.2", + "emojis-list": "^2.0.0", + "json5": "^1.0.1" } }, "minimist": { @@ -9628,8 +9985,8 @@ "resolved": "https://registry.npmjs.org/restore-cursor/-/restore-cursor-2.0.0.tgz", "integrity": "sha1-n37ih/gv0ybU/RYpI9YhKe7g368=", "requires": { - "onetime": "2.0.1", - "signal-exit": "3.0.2" + "onetime": "^2.0.0", + "signal-exit": "^3.0.2" } }, "ret": { @@ -9638,14 +9995,20 @@ "integrity": "sha512-TTlYpa+OL+vMMNG24xSlQGEJ3B/RzEfUlLct7b5G/ytav+wPrplCpVMFuwzXbkecJrb6IYo1iFb0S9v37754mg==", "dev": true }, + "retry": { + "version": "0.12.0", + "resolved": "https://registry.npmjs.org/retry/-/retry-0.12.0.tgz", + "integrity": "sha1-G0KmJmoh8HQh0bC1S33BZ7AcATs=", + "dev": true + }, "rework": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/rework/-/rework-1.0.1.tgz", "integrity": "sha1-MIBqhBNCtUUQqkEQhQzUhTQUSqc=", "dev": true, "requires": { - "convert-source-map": "0.3.5", - "css": "2.2.4" + "convert-source-map": "^0.3.3", + "css": "^2.0.0" }, "dependencies": { "convert-source-map": { @@ -9667,7 +10030,17 @@ "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-2.6.2.tgz", "integrity": "sha1-LtgVDSShbqhlHm1u8PR8QVjOejY=", "requires": { - "glob": "7.1.2" + "glob": "^7.0.5" + } + }, + "ripemd160": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/ripemd160/-/ripemd160-2.0.2.tgz", + "integrity": "sha512-ii4iagi25WusVoiC4B4lq7pbXfAp3D9v5CwfkY33vffw2+pkDjY1D8GaN7spsxvCSx8dkPqOZCEZyfxcmJG2IA==", + "dev": true, + "requires": { + "hash-base": "^3.0.0", + "inherits": "^2.0.1" } }, "run-async": { @@ -9675,7 +10048,7 @@ "resolved": "https://registry.npmjs.org/run-async/-/run-async-2.3.0.tgz", "integrity": "sha1-A3GrSuC91yDUFm19/aZP96RFpsA=", "requires": { - "is-promise": "2.1.0" + "is-promise": "^2.1.0" } }, "run-parallel": { @@ -9689,7 +10062,7 @@ "integrity": "sha1-6Eg5bwV9Ij8kOGkkYY4laUFh7Ec=", "dev": true, "requires": { - "aproba": "1.2.0" + "aproba": "^1.1.1" } }, "rx-lite": { @@ -9702,7 +10075,7 @@ "resolved": "https://registry.npmjs.org/rx-lite-aggregates/-/rx-lite-aggregates-4.0.8.tgz", "integrity": "sha1-dTuHqJoRyVRnxKwWJsTvxOBcZ74=", "requires": { - "rx-lite": "4.0.8" + "rx-lite": "*" } }, "rxjs": { @@ -9725,7 +10098,7 @@ "integrity": "sha1-QKNmnzsHfR6UPURinhV91IAjvy4=", "dev": true, "requires": { - "ret": "0.1.15" + "ret": "~0.1.10" } }, "safer-buffer": { @@ -9740,10 +10113,10 @@ "integrity": "sha1-E/vWPNHK8JCLn9k0dq1DpR0eC0k=", "dev": true, "requires": { - "glob": "7.1.2", - "lodash": "4.17.11", - "scss-tokenizer": "0.2.3", - "yargs": "7.1.0" + "glob": "^7.0.0", + "lodash": "^4.0.0", + "scss-tokenizer": "^0.2.3", + "yargs": "^7.0.0" } }, "sass-loader": { @@ -9752,12 +10125,12 @@ "integrity": "sha512-+G+BKGglmZM2GUSfT9TLuEp6tzehHPjAMoRRItOojWIqIGPloVCMhNIQuG639eJ+y033PaGTSjLaTHts8Kw79w==", "dev": true, "requires": { - "clone-deep": "2.0.2", - "loader-utils": "1.2.3", - "lodash.tail": "4.1.1", - "neo-async": "2.5.0", - "pify": "3.0.0", - "semver": "5.5.0" + "clone-deep": "^2.0.1", + "loader-utils": "^1.0.1", + "lodash.tail": "^4.1.1", + "neo-async": "^2.5.0", + "pify": "^3.0.0", + "semver": "^5.5.0" }, "dependencies": { "big.js": { @@ -9772,7 +10145,7 @@ "integrity": "sha512-aKS4WQjPenRxiQsC93MNfjx+nbF4PAdYzmd/1JIj8HYzqfbu86beTuNgXDzPknWk0n0uARlyewZo4s++ES36Ow==", "dev": true, "requires": { - "minimist": "1.2.0" + "minimist": "^1.2.0" } }, "loader-utils": { @@ -9781,9 +10154,9 @@ "integrity": "sha512-fkpz8ejdnEMG3s37wGL07iSBDg99O9D5yflE9RGNH3hRdx9SOwYfnGYdZOUIZitN8E+E2vkq3MUMYMvPYl5ZZA==", "dev": true, "requires": { - "big.js": "5.2.2", - "emojis-list": "2.1.0", - "json5": "1.0.1" + "big.js": "^5.2.2", + "emojis-list": "^2.0.0", + "json5": "^1.0.1" } }, "minimist": { @@ -9800,32 +10173,42 @@ } } }, + "scheduler": { + "version": "0.13.6", + "resolved": "https://registry.npmjs.org/scheduler/-/scheduler-0.13.6.tgz", + "integrity": "sha512-IWnObHt413ucAYKsD9J1QShUKkbKLQQHdxRyw73sw4FN26iWr3DY/H34xGPe4nmL1DwXyWmSWmMrA9TfQbE/XQ==", + "requires": { + "loose-envify": "^1.1.0", + "object-assign": "^4.1.1" + } + }, "schema-utils": { - "version": "0.4.7", - "resolved": "https://registry.npmjs.org/schema-utils/-/schema-utils-0.4.7.tgz", - "integrity": "sha512-v/iwU6wvwGK8HbU9yi3/nhGzP0yGSuhQMzL6ySiec1FSrZZDkhm4noOSWzrNFo/jEc+SJY6jRTwuwbSXJPDUnQ==", + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/schema-utils/-/schema-utils-1.0.0.tgz", + "integrity": "sha512-i27Mic4KovM/lnGsy8whRCHhc7VicJajAjTrYg11K9zfZXnYIt4k5F+kZkwjnrhKzLic/HLU4j11mjsz2G/75g==", "dev": true, "requires": { - "ajv": "6.7.0", - "ajv-keywords": "3.2.0" + "ajv": "^6.1.0", + "ajv-errors": "^1.0.0", + "ajv-keywords": "^3.1.0" }, "dependencies": { "ajv": { - "version": "6.7.0", - "resolved": "https://registry.npmjs.org/ajv/-/ajv-6.7.0.tgz", - "integrity": "sha512-RZXPviBTtfmtka9n9sy1N5M5b82CbxWIR6HIis4s3WQTXDJamc/0gpCWNGz6EWdWp4DOfjzJfhz/AS9zVPjjWg==", + "version": "6.10.2", + "resolved": "https://registry.npmjs.org/ajv/-/ajv-6.10.2.tgz", + "integrity": "sha512-TXtUUEYHuaTEbLZWIKUr5pmBuhDLy+8KYtPYdcV8qC+pOZL+NKqYwvWSRrVXHn+ZmRRAu8vJTAznH7Oag6RVRw==", "dev": true, "requires": { - "fast-deep-equal": "2.0.1", - "fast-json-stable-stringify": "2.0.0", - "json-schema-traverse": "0.4.1", - "uri-js": "4.2.2" + "fast-deep-equal": "^2.0.1", + "fast-json-stable-stringify": "^2.0.0", + "json-schema-traverse": "^0.4.1", + "uri-js": "^4.2.2" } }, "ajv-keywords": { - "version": "3.2.0", - "resolved": "https://registry.npmjs.org/ajv-keywords/-/ajv-keywords-3.2.0.tgz", - "integrity": "sha1-6GuBnGAs+IIa1jdBNpjx3sAhhHo=", + "version": "3.4.1", + "resolved": "https://registry.npmjs.org/ajv-keywords/-/ajv-keywords-3.4.1.tgz", + "integrity": "sha512-RO1ibKvd27e6FEShVFfPALuHI3WjSVNeK5FIsmme/LYRNxjKuNj+Dt7bucLa6NdSv3JcVTyMlm9kGR84z1XpaQ==", "dev": true }, "fast-deep-equal": { @@ -9848,8 +10231,8 @@ "integrity": "sha1-jrBtualyMzOCTT9VMGQRSYR85dE=", "dev": true, "requires": { - "js-base64": "2.5.0", - "source-map": "0.4.4" + "js-base64": "^2.1.8", + "source-map": "^0.4.2" }, "dependencies": { "source-map": { @@ -9858,7 +10241,7 @@ "integrity": "sha1-66T12pwNyZneaAMti092FzZSA2s=", "dev": true, "requires": { - "amdefine": "1.0.1" + "amdefine": ">=0.0.4" } } } @@ -9870,12 +10253,12 @@ "dev": true }, "selfsigned": { - "version": "1.10.4", - "resolved": "https://registry.npmjs.org/selfsigned/-/selfsigned-1.10.4.tgz", - "integrity": "sha512-9AukTiDmHXGXWtWjembZ5NDmVvP2695EtpgbCsxCa68w3c88B+alqbmZ4O3hZ4VWGXeGWzEVdvqgAJD8DQPCDw==", + "version": "1.10.7", + "resolved": "https://registry.npmjs.org/selfsigned/-/selfsigned-1.10.7.tgz", + "integrity": "sha512-8M3wBCzeWIJnQfl43IKwOmC4H/RAp50S8DF60znzjW5GVqTcSe2vWclt7hmYVPkKPlHWOu5EaWOMZ2Y6W8ZXTA==", "dev": true, "requires": { - "node-forge": "0.7.5" + "node-forge": "0.9.0" } }, "semver": { @@ -9884,38 +10267,38 @@ "integrity": "sha1-3Eu8emyp2Rbe5dQ1FvAJK1j3uKs=" }, "send": { - "version": "0.16.2", - "resolved": "https://registry.npmjs.org/send/-/send-0.16.2.tgz", - "integrity": "sha1-bsyh4PjBVtFBWXVZhI32RzCmu8E=", + "version": "0.17.1", + "resolved": "https://registry.npmjs.org/send/-/send-0.17.1.tgz", + "integrity": "sha512-BsVKsiGcQMFwT8UxypobUKyv7irCNRHk1T0G680vk88yf6LBByGcZJOTJCrTP2xVN6yI+XjPJcNuE3V4fT9sAg==", "dev": true, "requires": { "debug": "2.6.9", - "depd": "1.1.2", - "destroy": "1.0.4", - "encodeurl": "1.0.2", - "escape-html": "1.0.3", - "etag": "1.8.1", + "depd": "~1.1.2", + "destroy": "~1.0.4", + "encodeurl": "~1.0.2", + "escape-html": "~1.0.3", + "etag": "~1.8.1", "fresh": "0.5.2", - "http-errors": "1.6.3", - "mime": "1.4.1", - "ms": "2.0.0", - "on-finished": "2.3.0", - "range-parser": "1.2.0", - "statuses": "1.4.0" + "http-errors": "~1.7.2", + "mime": "1.6.0", + "ms": "2.1.1", + "on-finished": "~2.3.0", + "range-parser": "~1.2.1", + "statuses": "~1.5.0" }, "dependencies": { - "mime": { - "version": "1.4.1", - "resolved": "https://registry.npmjs.org/mime/-/mime-1.4.1.tgz", - "integrity": "sha1-Eh+evEnjdm8xGnbh+hyAA8SwOqY=", + "ms": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.1.tgz", + "integrity": "sha512-tgp+dl5cGk28utYktBsrFqA7HKgrhgPsg6Z/EfhWI4gl1Hwq8B/GmY/0oXZ6nF8hDVesS/FpnYaD/kOWhYQvyg==", "dev": true } } }, "serialize-javascript": { - "version": "1.6.1", - "resolved": "https://registry.npmjs.org/serialize-javascript/-/serialize-javascript-1.6.1.tgz", - "integrity": "sha512-A5MOagrPFga4YaKQSWHryl7AXvbQkEqpw4NNYMTNYUNV51bA8ABHgYFpqKx+YFFrw59xMV1qGH1R4AgoNIVgCw==", + "version": "1.9.1", + "resolved": "https://registry.npmjs.org/serialize-javascript/-/serialize-javascript-1.9.1.tgz", + "integrity": "sha512-0Vb/54WJ6k5v8sSWN09S0ora+Hnr+cX40r9F170nT+mSkaxltoE/7R3OrIdBSUv1OoiobH1QoWQbCnAO+e8J1A==", "dev": true }, "serve-index": { @@ -9924,25 +10307,51 @@ "integrity": "sha1-03aNabHn2C5c4FD/9bRTvqEqkjk=", "dev": true, "requires": { - "accepts": "1.3.5", + "accepts": "~1.3.4", "batch": "0.6.1", "debug": "2.6.9", - "escape-html": "1.0.3", - "http-errors": "1.6.3", - "mime-types": "2.1.18", - "parseurl": "1.3.2" + "escape-html": "~1.0.3", + "http-errors": "~1.6.2", + "mime-types": "~2.1.17", + "parseurl": "~1.3.2" + }, + "dependencies": { + "http-errors": { + "version": "1.6.3", + "resolved": "https://registry.npmjs.org/http-errors/-/http-errors-1.6.3.tgz", + "integrity": "sha1-i1VoC7S+KDoLW/TqLjhYC+HZMg0=", + "dev": true, + "requires": { + "depd": "~1.1.2", + "inherits": "2.0.3", + "setprototypeof": "1.1.0", + "statuses": ">= 1.4.0 < 2" + } + }, + "inherits": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.3.tgz", + "integrity": "sha1-Yzwsg+PaQqUC9SRmAiSA9CCCYd4=", + "dev": true + }, + "setprototypeof": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/setprototypeof/-/setprototypeof-1.1.0.tgz", + "integrity": "sha512-BvE/TwpZX4FXExxOxZyRGQQv651MSwmWKZGqvmPcRIjDqWub67kTKuIMx43cZZrS/cBBzwBcNDWoFxt2XEFIpQ==", + "dev": true + } } }, "serve-static": { - "version": "1.13.2", - "resolved": "https://registry.npmjs.org/serve-static/-/serve-static-1.13.2.tgz", - "integrity": "sha1-CV6Ecv1bRiN9tQzkhqQ/S4bGzsE=", + "version": "1.14.1", + "resolved": "https://registry.npmjs.org/serve-static/-/serve-static-1.14.1.tgz", + "integrity": "sha512-JMrvUwE54emCYWlTI+hGrGv5I8dEwmco/00EvkzIIsR7MqrHonbD9pO2MOfFnpFntl7ecpZs+3mW+XbQZu9QCg==", "dev": true, "requires": { - "encodeurl": "1.0.2", - "escape-html": "1.0.3", - "parseurl": "1.3.2", - "send": "0.16.2" + "encodeurl": "~1.0.2", + "escape-html": "~1.0.3", + "parseurl": "~1.3.3", + "send": "0.17.1" } }, "set-blocking": { @@ -9952,15 +10361,15 @@ "dev": true }, "set-value": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/set-value/-/set-value-2.0.0.tgz", - "integrity": "sha512-hw0yxk9GT/Hr5yJEYnHNKYXkIA8mVJgd9ditYZCe16ZczcaELYYcfvaXesNACk2O8O0nTiPQcQhGUQj8JLzeeg==", + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/set-value/-/set-value-2.0.1.tgz", + "integrity": "sha512-JxHc1weCN68wRY0fhCoXpyK55m/XPHafOmK4UWD7m2CI14GMcFypt4w/0+NV5f/ZMby2F6S2wwA7fgynh9gWSw==", "dev": true, "requires": { - "extend-shallow": "2.0.1", - "is-extendable": "0.1.1", - "is-plain-object": "2.0.4", - "split-string": "3.1.0" + "extend-shallow": "^2.0.1", + "is-extendable": "^0.1.1", + "is-plain-object": "^2.0.3", + "split-string": "^3.0.1" }, "dependencies": { "extend-shallow": { @@ -9969,7 +10378,7 @@ "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=", "dev": true, "requires": { - "is-extendable": "0.1.1" + "is-extendable": "^0.1.0" } } } @@ -9980,20 +10389,30 @@ "integrity": "sha1-KQy7Iy4waULX1+qbg3Mqt4VvgoU=" }, "setprototypeof": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/setprototypeof/-/setprototypeof-1.1.0.tgz", - "integrity": "sha1-0L2FU2iHtv58DYGMuWLZ2RxU5lY=", + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/setprototypeof/-/setprototypeof-1.1.1.tgz", + "integrity": "sha512-JvdAWfbXeIGaZ9cILp38HntZSFSo3mWg6xGcJJsd+d4aRMOqauag1C63dJfDw7OaMYwEbHMOxEZ1lqVRYP2OAw==", "dev": true }, + "sha.js": { + "version": "2.4.11", + "resolved": "https://registry.npmjs.org/sha.js/-/sha.js-2.4.11.tgz", + "integrity": "sha512-QMEp5B7cftE7APOjk5Y6xgrbWu+WkLVQwk8JNjZ8nKRciZaByEW6MubieAiToS7+dwvrjGhH8jRXz3MVd0AYqQ==", + "dev": true, + "requires": { + "inherits": "^2.0.1", + "safe-buffer": "^5.0.1" + } + }, "shallow-clone": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/shallow-clone/-/shallow-clone-1.0.0.tgz", "integrity": "sha1-RIDNBuiC72iyrYij6lSDLixItXE=", "dev": true, "requires": { - "is-extendable": "0.1.1", - "kind-of": "5.1.0", - "mixin-object": "2.0.1" + "is-extendable": "^0.1.1", + "kind-of": "^5.0.0", + "mixin-object": "^2.0.1" }, "dependencies": { "kind-of": { @@ -10009,7 +10428,7 @@ "resolved": "https://registry.npmjs.org/shebang-command/-/shebang-command-1.2.0.tgz", "integrity": "sha1-RKrGW2lbAzmJaMOfNj/uXer98eo=", "requires": { - "shebang-regex": "1.0.0" + "shebang-regex": "^1.0.0" } }, "shebang-regex": { @@ -10033,7 +10452,7 @@ "resolved": "https://registry.npmjs.org/slice-ansi/-/slice-ansi-1.0.0.tgz", "integrity": "sha1-BE8aSdiEL/MHqta1Be0Xi9lQE00=", "requires": { - "is-fullwidth-code-point": "2.0.0" + "is-fullwidth-code-point": "^2.0.0" } }, "snapdragon": { @@ -10042,29 +10461,23 @@ "integrity": "sha512-FtyOnWN/wCHTVXOMwvSv26d+ko5vWlIDD6zoUJ7LW8vh+ZBC8QdljveRP+crNrtBwioEUWy/4dMtbBjA4ioNlg==", "dev": true, "requires": { - "base": "0.11.2", - "debug": "2.6.9", - "define-property": "0.2.5", - "extend-shallow": "2.0.1", - "map-cache": "0.2.2", - "source-map": "0.5.7", - "source-map-resolve": "0.5.2", - "use": "3.1.1" + "base": "^0.11.1", + "debug": "^2.2.0", + "define-property": "^0.2.5", + "extend-shallow": "^2.0.1", + "map-cache": "^0.2.2", + "source-map": "^0.5.6", + "source-map-resolve": "^0.5.0", + "use": "^3.1.0" }, "dependencies": { - "atob": { - "version": "2.1.2", - "resolved": "https://registry.npmjs.org/atob/-/atob-2.1.2.tgz", - "integrity": "sha512-Wm6ukoaOGJi/73p/cl2GvLjTI5JM1k/O14isD73YML8StrH/7/lRFgmg8nICZgD3bZZvjwCGxtMOD3wWNAu8cg==", - "dev": true - }, "define-property": { "version": "0.2.5", "resolved": "https://registry.npmjs.org/define-property/-/define-property-0.2.5.tgz", "integrity": "sha1-w1se+RjsPJkPmlvFe+BKrOxcgRY=", "dev": true, "requires": { - "is-descriptor": "0.1.6" + "is-descriptor": "^0.1.0" } }, "extend-shallow": { @@ -10073,27 +10486,8 @@ "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=", "dev": true, "requires": { - "is-extendable": "0.1.1" - } - }, - "source-map-resolve": { - "version": "0.5.2", - "resolved": "https://registry.npmjs.org/source-map-resolve/-/source-map-resolve-0.5.2.tgz", - "integrity": "sha512-MjqsvNwyz1s0k81Goz/9vRBe9SZdB09Bdw+/zYyO+3CuPk6fouTaxscHkgtE8jKvf01kVfl8riHzERQ/kefaSA==", - "dev": true, - "requires": { - "atob": "2.1.2", - "decode-uri-component": "0.2.0", - "resolve-url": "0.2.1", - "source-map-url": "0.4.0", - "urix": "0.1.0" + "is-extendable": "^0.1.0" } - }, - "source-map-url": { - "version": "0.4.0", - "resolved": "https://registry.npmjs.org/source-map-url/-/source-map-url-0.4.0.tgz", - "integrity": "sha1-PpNdfd1zYxuXZZlW1VEo6HtQhKM=", - "dev": true } } }, @@ -10103,9 +10497,9 @@ "integrity": "sha512-O27l4xaMYt/RSQ5TR3vpWCAB5Kb/czIcqUFOM/C4fYcLnbZUc1PkjTAMjof2pBWaSTwOUd6qUHcFGVGj7aIwnw==", "dev": true, "requires": { - "define-property": "1.0.0", - "isobject": "3.0.1", - "snapdragon-util": "3.0.1" + "define-property": "^1.0.0", + "isobject": "^3.0.0", + "snapdragon-util": "^3.0.1" }, "dependencies": { "define-property": { @@ -10114,7 +10508,7 @@ "integrity": "sha1-dp66rz9KY6rTr56NMEybvnm/sOY=", "dev": true, "requires": { - "is-descriptor": "1.0.2" + "is-descriptor": "^1.0.0" } }, "is-accessor-descriptor": { @@ -10123,7 +10517,7 @@ "integrity": "sha512-m5hnHTkcVsPfqx3AKlyttIPb7J+XykHvJP2B9bZDjlhLIoEq4XoK64Vg7boZlVWYK6LUY94dYPEE7Lh0ZkZKcQ==", "dev": true, "requires": { - "kind-of": "6.0.2" + "kind-of": "^6.0.0" } }, "is-data-descriptor": { @@ -10132,7 +10526,7 @@ "integrity": "sha512-jbRXy1FmtAoCjQkVmIVYwuuqDFUbaOeDjmed1tOGPrsMhtJA4rD9tkgA0F1qJ3gRFRXcHYVkdeaP50Q5rE/jLQ==", "dev": true, "requires": { - "kind-of": "6.0.2" + "kind-of": "^6.0.0" } }, "is-descriptor": { @@ -10141,9 +10535,9 @@ "integrity": "sha512-2eis5WqQGV7peooDyLmNEPUrps9+SXX5c9pL3xEB+4e9HnGuDa7mB7kHxHw4CbqS9k1T2hOH3miL8n8WtiYVtg==", "dev": true, "requires": { - "is-accessor-descriptor": "1.0.0", - "is-data-descriptor": "1.0.0", - "kind-of": "6.0.2" + "is-accessor-descriptor": "^1.0.0", + "is-data-descriptor": "^1.0.0", + "kind-of": "^6.0.2" } } } @@ -10154,7 +10548,7 @@ "integrity": "sha512-mbKkMdQKsjX4BAL4bRYTj21edOf8cN7XHdYUJEe+Zn99hVEYcMvKPct1IqNe7+AZPirn8BCDOQBHQZknqmKlZQ==", "dev": true, "requires": { - "kind-of": "3.2.2" + "kind-of": "^3.2.0" }, "dependencies": { "kind-of": { @@ -10163,7 +10557,7 @@ "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=", "dev": true, "requires": { - "is-buffer": "1.1.6" + "is-buffer": "^1.1.5" } } } @@ -10173,21 +10567,26 @@ "resolved": "https://registry.npmjs.org/snazzy/-/snazzy-6.0.0.tgz", "integrity": "sha1-ahfUeYy7yLxuETFTaUkHqLrJSU0=", "requires": { - "chalk": "1.1.3", - "inherits": "2.0.1", - "minimist": "1.2.0", - "readable-stream": "2.3.5", - "standard": "11.0.0", - "standard-json": "1.0.2", - "text-table": "0.2.0" + "chalk": "^1.1.0", + "inherits": "^2.0.1", + "minimist": "^1.1.1", + "readable-stream": "^2.0.6", + "standard": "*", + "standard-json": "^1.0.0", + "text-table": "^0.2.0" }, "dependencies": { + "acorn": { + "version": "5.7.3", + "resolved": "https://registry.npmjs.org/acorn/-/acorn-5.7.3.tgz", + "integrity": "sha512-T/zvzYRfbVojPWahDsE5evJdHb3oJoQfFbsrKM7w5Zcs++Tr257tia3BmMP8XYVjp1S9RZXQMh7gao96BlqZOw==" + }, "acorn-jsx": { "version": "3.0.1", "resolved": "https://registry.npmjs.org/acorn-jsx/-/acorn-jsx-3.0.1.tgz", "integrity": "sha1-r9+UiPsezvyDSPb7IvRk4ypYs2s=", "requires": { - "acorn": "3.3.0" + "acorn": "^3.0.4" }, "dependencies": { "acorn": { @@ -10207,7 +10606,7 @@ "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz", "integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==", "requires": { - "color-convert": "1.9.1" + "color-convert": "^1.9.0" } }, "debug": { @@ -10215,7 +10614,7 @@ "resolved": "https://registry.npmjs.org/debug/-/debug-3.2.6.tgz", "integrity": "sha512-mel+jf7nrtEl5Pn1Qx46zARXKDpBbvzezse7p7LqINmdoIk8PYP5SySaxEmYv6TZ0JyEKA1hsCId6DIhgITtWQ==", "requires": { - "ms": "2.1.1" + "ms": "^2.1.1" } }, "espree": { @@ -10223,8 +10622,8 @@ "resolved": "https://registry.npmjs.org/espree/-/espree-3.5.4.tgz", "integrity": "sha512-yAcIQxtmMiB/jL32dzEp2enBeidsB7xWPLNiw3IIkpVds1P+h7qF9YwJq1yUNzp2OKXgAprs4F61ih66UsoD1A==", "requires": { - "acorn": "5.5.3", - "acorn-jsx": "3.0.1" + "acorn": "^5.5.0", + "acorn-jsx": "^3.0.0" } }, "esprima": { @@ -10237,20 +10636,20 @@ "resolved": "https://registry.npmjs.org/inquirer/-/inquirer-3.3.0.tgz", "integrity": "sha512-h+xtnyk4EwKvFWHrUYsWErEVR+igKtLdchu+o0Z1RL7VU/jVMFbYir2bp6bAj8efFNxWqHX0dIss6fJQ+/+qeQ==", "requires": { - "ansi-escapes": "3.0.0", - "chalk": "2.4.2", - "cli-cursor": "2.1.0", - "cli-width": "2.2.0", - "external-editor": "2.1.0", - "figures": "2.0.0", - "lodash": "4.17.11", + "ansi-escapes": "^3.0.0", + "chalk": "^2.0.0", + "cli-cursor": "^2.1.0", + "cli-width": "^2.0.0", + "external-editor": "^2.0.4", + "figures": "^2.0.0", + "lodash": "^4.3.0", "mute-stream": "0.0.7", - "run-async": "2.3.0", - "rx-lite": "4.0.8", - "rx-lite-aggregates": "4.0.8", - "string-width": "2.1.1", - "strip-ansi": "4.0.0", - "through": "2.3.8" + "run-async": "^2.2.0", + "rx-lite": "^4.0.8", + "rx-lite-aggregates": "^4.0.8", + "string-width": "^2.1.0", + "strip-ansi": "^4.0.0", + "through": "^2.3.6" }, "dependencies": { "chalk": { @@ -10258,9 +10657,9 @@ "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz", "integrity": "sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==", "requires": { - "ansi-styles": "3.2.1", - "escape-string-regexp": "1.0.5", - "supports-color": "5.5.0" + "ansi-styles": "^3.2.1", + "escape-string-regexp": "^1.0.5", + "supports-color": "^5.3.0" } } } @@ -10270,8 +10669,8 @@ "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-3.12.1.tgz", "integrity": "sha512-um46hB9wNOKlwkHgiuyEVAybXBjwFUV0Z/RaHJblRd9DXltue9FTYvzCr9ErQrK9Adz5MU4gHWVaNUfdmrC8qA==", "requires": { - "argparse": "1.0.10", - "esprima": "4.0.1" + "argparse": "^1.0.7", + "esprima": "^4.0.0" } }, "minimist": { @@ -10289,15 +10688,15 @@ "resolved": "https://registry.npmjs.org/standard/-/standard-11.0.0.tgz", "integrity": "sha1-C6GMdT9oiD+//+3z44U0prnSbco=", "requires": { - "eslint": "4.18.2", + "eslint": "~4.18.0", "eslint-config-standard": "11.0.0", "eslint-config-standard-jsx": "5.0.0", - "eslint-plugin-import": "2.8.0", - "eslint-plugin-node": "6.0.1", - "eslint-plugin-promise": "3.6.0", - "eslint-plugin-react": "7.6.1", - "eslint-plugin-standard": "3.0.1", - "standard-engine": "8.0.1" + "eslint-plugin-import": "~2.8.0", + "eslint-plugin-node": "~6.0.0", + "eslint-plugin-promise": "~3.6.0", + "eslint-plugin-react": "~7.6.1", + "eslint-plugin-standard": "~3.0.1", + "standard-engine": "~8.0.0" }, "dependencies": { "chalk": { @@ -10305,9 +10704,9 @@ "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz", "integrity": "sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==", "requires": { - "ansi-styles": "3.2.1", - "escape-string-regexp": "1.0.5", - "supports-color": "5.5.0" + "ansi-styles": "^3.2.1", + "escape-string-regexp": "^1.0.5", + "supports-color": "^5.3.0" } }, "eslint": { @@ -10315,44 +10714,96 @@ "resolved": "https://registry.npmjs.org/eslint/-/eslint-4.18.2.tgz", "integrity": "sha512-qy4i3wODqKMYfz9LUI8N2qYDkHkoieTbiHpMrYUI/WbjhXJQr7lI4VngixTgaG+yHX+NBCv7nW4hA0ShbvaNKw==", "requires": { - "ajv": "5.5.2", - "babel-code-frame": "6.26.0", - "chalk": "2.4.2", - "concat-stream": "1.6.1", - "cross-spawn": "5.1.0", - "debug": "3.2.6", - "doctrine": "2.1.0", - "eslint-scope": "3.7.1", - "eslint-visitor-keys": "1.0.0", - "espree": "3.5.4", - "esquery": "1.0.1", - "esutils": "2.0.2", - "file-entry-cache": "2.0.0", - "functional-red-black-tree": "1.0.1", - "glob": "7.1.2", - "globals": "11.10.0", - "ignore": "3.3.7", - "imurmurhash": "0.1.4", - "inquirer": "3.3.0", - "is-resolvable": "1.1.0", - "js-yaml": "3.12.1", - "json-stable-stringify-without-jsonify": "1.0.1", - "levn": "0.3.0", - "lodash": "4.17.11", - "minimatch": "3.0.4", - "mkdirp": "0.5.1", - "natural-compare": "1.4.0", - "optionator": "0.8.2", - "path-is-inside": "1.0.2", - "pluralize": "7.0.0", - "progress": "2.0.0", - "require-uncached": "1.0.3", - "semver": "5.5.0", - "strip-ansi": "4.0.0", - "strip-json-comments": "2.0.1", + "ajv": "^5.3.0", + "babel-code-frame": "^6.22.0", + "chalk": "^2.1.0", + "concat-stream": "^1.6.0", + "cross-spawn": "^5.1.0", + "debug": "^3.1.0", + "doctrine": "^2.1.0", + "eslint-scope": "^3.7.1", + "eslint-visitor-keys": "^1.0.0", + "espree": "^3.5.2", + "esquery": "^1.0.0", + "esutils": "^2.0.2", + "file-entry-cache": "^2.0.0", + "functional-red-black-tree": "^1.0.1", + "glob": "^7.1.2", + "globals": "^11.0.1", + "ignore": "^3.3.3", + "imurmurhash": "^0.1.4", + "inquirer": "^3.0.6", + "is-resolvable": "^1.0.0", + "js-yaml": "^3.9.1", + "json-stable-stringify-without-jsonify": "^1.0.1", + "levn": "^0.3.0", + "lodash": "^4.17.4", + "minimatch": "^3.0.2", + "mkdirp": "^0.5.1", + "natural-compare": "^1.4.0", + "optionator": "^0.8.2", + "path-is-inside": "^1.0.2", + "pluralize": "^7.0.0", + "progress": "^2.0.0", + "require-uncached": "^1.0.3", + "semver": "^5.3.0", + "strip-ansi": "^4.0.0", + "strip-json-comments": "~2.0.1", "table": "4.0.2", - "text-table": "0.2.0" + "text-table": "~0.2.0" + } + }, + "eslint-plugin-import": { + "version": "2.8.0", + "resolved": "https://registry.npmjs.org/eslint-plugin-import/-/eslint-plugin-import-2.8.0.tgz", + "integrity": "sha512-Rf7dfKJxZ16QuTgVv1OYNxkZcsu/hULFnC+e+w0Gzi6jMC3guQoWQgxYxc54IDRinlb6/0v5z/PxxIKmVctN+g==", + "requires": { + "builtin-modules": "^1.1.1", + "contains-path": "^0.1.0", + "debug": "^2.6.8", + "doctrine": "1.5.0", + "eslint-import-resolver-node": "^0.3.1", + "eslint-module-utils": "^2.1.1", + "has": "^1.0.1", + "lodash.cond": "^4.3.0", + "minimatch": "^3.0.3", + "read-pkg-up": "^2.0.0" + }, + "dependencies": { + "debug": { + "version": "2.6.9", + "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", + "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", + "requires": { + "ms": "2.0.0" + } + }, + "doctrine": { + "version": "1.5.0", + "resolved": "https://registry.npmjs.org/doctrine/-/doctrine-1.5.0.tgz", + "integrity": "sha1-N53Ocw9hZvds76TmcHoVmwLFpvo=", + "requires": { + "esutils": "^2.0.2", + "isarray": "^1.0.0" + } + } + } + }, + "eslint-plugin-react": { + "version": "7.6.1", + "resolved": "https://registry.npmjs.org/eslint-plugin-react/-/eslint-plugin-react-7.6.1.tgz", + "integrity": "sha512-30aMOHWX/DOaaLJVBHz6RMvYM2qy5GH63+y2PLFdIrYe4YLtODFmT3N1YA7ZqUnaBweVbedr4K4cqxOlWAPjIw==", + "requires": { + "doctrine": "^2.0.2", + "has": "^1.0.1", + "jsx-ast-utils": "^2.0.1", + "prop-types": "^15.6.0" } + }, + "ms": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", + "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g=" } } }, @@ -10361,7 +10812,7 @@ "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-4.0.0.tgz", "integrity": "sha1-qEeQIusaw2iocTibY1JixQXuNo8=", "requires": { - "ansi-regex": "3.0.0" + "ansi-regex": "^3.0.0" } }, "supports-color": { @@ -10369,7 +10820,7 @@ "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz", "integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==", "requires": { - "has-flag": "3.0.0" + "has-flag": "^3.0.0" } }, "table": { @@ -10377,12 +10828,12 @@ "resolved": "https://registry.npmjs.org/table/-/table-4.0.2.tgz", "integrity": "sha512-UUkEAPdSGxtRpiV9ozJ5cMTtYiqz7Ni1OGqLXRCynrvzdtR1p+cfOWe2RJLwvUG8hNanaSRjecIqwOjqeatDsA==", "requires": { - "ajv": "5.5.2", - "ajv-keywords": "2.1.1", - "chalk": "2.4.2", - "lodash": "4.17.11", + "ajv": "^5.2.3", + "ajv-keywords": "^2.1.0", + "chalk": "^2.1.0", + "lodash": "^4.17.4", "slice-ansi": "1.0.0", - "string-width": "2.1.1" + "string-width": "^2.1.1" }, "dependencies": { "chalk": { @@ -10390,9 +10841,9 @@ "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz", "integrity": "sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==", "requires": { - "ansi-styles": "3.2.1", - "escape-string-regexp": "1.0.5", - "supports-color": "5.5.0" + "ansi-styles": "^3.2.1", + "escape-string-regexp": "^1.0.5", + "supports-color": "^5.3.0" } } } @@ -10406,31 +10857,31 @@ "dev": true, "optional": true, "requires": { - "hoek": "4.2.1" + "hoek": "4.x.x" } }, "sockjs": { "version": "0.3.19", "resolved": "https://registry.npmjs.org/sockjs/-/sockjs-0.3.19.tgz", - "integrity": "sha1-2Xa76ACve9IK4IWY1YI5NQiZPA0=", + "integrity": "sha512-V48klKZl8T6MzatbLlzzRNhMepEys9Y4oGFpypBFFn1gLI/QQ9HtLLyWJNbPlwGLelOVOEijUbTTJeLLI59jLw==", "dev": true, "requires": { - "faye-websocket": "0.10.0", - "uuid": "3.3.2" + "faye-websocket": "^0.10.0", + "uuid": "^3.0.1" } }, "sockjs-client": { - "version": "1.3.0", - "resolved": "https://registry.npmjs.org/sockjs-client/-/sockjs-client-1.3.0.tgz", - "integrity": "sha512-R9jxEzhnnrdxLCNln0xg5uGHqMnkhPSTzUZH2eXcR03S/On9Yvoq2wyUZILRUhZCNVu2PmwWVoyuiPz8th8zbg==", + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/sockjs-client/-/sockjs-client-1.4.0.tgz", + "integrity": "sha512-5zaLyO8/nri5cua0VtOrFXBPK1jbL4+1cebT/mmKA1E1ZXOvJrII75bPu0l0k843G/+iAbhEqzyKr0w/eCCj7g==", "dev": true, "requires": { - "debug": "3.2.6", - "eventsource": "1.0.7", - "faye-websocket": "0.11.1", - "inherits": "2.0.3", - "json3": "3.3.2", - "url-parse": "1.4.3" + "debug": "^3.2.5", + "eventsource": "^1.0.7", + "faye-websocket": "~0.11.1", + "inherits": "^2.0.3", + "json3": "^3.3.2", + "url-parse": "^1.4.3" }, "dependencies": { "debug": { @@ -10439,32 +10890,38 @@ "integrity": "sha512-mel+jf7nrtEl5Pn1Qx46zARXKDpBbvzezse7p7LqINmdoIk8PYP5SySaxEmYv6TZ0JyEKA1hsCId6DIhgITtWQ==", "dev": true, "requires": { - "ms": "2.1.1" + "ms": "^2.1.1" } }, "faye-websocket": { - "version": "0.11.1", - "resolved": "https://registry.npmjs.org/faye-websocket/-/faye-websocket-0.11.1.tgz", - "integrity": "sha1-8O/hjE9W5PQK/H4Gxxn9XuYYjzg=", + "version": "0.11.3", + "resolved": "https://registry.npmjs.org/faye-websocket/-/faye-websocket-0.11.3.tgz", + "integrity": "sha512-D2y4bovYpzziGgbHYtGCMjlJM36vAl/y+xUyn1C+FVx8szd1E+86KwVw6XvYSzOP8iMpm1X0I4xJD+QtUb36OA==", "dev": true, "requires": { - "websocket-driver": "0.7.0" + "websocket-driver": ">=0.5.1" } }, "inherits": { - "version": "2.0.3", - "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.3.tgz", - "integrity": "sha1-Yzwsg+PaQqUC9SRmAiSA9CCCYd4=", + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.4.tgz", + "integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==", "dev": true }, "ms": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.1.tgz", - "integrity": "sha512-tgp+dl5cGk28utYktBsrFqA7HKgrhgPsg6Z/EfhWI4gl1Hwq8B/GmY/0oXZ6nF8hDVesS/FpnYaD/kOWhYQvyg==", + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", + "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==", "dev": true } } }, + "source-list-map": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/source-list-map/-/source-list-map-2.0.1.tgz", + "integrity": "sha512-qnQ7gVMxGNxsiL4lEuJwe/To8UnK7fAnmbGEEH8RpLouuKbeEm0lhbQVFIrNSuB+G7tVrAlVsZgETT5nljf+Iw==", + "dev": true + }, "source-map": { "version": "0.5.7", "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.5.7.tgz", @@ -10477,11 +10934,29 @@ "integrity": "sha512-MjqsvNwyz1s0k81Goz/9vRBe9SZdB09Bdw+/zYyO+3CuPk6fouTaxscHkgtE8jKvf01kVfl8riHzERQ/kefaSA==", "dev": true, "requires": { - "atob": "2.1.2", - "decode-uri-component": "0.2.0", - "resolve-url": "0.2.1", - "source-map-url": "0.4.0", - "urix": "0.1.0" + "atob": "^2.1.1", + "decode-uri-component": "^0.2.0", + "resolve-url": "^0.2.1", + "source-map-url": "^0.4.0", + "urix": "^0.1.0" + } + }, + "source-map-support": { + "version": "0.5.16", + "resolved": "https://registry.npmjs.org/source-map-support/-/source-map-support-0.5.16.tgz", + "integrity": "sha512-efyLRJDr68D9hBBNIPWFjhpFzURh+KJykQwvMyW5UiZzYwoF6l4YMMDIJJEyFWxWCqfyxLzz6tSfUFR+kXXsVQ==", + "dev": true, + "requires": { + "buffer-from": "^1.0.0", + "source-map": "^0.6.0" + }, + "dependencies": { + "source-map": { + "version": "0.6.1", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", + "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", + "dev": true + } } }, "source-map-url": { @@ -10495,8 +10970,8 @@ "resolved": "https://registry.npmjs.org/spdx-correct/-/spdx-correct-3.0.0.tgz", "integrity": "sha1-BaW01xU6GVvJLDxCW2nzsqlSTII=", "requires": { - "spdx-expression-parse": "3.0.0", - "spdx-license-ids": "3.0.0" + "spdx-expression-parse": "^3.0.0", + "spdx-license-ids": "^3.0.0" } }, "spdx-exceptions": { @@ -10509,8 +10984,8 @@ "resolved": "https://registry.npmjs.org/spdx-expression-parse/-/spdx-expression-parse-3.0.0.tgz", "integrity": "sha1-meEZt6XaAOBUkcn6M4t5BII7QdA=", "requires": { - "spdx-exceptions": "2.1.0", - "spdx-license-ids": "3.0.0" + "spdx-exceptions": "^2.1.0", + "spdx-license-ids": "^3.0.0" } }, "spdx-license-ids": { @@ -10519,16 +10994,16 @@ "integrity": "sha1-enzShHDMbToc/m1miG9rxDDTrIc=" }, "spdy": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/spdy/-/spdy-4.0.0.tgz", - "integrity": "sha512-ot0oEGT/PGUpzf/6uk4AWLqkq+irlqHXkrdbk51oWONh3bxQmBuljxPNl66zlRRcIJStWq0QkLUCPOPjgjvU0Q==", + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/spdy/-/spdy-4.0.1.tgz", + "integrity": "sha512-HeZS3PBdMA+sZSu0qwpCxl3DeALD5ASx8pAX0jZdKXSpPWbQ6SYGnlg3BBmYLx5LtiZrmkAZfErCm2oECBcioA==", "dev": true, "requires": { - "debug": "4.1.1", - "handle-thing": "2.0.0", - "http-deceiver": "1.2.7", - "select-hose": "2.0.0", - "spdy-transport": "3.0.0" + "debug": "^4.1.0", + "handle-thing": "^2.0.0", + "http-deceiver": "^1.2.7", + "select-hose": "^2.0.0", + "spdy-transport": "^3.0.0" }, "dependencies": { "debug": { @@ -10537,13 +11012,13 @@ "integrity": "sha512-pYAIzeRo8J6KPEaJ0VWOh5Pzkbw/RetuzehGM7QRRX5he4fPHx2rdKMB256ehJCkX+XRQm16eZLqLNS8RSZXZw==", "dev": true, "requires": { - "ms": "2.1.1" + "ms": "^2.1.1" } }, "ms": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.1.tgz", - "integrity": "sha512-tgp+dl5cGk28utYktBsrFqA7HKgrhgPsg6Z/EfhWI4gl1Hwq8B/GmY/0oXZ6nF8hDVesS/FpnYaD/kOWhYQvyg==", + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", + "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==", "dev": true } } @@ -10554,12 +11029,12 @@ "integrity": "sha512-hsLVFE5SjA6TCisWeJXFKniGGOpBgMLmerfO2aCyCU5s7nJ/rpAepqmFifv/GCbSbueEeAJJnmSQ2rKC/g8Fcw==", "dev": true, "requires": { - "debug": "4.1.1", - "detect-node": "2.0.4", - "hpack.js": "2.1.6", - "obuf": "1.1.2", - "readable-stream": "3.1.1", - "wbuf": "1.7.3" + "debug": "^4.1.0", + "detect-node": "^2.0.4", + "hpack.js": "^2.1.6", + "obuf": "^1.1.2", + "readable-stream": "^3.0.6", + "wbuf": "^1.7.3" }, "dependencies": { "debug": { @@ -10568,39 +11043,45 @@ "integrity": "sha512-pYAIzeRo8J6KPEaJ0VWOh5Pzkbw/RetuzehGM7QRRX5he4fPHx2rdKMB256ehJCkX+XRQm16eZLqLNS8RSZXZw==", "dev": true, "requires": { - "ms": "2.1.1" + "ms": "^2.1.1" } }, "inherits": { - "version": "2.0.3", - "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.3.tgz", - "integrity": "sha1-Yzwsg+PaQqUC9SRmAiSA9CCCYd4=", + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.4.tgz", + "integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==", "dev": true }, "ms": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.1.tgz", - "integrity": "sha512-tgp+dl5cGk28utYktBsrFqA7HKgrhgPsg6Z/EfhWI4gl1Hwq8B/GmY/0oXZ6nF8hDVesS/FpnYaD/kOWhYQvyg==", + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", + "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==", "dev": true }, "readable-stream": { - "version": "3.1.1", - "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-3.1.1.tgz", - "integrity": "sha512-DkN66hPyqDhnIQ6Jcsvx9bFjhw214O4poMBcIMgPVpQvNy9a0e0Uhg5SqySyDKAmUlwt8LonTBz1ezOnM8pUdA==", + "version": "3.4.0", + "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-3.4.0.tgz", + "integrity": "sha512-jItXPLmrSR8jmTRmRWJXCnGJsfy85mB3Wd/uINMXA65yrnFo0cPClFIUWzo2najVNSl+mx7/4W8ttlLWJe99pQ==", "dev": true, "requires": { - "inherits": "2.0.3", - "string_decoder": "1.2.0", - "util-deprecate": "1.0.2" + "inherits": "^2.0.3", + "string_decoder": "^1.1.1", + "util-deprecate": "^1.0.1" } }, + "safe-buffer": { + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.2.0.tgz", + "integrity": "sha512-fZEwUGbVl7kouZs1jCdMLdt95hdIv0ZeHg6L7qPeciMZhZ+/gdesW4wgTARkrFWEpspjEATAzUGPG8N2jJiwbg==", + "dev": true + }, "string_decoder": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.2.0.tgz", - "integrity": "sha512-6YqyX6ZWEYguAxgZzHGL7SsCeGx3V2TtOTqZz1xSTSWnqsbWwbptafNyvf/ACquZUXV3DANr5BDIwNYe1mN42w==", + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.3.0.tgz", + "integrity": "sha512-hkRX8U1WjJFd8LsDJ2yQ/wWWxaopEsABU1XfkM8A+j0+85JAGppt16cr1Whg6KIbb4okU6Mql6BOj+uup/wKeA==", "dev": true, "requires": { - "safe-buffer": "5.1.1" + "safe-buffer": "~5.2.0" } } } @@ -10611,7 +11092,7 @@ "integrity": "sha512-NzNVhJDYpwceVVii8/Hu6DKfD2G+NrQHlS/V/qgv763EYudVwEcMQNxd2lh+0VrUByXN/oJkl5grOhYWvQUYiw==", "dev": true, "requires": { - "extend-shallow": "3.0.2" + "extend-shallow": "^3.0.0" } }, "sprintf-js": { @@ -10625,14 +11106,14 @@ "integrity": "sha1-Ew9Zde3a2WPx1W+SuaxsUfqfg+s=", "dev": true, "requires": { - "asn1": "0.2.3", - "assert-plus": "1.0.0", - "bcrypt-pbkdf": "1.0.1", - "dashdash": "1.14.1", - "ecc-jsbn": "0.1.1", - "getpass": "0.1.7", - "jsbn": "0.1.1", - "tweetnacl": "0.14.5" + "asn1": "~0.2.3", + "assert-plus": "^1.0.0", + "bcrypt-pbkdf": "^1.0.0", + "dashdash": "^1.12.0", + "ecc-jsbn": "~0.1.1", + "getpass": "^0.1.1", + "jsbn": "~0.1.0", + "tweetnacl": "~0.14.0" } }, "ssri": { @@ -10641,7 +11122,7 @@ "integrity": "sha512-3Wge10hNcT1Kur4PDFwEieXSCMCJs/7WvSACcrMYrNp+b8kDL1/0wJch5Ni2WrtwEa2IO8OsVfeKIciKCDx/QA==", "dev": true, "requires": { - "figgy-pudding": "3.5.1" + "figgy-pudding": "^3.5.1" } }, "standard": { @@ -10650,15 +11131,15 @@ "integrity": "sha512-UqdHjh87OG2gUrNCSM4QRLF5n9h3TFPwrCNyVlkqu31Hej0L/rc8hzKqVvkb2W3x0WMq7PzZdkLfEcBhVOR6lg==", "dev": true, "requires": { - "eslint": "5.4.0", + "eslint": "~5.4.0", "eslint-config-standard": "12.0.0", "eslint-config-standard-jsx": "6.0.2", - "eslint-plugin-import": "2.14.0", - "eslint-plugin-node": "7.0.1", - "eslint-plugin-promise": "4.0.1", - "eslint-plugin-react": "7.11.1", - "eslint-plugin-standard": "4.0.0", - "standard-engine": "9.0.0" + "eslint-plugin-import": "~2.14.0", + "eslint-plugin-node": "~7.0.1", + "eslint-plugin-promise": "~4.0.0", + "eslint-plugin-react": "~7.11.1", + "eslint-plugin-standard": "~4.0.0", + "standard-engine": "~9.0.0" }, "dependencies": { "acorn": { @@ -10679,10 +11160,10 @@ "integrity": "sha512-RZXPviBTtfmtka9n9sy1N5M5b82CbxWIR6HIis4s3WQTXDJamc/0gpCWNGz6EWdWp4DOfjzJfhz/AS9zVPjjWg==", "dev": true, "requires": { - "fast-deep-equal": "2.0.1", - "fast-json-stable-stringify": "2.0.0", - "json-schema-traverse": "0.4.1", - "uri-js": "4.2.2" + "fast-deep-equal": "^2.0.1", + "fast-json-stable-stringify": "^2.0.0", + "json-schema-traverse": "^0.4.1", + "uri-js": "^4.2.2" } }, "ajv-keywords": { @@ -10703,7 +11184,7 @@ "integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==", "dev": true, "requires": { - "color-convert": "1.9.1" + "color-convert": "^1.9.0" } }, "chalk": { @@ -10712,9 +11193,9 @@ "integrity": "sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==", "dev": true, "requires": { - "ansi-styles": "3.2.1", - "escape-string-regexp": "1.0.5", - "supports-color": "5.5.0" + "ansi-styles": "^3.2.1", + "escape-string-regexp": "^1.0.5", + "supports-color": "^5.3.0" } }, "cross-spawn": { @@ -10723,11 +11204,11 @@ "integrity": "sha512-eTVLrBSt7fjbDygz805pMnstIs2VTBNkRm0qxZd+M7A5XDdxVRWO5MxGBXZhjY4cqLYLdtrGqRf8mBPmzwSpWQ==", "dev": true, "requires": { - "nice-try": "1.0.5", - "path-key": "2.0.1", - "semver": "5.5.0", - "shebang-command": "1.2.0", - "which": "1.3.0" + "nice-try": "^1.0.4", + "path-key": "^2.0.1", + "semver": "^5.5.0", + "shebang-command": "^1.2.0", + "which": "^1.2.9" } }, "debug": { @@ -10736,7 +11217,7 @@ "integrity": "sha512-mel+jf7nrtEl5Pn1Qx46zARXKDpBbvzezse7p7LqINmdoIk8PYP5SySaxEmYv6TZ0JyEKA1hsCId6DIhgITtWQ==", "dev": true, "requires": { - "ms": "2.1.1" + "ms": "^2.1.1" } }, "eslint": { @@ -10745,44 +11226,44 @@ "integrity": "sha512-UIpL91XGex3qtL6qwyCQJar2j3osKxK9e3ano3OcGEIRM4oWIpCkDg9x95AXEC2wMs7PnxzOkPZ2gq+tsMS9yg==", "dev": true, "requires": { - "ajv": "6.7.0", - "babel-code-frame": "6.26.0", - "chalk": "2.4.2", - "cross-spawn": "6.0.5", - "debug": "3.2.6", - "doctrine": "2.1.0", - "eslint-scope": "4.0.0", - "eslint-utils": "1.3.1", - "eslint-visitor-keys": "1.0.0", - "espree": "4.1.0", - "esquery": "1.0.1", - "esutils": "2.0.2", - "file-entry-cache": "2.0.0", - "functional-red-black-tree": "1.0.1", - "glob": "7.1.2", - "globals": "11.10.0", - "ignore": "4.0.6", - "imurmurhash": "0.1.4", - "inquirer": "5.2.0", - "is-resolvable": "1.1.0", - "js-yaml": "3.12.1", - "json-stable-stringify-without-jsonify": "1.0.1", - "levn": "0.3.0", - "lodash": "4.17.11", - "minimatch": "3.0.4", - "mkdirp": "0.5.1", - "natural-compare": "1.4.0", - "optionator": "0.8.2", - "path-is-inside": "1.0.2", - "pluralize": "7.0.0", - "progress": "2.0.0", - "regexpp": "2.0.1", - "require-uncached": "1.0.3", - "semver": "5.5.0", - "strip-ansi": "4.0.0", - "strip-json-comments": "2.0.1", - "table": "4.0.3", - "text-table": "0.2.0" + "ajv": "^6.5.0", + "babel-code-frame": "^6.26.0", + "chalk": "^2.1.0", + "cross-spawn": "^6.0.5", + "debug": "^3.1.0", + "doctrine": "^2.1.0", + "eslint-scope": "^4.0.0", + "eslint-utils": "^1.3.1", + "eslint-visitor-keys": "^1.0.0", + "espree": "^4.0.0", + "esquery": "^1.0.1", + "esutils": "^2.0.2", + "file-entry-cache": "^2.0.0", + "functional-red-black-tree": "^1.0.1", + "glob": "^7.1.2", + "globals": "^11.7.0", + "ignore": "^4.0.2", + "imurmurhash": "^0.1.4", + "inquirer": "^5.2.0", + "is-resolvable": "^1.1.0", + "js-yaml": "^3.11.0", + "json-stable-stringify-without-jsonify": "^1.0.1", + "levn": "^0.3.0", + "lodash": "^4.17.5", + "minimatch": "^3.0.4", + "mkdirp": "^0.5.1", + "natural-compare": "^1.4.0", + "optionator": "^0.8.2", + "path-is-inside": "^1.0.2", + "pluralize": "^7.0.0", + "progress": "^2.0.0", + "regexpp": "^2.0.0", + "require-uncached": "^1.0.3", + "semver": "^5.5.0", + "strip-ansi": "^4.0.0", + "strip-json-comments": "^2.0.1", + "table": "^4.0.3", + "text-table": "^0.2.0" } }, "eslint-config-standard": { @@ -10803,8 +11284,8 @@ "integrity": "sha1-snA2LNiLGkitMIl2zn+lTphBF0Y=", "dev": true, "requires": { - "debug": "2.6.9", - "pkg-dir": "1.0.0" + "debug": "^2.6.8", + "pkg-dir": "^1.0.0" }, "dependencies": { "debug": { @@ -10830,16 +11311,16 @@ "integrity": "sha512-FpuRtniD/AY6sXByma2Wr0TXvXJ4nA/2/04VPlfpmUDPOpOY264x+ILiwnrk/k4RINgDAyFZByxqPUbSQ5YE7g==", "dev": true, "requires": { - "contains-path": "0.1.0", - "debug": "2.6.9", + "contains-path": "^0.1.0", + "debug": "^2.6.8", "doctrine": "1.5.0", - "eslint-import-resolver-node": "0.3.2", - "eslint-module-utils": "2.2.0", - "has": "1.0.1", - "lodash": "4.17.11", - "minimatch": "3.0.4", - "read-pkg-up": "2.0.0", - "resolve": "1.9.0" + "eslint-import-resolver-node": "^0.3.1", + "eslint-module-utils": "^2.2.0", + "has": "^1.0.1", + "lodash": "^4.17.4", + "minimatch": "^3.0.3", + "read-pkg-up": "^2.0.0", + "resolve": "^1.6.0" }, "dependencies": { "debug": { @@ -10857,8 +11338,8 @@ "integrity": "sha1-N53Ocw9hZvds76TmcHoVmwLFpvo=", "dev": true, "requires": { - "esutils": "2.0.2", - "isarray": "1.0.0" + "esutils": "^2.0.2", + "isarray": "^1.0.0" } }, "ms": { @@ -10875,12 +11356,12 @@ "integrity": "sha512-lfVw3TEqThwq0j2Ba/Ckn2ABdwmL5dkOgAux1rvOk6CO7A6yGyPI2+zIxN6FyNkp1X1X/BSvKOceD6mBWSj4Yw==", "dev": true, "requires": { - "eslint-plugin-es": "1.4.0", - "eslint-utils": "1.3.1", - "ignore": "4.0.6", - "minimatch": "3.0.4", - "resolve": "1.9.0", - "semver": "5.5.0" + "eslint-plugin-es": "^1.3.1", + "eslint-utils": "^1.3.1", + "ignore": "^4.0.2", + "minimatch": "^3.0.4", + "resolve": "^1.8.1", + "semver": "^5.5.0" } }, "eslint-plugin-promise": { @@ -10895,11 +11376,11 @@ "integrity": "sha512-cVVyMadRyW7qsIUh3FHp3u6QHNhOgVrLQYdQEB1bPWBsgbNCHdFAeNMquBMCcZJu59eNthX053L70l7gRt4SCw==", "dev": true, "requires": { - "array-includes": "3.0.3", - "doctrine": "2.1.0", - "has": "1.0.3", - "jsx-ast-utils": "2.0.1", - "prop-types": "15.6.2" + "array-includes": "^3.0.3", + "doctrine": "^2.1.0", + "has": "^1.0.3", + "jsx-ast-utils": "^2.0.1", + "prop-types": "^15.6.2" }, "dependencies": { "has": { @@ -10908,7 +11389,7 @@ "integrity": "sha512-f2dvO0VU6Oej7RkWJGrehjbzMAjFp5/VKPp5tTpWIV4JHHZK1/BxbFRtf/siA2SWTe09caDmVtYYzWEIbBS4zw==", "dev": true, "requires": { - "function-bind": "1.1.1" + "function-bind": "^1.1.1" } } } @@ -10925,8 +11406,8 @@ "integrity": "sha512-1G6UTDi7Jc1ELFwnR58HV4fK9OQK4S6N985f166xqXxpjU6plxFISJa2Ba9KCQuFa8RCnj/lSFJbHo7UFDBnUA==", "dev": true, "requires": { - "esrecurse": "4.2.1", - "estraverse": "4.2.0" + "esrecurse": "^4.1.0", + "estraverse": "^4.1.1" } }, "espree": { @@ -10935,9 +11416,9 @@ "integrity": "sha512-I5BycZW6FCVIub93TeVY1s7vjhP9CY6cXCznIRfiig7nRviKZYdRnj/sHEWC6A7WE9RDWOFq9+7OsWSYz8qv2w==", "dev": true, "requires": { - "acorn": "6.0.5", - "acorn-jsx": "5.0.1", - "eslint-visitor-keys": "1.0.0" + "acorn": "^6.0.2", + "acorn-jsx": "^5.0.0", + "eslint-visitor-keys": "^1.0.0" } }, "esprima": { @@ -10952,7 +11433,7 @@ "integrity": "sha512-SmiyZ5zIWH9VM+SRUReLS5Q8a7GxtRdxEBVZpm98rJM7Sb+A9DVCndXfkeFUd3byderg+EbDkfnevfCwynWaNA==", "dev": true, "requires": { - "estraverse": "4.2.0" + "estraverse": "^4.0.0" } }, "fast-deep-equal": { @@ -10973,19 +11454,19 @@ "integrity": "sha512-E9BmnJbAKLPGonz0HeWHtbKf+EeSP93paWO3ZYoUpq/aowXvYGjjCSuashhXPpzbArIjBbji39THkxTz9ZeEUQ==", "dev": true, "requires": { - "ansi-escapes": "3.0.0", - "chalk": "2.4.2", - "cli-cursor": "2.1.0", - "cli-width": "2.2.0", - "external-editor": "2.1.0", - "figures": "2.0.0", - "lodash": "4.17.11", + "ansi-escapes": "^3.0.0", + "chalk": "^2.0.0", + "cli-cursor": "^2.1.0", + "cli-width": "^2.0.0", + "external-editor": "^2.1.0", + "figures": "^2.0.0", + "lodash": "^4.3.0", "mute-stream": "0.0.7", - "run-async": "2.3.0", - "rxjs": "5.5.12", - "string-width": "2.1.1", - "strip-ansi": "4.0.0", - "through": "2.3.8" + "run-async": "^2.2.0", + "rxjs": "^5.5.2", + "string-width": "^2.1.0", + "strip-ansi": "^4.0.0", + "through": "^2.3.6" } }, "js-yaml": { @@ -10994,8 +11475,8 @@ "integrity": "sha512-um46hB9wNOKlwkHgiuyEVAybXBjwFUV0Z/RaHJblRd9DXltue9FTYvzCr9ErQrK9Adz5MU4gHWVaNUfdmrC8qA==", "dev": true, "requires": { - "argparse": "1.0.10", - "esprima": "4.0.1" + "argparse": "^1.0.7", + "esprima": "^4.0.0" } }, "json-schema-traverse": { @@ -11028,8 +11509,8 @@ "integrity": "sha512-3pboPvLiWD7dkI3qf3KbUe6hKFKa52w+AE0VCqECtf+QHAKgOL37tTaNCnuX1nAAQ4ZhyP+kYVKf8rLmJ/feDQ==", "dev": true, "requires": { - "loose-envify": "1.3.1", - "object-assign": "4.1.1" + "loose-envify": "^1.3.1", + "object-assign": "^4.1.1" } }, "resolve": { @@ -11038,7 +11519,7 @@ "integrity": "sha512-TZNye00tI67lwYvzxCxHGjwTNlUV70io54/Ed4j6PscB8xVfuBJpRenI/o6dVk0cY0PYTY27AgCoGGxRnYuItQ==", "dev": true, "requires": { - "path-parse": "1.0.6" + "path-parse": "^1.0.6" } }, "standard-engine": { @@ -11047,10 +11528,10 @@ "integrity": "sha512-ZfNfCWZ2Xq67VNvKMPiVMKHnMdvxYzvZkf1AH8/cw2NLDBm5LRsxMqvEJpsjLI/dUosZ3Z1d6JlHDp5rAvvk2w==", "dev": true, "requires": { - "deglob": "2.1.0", - "get-stdin": "6.0.0", - "minimist": "1.2.0", - "pkg-conf": "2.1.0" + "deglob": "^2.1.0", + "get-stdin": "^6.0.0", + "minimist": "^1.1.0", + "pkg-conf": "^2.0.0" } }, "strip-ansi": { @@ -11059,7 +11540,7 @@ "integrity": "sha1-qEeQIusaw2iocTibY1JixQXuNo8=", "dev": true, "requires": { - "ansi-regex": "3.0.0" + "ansi-regex": "^3.0.0" } }, "supports-color": { @@ -11068,7 +11549,7 @@ "integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==", "dev": true, "requires": { - "has-flag": "3.0.0" + "has-flag": "^3.0.0" } }, "table": { @@ -11077,12 +11558,12 @@ "integrity": "sha512-S7rnFITmBH1EnyKcvxBh1LjYeQMmnZtCXSEbHcH6S0NoKit24ZuFO/T1vDcLdYsLQkM188PVVhQmzKIuThNkKg==", "dev": true, "requires": { - "ajv": "6.7.0", - "ajv-keywords": "3.2.0", - "chalk": "2.4.2", - "lodash": "4.17.11", + "ajv": "^6.0.1", + "ajv-keywords": "^3.0.0", + "chalk": "^2.1.0", + "lodash": "^4.17.4", "slice-ansi": "1.0.0", - "string-width": "2.1.1" + "string-width": "^2.1.1" } } } @@ -11092,10 +11573,10 @@ "resolved": "https://registry.npmjs.org/standard-engine/-/standard-engine-8.0.1.tgz", "integrity": "sha1-C3e+jXq5Y2dXF9vqwe8dZnX7YvA=", "requires": { - "deglob": "2.1.0", - "get-stdin": "6.0.0", - "minimist": "1.2.0", - "pkg-conf": "2.1.0" + "deglob": "^2.1.0", + "get-stdin": "^6.0.0", + "minimist": "^1.1.0", + "pkg-conf": "^2.0.0" }, "dependencies": { "minimist": { @@ -11110,7 +11591,7 @@ "resolved": "https://registry.npmjs.org/standard-json/-/standard-json-1.0.2.tgz", "integrity": "sha1-gt6koUx4zZ4104zeS4isa2JZaiM=", "requires": { - "concat-stream": "1.6.1" + "concat-stream": "^1.5.0" } }, "static-extend": { @@ -11119,8 +11600,8 @@ "integrity": "sha1-YICcOcv/VTNyJv1eC1IPNB8ftcY=", "dev": true, "requires": { - "define-property": "0.2.5", - "object-copy": "0.1.0" + "define-property": "^0.2.5", + "object-copy": "^0.1.0" }, "dependencies": { "define-property": { @@ -11129,15 +11610,15 @@ "integrity": "sha1-w1se+RjsPJkPmlvFe+BKrOxcgRY=", "dev": true, "requires": { - "is-descriptor": "0.1.6" + "is-descriptor": "^0.1.0" } } } }, "statuses": { - "version": "1.4.0", - "resolved": "https://registry.npmjs.org/statuses/-/statuses-1.4.0.tgz", - "integrity": "sha1-u3PURtonlhBu/MG2AaJT1sRr0Ic=", + "version": "1.5.0", + "resolved": "https://registry.npmjs.org/statuses/-/statuses-1.5.0.tgz", + "integrity": "sha1-Fhx9rBd2Wf2YEfQ3cfqZOBR4Yow=", "dev": true }, "stdout-stream": { @@ -11146,7 +11627,17 @@ "integrity": "sha512-j4emi03KXqJWcIeF8eIXkjMFN1Cmb8gUlDYGeBALLPo5qdyTfA9bOtl8m33lRoC+vFMkP3gl0WsDr6+gzxbbTA==", "dev": true, "requires": { - "readable-stream": "2.3.5" + "readable-stream": "^2.0.1" + } + }, + "stream-browserify": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/stream-browserify/-/stream-browserify-2.0.2.tgz", + "integrity": "sha512-nX6hmklHs/gr2FuxYDltq8fJA1GDlxKQCz8O/IM4atRqBH8OORmBNgfvW5gG10GT/qQ9u0CzIvr2X5Pkt6ntqg==", + "dev": true, + "requires": { + "inherits": "~2.0.1", + "readable-stream": "^2.0.2" } }, "stream-each": { @@ -11155,8 +11646,8 @@ "integrity": "sha512-vlMC2f8I2u/bZGqkdfLQW/13Zihpej/7PmSiMQsbYddxuTsJp8vRe2x2FvVExZg7FaOds43ROAuFJwPR4MTZLw==", "dev": true, "requires": { - "end-of-stream": "1.4.1", - "stream-shift": "1.0.0" + "end-of-stream": "^1.1.0", + "stream-shift": "^1.0.0" } }, "stream-http": { @@ -11165,11 +11656,11 @@ "integrity": "sha512-+TSkfINHDo4J+ZobQLWiMouQYB+UVYFttRA94FpEzzJ7ZdqcL4uUUQ7WkdkI4DSozGmgBUE/a47L+38PenXhUw==", "dev": true, "requires": { - "builtin-status-codes": "3.0.0", - "inherits": "2.0.1", - "readable-stream": "2.3.6", - "to-arraybuffer": "1.0.1", - "xtend": "4.0.1" + "builtin-status-codes": "^3.0.0", + "inherits": "^2.0.1", + "readable-stream": "^2.3.6", + "to-arraybuffer": "^1.0.0", + "xtend": "^4.0.0" }, "dependencies": { "readable-stream": { @@ -11178,19 +11669,19 @@ "integrity": "sha512-tQtKA9WIAhBF3+VLAseyMqZeBjW0AHJoxOtYqSUZNJxauErmLbVm2FW1y+J/YA9dUrAC39ITejlZWhVIwawkKw==", "dev": true, "requires": { - "core-util-is": "1.0.2", - "inherits": "2.0.3", - "isarray": "1.0.0", - "process-nextick-args": "2.0.0", - "safe-buffer": "5.1.1", - "string_decoder": "1.1.1", - "util-deprecate": "1.0.2" + "core-util-is": "~1.0.0", + "inherits": "~2.0.3", + "isarray": "~1.0.0", + "process-nextick-args": "~2.0.0", + "safe-buffer": "~5.1.1", + "string_decoder": "~1.1.1", + "util-deprecate": "~1.0.1" }, "dependencies": { "inherits": { - "version": "2.0.3", - "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.3.tgz", - "integrity": "sha1-Yzwsg+PaQqUC9SRmAiSA9CCCYd4=", + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.4.tgz", + "integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==", "dev": true } } @@ -11201,7 +11692,7 @@ "integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==", "dev": true, "requires": { - "safe-buffer": "5.1.1" + "safe-buffer": "~5.1.0" } } } @@ -11212,18 +11703,13 @@ "integrity": "sha1-1cdSgl5TZ+eG944Y5EXqIjoVWVI=", "dev": true }, - "strict-uri-encode": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/strict-uri-encode/-/strict-uri-encode-1.1.0.tgz", - "integrity": "sha1-J5siXfHVgrH1TmWt3UNS4Y+qBxM=" - }, "string-width": { "version": "2.1.1", "resolved": "https://registry.npmjs.org/string-width/-/string-width-2.1.1.tgz", "integrity": "sha1-q5Pyeo3BPSjKyBXEYhQ6bZASrp4=", "requires": { - "is-fullwidth-code-point": "2.0.0", - "strip-ansi": "4.0.0" + "is-fullwidth-code-point": "^2.0.0", + "strip-ansi": "^4.0.0" }, "dependencies": { "ansi-regex": { @@ -11236,7 +11722,7 @@ "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-4.0.0.tgz", "integrity": "sha1-qEeQIusaw2iocTibY1JixQXuNo8=", "requires": { - "ansi-regex": "3.0.0" + "ansi-regex": "^3.0.0" } } } @@ -11246,13 +11732,13 @@ "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.0.3.tgz", "integrity": "sha1-D8Z9fBQYJd6UKC3VNr7GubzoYKs=", "requires": { - "safe-buffer": "5.1.1" + "safe-buffer": "~5.1.0" } }, "stringstream": { - "version": "0.0.5", - "resolved": "https://registry.npmjs.org/stringstream/-/stringstream-0.0.5.tgz", - "integrity": "sha1-TkhM1N5aC7vuGORjB3EKioFiGHg=", + "version": "0.0.6", + "resolved": "https://registry.npmjs.org/stringstream/-/stringstream-0.0.6.tgz", + "integrity": "sha512-87GEBAkegbBcweToUrdzf3eLhWNg06FJTebl4BVJz/JgWy8CvEr9dRtX5qWphiynMSQlxxi+QqN0z5T32SLlhA==", "dev": true, "optional": true }, @@ -11261,7 +11747,7 @@ "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-3.0.1.tgz", "integrity": "sha1-ajhfuIU9lS1f8F0Oiq+UJ43GPc8=", "requires": { - "ansi-regex": "2.1.1" + "ansi-regex": "^2.0.0" } }, "strip-bom": { @@ -11281,7 +11767,7 @@ "integrity": "sha1-DHlipq3vp7vUrDZkYKY4VSrhoKI=", "dev": true, "requires": { - "get-stdin": "4.0.1" + "get-stdin": "^4.0.1" }, "dependencies": { "get-stdin": { @@ -11314,10 +11800,10 @@ "integrity": "sha512-qmhNs2GEHNqY5fd2Mo+8N1r2sw/rvTAAvBZTaTx+Y7PHLypqyrxr1MdIu0pLw6Xvl/Gi4ONu/sdceP8vvUjkyA==", "dev": true, "requires": { - "ajv": "6.7.0", - "lodash": "4.17.11", + "ajv": "^6.6.1", + "lodash": "^4.17.11", "slice-ansi": "2.0.0", - "string-width": "2.1.1" + "string-width": "^2.1.1" }, "dependencies": { "ajv": { @@ -11326,10 +11812,10 @@ "integrity": "sha512-RZXPviBTtfmtka9n9sy1N5M5b82CbxWIR6HIis4s3WQTXDJamc/0gpCWNGz6EWdWp4DOfjzJfhz/AS9zVPjjWg==", "dev": true, "requires": { - "fast-deep-equal": "2.0.1", - "fast-json-stable-stringify": "2.0.0", - "json-schema-traverse": "0.4.1", - "uri-js": "4.2.2" + "fast-deep-equal": "^2.0.1", + "fast-json-stable-stringify": "^2.0.0", + "json-schema-traverse": "^0.4.1", + "uri-js": "^4.2.2" } }, "ansi-styles": { @@ -11338,7 +11824,7 @@ "integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==", "dev": true, "requires": { - "color-convert": "1.9.1" + "color-convert": "^1.9.0" } }, "fast-deep-equal": { @@ -11359,9 +11845,9 @@ "integrity": "sha512-4j2WTWjp3GsZ+AOagyzVbzp4vWGtZ0hEZ/gDY/uTvm6MTxUfTUIsnMIFb1bn8o0RuXiqUw15H1bue8f22Vw2oQ==", "dev": true, "requires": { - "ansi-styles": "3.2.1", - "astral-regex": "1.0.0", - "is-fullwidth-code-point": "2.0.0" + "ansi-styles": "^3.2.0", + "astral-regex": "^1.0.0", + "is-fullwidth-code-point": "^2.0.0" } } } @@ -11373,14 +11859,14 @@ "dev": true }, "tar": { - "version": "2.2.1", - "resolved": "https://registry.npmjs.org/tar/-/tar-2.2.1.tgz", - "integrity": "sha1-jk0qJWwOIYXGsYrWlK7JaLg8sdE=", + "version": "2.2.2", + "resolved": "https://registry.npmjs.org/tar/-/tar-2.2.2.tgz", + "integrity": "sha512-FCEhQ/4rE1zYv9rYXJw/msRqsnmlje5jHP6huWeBZ704jUTy02c5AZyWujpMR1ax6mVw9NyJMfuK2CMDWVIfgA==", "dev": true, "requires": { - "block-stream": "0.0.9", - "fstream": "1.0.11", - "inherits": "2.0.1" + "block-stream": "*", + "fstream": "^1.0.12", + "inherits": "2" } }, "tar-js": { @@ -11389,20 +11875,20 @@ "integrity": "sha1-aUmqv7C6GLsVYq5RpDn9DzAYOhc=" }, "terser": { - "version": "3.14.1", - "resolved": "https://registry.npmjs.org/terser/-/terser-3.14.1.tgz", - "integrity": "sha512-NSo3E99QDbYSMeJaEk9YW2lTg3qS9V0aKGlb+PlOrei1X02r1wSBHCNX/O+yeTRFSWPKPIGj6MqvvdqV4rnVGw==", + "version": "4.4.2", + "resolved": "https://registry.npmjs.org/terser/-/terser-4.4.2.tgz", + "integrity": "sha512-Uufrsvhj9O1ikwgITGsZ5EZS6qPokUOkCegS7fYOdGTv+OA90vndUbU6PEjr5ePqHfNUbGyMO7xyIZv2MhsALQ==", "dev": true, "requires": { - "commander": "2.17.1", - "source-map": "0.6.1", - "source-map-support": "0.5.10" + "commander": "^2.20.0", + "source-map": "~0.6.1", + "source-map-support": "~0.5.12" }, "dependencies": { "commander": { - "version": "2.17.1", - "resolved": "https://registry.npmjs.org/commander/-/commander-2.17.1.tgz", - "integrity": "sha512-wPMUt6FnH2yzG95SA6mzjQOEKUU3aLaDEmzs1ti+1E9h+CsrZghRlqEM/EJ4KscsQVG8uNN4uVreUeT8+drlgg==", + "version": "2.20.3", + "resolved": "https://registry.npmjs.org/commander/-/commander-2.20.3.tgz", + "integrity": "sha512-GpVkmM8vF2vQUkj2LvZmD35JxeJOLCwJ9cUkugyk2nuhbv3+mJvpLYYt+0+USMxE+oj+ey/lJEnhZw75x/OMcQ==", "dev": true }, "source-map": { @@ -11410,68 +11896,35 @@ "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", "dev": true - }, - "source-map-support": { - "version": "0.5.10", - "resolved": "https://registry.npmjs.org/source-map-support/-/source-map-support-0.5.10.tgz", - "integrity": "sha512-YfQ3tQFTK/yzlGJuX8pTwa4tifQj4QS2Mj7UegOu8jAz59MqIiMGPXxQhVQiIMNzayuUSF/jEuVnfFF5JqybmQ==", - "dev": true, - "requires": { - "buffer-from": "1.1.1", - "source-map": "0.6.1" - } } } }, "terser-webpack-plugin": { - "version": "1.2.1", - "resolved": "https://registry.npmjs.org/terser-webpack-plugin/-/terser-webpack-plugin-1.2.1.tgz", - "integrity": "sha512-GGSt+gbT0oKcMDmPx4SRSfJPE1XaN3kQRWG4ghxKQw9cn5G9x6aCKSsgYdvyM0na9NJ4Drv0RG6jbBByZ5CMjw==", + "version": "1.4.1", + "resolved": "https://registry.npmjs.org/terser-webpack-plugin/-/terser-webpack-plugin-1.4.1.tgz", + "integrity": "sha512-ZXmmfiwtCLfz8WKZyYUuuHf3dMYEjg8NrjHMb0JqHVHVOSkzp3cW2/XG1fP3tRhqEqSzMwzzRQGtAPbs4Cncxg==", "dev": true, "requires": { - "cacache": "11.3.2", - "find-cache-dir": "2.0.0", - "schema-utils": "1.0.0", - "serialize-javascript": "1.6.1", - "source-map": "0.6.1", - "terser": "3.14.1", - "webpack-sources": "1.3.0", - "worker-farm": "1.6.0" + "cacache": "^12.0.2", + "find-cache-dir": "^2.1.0", + "is-wsl": "^1.1.0", + "schema-utils": "^1.0.0", + "serialize-javascript": "^1.7.0", + "source-map": "^0.6.1", + "terser": "^4.1.2", + "webpack-sources": "^1.4.0", + "worker-farm": "^1.7.0" }, "dependencies": { - "ajv": { - "version": "6.7.0", - "resolved": "https://registry.npmjs.org/ajv/-/ajv-6.7.0.tgz", - "integrity": "sha512-RZXPviBTtfmtka9n9sy1N5M5b82CbxWIR6HIis4s3WQTXDJamc/0gpCWNGz6EWdWp4DOfjzJfhz/AS9zVPjjWg==", - "dev": true, - "requires": { - "fast-deep-equal": "2.0.1", - "fast-json-stable-stringify": "2.0.0", - "json-schema-traverse": "0.4.1", - "uri-js": "4.2.2" - } - }, - "ajv-keywords": { - "version": "3.2.0", - "resolved": "https://registry.npmjs.org/ajv-keywords/-/ajv-keywords-3.2.0.tgz", - "integrity": "sha1-6GuBnGAs+IIa1jdBNpjx3sAhhHo=", - "dev": true - }, - "fast-deep-equal": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/fast-deep-equal/-/fast-deep-equal-2.0.1.tgz", - "integrity": "sha1-ewUhjd+WZ79/Nwv3/bLLFf3Qqkk=", - "dev": true - }, "find-cache-dir": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/find-cache-dir/-/find-cache-dir-2.0.0.tgz", - "integrity": "sha512-LDUY6V1Xs5eFskUVYtIwatojt6+9xC9Chnlk/jYOOvn3FAFfSaWddxahDGyNHh0b2dMXa6YW2m0tk8TdVaXHlA==", + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/find-cache-dir/-/find-cache-dir-2.1.0.tgz", + "integrity": "sha512-Tq6PixE0w/VMFfCgbONnkiQIVol/JJL7nRMi20fqzA4NRs9AfeqMGeRdPi3wIhYkxjeBaWh2rxwapn5Tu3IqOQ==", "dev": true, "requires": { - "commondir": "1.0.1", - "make-dir": "1.3.0", - "pkg-dir": "3.0.0" + "commondir": "^1.0.1", + "make-dir": "^2.0.0", + "pkg-dir": "^3.0.0" } }, "find-up": { @@ -11480,32 +11933,36 @@ "integrity": "sha512-1yD6RmLI1XBfxugvORwlck6f75tYL+iR0jqwsOrOxMZyGYqUuDhJ0l4AXdO1iX/FTs9cBAMEk1gWSEx1kSbylg==", "dev": true, "requires": { - "locate-path": "3.0.0" + "locate-path": "^3.0.0" } }, - "json-schema-traverse": { - "version": "0.4.1", - "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-0.4.1.tgz", - "integrity": "sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg==", - "dev": true - }, "locate-path": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-3.0.0.tgz", "integrity": "sha512-7AO748wWnIhNqAuaty2ZWHkQHRSNfPVIsPIfwEOWO22AmaoVrWavlOcMR5nzTLNYvp36X220/maaRsrec1G65A==", "dev": true, "requires": { - "p-locate": "3.0.0", - "path-exists": "3.0.0" + "p-locate": "^3.0.0", + "path-exists": "^3.0.0" } }, - "p-limit": { + "make-dir": { "version": "2.1.0", - "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-2.1.0.tgz", - "integrity": "sha512-NhURkNcrVB+8hNfLuysU8enY5xn2KXphsHBaC2YmRNTZRc7RWusw6apSpdEj3jo4CMb6W9nrF6tTnsJsJeyu6g==", + "resolved": "https://registry.npmjs.org/make-dir/-/make-dir-2.1.0.tgz", + "integrity": "sha512-LS9X+dc8KLxXCb8dni79fLIIUA5VyZoyjSMCwTluaXA0o27cCK0bhXkpgw+sTXVpPy/lSO57ilRixqk0vDmtRA==", + "dev": true, + "requires": { + "pify": "^4.0.1", + "semver": "^5.6.0" + } + }, + "p-limit": { + "version": "2.2.1", + "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-2.2.1.tgz", + "integrity": "sha512-85Tk+90UCVWvbDavCLKPOLC9vvY8OwEX/RtKF+/1OADJMVlFfEHOiMTPVyxg7mk/dKa+ipdHm0OUkTvCpMTuwg==", "dev": true, "requires": { - "p-try": "2.0.0" + "p-try": "^2.0.0" } }, "p-locate": { @@ -11514,13 +11971,13 @@ "integrity": "sha512-x+12w/To+4GFfgJhBEpiDcLozRJGegY+Ei7/z0tSLkMmxGZNybVMSfWj9aJn8Z5Fc7dBUNJOOVgPv2H7IwulSQ==", "dev": true, "requires": { - "p-limit": "2.1.0" + "p-limit": "^2.0.0" } }, "p-try": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/p-try/-/p-try-2.0.0.tgz", - "integrity": "sha512-hMp0onDKIajHfIkdRk3P4CdCmErkYAxxDtP3Wx/4nZ3aGlau2VKh3mZpcuFkH27WQkL/3WBCPOktzA9ZOAnMQQ==", + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/p-try/-/p-try-2.2.0.tgz", + "integrity": "sha512-R4nPAVTAU0B9D35/Gk3uJf/7XYbQcyohSKdvAxIRSNghFl4e71hVoGnBNQz9cWaXxO2I10KTC+3jMdvvoKw6dQ==", "dev": true }, "path-exists": { @@ -11529,30 +11986,25 @@ "integrity": "sha1-zg6+ql94yxiSXqfYENe1mwEP1RU=", "dev": true }, + "pify": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/pify/-/pify-4.0.1.tgz", + "integrity": "sha512-uB80kBFb/tfd68bVleG9T5GGsGPjJrLAUpR5PZIrhBnIaRTQRjqdJSsIKkOP6OAIFbj7GOrcudc5pNjZ+geV2g==", + "dev": true + }, "pkg-dir": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/pkg-dir/-/pkg-dir-3.0.0.tgz", "integrity": "sha512-/E57AYkoeQ25qkxMj5PBOVgF8Kiu/h7cYS30Z5+R7WaiCCBfLq58ZI/dSeaEKb9WVJV5n/03QwrN3IeWIFllvw==", "dev": true, "requires": { - "find-up": "3.0.0" + "find-up": "^3.0.0" } }, - "schema-utils": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/schema-utils/-/schema-utils-1.0.0.tgz", - "integrity": "sha512-i27Mic4KovM/lnGsy8whRCHhc7VicJajAjTrYg11K9zfZXnYIt4k5F+kZkwjnrhKzLic/HLU4j11mjsz2G/75g==", - "dev": true, - "requires": { - "ajv": "6.7.0", - "ajv-errors": "1.0.1", - "ajv-keywords": "3.2.0" - } - }, - "source-list-map": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/source-list-map/-/source-list-map-2.0.1.tgz", - "integrity": "sha512-qnQ7gVMxGNxsiL4lEuJwe/To8UnK7fAnmbGEEH8RpLouuKbeEm0lhbQVFIrNSuB+G7tVrAlVsZgETT5nljf+Iw==", + "semver": { + "version": "5.7.1", + "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.1.tgz", + "integrity": "sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ==", "dev": true }, "source-map": { @@ -11560,19 +12012,14 @@ "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", "dev": true - }, - "webpack-sources": { - "version": "1.3.0", - "resolved": "https://registry.npmjs.org/webpack-sources/-/webpack-sources-1.3.0.tgz", - "integrity": "sha512-OiVgSrbGu7NEnEvQJJgdSFPl2qWKkWq5lHMhgiToIiN9w34EBnjYzSYs+VbL5KoYiLNtFFa7BZIKxRED3I32pA==", - "dev": true, - "requires": { - "source-list-map": "2.0.1", - "source-map": "0.6.1" - } } } }, + "tether": { + "version": "1.4.5", + "resolved": "https://registry.npmjs.org/tether/-/tether-1.4.5.tgz", + "integrity": "sha512-fysT1Gug2wbRi7a6waeu39yVDwiNtvwj5m9eRD+qZDSHKNghLo6KqP/U3yM2ap6TNUL2skjXGJaJJTJqoC31vw==" + }, "text-table": { "version": "0.2.0", "resolved": "https://registry.npmjs.org/text-table/-/text-table-0.2.0.tgz", @@ -11589,14 +12036,14 @@ "integrity": "sha512-/mrRod8xqpA+IHSLyGCQ2s8SPHiCDEeQJSep1jqLYeEUClOFG2Qsh+4FU6G9VeqpZnGW/Su8LQGc4YKni5rYSQ==", "dev": true, "requires": { - "readable-stream": "2.3.6", - "xtend": "4.0.1" + "readable-stream": "~2.3.6", + "xtend": "~4.0.1" }, "dependencies": { "inherits": { - "version": "2.0.3", - "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.3.tgz", - "integrity": "sha1-Yzwsg+PaQqUC9SRmAiSA9CCCYd4=", + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.4.tgz", + "integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==", "dev": true }, "readable-stream": { @@ -11605,13 +12052,13 @@ "integrity": "sha512-tQtKA9WIAhBF3+VLAseyMqZeBjW0AHJoxOtYqSUZNJxauErmLbVm2FW1y+J/YA9dUrAC39ITejlZWhVIwawkKw==", "dev": true, "requires": { - "core-util-is": "1.0.2", - "inherits": "2.0.3", - "isarray": "1.0.0", - "process-nextick-args": "2.0.0", - "safe-buffer": "5.1.1", - "string_decoder": "1.1.1", - "util-deprecate": "1.0.2" + "core-util-is": "~1.0.0", + "inherits": "~2.0.3", + "isarray": "~1.0.0", + "process-nextick-args": "~2.0.0", + "safe-buffer": "~5.1.1", + "string_decoder": "~1.1.1", + "util-deprecate": "~1.0.1" } }, "string_decoder": { @@ -11620,23 +12067,42 @@ "integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==", "dev": true, "requires": { - "safe-buffer": "5.1.1" + "safe-buffer": "~5.1.0" } } } }, "thunky": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/thunky/-/thunky-1.0.3.tgz", - "integrity": "sha512-YwT8pjmNcAXBZqrubu22P4FYsh2D4dxRmnWBOL8Jk8bUcRUtc5326kx32tuTmFDAZtLOGEVNl8POAR8j896Iow==", + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/thunky/-/thunky-1.1.0.tgz", + "integrity": "sha512-eHY7nBftgThBqOyHGVN+l8gF0BucP09fMo0oO/Lb0w1OF80dJv+lDVpXG60WMQvkcxAkNybKsrEIE3ZtKGmPrA==", "dev": true }, + "timers-browserify": { + "version": "2.0.11", + "resolved": "https://registry.npmjs.org/timers-browserify/-/timers-browserify-2.0.11.tgz", + "integrity": "sha512-60aV6sgJ5YEbzUdn9c8kYGIqOubPoUdqQCul3SBAsRCZ40s6Y5cMcrW4dt3/k/EsbLVJNl9n6Vz3fTc+k2GeKQ==", + "dev": true, + "requires": { + "setimmediate": "^1.0.4" + } + }, + "tiny-invariant": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/tiny-invariant/-/tiny-invariant-1.0.5.tgz", + "integrity": "sha512-BziszNEQNwtyMS9OVJia2LK9N9b6VJ35kBrvhDDDpr4hreLYqhCie15dB35uZMdqv9ZTQ55GHQtkz2FnleTHIA==" + }, + "tiny-warning": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/tiny-warning/-/tiny-warning-1.0.3.tgz", + "integrity": "sha512-lBN9zLN/oAf68o3zNXYrdCt1kP8WsiGW8Oo2ka41b2IM5JL/S1CTyX1rW0mb/zSuJun0ZUrDxx4sqvYS2FWzPA==" + }, "tmp": { "version": "0.0.33", "resolved": "https://registry.npmjs.org/tmp/-/tmp-0.0.33.tgz", "integrity": "sha1-bTQzWIl2jSGyvNoKonfO07G/rfk=", "requires": { - "os-tmpdir": "1.0.2" + "os-tmpdir": "~1.0.2" } }, "to-arraybuffer": { @@ -11651,7 +12117,7 @@ "integrity": "sha1-KXWIt7Dn4KwI4E5nL4XB9JmeF68=", "dev": true, "requires": { - "kind-of": "3.2.2" + "kind-of": "^3.0.2" }, "dependencies": { "kind-of": { @@ -11660,7 +12126,7 @@ "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=", "dev": true, "requires": { - "is-buffer": "1.1.6" + "is-buffer": "^1.1.5" } } } @@ -11671,10 +12137,10 @@ "integrity": "sha512-FWtleNAtZ/Ki2qtqej2CXTOayOH9bHDQF+Q48VpWyDXjbYxA4Yz8iDB31zXOBUlOHHKidDbqGVrTUvQMPmBGBw==", "dev": true, "requires": { - "define-property": "2.0.2", - "extend-shallow": "3.0.2", - "regex-not": "1.0.2", - "safe-regex": "1.1.0" + "define-property": "^2.0.2", + "extend-shallow": "^3.0.2", + "regex-not": "^1.0.2", + "safe-regex": "^1.1.0" } }, "to-regex-range": { @@ -11683,30 +12149,16 @@ "integrity": "sha1-fIDBe53+vlmeJzZ+DU3VWQFB2zg=", "dev": true, "requires": { - "is-number": "3.0.0", - "repeat-string": "1.6.1" - }, - "dependencies": { - "is-number": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/is-number/-/is-number-3.0.0.tgz", - "integrity": "sha1-JP1iAaR4LPUFYcgQJ2r8fRLXEZU=", - "dev": true, - "requires": { - "kind-of": "3.2.2" - } - }, - "kind-of": { - "version": "3.2.2", - "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", - "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=", - "dev": true, - "requires": { - "is-buffer": "1.1.6" - } - } + "is-number": "^3.0.0", + "repeat-string": "^1.6.1" } }, + "toidentifier": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/toidentifier/-/toidentifier-1.0.0.tgz", + "integrity": "sha512-yaOH/Pk/VEhBWWTlhI+qXxDFXlejDGcQipMlyxda9nthulaxLZUNcUqFxokp0vcYnvteJln5FNQDRrxj3YcbVw==", + "dev": true + }, "toposort": { "version": "1.0.7", "resolved": "https://registry.npmjs.org/toposort/-/toposort-1.0.7.tgz", @@ -11720,7 +12172,7 @@ "dev": true, "optional": true, "requires": { - "punycode": "1.4.1" + "punycode": "^1.4.1" } }, "trim-newlines": { @@ -11741,7 +12193,7 @@ "integrity": "sha512-m6s2OdQe5wgpFMC+pAJ+q9djG82O2jcHPOI6RNg1yy9rCYR+WD6Nbpl32fDpfC56nirdRy+opFa/Vk7HYhqaew==", "dev": true, "requires": { - "glob": "7.1.2" + "glob": "^7.1.2" } }, "tslib": { @@ -11762,7 +12214,7 @@ "integrity": "sha1-J6XeoGs2sEoKmWZ3SykIaPD8QP0=", "dev": true, "requires": { - "safe-buffer": "5.1.1" + "safe-buffer": "^5.0.1" } }, "tweetnacl": { @@ -11777,17 +12229,34 @@ "resolved": "https://registry.npmjs.org/type-check/-/type-check-0.3.2.tgz", "integrity": "sha1-WITKtRLPHTVeP7eE8wgEsrUg23I=", "requires": { - "prelude-ls": "1.1.2" + "prelude-ls": "~1.1.2" } }, "type-is": { - "version": "1.6.16", - "resolved": "https://registry.npmjs.org/type-is/-/type-is-1.6.16.tgz", - "integrity": "sha1-+JzjQVQcZysl7nrjxz3uOyvlAZQ=", + "version": "1.6.18", + "resolved": "https://registry.npmjs.org/type-is/-/type-is-1.6.18.tgz", + "integrity": "sha512-TkRKr9sUTxEH8MdfuCSP7VizJyzRNMjj2J2do2Jr3Kym598JVdEksuzPQCnlFPW4ky9Q+iA+ma9BGm06XQBy8g==", "dev": true, "requires": { "media-typer": "0.3.0", - "mime-types": "2.1.18" + "mime-types": "~2.1.24" + }, + "dependencies": { + "mime-db": { + "version": "1.42.0", + "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.42.0.tgz", + "integrity": "sha512-UbfJCR4UAVRNgMpfImz05smAXK7+c+ZntjaA26ANtkXLlOe947Aag5zdIcKQULAiF9Cq4WxBi9jUs5zkA84bYQ==", + "dev": true + }, + "mime-types": { + "version": "2.1.25", + "resolved": "https://registry.npmjs.org/mime-types/-/mime-types-2.1.25.tgz", + "integrity": "sha512-5KhStqB5xpTAeGqKBAMgwaYMnQik7teQN4IAzC7npDv6kzeU6prfkR67bc87J1kWMPGkoaZSq1npmexMgkmEVg==", + "dev": true, + "requires": { + "mime-db": "1.42.0" + } + } } }, "typedarray": { @@ -11806,8 +12275,8 @@ "integrity": "sha512-8CJsbKOtEbnJsTyv6LE6m6ZKniqMiFWmm9sRbopbkGs3gMPPfd3Fh8iIA4Ykv5MgaTbqHr4BaoGLJLZNhsrW1Q==", "dev": true, "requires": { - "commander": "2.17.1", - "source-map": "0.6.1" + "commander": "~2.17.1", + "source-map": "~0.6.1" }, "dependencies": { "source-map": { @@ -11830,8 +12299,8 @@ "integrity": "sha512-L4Qoh15vTfntsn4P1zqnHulG0LdXgjSO035fEpdtp6YxXhMT51Q6vgM5lYdG/5X3MjS+k/Y9Xw4SFCY9IkR0rg==", "dev": true, "requires": { - "unicode-canonical-property-names-ecmascript": "1.0.4", - "unicode-property-aliases-ecmascript": "1.0.4" + "unicode-canonical-property-names-ecmascript": "^1.0.4", + "unicode-property-aliases-ecmascript": "^1.0.4" } }, "unicode-match-property-value-ecmascript": { @@ -11847,38 +12316,15 @@ "dev": true }, "union-value": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/union-value/-/union-value-1.0.0.tgz", - "integrity": "sha1-XHHDTLW61dzr4+oM0IIHulqhrqQ=", + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/union-value/-/union-value-1.0.1.tgz", + "integrity": "sha512-tJfXmxMeWYnczCVs7XAEvIV7ieppALdyepWMkHkwciRpZraG/xwT+s2JN8+pr1+8jCRf80FFzvr+MpQeeoF4Xg==", "dev": true, "requires": { - "arr-union": "3.1.0", - "get-value": "2.0.6", - "is-extendable": "0.1.1", - "set-value": "0.4.3" - }, - "dependencies": { - "extend-shallow": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz", - "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=", - "dev": true, - "requires": { - "is-extendable": "0.1.1" - } - }, - "set-value": { - "version": "0.4.3", - "resolved": "https://registry.npmjs.org/set-value/-/set-value-0.4.3.tgz", - "integrity": "sha1-fbCPnT0i3H945Trzw79GZuzfzPE=", - "dev": true, - "requires": { - "extend-shallow": "2.0.1", - "is-extendable": "0.1.1", - "is-plain-object": "2.0.4", - "to-object-path": "0.3.0" - } - } + "arr-union": "^3.1.0", + "get-value": "^2.0.6", + "is-extendable": "^0.1.1", + "set-value": "^2.0.1" } }, "uniq": { @@ -11892,18 +12338,24 @@ "integrity": "sha512-Vmp0jIp2ln35UTXuryvjzkjGdRyf9b2lTXuSYUiPmzRcl3FDtYqAwOnTJkAngD9SWhnoJzDbTKwaOrZ+STtxNQ==", "dev": true, "requires": { - "unique-slug": "2.0.1" + "unique-slug": "^2.0.0" } }, "unique-slug": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/unique-slug/-/unique-slug-2.0.1.tgz", - "integrity": "sha512-n9cU6+gITaVu7VGj1Z8feKMmfAjEAQGhwD9fE3zvpRRa0wEIx8ODYkVGfSc94M2OX00tUFV8wH3zYbm1I8mxFg==", + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/unique-slug/-/unique-slug-2.0.2.tgz", + "integrity": "sha512-zoWr9ObaxALD3DOPfjPSqxt4fnZiWblxHIgeWqW8x7UqDzEtHEQLzji2cuJYQFCU6KmoJikOYAZlrTHHebjx2w==", "dev": true, "requires": { - "imurmurhash": "0.1.4" + "imurmurhash": "^0.1.4" } }, + "universalify": { + "version": "0.1.2", + "resolved": "https://registry.npmjs.org/universalify/-/universalify-0.1.2.tgz", + "integrity": "sha512-rBJeI5CXAlmy1pV+617WB9J63U6XcazHHF2f2dbJix4XzpUF0RS3Zbj0FGIOCAva5P/d/GBOYaACQ1w+0azUkg==", + "dev": true + }, "unpipe": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/unpipe/-/unpipe-1.0.0.tgz", @@ -11916,8 +12368,8 @@ "integrity": "sha1-g3aHP30jNRef+x5vw6jtDfyKtVk=", "dev": true, "requires": { - "has-value": "0.3.1", - "isobject": "3.0.1" + "has-value": "^0.3.1", + "isobject": "^3.0.0" }, "dependencies": { "has-value": { @@ -11926,9 +12378,9 @@ "integrity": "sha1-ex9YutpiyoJ+wKIHgCVlSEWZXh8=", "dev": true, "requires": { - "get-value": "2.0.6", - "has-values": "0.1.4", - "isobject": "2.1.0" + "get-value": "^2.0.3", + "has-values": "^0.1.4", + "isobject": "^2.0.0" }, "dependencies": { "isobject": { @@ -11951,9 +12403,9 @@ } }, "upath": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/upath/-/upath-1.1.0.tgz", - "integrity": "sha512-bzpH/oBhoS/QI/YtbkqCg6VEiPYjSZtrHQM6/QnJS6OL9pKUFLqb3aFh4Scvwm45+7iAgiMkLhSbaZxUqmrprw==", + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/upath/-/upath-1.2.0.tgz", + "integrity": "sha512-aZwGpamFO61g3OlfT7OQCHqhGnW43ieH9WZeP7QxN/G/jS4jfqUkZxoryvJgVPEcrl5NL/ggHsSmLMHuH64Lhg==", "dev": true }, "upper-case": { @@ -11968,7 +12420,7 @@ "integrity": "sha512-KY9Frmirql91X2Qgjry0Wd4Y+YTdrdZheS8TFwvkbLWf/G5KNJDCh6pKL5OZctEW4+0Baa5idK2ZQuELRwPznQ==", "dev": true, "requires": { - "punycode": "2.1.1" + "punycode": "^2.1.0" }, "dependencies": { "punycode": { @@ -12014,9 +12466,9 @@ "integrity": "sha512-dXHkKmw8FhPqu8asTc1puBfe3TehOCo2+RmOOev5suNCIYBcT626kxiWg1NBVkwc4rO8BGa7gP70W7VXuqHrjg==", "dev": true, "requires": { - "loader-utils": "1.2.3", - "mime": "2.4.0", - "schema-utils": "1.0.0" + "loader-utils": "^1.1.0", + "mime": "^2.0.3", + "schema-utils": "^1.0.0" }, "dependencies": { "ajv": { @@ -12025,10 +12477,10 @@ "integrity": "sha512-RZXPviBTtfmtka9n9sy1N5M5b82CbxWIR6HIis4s3WQTXDJamc/0gpCWNGz6EWdWp4DOfjzJfhz/AS9zVPjjWg==", "dev": true, "requires": { - "fast-deep-equal": "2.0.1", - "fast-json-stable-stringify": "2.0.0", - "json-schema-traverse": "0.4.1", - "uri-js": "4.2.2" + "fast-deep-equal": "^2.0.1", + "fast-json-stable-stringify": "^2.0.0", + "json-schema-traverse": "^0.4.1", + "uri-js": "^4.2.2" } }, "ajv-keywords": { @@ -12061,7 +12513,7 @@ "integrity": "sha512-aKS4WQjPenRxiQsC93MNfjx+nbF4PAdYzmd/1JIj8HYzqfbu86beTuNgXDzPknWk0n0uARlyewZo4s++ES36Ow==", "dev": true, "requires": { - "minimist": "1.2.0" + "minimist": "^1.2.0" } }, "loader-utils": { @@ -12070,9 +12522,9 @@ "integrity": "sha512-fkpz8ejdnEMG3s37wGL07iSBDg99O9D5yflE9RGNH3hRdx9SOwYfnGYdZOUIZitN8E+E2vkq3MUMYMvPYl5ZZA==", "dev": true, "requires": { - "big.js": "5.2.2", - "emojis-list": "2.1.0", - "json5": "1.0.1" + "big.js": "^5.2.2", + "emojis-list": "^2.0.0", + "json5": "^1.0.1" } }, "mime": { @@ -12093,9 +12545,9 @@ "integrity": "sha512-i27Mic4KovM/lnGsy8whRCHhc7VicJajAjTrYg11K9zfZXnYIt4k5F+kZkwjnrhKzLic/HLU4j11mjsz2G/75g==", "dev": true, "requires": { - "ajv": "6.7.0", - "ajv-errors": "1.0.1", - "ajv-keywords": "3.2.0" + "ajv": "^6.1.0", + "ajv-errors": "^1.0.0", + "ajv-keywords": "^3.1.0" } } } @@ -12105,8 +12557,8 @@ "resolved": "https://registry.npmjs.org/url-parse/-/url-parse-1.4.3.tgz", "integrity": "sha512-rh+KuAW36YKo0vClhQzLLveoj8FwPJNu65xLb7Mrt+eZht0IPT0IXgSv8gcMegZ6NvjJUALf6Mf25POlMwD1Fw==", "requires": { - "querystringify": "2.0.0", - "requires-port": "1.0.0" + "querystringify": "^2.0.0", + "requires-port": "^1.0.0" }, "dependencies": { "querystringify": { @@ -12141,8 +12593,8 @@ "integrity": "sha512-i+6qA2MPhvoKLuxnJNpXAGhg7HphQOSUq2LKMZD0m15EiskXUkMvKdF4Uui0WYeCUGea+o2cw/ZuwehtfsrNkA==", "dev": true, "requires": { - "define-properties": "1.1.2", - "object.getownpropertydescriptors": "2.0.3" + "define-properties": "^1.1.2", + "object.getownpropertydescriptors": "^2.0.3" } }, "utila": { @@ -12163,9 +12615,9 @@ "integrity": "sha512-yXJmeNaw3DnnKAOKJE51sL/ZaYfWJRl1pK9dr19YFCu0ObS231AB1/LbqTKRAQ5kw8A90rA6fr4riOUpTZvQZA==" }, "v8-compile-cache": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/v8-compile-cache/-/v8-compile-cache-2.0.2.tgz", - "integrity": "sha512-1wFuMUIM16MDJRCrpbpuEPTUGmM5QMUg0cr3KFwra2XgOgFcPGDQHDh3CszSCD2Zewc/dh/pamNEW8CbfDebUw==", + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/v8-compile-cache/-/v8-compile-cache-2.0.3.tgz", + "integrity": "sha512-CNmdbwQMBjwr9Gsmohvm0pbL954tJrNzf6gWL3K+QMQf00PF7ERGrEiLgjuU3mKreLC2MeGhUsNV9ybTbLgd3w==", "dev": true }, "validate-npm-package-license": { @@ -12173,10 +12625,15 @@ "resolved": "https://registry.npmjs.org/validate-npm-package-license/-/validate-npm-package-license-3.0.3.tgz", "integrity": "sha1-gWQ7y+8b3+zUYjeT3EZIlIupgzg=", "requires": { - "spdx-correct": "3.0.0", - "spdx-expression-parse": "3.0.0" + "spdx-correct": "^3.0.0", + "spdx-expression-parse": "^3.0.0" } }, + "value-equal": { + "version": "0.4.0", + "resolved": "https://registry.npmjs.org/value-equal/-/value-equal-0.4.0.tgz", + "integrity": "sha512-x+cYdNnaA3CxvMaTX0INdTCN8m8aF2uY9BvEqmxuYp8bL09cs/kWVQPVGcA35fMktdOsP69IgU7wFj/61dJHEw==" + }, "vary": { "version": "1.1.2", "resolved": "https://registry.npmjs.org/vary/-/vary-1.1.2.tgz", @@ -12189,31 +12646,31 @@ "integrity": "sha1-OhBcoXBTr1XW4nDB+CiGguGNpAA=", "dev": true, "requires": { - "assert-plus": "1.0.0", + "assert-plus": "^1.0.0", "core-util-is": "1.0.2", - "extsprintf": "1.3.0" + "extsprintf": "^1.2.0" } }, "vm-browserify": { - "version": "0.0.4", - "resolved": "https://registry.npmjs.org/vm-browserify/-/vm-browserify-0.0.4.tgz", - "integrity": "sha1-XX6kW7755Kb/ZflUOOCofDV9WnM=", - "dev": true, - "requires": { - "indexof": "0.0.1" - } + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/vm-browserify/-/vm-browserify-1.1.2.tgz", + "integrity": "sha512-2ham8XPWTONajOR0ohOKOHXkm3+gaBmGut3SRuu75xLd/RRaY6vqgh8NBYYk7+RW3u5AtzPQZG8F10LHkl0lAQ==", + "dev": true }, "w3c-blob": { "version": "0.0.1", "resolved": "https://registry.npmjs.org/w3c-blob/-/w3c-blob-0.0.1.tgz", "integrity": "sha1-sM01KhpQ9RVWNCD/1YYflQ8dhbg=" }, - "warning": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/warning/-/warning-2.1.0.tgz", - "integrity": "sha1-ISINnGOvx3qMkhEeARr3Bc4MaQE=", + "watchpack": { + "version": "1.6.0", + "resolved": "https://registry.npmjs.org/watchpack/-/watchpack-1.6.0.tgz", + "integrity": "sha512-i6dHe3EyLjMmDlU1/bGQpEw25XSjkJULPuAVKCbNRefQVq48yXKUpwg538F7AZTf9kyr57zj++pQFltUa5H7yA==", + "dev": true, "requires": { - "loose-envify": "1.3.1" + "chokidar": "^2.0.2", + "graceful-fs": "^4.1.2", + "neo-async": "^2.5.0" } }, "wbuf": { @@ -12222,482 +12679,105 @@ "integrity": "sha512-O84QOnr0icsbFGLS0O3bI5FswxzRr8/gHwWkDlQFskhSPryQXvrTMxjxGP4+iWYoauLoBvfDpkrOauZ+0iZpDA==", "dev": true, "requires": { - "minimalistic-assert": "1.0.1" + "minimalistic-assert": "^1.0.0" } }, "webpack": { - "version": "4.28.4", - "resolved": "https://registry.npmjs.org/webpack/-/webpack-4.28.4.tgz", - "integrity": "sha512-NxjD61WsK/a3JIdwWjtIpimmvE6UrRi3yG54/74Hk9rwNj5FPkA4DJCf1z4ByDWLkvZhTZE+P3C/eh6UD5lDcw==", - "dev": true, - "requires": { - "@webassemblyjs/ast": "1.7.11", - "@webassemblyjs/helper-module-context": "1.7.11", - "@webassemblyjs/wasm-edit": "1.7.11", - "@webassemblyjs/wasm-parser": "1.7.11", - "acorn": "5.7.3", - "acorn-dynamic-import": "3.0.0", - "ajv": "6.7.0", - "ajv-keywords": "3.2.0", - "chrome-trace-event": "1.0.0", - "enhanced-resolve": "4.1.0", - "eslint-scope": "4.0.0", - "json-parse-better-errors": "1.0.2", - "loader-runner": "2.4.0", - "loader-utils": "1.2.3", - "memory-fs": "0.4.1", - "micromatch": "3.1.10", - "mkdirp": "0.5.1", - "neo-async": "2.5.0", - "node-libs-browser": "2.2.0", - "schema-utils": "0.4.7", - "tapable": "1.1.1", - "terser-webpack-plugin": "1.2.1", - "watchpack": "1.6.0", - "webpack-sources": "1.3.0" + "version": "4.41.2", + "resolved": "https://registry.npmjs.org/webpack/-/webpack-4.41.2.tgz", + "integrity": "sha512-Zhw69edTGfbz9/8JJoyRQ/pq8FYUoY0diOXqW0T6yhgdhCv6wr0hra5DwwWexNRns2Z2+gsnrNcbe9hbGBgk/A==", + "dev": true, + "requires": { + "@webassemblyjs/ast": "1.8.5", + "@webassemblyjs/helper-module-context": "1.8.5", + "@webassemblyjs/wasm-edit": "1.8.5", + "@webassemblyjs/wasm-parser": "1.8.5", + "acorn": "^6.2.1", + "ajv": "^6.10.2", + "ajv-keywords": "^3.4.1", + "chrome-trace-event": "^1.0.2", + "enhanced-resolve": "^4.1.0", + "eslint-scope": "^4.0.3", + "json-parse-better-errors": "^1.0.2", + "loader-runner": "^2.4.0", + "loader-utils": "^1.2.3", + "memory-fs": "^0.4.1", + "micromatch": "^3.1.10", + "mkdirp": "^0.5.1", + "neo-async": "^2.6.1", + "node-libs-browser": "^2.2.1", + "schema-utils": "^1.0.0", + "tapable": "^1.1.3", + "terser-webpack-plugin": "^1.4.1", + "watchpack": "^1.6.0", + "webpack-sources": "^1.4.1" }, "dependencies": { "acorn": { - "version": "5.7.3", - "resolved": "https://registry.npmjs.org/acorn/-/acorn-5.7.3.tgz", - "integrity": "sha512-T/zvzYRfbVojPWahDsE5evJdHb3oJoQfFbsrKM7w5Zcs++Tr257tia3BmMP8XYVjp1S9RZXQMh7gao96BlqZOw==", + "version": "6.4.0", + "resolved": "https://registry.npmjs.org/acorn/-/acorn-6.4.0.tgz", + "integrity": "sha512-gac8OEcQ2Li1dxIEWGZzsp2BitJxwkwcOm0zHAJLcPJaVvm58FRnk6RkuLRpU1EujipU2ZFODv2P9DLMfnV8mw==", "dev": true }, "ajv": { - "version": "6.7.0", - "resolved": "https://registry.npmjs.org/ajv/-/ajv-6.7.0.tgz", - "integrity": "sha512-RZXPviBTtfmtka9n9sy1N5M5b82CbxWIR6HIis4s3WQTXDJamc/0gpCWNGz6EWdWp4DOfjzJfhz/AS9zVPjjWg==", + "version": "6.10.2", + "resolved": "https://registry.npmjs.org/ajv/-/ajv-6.10.2.tgz", + "integrity": "sha512-TXtUUEYHuaTEbLZWIKUr5pmBuhDLy+8KYtPYdcV8qC+pOZL+NKqYwvWSRrVXHn+ZmRRAu8vJTAznH7Oag6RVRw==", "dev": true, "requires": { - "fast-deep-equal": "2.0.1", - "fast-json-stable-stringify": "2.0.0", - "json-schema-traverse": "0.4.1", - "uri-js": "4.2.2" + "fast-deep-equal": "^2.0.1", + "fast-json-stable-stringify": "^2.0.0", + "json-schema-traverse": "^0.4.1", + "uri-js": "^4.2.2" } }, "ajv-keywords": { - "version": "3.2.0", - "resolved": "https://registry.npmjs.org/ajv-keywords/-/ajv-keywords-3.2.0.tgz", - "integrity": "sha1-6GuBnGAs+IIa1jdBNpjx3sAhhHo=", + "version": "3.4.1", + "resolved": "https://registry.npmjs.org/ajv-keywords/-/ajv-keywords-3.4.1.tgz", + "integrity": "sha512-RO1ibKvd27e6FEShVFfPALuHI3WjSVNeK5FIsmme/LYRNxjKuNj+Dt7bucLa6NdSv3JcVTyMlm9kGR84z1XpaQ==", "dev": true }, - "anymatch": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/anymatch/-/anymatch-2.0.0.tgz", - "integrity": "sha512-5teOsQWABXHHBFP9y3skS5P3d/WfWXpv3FUpy+LorMrNYaT9pI4oLMQX7jzQ2KklNpGpWHzdCXTDT2Y3XGlZBw==", + "big.js": { + "version": "5.2.2", + "resolved": "https://registry.npmjs.org/big.js/-/big.js-5.2.2.tgz", + "integrity": "sha512-vyL2OymJxmarO8gxMr0mhChsO9QGwhynfuu4+MHTAW6czfq9humCB7rKpUjDd9YUiDPU4mzpyupFSvOClAwbmQ==", + "dev": true + }, + "eslint-scope": { + "version": "4.0.3", + "resolved": "https://registry.npmjs.org/eslint-scope/-/eslint-scope-4.0.3.tgz", + "integrity": "sha512-p7VutNr1O/QrxysMo3E45FjYDTeXBy0iTltPFNSqKAIfjDSXC+4dj+qfyuD8bfAXrW/y6lW3O76VaYNPKfpKrg==", "dev": true, "requires": { - "micromatch": "3.1.10", - "normalize-path": "2.1.1" + "esrecurse": "^4.1.0", + "estraverse": "^4.1.1" } }, - "arr-diff": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/arr-diff/-/arr-diff-4.0.0.tgz", - "integrity": "sha1-1kYQdP6/7HHn4VI1dhoyml3HxSA=", + "fast-deep-equal": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/fast-deep-equal/-/fast-deep-equal-2.0.1.tgz", + "integrity": "sha1-ewUhjd+WZ79/Nwv3/bLLFf3Qqkk=", "dev": true }, - "array-unique": { - "version": "0.3.2", - "resolved": "https://registry.npmjs.org/array-unique/-/array-unique-0.3.2.tgz", - "integrity": "sha1-qJS3XUvE9s1nnvMkSp/Y9Gri1Cg=", + "json-parse-better-errors": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/json-parse-better-errors/-/json-parse-better-errors-1.0.2.tgz", + "integrity": "sha512-mrqyZKfX5EhL7hvqcV6WG1yYjnjeuYDzDhhcAAUrq8Po85NBQBJP+ZDUT75qZQ98IkUoBqdkExkukOU7Ts2wrw==", "dev": true }, - "big.js": { - "version": "5.2.2", - "resolved": "https://registry.npmjs.org/big.js/-/big.js-5.2.2.tgz", - "integrity": "sha512-vyL2OymJxmarO8gxMr0mhChsO9QGwhynfuu4+MHTAW6czfq9humCB7rKpUjDd9YUiDPU4mzpyupFSvOClAwbmQ==", + "json-schema-traverse": { + "version": "0.4.1", + "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-0.4.1.tgz", + "integrity": "sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg==", "dev": true }, - "braces": { - "version": "2.3.2", - "resolved": "https://registry.npmjs.org/braces/-/braces-2.3.2.tgz", - "integrity": "sha512-aNdbnj9P8PjdXU4ybaWLK2IF3jc/EoDYbC7AazW6to3TRsfXxscC9UXOB5iDiEQrkyIbWp2SLQda4+QAa7nc3w==", + "json5": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/json5/-/json5-1.0.1.tgz", + "integrity": "sha512-aKS4WQjPenRxiQsC93MNfjx+nbF4PAdYzmd/1JIj8HYzqfbu86beTuNgXDzPknWk0n0uARlyewZo4s++ES36Ow==", "dev": true, "requires": { - "arr-flatten": "1.1.0", - "array-unique": "0.3.2", - "extend-shallow": "2.0.1", - "fill-range": "4.0.0", - "isobject": "3.0.1", - "repeat-element": "1.1.3", - "snapdragon": "0.8.2", - "snapdragon-node": "2.1.1", - "split-string": "3.1.0", - "to-regex": "3.0.2" - }, - "dependencies": { - "extend-shallow": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz", - "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=", - "dev": true, - "requires": { - "is-extendable": "0.1.1" - } - } - } - }, - "browserify-zlib": { - "version": "0.2.0", - "resolved": "https://registry.npmjs.org/browserify-zlib/-/browserify-zlib-0.2.0.tgz", - "integrity": "sha512-Z942RysHXmJrhqk88FmKBVq/v5tqmSkDz7p54G/MGyjMnCFFnC79XWNbg+Vta8W6Wb2qtSZTSxIGkJrRpCFEiA==", - "dev": true, - "requires": { - "pako": "1.0.5" - } - }, - "buffer": { - "version": "4.9.1", - "resolved": "https://registry.npmjs.org/buffer/-/buffer-4.9.1.tgz", - "integrity": "sha1-bRu2AbB6TvztlwlBMgkwJ8lbwpg=", - "dev": true, - "requires": { - "base64-js": "1.2.3", - "ieee754": "1.1.8", - "isarray": "1.0.0" - } - }, - "chokidar": { - "version": "2.0.4", - "resolved": "https://registry.npmjs.org/chokidar/-/chokidar-2.0.4.tgz", - "integrity": "sha512-z9n7yt9rOvIJrMhvDtDictKrkFHeihkNl6uWMmZlmL6tJtX9Cs+87oK+teBx+JIgzvbX3yZHT3eF8vpbDxHJXQ==", - "dev": true, - "requires": { - "anymatch": "2.0.0", - "async-each": "1.0.1", - "braces": "2.3.2", - "fsevents": "1.2.4", - "glob-parent": "3.1.0", - "inherits": "2.0.1", - "is-binary-path": "1.0.1", - "is-glob": "4.0.0", - "lodash.debounce": "4.0.8", - "normalize-path": "2.1.1", - "path-is-absolute": "1.0.1", - "readdirp": "2.2.1", - "upath": "1.1.0" - } - }, - "constants-browserify": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/constants-browserify/-/constants-browserify-1.0.0.tgz", - "integrity": "sha1-wguW2MYXdIqvHBYCF2DNJ/y4y3U=", - "dev": true - }, - "crypto-browserify": { - "version": "3.12.0", - "resolved": "https://registry.npmjs.org/crypto-browserify/-/crypto-browserify-3.12.0.tgz", - "integrity": "sha512-fz4spIh+znjO2VjL+IdhEpRJ3YN6sMzITSBijk6FK2UvTqruSQW+/cCZTSNsMiZNvUeq0CqurF+dAbyiGOY6Wg==", - "dev": true, - "requires": { - "browserify-cipher": "1.0.1", - "browserify-sign": "4.0.4", - "create-ecdh": "4.0.3", - "create-hash": "1.2.0", - "create-hmac": "1.1.7", - "diffie-hellman": "5.0.3", - "inherits": "2.0.1", - "pbkdf2": "3.0.17", - "public-encrypt": "4.0.3", - "randombytes": "2.0.6", - "randomfill": "1.0.4" - } - }, - "enhanced-resolve": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/enhanced-resolve/-/enhanced-resolve-4.1.0.tgz", - "integrity": "sha512-F/7vkyTtyc/llOIn8oWclcB25KdRaiPBpZYDgJHgh/UHtpgT2p2eldQgtQnLtUvfMKPKxbRaQM/hHkvLHt1Vng==", - "dev": true, - "requires": { - "graceful-fs": "4.1.11", - "memory-fs": "0.4.1", - "tapable": "1.1.1" - } - }, - "eslint-scope": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/eslint-scope/-/eslint-scope-4.0.0.tgz", - "integrity": "sha512-1G6UTDi7Jc1ELFwnR58HV4fK9OQK4S6N985f166xqXxpjU6plxFISJa2Ba9KCQuFa8RCnj/lSFJbHo7UFDBnUA==", - "dev": true, - "requires": { - "esrecurse": "4.2.1", - "estraverse": "4.2.0" - } - }, - "events": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/events/-/events-3.0.0.tgz", - "integrity": "sha512-Dc381HFWJzEOhQ+d8pkNon++bk9h6cdAoAj4iE6Q4y6xgTzySWXlKn05/TVNpjnfRqi/X0EpJEJohPjNI3zpVA==", - "dev": true - }, - "expand-brackets": { - "version": "2.1.4", - "resolved": "https://registry.npmjs.org/expand-brackets/-/expand-brackets-2.1.4.tgz", - "integrity": "sha1-t3c14xXOMPa27/D4OwQVGiJEliI=", - "dev": true, - "requires": { - "debug": "2.6.9", - "define-property": "0.2.5", - "extend-shallow": "2.0.1", - "posix-character-classes": "0.1.1", - "regex-not": "1.0.2", - "snapdragon": "0.8.2", - "to-regex": "3.0.2" - }, - "dependencies": { - "define-property": { - "version": "0.2.5", - "resolved": "https://registry.npmjs.org/define-property/-/define-property-0.2.5.tgz", - "integrity": "sha1-w1se+RjsPJkPmlvFe+BKrOxcgRY=", - "dev": true, - "requires": { - "is-descriptor": "0.1.6" - } - }, - "extend-shallow": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz", - "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=", - "dev": true, - "requires": { - "is-extendable": "0.1.1" - } - }, - "is-accessor-descriptor": { - "version": "0.1.6", - "resolved": "https://registry.npmjs.org/is-accessor-descriptor/-/is-accessor-descriptor-0.1.6.tgz", - "integrity": "sha1-qeEss66Nh2cn7u84Q/igiXtcmNY=", - "dev": true, - "requires": { - "kind-of": "3.2.2" - }, - "dependencies": { - "kind-of": { - "version": "3.2.2", - "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", - "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=", - "dev": true, - "requires": { - "is-buffer": "1.1.6" - } - } - } - }, - "is-data-descriptor": { - "version": "0.1.4", - "resolved": "https://registry.npmjs.org/is-data-descriptor/-/is-data-descriptor-0.1.4.tgz", - "integrity": "sha1-C17mSDiOLIYCgueT8YVv7D8wG1Y=", - "dev": true, - "requires": { - "kind-of": "3.2.2" - }, - "dependencies": { - "kind-of": { - "version": "3.2.2", - "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", - "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=", - "dev": true, - "requires": { - "is-buffer": "1.1.6" - } - } - } - }, - "is-descriptor": { - "version": "0.1.6", - "resolved": "https://registry.npmjs.org/is-descriptor/-/is-descriptor-0.1.6.tgz", - "integrity": "sha512-avDYr0SB3DwO9zsMov0gKCESFYqCnE4hq/4z3TdUlukEy5t9C0YRq7HLrsN52NAcqXKaepeCD0n+B0arnVG3Hg==", - "dev": true, - "requires": { - "is-accessor-descriptor": "0.1.6", - "is-data-descriptor": "0.1.4", - "kind-of": "5.1.0" - } - }, - "kind-of": { - "version": "5.1.0", - "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-5.1.0.tgz", - "integrity": "sha512-NGEErnH6F2vUuXDh+OlbcKW7/wOcfdRHaZ7VWtqCztfHri/++YKmP51OdWeGPuqCOba6kk2OTe5d02VmTB80Pw==", - "dev": true - } - } - }, - "extglob": { - "version": "2.0.4", - "resolved": "https://registry.npmjs.org/extglob/-/extglob-2.0.4.tgz", - "integrity": "sha512-Nmb6QXkELsuBr24CJSkilo6UHHgbekK5UiZgfE6UHD3Eb27YC6oD+bhcT+tJ6cl8dmsgdQxnWlcry8ksBIBLpw==", - "dev": true, - "requires": { - "array-unique": "0.3.2", - "define-property": "1.0.0", - "expand-brackets": "2.1.4", - "extend-shallow": "2.0.1", - "fragment-cache": "0.2.1", - "regex-not": "1.0.2", - "snapdragon": "0.8.2", - "to-regex": "3.0.2" - }, - "dependencies": { - "define-property": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/define-property/-/define-property-1.0.0.tgz", - "integrity": "sha1-dp66rz9KY6rTr56NMEybvnm/sOY=", - "dev": true, - "requires": { - "is-descriptor": "1.0.2" - } - }, - "extend-shallow": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz", - "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=", - "dev": true, - "requires": { - "is-extendable": "0.1.1" - } - } - } - }, - "fast-deep-equal": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/fast-deep-equal/-/fast-deep-equal-2.0.1.tgz", - "integrity": "sha1-ewUhjd+WZ79/Nwv3/bLLFf3Qqkk=", - "dev": true - }, - "fill-range": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-4.0.0.tgz", - "integrity": "sha1-1USBHUKPmOsGpj3EAtJAPDKMOPc=", - "dev": true, - "requires": { - "extend-shallow": "2.0.1", - "is-number": "3.0.0", - "repeat-string": "1.6.1", - "to-regex-range": "2.1.1" - }, - "dependencies": { - "extend-shallow": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz", - "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=", - "dev": true, - "requires": { - "is-extendable": "0.1.1" - } - } - } - }, - "glob-parent": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-3.1.0.tgz", - "integrity": "sha1-nmr2KZ2NO9K9QEMIMr0RPfkGxa4=", - "dev": true, - "requires": { - "is-glob": "3.1.0", - "path-dirname": "1.0.2" - }, - "dependencies": { - "is-glob": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-3.1.0.tgz", - "integrity": "sha1-e6WuJCF4BKxwcHuWkiVnSGzD6Eo=", - "dev": true, - "requires": { - "is-extglob": "2.1.1" - } - } - } - }, - "https-browserify": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/https-browserify/-/https-browserify-1.0.0.tgz", - "integrity": "sha1-7AbBDgo0wPL68Zn3/X/Hj//QPHM=", - "dev": true - }, - "is-accessor-descriptor": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/is-accessor-descriptor/-/is-accessor-descriptor-1.0.0.tgz", - "integrity": "sha512-m5hnHTkcVsPfqx3AKlyttIPb7J+XykHvJP2B9bZDjlhLIoEq4XoK64Vg7boZlVWYK6LUY94dYPEE7Lh0ZkZKcQ==", - "dev": true, - "requires": { - "kind-of": "6.0.2" - } - }, - "is-data-descriptor": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/is-data-descriptor/-/is-data-descriptor-1.0.0.tgz", - "integrity": "sha512-jbRXy1FmtAoCjQkVmIVYwuuqDFUbaOeDjmed1tOGPrsMhtJA4rD9tkgA0F1qJ3gRFRXcHYVkdeaP50Q5rE/jLQ==", - "dev": true, - "requires": { - "kind-of": "6.0.2" - } - }, - "is-descriptor": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/is-descriptor/-/is-descriptor-1.0.2.tgz", - "integrity": "sha512-2eis5WqQGV7peooDyLmNEPUrps9+SXX5c9pL3xEB+4e9HnGuDa7mB7kHxHw4CbqS9k1T2hOH3miL8n8WtiYVtg==", - "dev": true, - "requires": { - "is-accessor-descriptor": "1.0.0", - "is-data-descriptor": "1.0.0", - "kind-of": "6.0.2" - } - }, - "is-extglob": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/is-extglob/-/is-extglob-2.1.1.tgz", - "integrity": "sha1-qIwCU1eR8C7TfHahueqXc8gz+MI=", - "dev": true - }, - "is-glob": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-4.0.0.tgz", - "integrity": "sha1-lSHHaEXMJhCoUgPd8ICpWML/q8A=", - "dev": true, - "requires": { - "is-extglob": "2.1.1" - } - }, - "is-number": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/is-number/-/is-number-3.0.0.tgz", - "integrity": "sha1-JP1iAaR4LPUFYcgQJ2r8fRLXEZU=", - "dev": true, - "requires": { - "kind-of": "3.2.2" - }, - "dependencies": { - "kind-of": { - "version": "3.2.2", - "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", - "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=", - "dev": true, - "requires": { - "is-buffer": "1.1.6" - } - } - } - }, - "json-parse-better-errors": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/json-parse-better-errors/-/json-parse-better-errors-1.0.2.tgz", - "integrity": "sha512-mrqyZKfX5EhL7hvqcV6WG1yYjnjeuYDzDhhcAAUrq8Po85NBQBJP+ZDUT75qZQ98IkUoBqdkExkukOU7Ts2wrw==", - "dev": true - }, - "json-schema-traverse": { - "version": "0.4.1", - "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-0.4.1.tgz", - "integrity": "sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg==", - "dev": true - }, - "json5": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/json5/-/json5-1.0.1.tgz", - "integrity": "sha512-aKS4WQjPenRxiQsC93MNfjx+nbF4PAdYzmd/1JIj8HYzqfbu86beTuNgXDzPknWk0n0uARlyewZo4s++ES36Ow==", - "dev": true, - "requires": { - "minimist": "1.2.0" + "minimist": "^1.2.0" } }, "loader-utils": { @@ -12706,40 +12786,9 @@ "integrity": "sha512-fkpz8ejdnEMG3s37wGL07iSBDg99O9D5yflE9RGNH3hRdx9SOwYfnGYdZOUIZitN8E+E2vkq3MUMYMvPYl5ZZA==", "dev": true, "requires": { - "big.js": "5.2.2", - "emojis-list": "2.1.0", - "json5": "1.0.1" - } - }, - "memory-fs": { - "version": "0.4.1", - "resolved": "https://registry.npmjs.org/memory-fs/-/memory-fs-0.4.1.tgz", - "integrity": "sha1-OpoguEYlI+RHz7x+i7gO1me/xVI=", - "dev": true, - "requires": { - "errno": "0.1.7", - "readable-stream": "2.3.5" - } - }, - "micromatch": { - "version": "3.1.10", - "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-3.1.10.tgz", - "integrity": "sha512-MWikgl9n9M3w+bpsY3He8L+w9eF9338xRl8IAO5viDizwSzziFEyUzo2xrrloB64ADbTf8uA8vRqqttDTOmccg==", - "dev": true, - "requires": { - "arr-diff": "4.0.0", - "array-unique": "0.3.2", - "braces": "2.3.2", - "define-property": "2.0.2", - "extend-shallow": "3.0.2", - "extglob": "2.0.4", - "fragment-cache": "0.2.1", - "kind-of": "6.0.2", - "nanomatch": "1.2.13", - "object.pick": "1.3.0", - "regex-not": "1.0.2", - "snapdragon": "0.8.2", - "to-regex": "3.0.2" + "big.js": "^5.2.2", + "emojis-list": "^2.0.0", + "json5": "^1.0.1" } }, "minimist": { @@ -12748,163 +12797,43 @@ "integrity": "sha1-o1AIsg9BOD7sH7kU9M1d95omQoQ=", "dev": true }, - "node-libs-browser": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/node-libs-browser/-/node-libs-browser-2.2.0.tgz", - "integrity": "sha512-5MQunG/oyOaBdttrL40dA7bUfPORLRWMUJLQtMg7nluxUvk5XwnLdL9twQHFAjRx/y7mIMkLKT9++qPbbk6BZA==", - "dev": true, - "requires": { - "assert": "1.4.1", - "browserify-zlib": "0.2.0", - "buffer": "4.9.1", - "console-browserify": "1.1.0", - "constants-browserify": "1.0.0", - "crypto-browserify": "3.12.0", - "domain-browser": "1.2.0", - "events": "3.0.0", - "https-browserify": "1.0.0", - "os-browserify": "0.3.0", - "path-browserify": "0.0.0", - "process": "0.11.10", - "punycode": "1.4.1", - "querystring-es3": "0.2.1", - "readable-stream": "2.3.5", - "stream-browserify": "2.0.1", - "stream-http": "2.8.3", - "string_decoder": "1.0.3", - "timers-browserify": "2.0.10", - "tty-browserify": "0.0.0", - "url": "0.11.0", - "util": "0.11.1", - "vm-browserify": "0.0.4" - } - }, - "os-browserify": { - "version": "0.3.0", - "resolved": "https://registry.npmjs.org/os-browserify/-/os-browserify-0.3.0.tgz", - "integrity": "sha1-hUNzx/XCMVkU/Jv8a9gjj92h7Cc=", - "dev": true - }, - "source-list-map": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/source-list-map/-/source-list-map-2.0.1.tgz", - "integrity": "sha512-qnQ7gVMxGNxsiL4lEuJwe/To8UnK7fAnmbGEEH8RpLouuKbeEm0lhbQVFIrNSuB+G7tVrAlVsZgETT5nljf+Iw==", - "dev": true - }, - "source-map": { - "version": "0.6.1", - "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", - "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", + "neo-async": { + "version": "2.6.1", + "resolved": "https://registry.npmjs.org/neo-async/-/neo-async-2.6.1.tgz", + "integrity": "sha512-iyam8fBuCUpWeKPGpaNMetEocMt364qkCsfL9JuhjXX6dRnguRVOfk2GZaDpPjcOKiiXCPINZC1GczQ7iTq3Zw==", "dev": true }, - "stream-browserify": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/stream-browserify/-/stream-browserify-2.0.1.tgz", - "integrity": "sha1-ZiZu5fm9uZQKTkUUyvtDu3Hlyds=", - "dev": true, - "requires": { - "inherits": "2.0.1", - "readable-stream": "2.3.5" - } - }, "tapable": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/tapable/-/tapable-1.1.1.tgz", - "integrity": "sha512-9I2ydhj8Z9veORCw5PRm4u9uebCn0mcCa6scWoNcbZ6dAtoo2618u9UUzxgmsCOreJpqDDuv61LvwofW7hLcBA==", + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/tapable/-/tapable-1.1.3.tgz", + "integrity": "sha512-4WK/bYZmj8xLr+HUCODHGF1ZFzsYffasLUgEiMBY4fgtltdO6B4WJtlSbPaDTLpYTcGVwM2qLnFTICEcNxs3kA==", "dev": true - }, - "timers-browserify": { - "version": "2.0.10", - "resolved": "https://registry.npmjs.org/timers-browserify/-/timers-browserify-2.0.10.tgz", - "integrity": "sha512-YvC1SV1XdOUaL6gx5CoGroT3Gu49pK9+TZ38ErPldOWW4j49GI1HKs9DV+KGq/w6y+LZ72W1c8cKz2vzY+qpzg==", - "dev": true, - "requires": { - "setimmediate": "1.0.5" - } - }, - "url": { - "version": "0.11.0", - "resolved": "https://registry.npmjs.org/url/-/url-0.11.0.tgz", - "integrity": "sha1-ODjpfPxgUh63PFJajlW/3Z4uKPE=", - "dev": true, - "requires": { - "punycode": "1.3.2", - "querystring": "0.2.0" - }, - "dependencies": { - "punycode": { - "version": "1.3.2", - "resolved": "https://registry.npmjs.org/punycode/-/punycode-1.3.2.tgz", - "integrity": "sha1-llOgNvt8HuQjQvIyXM7v6jkmxI0=", - "dev": true - } - } - }, - "util": { - "version": "0.11.1", - "resolved": "https://registry.npmjs.org/util/-/util-0.11.1.tgz", - "integrity": "sha512-HShAsny+zS2TZfaXxD9tYj4HQGlBezXZMZuM/S5PKLLoZkShZiGk9o5CzukI1LVHZvjdvZ2Sj1aW/Ndn2NB/HQ==", - "dev": true, - "requires": { - "inherits": "2.0.3" - }, - "dependencies": { - "inherits": { - "version": "2.0.3", - "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.3.tgz", - "integrity": "sha1-Yzwsg+PaQqUC9SRmAiSA9CCCYd4=", - "dev": true - } - } - }, - "watchpack": { - "version": "1.6.0", - "resolved": "https://registry.npmjs.org/watchpack/-/watchpack-1.6.0.tgz", - "integrity": "sha512-i6dHe3EyLjMmDlU1/bGQpEw25XSjkJULPuAVKCbNRefQVq48yXKUpwg538F7AZTf9kyr57zj++pQFltUa5H7yA==", - "dev": true, - "requires": { - "chokidar": "2.0.4", - "graceful-fs": "4.1.11", - "neo-async": "2.5.0" - } - }, - "webpack-sources": { - "version": "1.3.0", - "resolved": "https://registry.npmjs.org/webpack-sources/-/webpack-sources-1.3.0.tgz", - "integrity": "sha512-OiVgSrbGu7NEnEvQJJgdSFPl2qWKkWq5lHMhgiToIiN9w34EBnjYzSYs+VbL5KoYiLNtFFa7BZIKxRED3I32pA==", - "dev": true, - "requires": { - "source-list-map": "2.0.1", - "source-map": "0.6.1" - } } } }, "webpack-cli": { - "version": "3.2.1", - "resolved": "https://registry.npmjs.org/webpack-cli/-/webpack-cli-3.2.1.tgz", - "integrity": "sha512-jeJveHwz/vwpJ3B8bxEL5a/rVKIpRNJDsKggfKnxuYeohNDW4Y/wB9N/XHJA093qZyS0r6mYL+/crLsIol4WKA==", + "version": "3.3.10", + "resolved": "https://registry.npmjs.org/webpack-cli/-/webpack-cli-3.3.10.tgz", + "integrity": "sha512-u1dgND9+MXaEt74sJR4PR7qkPxXUSQ0RXYq8x1L6Jg1MYVEmGPrH6Ah6C4arD4r0J1P5HKjRqpab36k0eIzPqg==", "dev": true, "requires": { "chalk": "2.4.2", "cross-spawn": "6.0.5", "enhanced-resolve": "4.1.0", - "findup-sync": "2.0.0", - "global-modules": "1.0.0", - "global-modules-path": "2.3.1", + "findup-sync": "3.0.0", + "global-modules": "2.0.0", "import-local": "2.0.0", - "interpret": "1.1.0", - "lightercollective": "0.1.0", + "interpret": "1.2.0", "loader-utils": "1.2.3", - "supports-color": "5.5.0", - "v8-compile-cache": "2.0.2", - "yargs": "12.0.5" + "supports-color": "6.1.0", + "v8-compile-cache": "2.0.3", + "yargs": "13.2.4" }, "dependencies": { "ansi-regex": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-3.0.0.tgz", - "integrity": "sha1-7QMXwyIGT3lGbAKWa922Bas32Zg=", + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-4.1.0.tgz", + "integrity": "sha512-1apePfXM1UOSqw0o9IiFAovVz9M5S1Dg+4TrDwfMewQ6p/rmMueb7tWZjQ1rx4Loy1ArBggoqGpfqqdI4rondg==", "dev": true }, "ansi-styles": { @@ -12913,7 +12842,7 @@ "integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==", "dev": true, "requires": { - "color-convert": "1.9.1" + "color-convert": "^1.9.0" } }, "big.js": { @@ -12923,9 +12852,9 @@ "dev": true }, "camelcase": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-5.0.0.tgz", - "integrity": "sha512-faqwZqnWxbxn+F1d399ygeamQNy3lPp/H9H6rNrqYh4FSVCtcY+3cub1MxA8o9mDd55mM8Aghuu/kuyYA6VTsA==", + "version": "5.3.1", + "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-5.3.1.tgz", + "integrity": "sha512-L28STB170nwWS63UjtlEOE3dldQApaJXZkOI1uMFfzf3rRuPegHaHesyee+YxQ+W6SvRDQV6UrdOdRiR153wJg==", "dev": true }, "chalk": { @@ -12934,20 +12863,31 @@ "integrity": "sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==", "dev": true, "requires": { - "ansi-styles": "3.2.1", - "escape-string-regexp": "1.0.5", - "supports-color": "5.5.0" + "ansi-styles": "^3.2.1", + "escape-string-regexp": "^1.0.5", + "supports-color": "^5.3.0" + }, + "dependencies": { + "supports-color": { + "version": "5.5.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz", + "integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==", + "dev": true, + "requires": { + "has-flag": "^3.0.0" + } + } } }, "cliui": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/cliui/-/cliui-4.1.0.tgz", - "integrity": "sha512-4FG+RSG9DL7uEwRUZXZn3SS34DiDPfzP0VOiEwtUWlE+AR2EIg+hSyvrIgUUfhdgR/UkAeW2QHgeP+hWrXs7jQ==", + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/cliui/-/cliui-5.0.0.tgz", + "integrity": "sha512-PYeGSEmmHM6zvoef2w8TPzlrnNpXIjTipYK780YswmIP9vjxmd6Y2a3CB2Ks6/AU8NHjZugXvo8w3oWM2qnwXA==", "dev": true, "requires": { - "string-width": "2.1.1", - "strip-ansi": "4.0.0", - "wrap-ansi": "2.1.0" + "string-width": "^3.1.0", + "strip-ansi": "^5.2.0", + "wrap-ansi": "^5.1.0" } }, "cross-spawn": { @@ -12956,26 +12896,22 @@ "integrity": "sha512-eTVLrBSt7fjbDygz805pMnstIs2VTBNkRm0qxZd+M7A5XDdxVRWO5MxGBXZhjY4cqLYLdtrGqRf8mBPmzwSpWQ==", "dev": true, "requires": { - "nice-try": "1.0.5", - "path-key": "2.0.1", - "semver": "5.5.0", - "shebang-command": "1.2.0", - "which": "1.3.0" + "nice-try": "^1.0.4", + "path-key": "^2.0.1", + "semver": "^5.5.0", + "shebang-command": "^1.2.0", + "which": "^1.2.9" } }, - "execa": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/execa/-/execa-1.0.0.tgz", - "integrity": "sha512-adbxcyWV46qiHyvSp50TKt05tB4tK3HcmF7/nxfAdhnox83seTDbwnaqKO4sXRy7roHAIFqJP/Rw/AuEbX61LA==", + "enhanced-resolve": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/enhanced-resolve/-/enhanced-resolve-4.1.0.tgz", + "integrity": "sha512-F/7vkyTtyc/llOIn8oWclcB25KdRaiPBpZYDgJHgh/UHtpgT2p2eldQgtQnLtUvfMKPKxbRaQM/hHkvLHt1Vng==", "dev": true, "requires": { - "cross-spawn": "6.0.5", - "get-stream": "4.1.0", - "is-stream": "1.1.0", - "npm-run-path": "2.0.2", - "p-finally": "1.0.0", - "signal-exit": "3.0.2", - "strip-eof": "1.0.0" + "graceful-fs": "^4.1.2", + "memory-fs": "^0.4.0", + "tapable": "^1.0.0" } }, "find-up": { @@ -12984,17 +12920,14 @@ "integrity": "sha512-1yD6RmLI1XBfxugvORwlck6f75tYL+iR0jqwsOrOxMZyGYqUuDhJ0l4AXdO1iX/FTs9cBAMEk1gWSEx1kSbylg==", "dev": true, "requires": { - "locate-path": "3.0.0" + "locate-path": "^3.0.0" } }, - "get-stream": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/get-stream/-/get-stream-4.1.0.tgz", - "integrity": "sha512-GMat4EJ5161kIy2HevLlr4luNjBgvmj413KaQA7jt4V8B4RDsfpHk7WQ9GVqfYyyx8OS/L66Kox+rJRNklLK7w==", - "dev": true, - "requires": { - "pump": "3.0.0" - } + "get-caller-file": { + "version": "2.0.5", + "resolved": "https://registry.npmjs.org/get-caller-file/-/get-caller-file-2.0.5.tgz", + "integrity": "sha512-DyFP3BM/3YHTQOCUL/w0OZHR0lpKeGrxotcHWcqNEdnltqFwXVfhEBQ94eIo34AfQpo0rGki4cyIiftY06h2Fg==", + "dev": true }, "invert-kv": { "version": "2.0.0", @@ -13008,7 +12941,7 @@ "integrity": "sha512-aKS4WQjPenRxiQsC93MNfjx+nbF4PAdYzmd/1JIj8HYzqfbu86beTuNgXDzPknWk0n0uARlyewZo4s++ES36Ow==", "dev": true, "requires": { - "minimist": "1.2.0" + "minimist": "^1.2.0" } }, "lcid": { @@ -13017,7 +12950,7 @@ "integrity": "sha512-avPEb8P8EGnwXKClwsNUgryVjllcRqtMYa49NTsbQagYuT1DcXnl1915oxWjoyGrXR6zH/Y0Zc96xWsPcoDKeA==", "dev": true, "requires": { - "invert-kv": "2.0.0" + "invert-kv": "^2.0.0" } }, "loader-utils": { @@ -13026,9 +12959,9 @@ "integrity": "sha512-fkpz8ejdnEMG3s37wGL07iSBDg99O9D5yflE9RGNH3hRdx9SOwYfnGYdZOUIZitN8E+E2vkq3MUMYMvPYl5ZZA==", "dev": true, "requires": { - "big.js": "5.2.2", - "emojis-list": "2.1.0", - "json5": "1.0.1" + "big.js": "^5.2.2", + "emojis-list": "^2.0.0", + "json5": "^1.0.1" } }, "locate-path": { @@ -13037,8 +12970,8 @@ "integrity": "sha512-7AO748wWnIhNqAuaty2ZWHkQHRSNfPVIsPIfwEOWO22AmaoVrWavlOcMR5nzTLNYvp36X220/maaRsrec1G65A==", "dev": true, "requires": { - "p-locate": "3.0.0", - "path-exists": "3.0.0" + "p-locate": "^3.0.0", + "path-exists": "^3.0.0" } }, "minimist": { @@ -13053,18 +12986,18 @@ "integrity": "sha512-Z8l3R4wYWM40/52Z+S265okfFj8Kt2cC2MKY+xNi3kFs+XGI7WXu/I309QQQYbRW4ijiZ+yxs9pqEhJh0DqW3Q==", "dev": true, "requires": { - "execa": "1.0.0", - "lcid": "2.0.0", - "mem": "4.0.0" + "execa": "^1.0.0", + "lcid": "^2.0.0", + "mem": "^4.0.0" } }, "p-limit": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-2.1.0.tgz", - "integrity": "sha512-NhURkNcrVB+8hNfLuysU8enY5xn2KXphsHBaC2YmRNTZRc7RWusw6apSpdEj3jo4CMb6W9nrF6tTnsJsJeyu6g==", + "version": "2.2.1", + "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-2.2.1.tgz", + "integrity": "sha512-85Tk+90UCVWvbDavCLKPOLC9vvY8OwEX/RtKF+/1OADJMVlFfEHOiMTPVyxg7mk/dKa+ipdHm0OUkTvCpMTuwg==", "dev": true, "requires": { - "p-try": "2.0.0" + "p-try": "^2.0.0" } }, "p-locate": { @@ -13073,13 +13006,13 @@ "integrity": "sha512-x+12w/To+4GFfgJhBEpiDcLozRJGegY+Ei7/z0tSLkMmxGZNybVMSfWj9aJn8Z5Fc7dBUNJOOVgPv2H7IwulSQ==", "dev": true, "requires": { - "p-limit": "2.1.0" + "p-limit": "^2.0.0" } }, "p-try": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/p-try/-/p-try-2.0.0.tgz", - "integrity": "sha512-hMp0onDKIajHfIkdRk3P4CdCmErkYAxxDtP3Wx/4nZ3aGlau2VKh3mZpcuFkH27WQkL/3WBCPOktzA9ZOAnMQQ==", + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/p-try/-/p-try-2.2.0.tgz", + "integrity": "sha512-R4nPAVTAU0B9D35/Gk3uJf/7XYbQcyohSKdvAxIRSNghFl4e71hVoGnBNQz9cWaXxO2I10KTC+3jMdvvoKw6dQ==", "dev": true }, "path-exists": { @@ -13088,22 +13021,39 @@ "integrity": "sha1-zg6+ql94yxiSXqfYENe1mwEP1RU=", "dev": true }, + "require-main-filename": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/require-main-filename/-/require-main-filename-2.0.0.tgz", + "integrity": "sha512-NKN5kMDylKuldxYLSUfrbo5Tuzh4hd+2E8NPPX02mZtn1VuREQToYe/ZdlJy+J3uCpfaiGF05e7B8W0iXbQHmg==", + "dev": true + }, + "string-width": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-3.1.0.tgz", + "integrity": "sha512-vafcv6KjVZKSgz06oM/H6GDBrAtz8vdhQakGjFIvNrHA6y3HCF1CInLy+QLq8dTJPQ1b+KDUqDFctkdRW44e1w==", + "dev": true, + "requires": { + "emoji-regex": "^7.0.1", + "is-fullwidth-code-point": "^2.0.0", + "strip-ansi": "^5.1.0" + } + }, "strip-ansi": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-4.0.0.tgz", - "integrity": "sha1-qEeQIusaw2iocTibY1JixQXuNo8=", + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-5.2.0.tgz", + "integrity": "sha512-DuRs1gKbBqsMKIZlrffwlug8MHkcnpjs5VPmL1PAh+mA30U0DTotfDZ0d2UUsXpPmPmMMJ6W773MaA3J+lbiWA==", "dev": true, "requires": { - "ansi-regex": "3.0.0" + "ansi-regex": "^4.1.0" } }, "supports-color": { - "version": "5.5.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz", - "integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==", + "version": "6.1.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-6.1.0.tgz", + "integrity": "sha512-qe1jfm1Mg7Nq/NSh6XE24gPXROEVsWHxC1LIx//XNlD9iw7YZQGjZNjYN7xGaEG6iKdA8EtNFW6R0gjnVXp+wQ==", "dev": true, "requires": { - "has-flag": "3.0.0" + "has-flag": "^3.0.0" } }, "which-module": { @@ -13112,114 +13062,116 @@ "integrity": "sha1-2e8H3Od7mQK4o6j6SzHD4/fm6Ho=", "dev": true }, + "wrap-ansi": { + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-5.1.0.tgz", + "integrity": "sha512-QC1/iN/2/RPVJ5jYK8BGttj5z83LmSKmvbvrXPNCLZSEb32KKVDJDl/MOt2N01qU2H/FkzEa9PKto1BqDjtd7Q==", + "dev": true, + "requires": { + "ansi-styles": "^3.2.0", + "string-width": "^3.0.0", + "strip-ansi": "^5.0.0" + } + }, + "y18n": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/y18n/-/y18n-4.0.0.tgz", + "integrity": "sha512-r9S/ZyXu/Xu9q1tYlpsLIsa3EeLXXk0VwlxqTcFRfg9EhMW+17kbt9G0NrgCmhGb5vT2hyhJZLfDGx+7+5Uj/w==", + "dev": true + }, "yargs": { - "version": "12.0.5", - "resolved": "https://registry.npmjs.org/yargs/-/yargs-12.0.5.tgz", - "integrity": "sha512-Lhz8TLaYnxq/2ObqHDql8dX8CJi97oHxrjUcYtzKbbykPtVW9WB+poxI+NM2UIzsMgNCZTIf0AQwsjK5yMAqZw==", + "version": "13.2.4", + "resolved": "https://registry.npmjs.org/yargs/-/yargs-13.2.4.tgz", + "integrity": "sha512-HG/DWAJa1PAnHT9JAhNa8AbAv3FPaiLzioSjCcmuXXhP8MlpHO5vwls4g4j6n30Z74GVQj8Xa62dWVx1QCGklg==", "dev": true, "requires": { - "cliui": "4.1.0", - "decamelize": "1.2.0", - "find-up": "3.0.0", - "get-caller-file": "1.0.2", - "os-locale": "3.1.0", - "require-directory": "2.1.1", - "require-main-filename": "1.0.1", - "set-blocking": "2.0.0", - "string-width": "2.1.1", - "which-module": "2.0.0", - "y18n": "3.2.1", - "yargs-parser": "11.1.1" + "cliui": "^5.0.0", + "find-up": "^3.0.0", + "get-caller-file": "^2.0.1", + "os-locale": "^3.1.0", + "require-directory": "^2.1.1", + "require-main-filename": "^2.0.0", + "set-blocking": "^2.0.0", + "string-width": "^3.0.0", + "which-module": "^2.0.0", + "y18n": "^4.0.0", + "yargs-parser": "^13.1.0" } }, "yargs-parser": { - "version": "11.1.1", - "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-11.1.1.tgz", - "integrity": "sha512-C6kB/WJDiaxONLJQnF8ccx9SEeoTTLek8RVbaOIsrAUS8VrBEXfmeSnCZxygc+XC2sNMBIwOOnfcxiynjHsVSQ==", + "version": "13.1.1", + "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-13.1.1.tgz", + "integrity": "sha512-oVAVsHz6uFrg3XQheFII8ESO2ssAf9luWuAd6Wexsu4F3OtIW0o8IribPXYrD4WC24LWtPrJlGy87y5udK+dxQ==", "dev": true, "requires": { - "camelcase": "5.0.0", - "decamelize": "1.2.0" + "camelcase": "^5.0.0", + "decamelize": "^1.2.0" } } } }, "webpack-dev-middleware": { - "version": "3.4.0", - "resolved": "https://registry.npmjs.org/webpack-dev-middleware/-/webpack-dev-middleware-3.4.0.tgz", - "integrity": "sha512-Q9Iyc0X9dP9bAsYskAVJ/hmIZZQwf/3Sy4xCAZgL5cUkjZmUZLt4l5HpbST/Pdgjn3u6pE7u5OdGd1apgzRujA==", + "version": "3.7.2", + "resolved": "https://registry.npmjs.org/webpack-dev-middleware/-/webpack-dev-middleware-3.7.2.tgz", + "integrity": "sha512-1xC42LxbYoqLNAhV6YzTYacicgMZQTqRd27Sim9wn5hJrX3I5nxYy1SxSd4+gjUFsz1dQFj+yEe6zEVmSkeJjw==", "dev": true, "requires": { - "memory-fs": "0.4.1", - "mime": "2.4.0", - "range-parser": "1.2.0", - "webpack-log": "2.0.0" + "memory-fs": "^0.4.1", + "mime": "^2.4.4", + "mkdirp": "^0.5.1", + "range-parser": "^1.2.1", + "webpack-log": "^2.0.0" }, "dependencies": { "mime": { - "version": "2.4.0", - "resolved": "https://registry.npmjs.org/mime/-/mime-2.4.0.tgz", - "integrity": "sha512-ikBcWwyqXQSHKtciCcctu9YfPbFYZ4+gbHEmE0Q8jzcTYQg5dHCr3g2wwAZjPoJfQVXZq6KXAjpXOTf5/cjT7w==", + "version": "2.4.4", + "resolved": "https://registry.npmjs.org/mime/-/mime-2.4.4.tgz", + "integrity": "sha512-LRxmNwziLPT828z+4YkNzloCFC2YM4wrB99k+AV5ZbEyfGNWfG8SO1FUXLmLDBSo89NrJZ4DIWeLjy1CHGhMGA==", "dev": true } } }, "webpack-dev-server": { - "version": "3.1.14", - "resolved": "https://registry.npmjs.org/webpack-dev-server/-/webpack-dev-server-3.1.14.tgz", - "integrity": "sha512-mGXDgz5SlTxcF3hUpfC8hrQ11yhAttuUQWf1Wmb+6zo3x6rb7b9mIfuQvAPLdfDRCGRGvakBWHdHOa0I9p/EVQ==", + "version": "3.9.0", + "resolved": "https://registry.npmjs.org/webpack-dev-server/-/webpack-dev-server-3.9.0.tgz", + "integrity": "sha512-E6uQ4kRrTX9URN9s/lIbqTAztwEPdvzVrcmHE8EQ9YnuT9J8Es5Wrd8n9BKg1a0oZ5EgEke/EQFgUsp18dSTBw==", "dev": true, "requires": { "ansi-html": "0.0.7", - "bonjour": "3.5.0", - "chokidar": "2.0.4", - "compression": "1.7.3", - "connect-history-api-fallback": "1.6.0", - "debug": "3.2.6", - "del": "3.0.0", - "express": "4.16.4", - "html-entities": "1.2.1", - "http-proxy-middleware": "0.18.0", - "import-local": "2.0.0", - "internal-ip": "3.0.1", - "ip": "1.1.5", - "killable": "1.0.1", - "loglevel": "1.6.1", - "opn": "5.4.0", - "portfinder": "1.0.20", - "schema-utils": "1.0.0", - "selfsigned": "1.10.4", - "semver": "5.6.0", - "serve-index": "1.9.1", + "bonjour": "^3.5.0", + "chokidar": "^2.1.8", + "compression": "^1.7.4", + "connect-history-api-fallback": "^1.6.0", + "debug": "^4.1.1", + "del": "^4.1.1", + "express": "^4.17.1", + "html-entities": "^1.2.1", + "http-proxy-middleware": "0.19.1", + "import-local": "^2.0.0", + "internal-ip": "^4.3.0", + "ip": "^1.1.5", + "is-absolute-url": "^3.0.3", + "killable": "^1.0.1", + "loglevel": "^1.6.4", + "opn": "^5.5.0", + "p-retry": "^3.0.1", + "portfinder": "^1.0.25", + "schema-utils": "^1.0.0", + "selfsigned": "^1.10.7", + "semver": "^6.3.0", + "serve-index": "^1.9.1", "sockjs": "0.3.19", - "sockjs-client": "1.3.0", - "spdy": "4.0.0", - "strip-ansi": "3.0.1", - "supports-color": "5.5.0", - "url": "0.11.0", - "webpack-dev-middleware": "3.4.0", - "webpack-log": "2.0.0", - "yargs": "12.0.2" + "sockjs-client": "1.4.0", + "spdy": "^4.0.1", + "strip-ansi": "^3.0.1", + "supports-color": "^6.1.0", + "url": "^0.11.0", + "webpack-dev-middleware": "^3.7.2", + "webpack-log": "^2.0.0", + "ws": "^6.2.1", + "yargs": "12.0.5" }, "dependencies": { - "ajv": { - "version": "6.7.0", - "resolved": "https://registry.npmjs.org/ajv/-/ajv-6.7.0.tgz", - "integrity": "sha512-RZXPviBTtfmtka9n9sy1N5M5b82CbxWIR6HIis4s3WQTXDJamc/0gpCWNGz6EWdWp4DOfjzJfhz/AS9zVPjjWg==", - "dev": true, - "requires": { - "fast-deep-equal": "2.0.1", - "fast-json-stable-stringify": "2.0.0", - "json-schema-traverse": "0.4.1", - "uri-js": "4.2.2" - } - }, - "ajv-keywords": { - "version": "3.2.0", - "resolved": "https://registry.npmjs.org/ajv-keywords/-/ajv-keywords-3.2.0.tgz", - "integrity": "sha1-6GuBnGAs+IIa1jdBNpjx3sAhhHo=", - "dev": true - }, "ansi-regex": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-3.0.0.tgz", @@ -13227,9 +13179,9 @@ "dev": true }, "camelcase": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-4.1.0.tgz", - "integrity": "sha1-1UVjW+HjPFQmScaRc+Xeas+uNN0=", + "version": "5.3.1", + "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-5.3.1.tgz", + "integrity": "sha512-L28STB170nwWS63UjtlEOE3dldQApaJXZkOI1uMFfzf3rRuPegHaHesyee+YxQ+W6SvRDQV6UrdOdRiR153wJg==", "dev": true }, "cliui": { @@ -13238,9 +13190,9 @@ "integrity": "sha512-4FG+RSG9DL7uEwRUZXZn3SS34DiDPfzP0VOiEwtUWlE+AR2EIg+hSyvrIgUUfhdgR/UkAeW2QHgeP+hWrXs7jQ==", "dev": true, "requires": { - "string-width": "2.1.1", - "strip-ansi": "4.0.0", - "wrap-ansi": "2.1.0" + "string-width": "^2.1.1", + "strip-ansi": "^4.0.0", + "wrap-ansi": "^2.0.0" }, "dependencies": { "strip-ansi": { @@ -13249,93 +13201,42 @@ "integrity": "sha1-qEeQIusaw2iocTibY1JixQXuNo8=", "dev": true, "requires": { - "ansi-regex": "3.0.0" + "ansi-regex": "^3.0.0" } } } }, - "cross-spawn": { - "version": "6.0.5", - "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-6.0.5.tgz", - "integrity": "sha512-eTVLrBSt7fjbDygz805pMnstIs2VTBNkRm0qxZd+M7A5XDdxVRWO5MxGBXZhjY4cqLYLdtrGqRf8mBPmzwSpWQ==", - "dev": true, - "requires": { - "nice-try": "1.0.5", - "path-key": "2.0.1", - "semver": "5.6.0", - "shebang-command": "1.2.0", - "which": "1.3.0" - } - }, "debug": { - "version": "3.2.6", - "resolved": "https://registry.npmjs.org/debug/-/debug-3.2.6.tgz", - "integrity": "sha512-mel+jf7nrtEl5Pn1Qx46zARXKDpBbvzezse7p7LqINmdoIk8PYP5SySaxEmYv6TZ0JyEKA1hsCId6DIhgITtWQ==", - "dev": true, - "requires": { - "ms": "2.1.1" - } - }, - "decamelize": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/decamelize/-/decamelize-2.0.0.tgz", - "integrity": "sha512-Ikpp5scV3MSYxY39ymh45ZLEecsTdv/Xj2CaQfI8RLMuwi7XvjX9H/fhraiSuU+C5w5NTDu4ZU72xNiZnurBPg==", + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/debug/-/debug-4.1.1.tgz", + "integrity": "sha512-pYAIzeRo8J6KPEaJ0VWOh5Pzkbw/RetuzehGM7QRRX5he4fPHx2rdKMB256ehJCkX+XRQm16eZLqLNS8RSZXZw==", "dev": true, "requires": { - "xregexp": "4.0.0" + "ms": "^2.1.1" } }, "del": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/del/-/del-3.0.0.tgz", - "integrity": "sha1-U+z2mf/LyzljdpGrE7rxYIGXZuU=", - "dev": true, - "requires": { - "globby": "6.1.0", - "is-path-cwd": "1.0.0", - "is-path-in-cwd": "1.0.0", - "p-map": "1.2.0", - "pify": "3.0.0", - "rimraf": "2.6.2" - } - }, - "execa": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/execa/-/execa-1.0.0.tgz", - "integrity": "sha512-adbxcyWV46qiHyvSp50TKt05tB4tK3HcmF7/nxfAdhnox83seTDbwnaqKO4sXRy7roHAIFqJP/Rw/AuEbX61LA==", + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/del/-/del-4.1.1.tgz", + "integrity": "sha512-QwGuEUouP2kVwQenAsOof5Fv8K9t3D8Ca8NxcXKrIpEHjTXK5J2nXLdP+ALI1cgv8wj7KuwBhTwBkOZSJKM5XQ==", "dev": true, "requires": { - "cross-spawn": "6.0.5", - "get-stream": "4.1.0", - "is-stream": "1.1.0", - "npm-run-path": "2.0.2", - "p-finally": "1.0.0", - "signal-exit": "3.0.2", - "strip-eof": "1.0.0" + "@types/glob": "^7.1.1", + "globby": "^6.1.0", + "is-path-cwd": "^2.0.0", + "is-path-in-cwd": "^2.0.0", + "p-map": "^2.0.0", + "pify": "^4.0.1", + "rimraf": "^2.6.3" } }, - "fast-deep-equal": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/fast-deep-equal/-/fast-deep-equal-2.0.1.tgz", - "integrity": "sha1-ewUhjd+WZ79/Nwv3/bLLFf3Qqkk=", - "dev": true - }, "find-up": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/find-up/-/find-up-3.0.0.tgz", "integrity": "sha512-1yD6RmLI1XBfxugvORwlck6f75tYL+iR0jqwsOrOxMZyGYqUuDhJ0l4AXdO1iX/FTs9cBAMEk1gWSEx1kSbylg==", "dev": true, "requires": { - "locate-path": "3.0.0" - } - }, - "get-stream": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/get-stream/-/get-stream-4.1.0.tgz", - "integrity": "sha512-GMat4EJ5161kIy2HevLlr4luNjBgvmj413KaQA7jt4V8B4RDsfpHk7WQ9GVqfYyyx8OS/L66Kox+rJRNklLK7w==", - "dev": true, - "requires": { - "pump": "3.0.0" + "locate-path": "^3.0.0" } }, "globby": { @@ -13344,11 +13245,11 @@ "integrity": "sha1-9abXDoOV4hyFj7BInWTfAkJNUGw=", "dev": true, "requires": { - "array-union": "1.0.2", - "glob": "7.1.2", - "object-assign": "4.1.1", - "pify": "2.3.0", - "pinkie-promise": "2.0.1" + "array-union": "^1.0.1", + "glob": "^7.0.3", + "object-assign": "^4.0.1", + "pify": "^2.0.0", + "pinkie-promise": "^2.0.0" }, "dependencies": { "pify": { @@ -13365,19 +13266,37 @@ "integrity": "sha512-wPVv/y/QQ/Uiirj/vh3oP+1Ww+AWehmi1g5fFWGPF6IpCBCDVrhgHRMvrLfdYcwDh3QJbGXDW4JAuzxElLSqKA==", "dev": true }, - "json-schema-traverse": { - "version": "0.4.1", - "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-0.4.1.tgz", - "integrity": "sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg==", + "is-path-cwd": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/is-path-cwd/-/is-path-cwd-2.2.0.tgz", + "integrity": "sha512-w942bTcih8fdJPJmQHFzkS76NEP8Kzzvmw92cXsazb8intwLqPibPPdXf4ANdKV3rYMuuQYGIWtvz9JilB3NFQ==", "dev": true }, + "is-path-in-cwd": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/is-path-in-cwd/-/is-path-in-cwd-2.1.0.tgz", + "integrity": "sha512-rNocXHgipO+rvnP6dk3zI20RpOtrAM/kzbB258Uw5BWr3TpXi861yzjo16Dn4hUox07iw5AyeMLHWsujkjzvRQ==", + "dev": true, + "requires": { + "is-path-inside": "^2.1.0" + } + }, + "is-path-inside": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/is-path-inside/-/is-path-inside-2.1.0.tgz", + "integrity": "sha512-wiyhTzfDWsvwAW53OBWF5zuvaOGlZ6PwYxAbPVDhpm+gM09xKQGjBq/8uYN12aDvMxnAnq3dxTyoSoRNmg5YFg==", + "dev": true, + "requires": { + "path-is-inside": "^1.0.2" + } + }, "lcid": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/lcid/-/lcid-2.0.0.tgz", "integrity": "sha512-avPEb8P8EGnwXKClwsNUgryVjllcRqtMYa49NTsbQagYuT1DcXnl1915oxWjoyGrXR6zH/Y0Zc96xWsPcoDKeA==", "dev": true, "requires": { - "invert-kv": "2.0.0" + "invert-kv": "^2.0.0" } }, "locate-path": { @@ -13386,14 +13305,14 @@ "integrity": "sha512-7AO748wWnIhNqAuaty2ZWHkQHRSNfPVIsPIfwEOWO22AmaoVrWavlOcMR5nzTLNYvp36X220/maaRsrec1G65A==", "dev": true, "requires": { - "p-locate": "3.0.0", - "path-exists": "3.0.0" + "p-locate": "^3.0.0", + "path-exists": "^3.0.0" } }, "ms": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.1.tgz", - "integrity": "sha512-tgp+dl5cGk28utYktBsrFqA7HKgrhgPsg6Z/EfhWI4gl1Hwq8B/GmY/0oXZ6nF8hDVesS/FpnYaD/kOWhYQvyg==", + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", + "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==", "dev": true }, "os-locale": { @@ -13402,18 +13321,18 @@ "integrity": "sha512-Z8l3R4wYWM40/52Z+S265okfFj8Kt2cC2MKY+xNi3kFs+XGI7WXu/I309QQQYbRW4ijiZ+yxs9pqEhJh0DqW3Q==", "dev": true, "requires": { - "execa": "1.0.0", - "lcid": "2.0.0", - "mem": "4.0.0" + "execa": "^1.0.0", + "lcid": "^2.0.0", + "mem": "^4.0.0" } }, "p-limit": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-2.1.0.tgz", - "integrity": "sha512-NhURkNcrVB+8hNfLuysU8enY5xn2KXphsHBaC2YmRNTZRc7RWusw6apSpdEj3jo4CMb6W9nrF6tTnsJsJeyu6g==", + "version": "2.2.1", + "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-2.2.1.tgz", + "integrity": "sha512-85Tk+90UCVWvbDavCLKPOLC9vvY8OwEX/RtKF+/1OADJMVlFfEHOiMTPVyxg7mk/dKa+ipdHm0OUkTvCpMTuwg==", "dev": true, "requires": { - "p-try": "2.0.0" + "p-try": "^2.0.0" } }, "p-locate": { @@ -13422,13 +13341,13 @@ "integrity": "sha512-x+12w/To+4GFfgJhBEpiDcLozRJGegY+Ei7/z0tSLkMmxGZNybVMSfWj9aJn8Z5Fc7dBUNJOOVgPv2H7IwulSQ==", "dev": true, "requires": { - "p-limit": "2.1.0" + "p-limit": "^2.0.0" } }, "p-try": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/p-try/-/p-try-2.0.0.tgz", - "integrity": "sha512-hMp0onDKIajHfIkdRk3P4CdCmErkYAxxDtP3Wx/4nZ3aGlau2VKh3mZpcuFkH27WQkL/3WBCPOktzA9ZOAnMQQ==", + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/p-try/-/p-try-2.2.0.tgz", + "integrity": "sha512-R4nPAVTAU0B9D35/Gk3uJf/7XYbQcyohSKdvAxIRSNghFl4e71hVoGnBNQz9cWaXxO2I10KTC+3jMdvvoKw6dQ==", "dev": true }, "path-exists": { @@ -13438,35 +13357,49 @@ "dev": true }, "pify": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/pify/-/pify-3.0.0.tgz", - "integrity": "sha1-5aSs0sEB/fPZpNB/DbxNtJ3SgXY=", + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/pify/-/pify-4.0.1.tgz", + "integrity": "sha512-uB80kBFb/tfd68bVleG9T5GGsGPjJrLAUpR5PZIrhBnIaRTQRjqdJSsIKkOP6OAIFbj7GOrcudc5pNjZ+geV2g==", "dev": true }, - "schema-utils": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/schema-utils/-/schema-utils-1.0.0.tgz", - "integrity": "sha512-i27Mic4KovM/lnGsy8whRCHhc7VicJajAjTrYg11K9zfZXnYIt4k5F+kZkwjnrhKzLic/HLU4j11mjsz2G/75g==", + "rimraf": { + "version": "2.7.1", + "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-2.7.1.tgz", + "integrity": "sha512-uWjbaKIK3T1OSVptzX7Nl6PvQ3qAGtKEtVRjRuazjfL3Bx5eI409VZSqgND+4UNnmzLVdPj9FqFJNPqBZFve4w==", "dev": true, "requires": { - "ajv": "6.7.0", - "ajv-errors": "1.0.1", - "ajv-keywords": "3.2.0" + "glob": "^7.1.3" + }, + "dependencies": { + "glob": { + "version": "7.1.6", + "resolved": "https://registry.npmjs.org/glob/-/glob-7.1.6.tgz", + "integrity": "sha512-LwaxwyZ72Lk7vZINtNNrywX0ZuLyStrdDtabefZKAY5ZGJhVtgdznluResxNmPitE0SAO+O26sWTHeKSI2wMBA==", + "dev": true, + "requires": { + "fs.realpath": "^1.0.0", + "inflight": "^1.0.4", + "inherits": "2", + "minimatch": "^3.0.4", + "once": "^1.3.0", + "path-is-absolute": "^1.0.0" + } + } } }, "semver": { - "version": "5.6.0", - "resolved": "https://registry.npmjs.org/semver/-/semver-5.6.0.tgz", - "integrity": "sha512-RS9R6R35NYgQn++fkDWaOmqGoj4Ek9gGs+DPxNUZKuwE183xjJroKvyo1IzVFeXvUrvmALy6FWD5xrdJT25gMg==", + "version": "6.3.0", + "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.0.tgz", + "integrity": "sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw==", "dev": true }, "supports-color": { - "version": "5.5.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz", - "integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==", + "version": "6.1.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-6.1.0.tgz", + "integrity": "sha512-qe1jfm1Mg7Nq/NSh6XE24gPXROEVsWHxC1LIx//XNlD9iw7YZQGjZNjYN7xGaEG6iKdA8EtNFW6R0gjnVXp+wQ==", "dev": true, "requires": { - "has-flag": "3.0.0" + "has-flag": "^3.0.0" } }, "which-module": { @@ -13476,32 +13409,33 @@ "dev": true }, "yargs": { - "version": "12.0.2", - "resolved": "https://registry.npmjs.org/yargs/-/yargs-12.0.2.tgz", - "integrity": "sha512-e7SkEx6N6SIZ5c5H22RTZae61qtn3PYUE8JYbBFlK9sYmh3DMQ6E5ygtaG/2BW0JZi4WGgTR2IV5ChqlqrDGVQ==", + "version": "12.0.5", + "resolved": "https://registry.npmjs.org/yargs/-/yargs-12.0.5.tgz", + "integrity": "sha512-Lhz8TLaYnxq/2ObqHDql8dX8CJi97oHxrjUcYtzKbbykPtVW9WB+poxI+NM2UIzsMgNCZTIf0AQwsjK5yMAqZw==", "dev": true, "requires": { - "cliui": "4.1.0", - "decamelize": "2.0.0", - "find-up": "3.0.0", - "get-caller-file": "1.0.2", - "os-locale": "3.1.0", - "require-directory": "2.1.1", - "require-main-filename": "1.0.1", - "set-blocking": "2.0.0", - "string-width": "2.1.1", - "which-module": "2.0.0", - "y18n": "3.2.1", - "yargs-parser": "10.1.0" + "cliui": "^4.0.0", + "decamelize": "^1.2.0", + "find-up": "^3.0.0", + "get-caller-file": "^1.0.1", + "os-locale": "^3.0.0", + "require-directory": "^2.1.1", + "require-main-filename": "^1.0.1", + "set-blocking": "^2.0.0", + "string-width": "^2.0.0", + "which-module": "^2.0.0", + "y18n": "^3.2.1 || ^4.0.0", + "yargs-parser": "^11.1.1" } }, "yargs-parser": { - "version": "10.1.0", - "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-10.1.0.tgz", - "integrity": "sha512-VCIyR1wJoEBZUqk5PA+oOBF6ypbwh5aNB3I50guxAL/quggdfs4TtNHQrSazFA3fYZ+tEqfs0zIGlv0c/rgjbQ==", + "version": "11.1.1", + "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-11.1.1.tgz", + "integrity": "sha512-C6kB/WJDiaxONLJQnF8ccx9SEeoTTLek8RVbaOIsrAUS8VrBEXfmeSnCZxygc+XC2sNMBIwOOnfcxiynjHsVSQ==", "dev": true, "requires": { - "camelcase": "4.1.0" + "camelcase": "^5.0.0", + "decamelize": "^1.2.0" } } } @@ -13512,24 +13446,43 @@ "integrity": "sha512-cX8G2vR/85UYG59FgkoMamwHUIkSSlV3bBMRsbxVXVUk2j6NleCKjQ/WE9eYg9WY4w25O9w8wKP4rzNZFmUcUg==", "dev": true, "requires": { - "ansi-colors": "3.2.3", - "uuid": "3.3.2" + "ansi-colors": "^3.0.0", + "uuid": "^3.3.2" + } + }, + "webpack-sources": { + "version": "1.4.3", + "resolved": "https://registry.npmjs.org/webpack-sources/-/webpack-sources-1.4.3.tgz", + "integrity": "sha512-lgTS3Xhv1lCOKo7SA5TjKXMjpSM4sBjNV5+q2bqesbSPs5FjGmU6jjtBSkX9b4qW87vDIsCIlUPOEhbZrMdjeQ==", + "dev": true, + "requires": { + "source-list-map": "^2.0.0", + "source-map": "~0.6.1" + }, + "dependencies": { + "source-map": { + "version": "0.6.1", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", + "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", + "dev": true + } } }, "websocket-driver": { - "version": "0.7.0", - "resolved": "https://registry.npmjs.org/websocket-driver/-/websocket-driver-0.7.0.tgz", - "integrity": "sha1-DK+dLXVdk67gSdS90NP+LMoqJOs=", + "version": "0.7.3", + "resolved": "https://registry.npmjs.org/websocket-driver/-/websocket-driver-0.7.3.tgz", + "integrity": "sha512-bpxWlvbbB459Mlipc5GBzzZwhoZgGEZLuqPaR0INBGnPAY1vdBX6hPnoFXiw+3yWxDuHyQjO2oXTMyS8A5haFg==", "dev": true, "requires": { - "http-parser-js": "0.5.0", - "websocket-extensions": "0.1.3" + "http-parser-js": ">=0.4.0 <0.4.11", + "safe-buffer": ">=5.1.0", + "websocket-extensions": ">=0.1.1" } }, "websocket-extensions": { "version": "0.1.3", "resolved": "https://registry.npmjs.org/websocket-extensions/-/websocket-extensions-0.1.3.tgz", - "integrity": "sha1-XS/yKXcAPsaHpLhwc9+7rBRszyk=", + "integrity": "sha512-nqHUnMXmBzT0w570r2JpJxfiSD1IzoI+HGVdd3aZ0yNi3ngvQ4jv1dtHt5VGxfI2yj5yqImPhOK4vmIh2xMbGg==", "dev": true }, "whatwg-fetch": { @@ -13542,7 +13495,7 @@ "resolved": "https://registry.npmjs.org/which/-/which-1.3.0.tgz", "integrity": "sha1-/wS9/AEO5UfXgL7DjhrBwnd9JTo=", "requires": { - "isexe": "2.0.0" + "isexe": "^2.0.0" } }, "which-module": { @@ -13557,7 +13510,7 @@ "integrity": "sha512-QGkOQc8XL6Bt5PwnsExKBPuMKBxnGxWWW3fU55Xt4feHozMUhdUMaBCk290qpm/wG5u/RSKzwdAC4i51YigihA==", "dev": true, "requires": { - "string-width": "2.1.1" + "string-width": "^1.0.2 || 2" } }, "wordwrap": { @@ -13566,12 +13519,12 @@ "integrity": "sha1-J1hIEIkUVqQXHI0CJkQa3pDLyus=" }, "worker-farm": { - "version": "1.6.0", - "resolved": "https://registry.npmjs.org/worker-farm/-/worker-farm-1.6.0.tgz", - "integrity": "sha512-6w+3tHbM87WnSWnENBUvA2pxJPLhQUg5LKwUQHq3r+XPhIM+Gh2R5ycbwPCyuGbNg+lPgdcnQUhuC02kJCvffQ==", + "version": "1.7.0", + "resolved": "https://registry.npmjs.org/worker-farm/-/worker-farm-1.7.0.tgz", + "integrity": "sha512-rvw3QTZc8lAxyVrqcSGVm5yP/IJ2UcB3U0graE3LCFoZ0Yn2x4EoVSqJKdB/T5M+FLcRPjz4TDacRf3OCfNUzw==", "dev": true, "requires": { - "errno": "0.1.7" + "errno": "~0.1.7" } }, "wrap-ansi": { @@ -13580,8 +13533,8 @@ "integrity": "sha1-2Pw9KE3QV5T+hJc8rs3Rz4JP3YU=", "dev": true, "requires": { - "string-width": "1.0.2", - "strip-ansi": "3.0.1" + "string-width": "^1.0.1", + "strip-ansi": "^3.0.1" }, "dependencies": { "is-fullwidth-code-point": { @@ -13590,7 +13543,7 @@ "integrity": "sha1-754xOG8DGn8NZDr4L95QxFfvAMs=", "dev": true, "requires": { - "number-is-nan": "1.0.1" + "number-is-nan": "^1.0.0" } }, "string-width": { @@ -13599,9 +13552,9 @@ "integrity": "sha1-EYvfW4zcUaKn5w0hHgfisLmxB9M=", "dev": true, "requires": { - "code-point-at": "1.1.0", - "is-fullwidth-code-point": "1.0.0", - "strip-ansi": "3.0.1" + "code-point-at": "^1.0.0", + "is-fullwidth-code-point": "^1.0.0", + "strip-ansi": "^3.0.0" } } } @@ -13616,14 +13569,17 @@ "resolved": "https://registry.npmjs.org/write/-/write-0.2.1.tgz", "integrity": "sha1-X8A4KOJkzqP+kUVUdvejxWbLB1c=", "requires": { - "mkdirp": "0.5.1" + "mkdirp": "^0.5.1" } }, - "xregexp": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/xregexp/-/xregexp-4.0.0.tgz", - "integrity": "sha512-PHyM+sQouu7xspQQwELlGwwd05mXUFqwFYfqPO0cC7x4fxyHnnuetmQr6CjJiafIDoH4MogHb9dOoJzR/Y4rFg==", - "dev": true + "ws": { + "version": "6.2.1", + "resolved": "https://registry.npmjs.org/ws/-/ws-6.2.1.tgz", + "integrity": "sha512-GIyAXC2cB7LjvpgMt9EKS2ldqr0MTrORaleiOno6TweZ6r3TKtoFQWay/2PceJ3RuBasOHzXNn5Lrw1X0bEjqA==", + "dev": true, + "requires": { + "async-limiter": "~1.0.0" + } }, "xtend": { "version": "4.0.1", @@ -13647,19 +13603,19 @@ "integrity": "sha1-a6MY6xaWFyf10oT46gA+jWFU0Mg=", "dev": true, "requires": { - "camelcase": "3.0.0", - "cliui": "3.2.0", - "decamelize": "1.2.0", - "get-caller-file": "1.0.2", - "os-locale": "1.4.0", - "read-pkg-up": "1.0.1", - "require-directory": "2.1.1", - "require-main-filename": "1.0.1", - "set-blocking": "2.0.0", - "string-width": "1.0.2", - "which-module": "1.0.0", - "y18n": "3.2.1", - "yargs-parser": "5.0.0" + "camelcase": "^3.0.0", + "cliui": "^3.2.0", + "decamelize": "^1.1.1", + "get-caller-file": "^1.0.1", + "os-locale": "^1.4.0", + "read-pkg-up": "^1.0.1", + "require-directory": "^2.1.1", + "require-main-filename": "^1.0.1", + "set-blocking": "^2.0.0", + "string-width": "^1.0.2", + "which-module": "^1.0.0", + "y18n": "^3.2.1", + "yargs-parser": "^5.0.0" }, "dependencies": { "camelcase": { @@ -13674,7 +13630,7 @@ "integrity": "sha1-754xOG8DGn8NZDr4L95QxFfvAMs=", "dev": true, "requires": { - "number-is-nan": "1.0.1" + "number-is-nan": "^1.0.0" } }, "load-json-file": { @@ -13683,11 +13639,11 @@ "integrity": "sha1-lWkFcI1YtLq0wiYbBPWfMcmTdMA=", "dev": true, "requires": { - "graceful-fs": "4.1.11", - "parse-json": "2.2.0", - "pify": "2.3.0", - "pinkie-promise": "2.0.1", - "strip-bom": "2.0.0" + "graceful-fs": "^4.1.2", + "parse-json": "^2.2.0", + "pify": "^2.0.0", + "pinkie-promise": "^2.0.0", + "strip-bom": "^2.0.0" } }, "path-type": { @@ -13696,9 +13652,9 @@ "integrity": "sha1-WcRPfuSR2nBNpBXaWkBwuk+P5EE=", "dev": true, "requires": { - "graceful-fs": "4.1.11", - "pify": "2.3.0", - "pinkie-promise": "2.0.1" + "graceful-fs": "^4.1.2", + "pify": "^2.0.0", + "pinkie-promise": "^2.0.0" } }, "read-pkg": { @@ -13707,9 +13663,9 @@ "integrity": "sha1-9f+qXs0pyzHAR0vKfXVra7KePyg=", "dev": true, "requires": { - "load-json-file": "1.1.0", - "normalize-package-data": "2.4.0", - "path-type": "1.1.0" + "load-json-file": "^1.0.0", + "normalize-package-data": "^2.3.2", + "path-type": "^1.0.0" } }, "read-pkg-up": { @@ -13718,8 +13674,8 @@ "integrity": "sha1-nWPBMnbAZZGNV/ACpX9AobZD+wI=", "dev": true, "requires": { - "find-up": "1.1.2", - "read-pkg": "1.1.0" + "find-up": "^1.0.0", + "read-pkg": "^1.0.0" } }, "string-width": { @@ -13728,9 +13684,9 @@ "integrity": "sha1-EYvfW4zcUaKn5w0hHgfisLmxB9M=", "dev": true, "requires": { - "code-point-at": "1.1.0", - "is-fullwidth-code-point": "1.0.0", - "strip-ansi": "3.0.1" + "code-point-at": "^1.0.0", + "is-fullwidth-code-point": "^1.0.0", + "strip-ansi": "^3.0.0" } }, "strip-bom": { @@ -13739,7 +13695,7 @@ "integrity": "sha1-YhmoVhZSBJHzV4i9vxRHqZx+aw4=", "dev": true, "requires": { - "is-utf8": "0.2.1" + "is-utf8": "^0.2.0" } } } @@ -13750,7 +13706,7 @@ "integrity": "sha1-J17PDX/+Bcd+ZOfIbkzZS/DhIoo=", "dev": true, "requires": { - "camelcase": "3.0.0" + "camelcase": "^3.0.0" }, "dependencies": { "camelcase": { diff --git a/digdag-ui/package.json b/digdag-ui/package.json index e27c1b22a1..8e683c1e12 100644 --- a/digdag-ui/package.json +++ b/digdag-ui/package.json @@ -17,31 +17,36 @@ "license": "", "dependencies": { "@babel/runtime": "^7.2.0", - "bootstrap": "4.1.2", + "@types/react": "^16.8.23", + "@fortawesome/fontawesome-svg-core": "^1.2.19", + "@fortawesome/free-solid-svg-icons": "^5.9.0", + "@fortawesome/react-fontawesome": "^0.1.4", + "bootstrap": "4.3.1", "brace": "^0.10.0", "buffer": "5.0.5", "cryptiles": "4.1.2", "duration": "^0.2.0", - "jquery": "3.2.1", + "jquery": "3.4.0", "js-untar": "0.1.4", - "js-yaml": "3.8.2", - "lodash": "^4.17.5", + "js-yaml": "3.13.1", + "lodash": "^4.17.13", "lru-cache": "4.0.2", "macaddress": "0.2.9", "moment": "^2.22.1", "moment-duration-format": "1.3.0", "pako": "1.0.5", "path": "0.12.7", - "popper.js": "1.14.4", - "react": "15.4.2", - "react-addons-pure-render-mixin": "15.4.2", - "react-dom": "15.4.2", - "react-interval": "1.3.3", + "popper.js": "^1.15.0", + "react": "16.8.6", + "react-addons-pure-render-mixin": "15.6.2", + "react-dom": "16.8.6", + "react-interval": "2.1.0", "react-json-pretty": "1.5.0", "react-measure": "^1.4.7", - "react-router": "2.4.1", + "react-router-dom": "^5.0.1", "snazzy": "^6.0.0", "tar-js": "^0.3.0", + "tether": "^1.4.5", "urijs": "1.18.9", "url-parse": "1.4.3", "uuid": "^3.2.1", @@ -74,32 +79,35 @@ "@babel/preset-env": "^7.2.3", "@babel/preset-flow": "^7.0.0", "@babel/preset-react": "^7.0.0", + "acorn": "^6.1.1", "babel-eslint": "^10.0.1", "babel-loader": "8.0.5", "bootstrap-loader": "3.0.2", - "bootstrap-sass": "3.4.0", - "cross-env": "3.2.4", + "bootstrap-sass": "3.4.1", + "cross-env": "6.0.3", "css-loader": "^2.1.0", "eslint": "^5.12.1", + "eslint-plugin-import": "^2.16.0", + "eslint-plugin-react": "^7.12.4", "exports-loader": "^0.7.0", "file-loader": "3.0.1", "flow-bin": "^0.42.0", "flow-status-webpack-plugin": "0.1.7", + "fs-extra": "^8.1.0", "html-webpack-plugin": "^3.2.0", "imports-loader": "^0.8.0", "less": "2.7.2", "less-loader": "4.1.0", "mini-css-extract-plugin": "^0.5.0", - "node-fs-extra": "^0.8.2", - "node-sass": "^4.11.0", + "node-sass": "^4.13.0", "resolve-url-loader": "^2.3.1", "rimraf": "^2.6.1", "sass-loader": "^7.1.0", "standard": "^12.0.1", "url-loader": "^1.1.2", - "webpack": "4.28.4", - "webpack-cli": "^3.2.1", - "webpack-dev-server": "3.1.14" + "webpack": "4.41.2", + "webpack-cli": "^3.3.10", + "webpack-dev-server": "3.9.0" }, "standard": { "parser": "babel-eslint", diff --git a/digdag-ui/prepare-release.js b/digdag-ui/prepare-release.js index 2cb41309bc..7db5d1a1d5 100644 --- a/digdag-ui/prepare-release.js +++ b/digdag-ui/prepare-release.js @@ -1,4 +1,4 @@ -var fs = require('node-fs-extra') +var fs = require('fs-extra') var path = require('path') const getSha = require('./lib/git-sha1') diff --git a/digdag-ui/style.less b/digdag-ui/style.less index 0221559017..a6220d31ef 100644 --- a/digdag-ui/style.less +++ b/digdag-ui/style.less @@ -1,45 +1,24 @@ -html, #root { - width: 100%; - height: 100%; -} - -body { - padding-top: 80px; - width: 100%; - height: 100%; -} - code, pre { tab-size: 2 !important; } -.loadingContainer { +.app-wrapper { + padding-top: 1.5rem; + margin: 0 1.5rem; +} + +.loading-container { display: flex; flex-direction: column; width: 100%; height: 100%; justify-content: center; align-items: center; + padding-top: 1.5rem; } -.glyphicon.spinning { - font-size: 30px; - animation: spin 1s infinite linear; - -webkit-animation: spin2 1s infinite linear; -} - -@keyframes spin { - from { transform: scale(1) rotate(0deg); } - to { transform: scale(1) rotate(360deg); } -} - -@-webkit-keyframes spin2 { - from { -webkit-transform: rotate(0deg); } - to { -webkit-transform: rotate(360deg); } -} - -.loadingText { +.loading-text { margin-top: 40px; font-size: 22px; } @@ -75,7 +54,6 @@ pre { } .params-view { - width: 190px; height: 130px; } diff --git a/digdag-ui/webpack.make.js b/digdag-ui/webpack.make.js index 0fe1c38ddf..e6fdefc14e 100644 --- a/digdag-ui/webpack.make.js +++ b/digdag-ui/webpack.make.js @@ -19,6 +19,7 @@ module.exports = function buildWebpackConfig ({ build = false }) { const config = { mode: build ? 'production' : 'development', entry: { + tether: 'tether', bootstrap: 'bootstrap-loader/extractStyles', app: './index.jsx' }, @@ -81,7 +82,8 @@ module.exports = function buildWebpackConfig ({ build = false }) { new webpack.ProvidePlugin({ $: 'jquery', jQuery: 'jquery', - 'window.jQuery': 'jquery' + 'window.jQuery': 'jquery', + 'window.Tether': 'tether' }), new webpack.DefinePlugin({ 'process.env.NODE_ENV': `'${build ? 'production' : 'development'}'` diff --git a/docker/Makefile b/docker/Makefile index 70b561dc56..79bcbd7103 100644 --- a/docker/Makefile +++ b/docker/Makefile @@ -3,6 +3,8 @@ IMAGE_TAG = $(shell git show --pretty=format:'%ad-%H' --date 'format:%Y%m%dT%H%M IMAGE = $(IMAGE_NAME):$(IMAGE_TAG) build: + cp ../digdag-docs/requirements.txt bootstrap/ + cp ../digdag-docs/constraints.txt bootstrap/ docker build -t $(IMAGE) . @echo Built $(IMAGE) diff --git a/docker/bootstrap/dependencies.sh b/docker/bootstrap/dependencies.sh index 4eaa3971b7..6c1beb6783 100755 --- a/docker/bootstrap/dependencies.sh +++ b/docker/bootstrap/dependencies.sh @@ -8,7 +8,7 @@ apt-get -y install maven # npm apt-get -y install curl -curl -sL https://deb.nodesource.com/setup_8.x | bash - +curl -sL https://deb.nodesource.com/setup_12.x | bash - apt-get -y install nodejs # Docker required by CircleCI to execute docker command in Docker container @@ -28,16 +28,18 @@ sudo -u postgres createuser -s digdag_test sudo -u postgres createdb -O digdag_test digdag_test # Python -apt-get -y install python python-pip python-dev -pip install pip --upgrade && hash -r pip # rehashed https://github.com/pypa/pip/issues/5240 -# Using sphinx==1.4.9 because sphinx_rtd_theme with sphinx 1.5.x has a problem with search and its fix is not released: https://github.com/snide/sphinx_rtd_theme/pull/346 -pip install sphinx==1.4.9 recommonmark sphinx_rtd_theme +apt-get -y install python3 python3-pip +python3 -m pip install -U pip +python3 -m pip install -r requirements.txt -c constraints.txt + +# Ruby +apt-get -y install ruby-full # Redis apt-get -y install redis-server # Minio (S3) -wget -O /usr/local/bin/minio https://dl.minio.io/server/minio/release/linux-amd64/minio +wget -O /usr/local/bin/minio https://dl.minio.io/server/minio/release/linux-amd64/archive/minio.RELEASE.2019-01-23T23-18-58Z chmod 777 /usr/local/bin/minio # Redis diff --git a/examples/REST_API.md b/examples/REST_API.md new file mode 100644 index 0000000000..4f1a4e8361 --- /dev/null +++ b/examples/REST_API.md @@ -0,0 +1,26 @@ +The following example demonstrates how to launch a workflow via REST API. To find out more about available API calls please refer to "[Check Digdag REST API](https://github.com/treasure-data/digdag)". + +1. Launch a server with +``` +$ digdag server --memory +``` +2. Create and push the following workflow to the server (observe the value of id) +``` +$ mkdir resttest +$ cd resttest +$ cat << 'EODAG' > resttest.dig +timezone: Europe/Zurich + ++echoparam: + echo>: ${msg} +EODAG + +$ digdag push resttest +``` +3. Call the workflow via REST API with curl to pass a message (workflowId has to be the value from the previous command) +``` +$ curl -X PUT "http://localhost:65432/api/attempts" \ + -H "accept: application/json" \ + -H "Content-Type: application/json" \ + -d "{ \"params\": { \"msg\": \"Hello from REST API.\" }, \"sessionTime\": \"2019-05-01T13:38:52+09:00\", \"workflowId\": \"1\"}" +``` diff --git a/gradle/wrapper/gradle-wrapper.jar b/gradle/wrapper/gradle-wrapper.jar index 87b738cbd0..1948b9074f 100644 Binary files a/gradle/wrapper/gradle-wrapper.jar and b/gradle/wrapper/gradle-wrapper.jar differ diff --git a/gradle/wrapper/gradle-wrapper.properties b/gradle/wrapper/gradle-wrapper.properties index 5a7a6a11ce..d2c45a4b26 100644 --- a/gradle/wrapper/gradle-wrapper.properties +++ b/gradle/wrapper/gradle-wrapper.properties @@ -1,5 +1,5 @@ distributionBase=GRADLE_USER_HOME distributionPath=wrapper/dists -distributionUrl=https\://services.gradle.org/distributions/gradle-5.2-bin.zip +distributionUrl=https\://services.gradle.org/distributions/gradle-4.8-bin.zip zipStoreBase=GRADLE_USER_HOME zipStorePath=wrapper/dists diff --git a/gradlew b/gradlew index af6708ff22..cccdd3d517 100755 --- a/gradlew +++ b/gradlew @@ -28,7 +28,7 @@ APP_NAME="Gradle" APP_BASE_NAME=`basename "$0"` # Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script. -DEFAULT_JVM_OPTS='"-Xmx64m"' +DEFAULT_JVM_OPTS="" # Use the maximum available, or set MAX_FD != -1 to use that value. MAX_FD="maximum" diff --git a/gradlew.bat b/gradlew.bat index 0f8d5937c4..e95643d6a2 100644 --- a/gradlew.bat +++ b/gradlew.bat @@ -14,7 +14,7 @@ set APP_BASE_NAME=%~n0 set APP_HOME=%DIRNAME% @rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script. -set DEFAULT_JVM_OPTS="-Xmx64m" +set DEFAULT_JVM_OPTS= @rem Find java.exe if defined JAVA_HOME goto findJavaFromJavaHome diff --git a/settings.gradle b/settings.gradle index d0573d345a..112eac3b65 100644 --- a/settings.gradle +++ b/settings.gradle @@ -1,10 +1,12 @@ rootProject.name = 'digdag' +enableFeaturePreview('STABLE_PUBLISHING') include 'digdag-core' include 'digdag-spi' include 'digdag-client' include 'digdag-standards' include 'digdag-storage-s3' +include 'digdag-storage-gcs' include 'digdag-server' include 'digdag-cli' include 'digdag-docs'