Przeglądaj źródła

examples: add `npm run example` script

a bad result from adding the examples as dependencies of the root
repository is that they now don't have access to the npm binaries they
need to run in their own folder, because they are installed into the
root repository instead.

this works around that issue.

we may need to consider undoing that change and making the examples work
as standalone projects again, that's easier to understand.

fixes #2024 for now.
Renée Kooi 5 lat temu
rodzic
commit
7b2283d8ef

+ 29 - 0
bin/run-example.js

@@ -0,0 +1,29 @@
+#!/usr/bin/env node
+
+/**
+ * Lerna installs all the example dependencies into the root `node_modules`.
+ * To run the examples they need to have access to executables from npm dependencies in their $PATH.
+ * If you run `npm start` in a dependency folder, the root `node_modules/.bin` is not in the $PATH.
+ *
+ * This proxy executable can be run from the repository root using `npm run example`, so the root
+ * `node_modules/.bin` will be in the $PATH. It then runs `npm start` in the specific example folder,
+ * which will inherit the $PATH, so the example has access to executables from npm dependencies in both
+ * its own and in the root `node_modules`.
+ */
+
+const path = require('path')
+const { execSync } = require('child_process')
+const exampleName = process.argv[2]
+
+if (!exampleName) {
+  console.error('Usage: npm run example "name-of-example"')
+  process.exit(1)
+}
+
+const exampleDir = path.join(__dirname, '../examples', exampleName)
+const pkg = require(path.join(exampleDir, 'package.json'))
+if (pkg.scripts && pkg.scripts.build) {
+  execSync('npm run build', { cwd: exampleDir, stdio: 'inherit' })
+}
+
+execSync('npm start', { cwd: exampleDir, stdio: 'inherit' })

+ 4 - 6
examples/aws-companion/readme.md

@@ -5,17 +5,15 @@ Files are uploaded to a randomly named directory inside the `whatever/` director
 
 ## Run it
 
-To run this example, make sure you've correctly installed the root repository:
-
+To run this example, make sure you've correctly installed the **repository root**:
 ```bash
 npm install
-npm run build
 ```
+That will also install the dependencies for this example.
 
 Then, set up the `COMPANION_AWS_KEY`, `COMPANION_AWS_SECRET`, `COMPANION_AWS_REGION`, and `COMPANION_AWS_BUCKET` environment variables for @uppy/companion.
 
-Then, navigate to this directory and run:
-
+Then, again in the **repository root**, start this example by doing:
 ```bash
-npm start
+npm run example aws-companion
 ```

+ 7 - 10
examples/aws-presigned-url/readme.md

@@ -4,14 +4,14 @@ This example uses a server-side PHP endpoint to sign uploads to S3.
 
 ## Running It
 
-To run this example, make sure you've correctly installed the root repository:
-
+To run this example, make sure you've correctly installed the **repository root**:
 ```bash
 npm install
 ```
+That will also install the npm dependencies for this example.
 
-This example uses the AWS PHP SDK.
-To install it, [get composer](https://getcomposer.org) and run `composer update` in this folder.
+This example also uses the AWS PHP SDK.
+To install it, [get composer](https://getcomposer.org) and run `composer update` in **this** folder.
 
 ```bash
 cd ./examples/aws-presigned-url
@@ -21,16 +21,13 @@ composer update
 Configure AWS S3 credentials using [environment variables](https://docs.aws.amazon.com/aws-sdk-php/v3/guide/guide/credentials.html#environment-credentials) or a [credentials file in `~/.aws/credentials`](https://docs.aws.amazon.com/aws-sdk-php/v3/guide/guide/credentials.html#credential-profiles).
 Configure a bucket name and region in the `s3-sign.php` file.
 
-Then start the demo server using:
-
+Then, again in the **repository root**, start this example by doing:
 ```bash
-npm start
+npm run example aws-presigned-url
 ```
-
 The demo should now be available at http://localhost:8080.
 
 Optionally, provide a port in the `PORT` environment variable:
-
 ```bash
-PORT=8080 npm start
+PORT=8080 npm run example aws-presigned-url
 ```

+ 4 - 5
examples/custom-provider/readme.md

@@ -5,14 +5,13 @@ This serves as an illustration on how integrating custom providers would work
 
 ## Run it
 
-To run this example, make sure you've correctly installed the root repository:
-
+To run this example, make sure you've correctly installed the **repository root**:
 ```bash
 npm install
 ```
+That will also install the dependencies for this example.
 
-Move into this directory, then:
-
+Then, again in the **repository root**, start this example by doing:
 ```bash
-npm start
+npm run example custom-provider
 ```

+ 5 - 4
examples/digitalocean-spaces/readme.md

@@ -2,18 +2,19 @@
 
 This example uses Uppy to upload files to a DigitolOcean Space. DigitalOcean Spaces has an identical API to S3, so we can use the [AwsS3](https://uppy.io/docs/aws-s3) plugin. We use @uppy/companion with a [custom `endpoint` configuration](./server.js#L32-L33) that points to DigitalOcean.
 
-To run this example, make sure you've correctly installed the root repository:
+## Running it
 
+To run this example, make sure you've correctly installed the **repository root**:
 ```bash
 npm install
 ```
+That will also install the dependencies for this example.
 
-Then navigate to this directory, configure some environment variables, and run:
-
+Then, again in the **repository root**, configure some environment variables, and run:
 ```bash
 COMPANION_AWS_REGION=ams3 \
 COMPANION_AWS_KEY=your_access_key_id \
 COMPANION_AWS_SECRET=your_secret_access_key \
 COMPANION_AWS_BUCKET=your_space_name \
-npm start
+npm run example digitalocean-spaces
 ```

+ 5 - 6
examples/multiple-instances/readme.md

@@ -1,18 +1,17 @@
 # Multiple Instances
 
-This example uses Uppy with the RestoreFiles plugin.
+This example uses Uppy with the `@uppy/golden-retriever` plugin.
 It has two instances on the same page, side-by-side, but with different `id`s so their stored files don't interfere with each other.
 
 ## Run it
 
-To run this example, make sure you've correctly installed the root repository:
-
+To run this example, make sure you've correctly installed the **repository root**:
 ```bash
 npm install
 ```
+That will also install the dependencies for this example.
 
-Move into this directory, then:
-
+Then, again in the **repository root**, start this example by doing:
 ```bash
-npm start
+npm run example multiple-instances
 ```

+ 4 - 5
examples/node-xhr/readme.md

@@ -4,14 +4,13 @@ This example uses Node server and `@uppy/xhr-upload` to upload files to the loca
 
 ## Run it
 
-To run this example, make sure you've correctly installed the root repository:
-
+To run this example, make sure you've correctly installed the **repository root**:
 ```bash
 npm install
 ```
+That will also install the dependencies for this example.
 
-Then move into this directory (`examples/node-xhr`), and:
-
+Then, again in the **repository root**, start this example by doing:
 ```bash
-npm start
+npm run example node-xhr
 ```

+ 4 - 6
examples/php-xhr/readme.md

@@ -4,15 +4,13 @@ This example uses PHP server and `@uppy/xhr-upload` to upload files to the local
 
 ## Run it
 
-To run this example, make sure you've correctly installed the root repository:
-
+To run this example, make sure you've correctly installed the **repository root**:
 ```bash
 npm install
-npm run build
 ```
+That will also install the dependencies for this example.
 
-Then move into this directory (`examples/php-xhr`), and:
-
+Then, again in the **repository root**, start this example by doing:
 ```bash
-npm start
+npm run example php-xhr
 ```

+ 9 - 6
examples/python-xhr/readme.md

@@ -4,16 +4,19 @@ This example uses a Python Flask server and `@uppy/xhr-upload` to upload files t
 
 ## Run it
 
-To run this example, make sure you've correctly installed the root repository:
-
+To run this example, make sure you've correctly installed the **repository root**:
 ```bash
 npm install
-npm run build
 ```
+That will also install the npm dependencies for this example.
 
-Then move into this directory (`examples/python-xhr`), and:
-
+Additionally, this example uses python dependencies. Move into this directory, and install them using pip:
 ```bash
+cd ./examples/python-xhr
 pip install -r requirements.txt
-npm start
+```
+
+Then, again in the **repository root**, start this example by doing:
+```bash
+npm run example python-xhr
 ```

+ 4 - 7
examples/react-native-expo/readme.md

@@ -6,18 +6,15 @@
 
 ## Run it
 
-To run this example, make sure you've correctly installed the root repository:
-
+To run this example, make sure you've correctly installed the **repository root**:
 ```bash
 npm install
-npm run build
 ```
+That will also install the dependencies for this example.
 
-Then navigate to this directory and run it:
-
+Then, again in the **repository root**, start this example by doing:
 ```bash
-cd examples/react-native-expo
-npm start
+npm run example react-native-expo
 ```
 
 Then a tab will open in your browser with Expo UI, and you can choose to run the example in either an iOS or Android simulator, or right on your mobile device with an Expo app — might be easier, if you don’t want to install emulators.

+ 4 - 5
examples/redux/readme.md

@@ -8,14 +8,13 @@ This example supports the [Redux Devtools extension](https://github.com/zalmoxis
 
 ## Run it
 
-To run this example, make sure you've correctly installed the root repository:
-
+To run this example, make sure you've correctly installed the **repository root**:
 ```bash
 npm install
 ```
+That will also install the dependencies for this example.
 
-Move into this directory, then:
-
+Then, again in the **repository root**, start this example by doing:
 ```bash
-npm start
+npm run example redux
 ```

+ 4 - 5
examples/transloadit/readme.md

@@ -4,14 +4,13 @@ This example shows all the different Robodog APIs in action on a single page.
 
 ## Run it
 
-To run this example, make sure you've correctly installed the root repository:
-
+To run this example, make sure you've correctly installed the **repository root**:
 ```bash
 npm install
 ```
+That will also install the dependencies for this example.
 
-Move into this directory, then:
-
+Then, again in the **repository root**, start this example by doing:
 ```bash
-npm start
+npm run example transloadit
 ```

+ 4 - 5
examples/uppy-with-companion/README.md

@@ -4,14 +4,13 @@ This is a simple, lean example that combines the usage of @uppy/companion and up
 
 ## Test it
 
-To run this example, make sure you've correctly installed the root repository:
-
+To run this example, make sure you've correctly installed the **repository root**:
 ```bash
 npm install
 ```
+That will also install the dependencies for this example.
 
-Then, navigate to this directory and run:
-
+Then, again in the **repository root**, start this example by doing:
 ```bash
-npm start
+npm run example uppy-with-companion
 ```

+ 4 - 5
examples/xhr-bundle/readme.md

@@ -6,14 +6,13 @@ This example uses Uppy with XHRUpload plugin in `bundle` mode. Bundle mode uploa
 
 ## Run it
 
-To run this example, make sure you've correctly installed the root repository:
-
+To run this example, make sure you've correctly installed the **repository root**:
 ```bash
 npm install
 ```
+That will also install the dependencies for this example.
 
-Move into this directory, then:
-
+Then, again in the **repository root**, start this example by doing:
 ```bash
-npm start
+npm run example xhr-bundle
 ```

+ 215 - 34
package-lock.json

@@ -4095,6 +4095,88 @@
         }
       }
     },
+    "@lerna/profiler": {
+      "version": "3.20.0",
+      "resolved": "https://registry.npmjs.org/@lerna/profiler/-/profiler-3.20.0.tgz",
+      "integrity": "sha512-bh8hKxAlm6yu8WEOvbLENm42i2v9SsR4WbrCWSbsmOElx3foRnMlYk7NkGECa+U5c3K4C6GeBbwgqs54PP7Ljg==",
+      "dev": true,
+      "requires": {
+        "figgy-pudding": "^3.5.1",
+        "fs-extra": "^8.1.0",
+        "npmlog": "^4.1.2",
+        "upath": "^1.2.0"
+      },
+      "dependencies": {
+        "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"
+          }
+        },
+        "gauge": {
+          "version": "2.7.4",
+          "resolved": "https://registry.npmjs.org/gauge/-/gauge-2.7.4.tgz",
+          "integrity": "sha1-LANAXHU4w51+s3sxcCLjJfsBi/c=",
+          "dev": true,
+          "requires": {
+            "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"
+          }
+        },
+        "is-fullwidth-code-point": {
+          "version": "1.0.0",
+          "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-1.0.0.tgz",
+          "integrity": "sha1-754xOG8DGn8NZDr4L95QxFfvAMs=",
+          "dev": true,
+          "requires": {
+            "number-is-nan": "^1.0.0"
+          }
+        },
+        "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"
+          }
+        },
+        "npmlog": {
+          "version": "4.1.2",
+          "resolved": "https://registry.npmjs.org/npmlog/-/npmlog-4.1.2.tgz",
+          "integrity": "sha512-2uUqazuKlTaSI/dC8AzicUck7+IrEaOnN/e0jd3Xtt1KcGpwx30v50mL7oPyr/h9bL3E4aZccVwpwP+5W9Vjkg==",
+          "dev": true,
+          "requires": {
+            "are-we-there-yet": "~1.1.2",
+            "console-control-strings": "~1.1.0",
+            "gauge": "~2.7.3",
+            "set-blocking": "~2.0.0"
+          }
+        },
+        "string-width": {
+          "version": "1.0.2",
+          "resolved": "https://registry.npmjs.org/string-width/-/string-width-1.0.2.tgz",
+          "integrity": "sha1-EYvfW4zcUaKn5w0hHgfisLmxB9M=",
+          "dev": true,
+          "requires": {
+            "code-point-at": "^1.0.0",
+            "is-fullwidth-code-point": "^1.0.0",
+            "strip-ansi": "^3.0.0"
+          }
+        }
+      }
+    },
     "@lerna/project": {
       "version": "3.18.0",
       "resolved": "https://registry.npmjs.org/@lerna/project/-/project-3.18.0.tgz",
@@ -4706,19 +4788,108 @@
       }
     },
     "@lerna/run": {
-      "version": "3.18.5",
-      "resolved": "https://registry.npmjs.org/@lerna/run/-/run-3.18.5.tgz",
-      "integrity": "sha512-1S0dZccNJO8+gT5ztYE4rHTEnbXVwThHOfDnlVt2KDxl9cbnBALk3xprGLW7lSzJsxegS849hxrAPUh0UorMgw==",
+      "version": "3.20.0",
+      "resolved": "https://registry.npmjs.org/@lerna/run/-/run-3.20.0.tgz",
+      "integrity": "sha512-9U3AqeaCeB7KsGS9oyKNp62s9vYoULg/B4cqXTKZkc+OKL6QOEjYHYVSBcMK9lUXrMjCjDIuDSX3PnTCPxQ2Dw==",
       "dev": true,
       "requires": {
         "@lerna/command": "3.18.5",
-        "@lerna/filter-options": "3.18.4",
+        "@lerna/filter-options": "3.20.0",
         "@lerna/npm-run-script": "3.16.5",
         "@lerna/output": "3.13.0",
+        "@lerna/profiler": "3.20.0",
         "@lerna/run-topologically": "3.18.5",
         "@lerna/timer": "3.13.0",
         "@lerna/validation-error": "3.13.0",
         "p-map": "^2.1.0"
+      },
+      "dependencies": {
+        "@lerna/collect-updates": {
+          "version": "3.20.0",
+          "resolved": "https://registry.npmjs.org/@lerna/collect-updates/-/collect-updates-3.20.0.tgz",
+          "integrity": "sha512-qBTVT5g4fupVhBFuY4nI/3FSJtQVcDh7/gEPOpRxoXB/yCSnT38MFHXWl+y4einLciCjt/+0x6/4AG80fjay2Q==",
+          "dev": true,
+          "requires": {
+            "@lerna/child-process": "3.16.5",
+            "@lerna/describe-ref": "3.16.5",
+            "minimatch": "^3.0.4",
+            "npmlog": "^4.1.2",
+            "slash": "^2.0.0"
+          }
+        },
+        "@lerna/filter-options": {
+          "version": "3.20.0",
+          "resolved": "https://registry.npmjs.org/@lerna/filter-options/-/filter-options-3.20.0.tgz",
+          "integrity": "sha512-bmcHtvxn7SIl/R9gpiNMVG7yjx7WyT0HSGw34YVZ9B+3xF/83N3r5Rgtjh4hheLZ+Q91Or0Jyu5O3Nr+AwZe2g==",
+          "dev": true,
+          "requires": {
+            "@lerna/collect-updates": "3.20.0",
+            "@lerna/filter-packages": "3.18.0",
+            "dedent": "^0.7.0",
+            "figgy-pudding": "^3.5.1",
+            "npmlog": "^4.1.2"
+          }
+        },
+        "dedent": {
+          "version": "0.7.0",
+          "resolved": "https://registry.npmjs.org/dedent/-/dedent-0.7.0.tgz",
+          "integrity": "sha1-JJXduvbrh0q7Dhvp3yLS5aVEMmw=",
+          "dev": true
+        },
+        "gauge": {
+          "version": "2.7.4",
+          "resolved": "https://registry.npmjs.org/gauge/-/gauge-2.7.4.tgz",
+          "integrity": "sha1-LANAXHU4w51+s3sxcCLjJfsBi/c=",
+          "dev": true,
+          "requires": {
+            "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"
+          }
+        },
+        "is-fullwidth-code-point": {
+          "version": "1.0.0",
+          "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-1.0.0.tgz",
+          "integrity": "sha1-754xOG8DGn8NZDr4L95QxFfvAMs=",
+          "dev": true,
+          "requires": {
+            "number-is-nan": "^1.0.0"
+          }
+        },
+        "npmlog": {
+          "version": "4.1.2",
+          "resolved": "https://registry.npmjs.org/npmlog/-/npmlog-4.1.2.tgz",
+          "integrity": "sha512-2uUqazuKlTaSI/dC8AzicUck7+IrEaOnN/e0jd3Xtt1KcGpwx30v50mL7oPyr/h9bL3E4aZccVwpwP+5W9Vjkg==",
+          "dev": true,
+          "requires": {
+            "are-we-there-yet": "~1.1.2",
+            "console-control-strings": "~1.1.0",
+            "gauge": "~2.7.3",
+            "set-blocking": "~2.0.0"
+          }
+        },
+        "slash": {
+          "version": "2.0.0",
+          "resolved": "https://registry.npmjs.org/slash/-/slash-2.0.0.tgz",
+          "integrity": "sha512-ZYKh3Wh2z1PpEXWr0MpSBZ0V6mZHAQfYevttO11c51CaWjGTaadiKZ+wVt1PbMlDV5qhMFslpZCemhwOK7C89A==",
+          "dev": true
+        },
+        "string-width": {
+          "version": "1.0.2",
+          "resolved": "https://registry.npmjs.org/string-width/-/string-width-1.0.2.tgz",
+          "integrity": "sha1-EYvfW4zcUaKn5w0hHgfisLmxB9M=",
+          "dev": true,
+          "requires": {
+            "code-point-at": "^1.0.0",
+            "is-fullwidth-code-point": "^1.0.0",
+            "strip-ansi": "^3.0.0"
+          }
+        }
       }
     },
     "@lerna/run-lifecycle": {
@@ -6358,31 +6529,6 @@
           "resolved": "https://registry.npmjs.org/frameguard/-/frameguard-3.1.0.tgz",
           "integrity": "sha512-TxgSKM+7LTA6sidjOiSZK9wxY0ffMPY3Wta//MqwmX0nZuEHc8QrkV8Fh3ZhMJeiH+Uyh/tcaarImRy8u77O7g=="
         },
-        "grant": {
-          "version": "4.6.5",
-          "resolved": "https://registry.npmjs.org/grant/-/grant-4.6.5.tgz",
-          "integrity": "sha512-gxMaIw6MRI/HaPxuV04NTOCZTFtPRCjpZIAQH3NqCnOHUHXenor+IOTYqjmeSQzcH0KJ0rv3PQp9Q3Cj18n8jw==",
-          "requires": {
-            "qs": "^6.9.1",
-            "request-compose": "^1.2.1",
-            "request-oauth": "0.0.3"
-          },
-          "dependencies": {
-            "qs": {
-              "version": "6.9.1",
-              "resolved": "https://registry.npmjs.org/qs/-/qs-6.9.1.tgz",
-              "integrity": "sha512-Cxm7/SS/y/Z3MHWSxXb8lIFqgqBowP5JMlTUFyJN88y0SGQhVmZnqFK/PeuMX9LzUyWsqqhNxIyg0jlzq946yA=="
-            }
-          }
-        },
-        "grant-express": {
-          "version": "4.6.5",
-          "resolved": "https://registry.npmjs.org/grant-express/-/grant-express-4.6.5.tgz",
-          "integrity": "sha512-oHWXlKkidPQUHMY2wOzL8xQ6/OQKaib1G1jrWfKXXxIcNGYl8IRZk8SqYy6qT8rjEFQ4hcTd8NrTuNIemSxUXQ==",
-          "requires": {
-            "grant": "4.6.5"
-          }
-        },
         "helmet": {
           "version": "3.21.2",
           "resolved": "https://registry.npmjs.org/helmet/-/helmet-3.21.2.tgz",
@@ -6541,11 +6687,6 @@
           "resolved": "https://registry.npmjs.org/referrer-policy/-/referrer-policy-1.2.0.tgz",
           "integrity": "sha512-LgQJIuS6nAy1Jd88DCQRemyE3mS+ispwlqMk3b0yjZ257fI1v9c+/p6SD5gP5FGyXUIgrNOAfmyioHwZtYv2VA=="
         },
-        "request-compose": {
-          "version": "1.2.1",
-          "resolved": "https://registry.npmjs.org/request-compose/-/request-compose-1.2.1.tgz",
-          "integrity": "sha512-w4qjUH1N4OdMfnHVi4Z0oKvDZyu75rJlvnuKe40wVg+khnfdJLt0qf+LF8QjIiDqSOSYdbMZE6a0ixU58B3Jow=="
-        },
         "sax": {
           "version": "1.2.1",
           "resolved": "https://registry.npmjs.org/sax/-/sax-1.2.1.tgz",
@@ -18504,6 +18645,25 @@
       "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.3.tgz",
       "integrity": "sha512-a30VEBm4PEdx1dRB7MFK7BejejvCvBronbLjht+sHuGYj8PHs7M/5Z+rt5lw551vZ7yfTCj4Vuyy3mSJytDWRQ=="
     },
+    "grant": {
+      "version": "4.1.2",
+      "resolved": "https://registry.npmjs.org/grant/-/grant-4.1.2.tgz",
+      "integrity": "sha512-J+Cb0m8vDYU3tvcA47AbcD4KMioWeN6RDPxnPbcqpqAuHrn/J61YZZO4nx2B1qDQEhSahW3NwQCM1PZov4uMyw==",
+      "requires": {
+        "deep-copy": "^1.4.2",
+        "qs": "^6.5.1",
+        "request-compose": "0.0.19",
+        "request-oauth": "0.0.3"
+      }
+    },
+    "grant-express": {
+      "version": "4.1.2",
+      "resolved": "https://registry.npmjs.org/grant-express/-/grant-express-4.1.2.tgz",
+      "integrity": "sha512-q90pj9XM5tUNAVkTIy/N73vK9rc+SiW4J5CUG/z30yL29PM5Yzpt1kORBoqsAmygTSUH3L/ZupXg1Dng3SXM1g==",
+      "requires": {
+        "grant": "4.1.2"
+      }
+    },
     "grapheme-breaker": {
       "version": "0.3.2",
       "resolved": "https://registry.npmjs.org/grapheme-breaker/-/grapheme-breaker-0.3.2.tgz",
@@ -21868,6 +22028,22 @@
         "npmlog": "^4.1.2"
       },
       "dependencies": {
+        "@lerna/run": {
+          "version": "3.18.5",
+          "resolved": "https://registry.npmjs.org/@lerna/run/-/run-3.18.5.tgz",
+          "integrity": "sha512-1S0dZccNJO8+gT5ztYE4rHTEnbXVwThHOfDnlVt2KDxl9cbnBALk3xprGLW7lSzJsxegS849hxrAPUh0UorMgw==",
+          "dev": true,
+          "requires": {
+            "@lerna/command": "3.18.5",
+            "@lerna/filter-options": "3.18.4",
+            "@lerna/npm-run-script": "3.16.5",
+            "@lerna/output": "3.13.0",
+            "@lerna/run-topologically": "3.18.5",
+            "@lerna/timer": "3.13.0",
+            "@lerna/validation-error": "3.13.0",
+            "p-map": "^2.1.0"
+          }
+        },
         "gauge": {
           "version": "2.7.4",
           "resolved": "https://registry.npmjs.org/gauge/-/gauge-2.7.4.tgz",
@@ -29159,6 +29335,11 @@
         }
       }
     },
+    "request-compose": {
+      "version": "0.0.19",
+      "resolved": "https://registry.npmjs.org/request-compose/-/request-compose-0.0.19.tgz",
+      "integrity": "sha512-BBMilZ4uReMzOCXvysw6l8nT5WwQDo/H8vaYNQ4BXPa7/0OJIaJskk4Ozzfpd2bmLb5ZQLpxJf/FMCeTX5QrkQ=="
+    },
     "request-oauth": {
       "version": "0.0.3",
       "resolved": "https://registry.npmjs.org/request-oauth/-/request-oauth-0.0.3.tgz",

+ 2 - 0
package.json

@@ -79,6 +79,7 @@
     "@babel/preset-env": "^7.7.6",
     "@babel/register": "^7.7.4",
     "@jamen/lorem": "^0.2.0",
+    "@lerna/run": "^3.20.0",
     "@octokit/rest": "^16.25.0",
     "@size-limit/preset-big-lib": "^2.2.2",
     "@types/aws-serverless-express": "^3.0.1",
@@ -200,6 +201,7 @@
     "dev:watch-sandbox": "cd examples/dev && npm run watch:sandbox",
     "dev:with-companion": "npm-run-all --parallel start:companion dev:watch-sandbox watch:js:lib watch:css dev:browsersync",
     "dev": "npm-run-all --parallel dev:watch-sandbox watch:js:lib watch:css dev:browsersync",
+    "example": "node bin/run-example",
     "lint:fix": "npm run lint -- --fix",
     "lint:staged": "lint-staged",
     "lint": "eslint . --cache",