├── .nvmrc ├── .gitignore ├── .codeclimate.yml ├── CHANGELOG.md ├── circle.yml ├── .editorconfig ├── package.json ├── LICENSE ├── cloudformation-role-policies-example.json ├── tests ├── bootstrap.template └── unit │ └── test.js ├── index.js ├── README.md ├── gulpfile.js ├── cloudformation.json └── yarn.lock /.nvmrc: -------------------------------------------------------------------------------- 1 | lts/boron -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | node_modules/ 2 | config* 3 | dist/ 4 | dist.zip -------------------------------------------------------------------------------- /.codeclimate.yml: -------------------------------------------------------------------------------- 1 | languages: 2 | JavaScript: true 3 | exclude_paths: 4 | - "test.js" -------------------------------------------------------------------------------- /CHANGELOG.md: -------------------------------------------------------------------------------- 1 | # 1.0.1 2 | - bugfix: gulpfile deployment issue 3 | 4 | # 1.0.0 5 | - meta: Start keeping a Changelog 6 | - feature: Add CI Boostrap template and gulp task 7 | - feature: Configure Circle CI 8 | - feature: Use node.js 6.10 runtime on lambda and locally 9 | - `nvm use 6.10` locally (required) 10 | - feature: Use Yarn package manager 11 | -------------------------------------------------------------------------------- /circle.yml: -------------------------------------------------------------------------------- 1 | version: 2 2 | jobs: 3 | build: 4 | docker: 5 | - image: node:boron 6 | working_directory: ~/aws-cloudformation-cognito-identity-pool 7 | steps: 8 | - checkout 9 | - run: 10 | name: Install Dependencies 11 | command: yarn --pure-lockfile 12 | - run: 13 | name: Test 14 | command: yarn test 15 | -------------------------------------------------------------------------------- /.editorconfig: -------------------------------------------------------------------------------- 1 | # EditorConfig is awesome: http://EditorConfig.org 2 | 3 | # top-most EditorConfig file 4 | root = true 5 | 6 | # Unix-style newlines with a newline ending every file 7 | [*] 8 | end_of_line = lf 9 | insert_final_newline = true 10 | indent_style = tab 11 | indent_size = 4 12 | 13 | # Matches multiple files with brace expansion notation 14 | # Set default charset 15 | [*.js] 16 | charset = utf-8 17 | 18 | # Matches the exact files either package.json or .travis.yml 19 | [{package.json,.travis.yml}] 20 | indent_style = space 21 | indent_size = 2 22 | -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "aws-cloudformation-cognito-identity-pool", 3 | "version": "1.0.1", 4 | "private": true, 5 | "description": "AWS Cloudformation Lambda-backed Custom Resource to Create/Update/Delete Cognito Identity Pools", 6 | "engines": { 7 | "node": ">=6" 8 | }, 9 | "main": "index.js", 10 | "scripts": { 11 | "test": "mocha tests/**/*.js" 12 | }, 13 | "keywords": [ 14 | "aws", 15 | "cloudformation", 16 | "lambda", 17 | "cognito", 18 | "cognitoidentity", 19 | "iam" 20 | ], 21 | "author": "Barrett K. Harber", 22 | "license": "Unlicense", 23 | "devDependencies": { 24 | "aws-sdk-js-on-lambda": "binoculars/aws-sdk-js-on-lambda", 25 | "del": "^2.2.2", 26 | "gulp": "^3.9.1", 27 | "gulp-install": "^1.1.0", 28 | "gulp-zip": "^4.0.0", 29 | "mocha": "^3.0.2", 30 | "run-sequence": "^1.2.2" 31 | } 32 | } 33 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | This is free and unencumbered software released into the public domain. 2 | 3 | Anyone is free to copy, modify, publish, use, compile, sell, or 4 | distribute this software, either in source code form or as a compiled 5 | binary, for any purpose, commercial or non-commercial, and by any 6 | means. 7 | 8 | In jurisdictions that recognize copyright laws, the author or authors 9 | of this software dedicate any and all copyright interest in the 10 | software to the public domain. We make this dedication for the benefit 11 | of the public at large and to the detriment of our heirs and 12 | successors. We intend this dedication to be an overt act of 13 | relinquishment in perpetuity of all present and future rights to this 14 | software under copyright law. 15 | 16 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, 17 | EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 18 | MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. 19 | IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY CLAIM, DAMAGES OR 20 | OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, 21 | ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR 22 | OTHER DEALINGS IN THE SOFTWARE. 23 | 24 | For more information, please refer to 25 | -------------------------------------------------------------------------------- /cloudformation-role-policies-example.json: -------------------------------------------------------------------------------- 1 | { 2 | "AWSTemplateFormatVersion": "2010-09-09", 3 | "Parameters": { 4 | "CognitoAuthenticatedRoleName": { 5 | "Type": "String", 6 | "MinLength": 1, 7 | "Description": "The name of the Cognito Authenticated Role" 8 | }, 9 | "CognitoUnauthenticatedRoleName": { 10 | "Type": "String", 11 | "Default": "", 12 | "Description": "The name of the Cognito Unauthenticated Role" 13 | } 14 | }, 15 | "Conditions": { 16 | "UseUnauthenticatedIdentities": { 17 | "Fn::Not": [ 18 | { 19 | "Fn::Equals": [ 20 | { 21 | "Ref": "CognitoUnauthenticatedRoleName" 22 | }, 23 | "" 24 | ] 25 | } 26 | ] 27 | } 28 | }, 29 | "Resources": { 30 | "CognitoAuthenticatedRolePolicy": { 31 | "Type": "AWS::IAM::ManagedPolicy", 32 | "Properties": { 33 | "Description": "Policy for the Authenticated Role", 34 | "Path" : "/", 35 | "PolicyDocument": { 36 | "Version": "2012-10-17", 37 | "Statement": [ 38 | { 39 | "Effect": "Allow", 40 | "Action": [ 41 | "mobileanalytics:PutEvents", 42 | "cognito-sync:*", 43 | "cognito-identity:*" 44 | ], 45 | "Resource": [ 46 | "*" 47 | ] 48 | } 49 | ] 50 | }, 51 | "Roles": [ 52 | { 53 | "Ref": "CognitoAuthenticatedRoleName" 54 | } 55 | ] 56 | } 57 | }, 58 | "CognitoUnauthenticatedRolePolicy": { 59 | "Type": "AWS::IAM::ManagedPolicy", 60 | "Condition" : "UseUnauthenticatedIdentities", 61 | "Properties": { 62 | "Description": "Policy for the Unauthenticated Role", 63 | "Path" : "/", 64 | "PolicyDocument": { 65 | "Version": "2012-10-17", 66 | "Statement": [ 67 | { 68 | "Effect": "Allow", 69 | "Action": [ 70 | "mobileanalytics:PutEvents", 71 | "cognito-sync:*" 72 | ], 73 | "Resource": [ 74 | "*" 75 | ] 76 | } 77 | ] 78 | }, 79 | "Roles": [ 80 | { 81 | "Ref": "CognitoUnauthenticatedRoleName" 82 | } 83 | ] 84 | } 85 | } 86 | } 87 | } 88 | -------------------------------------------------------------------------------- /tests/bootstrap.template: -------------------------------------------------------------------------------- 1 | { 2 | "AWSTemplateFormatVersion": "2010-09-09", 3 | "Description": "Bootstrap template for creating a continuous integration user and permissions", 4 | "Resources": { 5 | "Bucket": { 6 | "Type": "AWS::S3::Bucket" 7 | }, 8 | "CognitoRole": { 9 | "Type": "AWS::IAM::Role", 10 | "Properties": { 11 | "AssumeRolePolicyDocument": { 12 | "Version": "2012-10-17", 13 | "Statement": [ 14 | { 15 | "Effect": "Allow", 16 | "Principal": { 17 | "Federated": "cognito-identity.amazonaws.com" 18 | }, 19 | "Action": "sts:AssumeRoleWithWebIdentity", 20 | "Condition": { 21 | "StringEquals": { 22 | "cognito-identity.amazonaws.com:aud": "" 23 | }, 24 | "ForAnyValue:StringLike": { 25 | "cognito-identity.amazonaws.com:amr": "authenticated" 26 | } 27 | } 28 | } 29 | ] 30 | } 31 | } 32 | }, 33 | "CIPolicy": { 34 | "Type": "AWS::IAM::ManagedPolicy", 35 | "Properties": { 36 | "Description": "Policy for the CI User", 37 | "PolicyDocument": { 38 | "Version": "2012-10-17", 39 | "Statement": [ 40 | { 41 | "Effect": "Allow", 42 | "Action": [ 43 | "s3:DeleteObject", 44 | "s3:GetObject", 45 | "s3:PutObject" 46 | ], 47 | "Resource": { 48 | "Fn::Join": [ 49 | "", 50 | [ 51 | "arn:aws:s3:::", 52 | { 53 | "Ref": "Bucket" 54 | }, 55 | "/*" 56 | ] 57 | ] 58 | } 59 | }, 60 | { 61 | "Effect": "Allow", 62 | "Action": [ 63 | "cognito-identity:CreateIdentityPool", 64 | "cognito-identity:DeleteIdentityPool", 65 | "cognito-identity:SetIdentityPoolRoles", 66 | "cognito-identity:UpdateIdentityPool" 67 | ], 68 | "Resource": { 69 | "Fn::Join": [ 70 | "", 71 | [ 72 | "arn:aws:cognito-identity:", 73 | { 74 | "Ref": "AWS::Region" 75 | }, 76 | ":", 77 | { 78 | "Ref": "AWS::AccountId" 79 | }, 80 | ":identitypool/*" 81 | ] 82 | ] 83 | } 84 | }, 85 | { 86 | "Effect": "Allow", 87 | "Action": [ 88 | "iam:PassRole" 89 | ], 90 | "Resource": { 91 | "Fn::GetAtt": [ 92 | "CognitoRole", 93 | "Arn" 94 | ] 95 | } 96 | } 97 | ] 98 | } 99 | } 100 | }, 101 | "CIUser": { 102 | "Type": "AWS::IAM::User", 103 | "DependsOn": [ 104 | "CIPolicy" 105 | ], 106 | "Properties": { 107 | "Path": "/ci/", 108 | "ManagedPolicyArns": [ 109 | { 110 | "Ref": "CIPolicy" 111 | } 112 | ] 113 | } 114 | }, 115 | "CIUserAccessKey": { 116 | "Type": "AWS::IAM::AccessKey", 117 | "DependsOn": [ 118 | "CIUser" 119 | ], 120 | "Properties": { 121 | "UserName": { 122 | "Ref": "CIUser" 123 | } 124 | } 125 | } 126 | }, 127 | "Outputs": { 128 | "CIUserAccessKey": { 129 | "Value": { 130 | "Ref": "CIUserAccessKey" 131 | } 132 | }, 133 | "CIUserSecretKey": { 134 | "Value": { 135 | "Fn::GetAtt": [ 136 | "CIUserAccessKey", 137 | "SecretAccessKey" 138 | ] 139 | } 140 | }, 141 | "CIRegion": { 142 | "Value": { 143 | "Ref": "AWS::Region" 144 | } 145 | }, 146 | "Bucket": { 147 | "Value": { 148 | "Ref": "Bucket" 149 | } 150 | }, 151 | "CognitoRole": { 152 | "Value": { 153 | "Fn::GetAtt": [ 154 | "CognitoRole", 155 | "Arn" 156 | ] 157 | } 158 | } 159 | } 160 | } 161 | -------------------------------------------------------------------------------- /index.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | const https = require('https'); 4 | const url = require('url'); 5 | const CognitoIdentity = require('aws-sdk/clients/cognitoidentity'); 6 | const cognitoidentity = new CognitoIdentity(); 7 | const SUCCESS = 'SUCCESS'; 8 | const FAILED = 'FAILED'; 9 | const UNKNOWN = { 10 | Error: 'Unknown operation' 11 | }; 12 | const validRequestTypes = new Set([ 13 | 'Create', 14 | 'Update', 15 | 'Delete' 16 | ]); 17 | 18 | /** 19 | * The Lambda function handler 20 | * See also: https://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/crpg-ref.html 21 | * 22 | * @param {!Object} event 23 | * @param {!string} event.RequestType 24 | * @param {!string} event.ServiceToken 25 | * @param {!string} event.ResponseURL 26 | * @param {!string} event.StackId 27 | * @param {!string} event.RequestId 28 | * @param {!string} event.LogicalResourceId 29 | * @param {!string} event.PhysicalResourceId 30 | * @param {!Object} event.ResourceProperties 31 | * @param {!Object} event.ResourceProperties.Options 32 | * @param {!Object} context 33 | * @param {!Requester~requestCallback} callback 34 | */ 35 | exports.handler = (event, context, callback) => { 36 | console.log(event, context); 37 | 38 | const { 39 | StackId, 40 | RequestId, 41 | LogicalResourceId, 42 | PhysicalResourceId, 43 | RequestType, 44 | ResponseURL, 45 | ResourceProperties 46 | } = event; 47 | 48 | const {logStreamName} = context; 49 | 50 | function respond(Status, Data, PhysicalResourceId=logStreamName) { 51 | const responseBody = JSON.stringify({ 52 | Status, 53 | Reason: `See the details in CloudWatch Log Stream: ${logStreamName}`, 54 | PhysicalResourceId, 55 | StackId, 56 | RequestId, 57 | LogicalResourceId, 58 | Data 59 | }); 60 | 61 | console.log('Response body:\n', responseBody); 62 | 63 | const {hostname, path} = url.parse(ResponseURL); 64 | const options = { 65 | hostname, 66 | port: 443, 67 | path, 68 | method: 'PUT', 69 | headers: { 70 | 'content-type': '', 71 | 'content-length': responseBody.length 72 | } 73 | }; 74 | 75 | return new Promise((resolve, reject) => { 76 | const request = https 77 | .request(options, resolve); 78 | 79 | request.on('error', error => reject(`send(..) failed executing https.request(..): ${error}`)); 80 | request.write(responseBody); 81 | request.end(); 82 | }) 83 | .then(() => callback(Status === FAILED ? Status : null, Data)) 84 | .catch(callback); 85 | } 86 | 87 | if (!validRequestTypes.has(RequestType)) 88 | return respond(FAILED, UNKNOWN); 89 | 90 | const params = RequestType === 'Delete' ? {} : Object.assign({}, ResourceProperties.Options); 91 | 92 | switch (LogicalResourceId) { 93 | case 'CognitoIdentityPool': 94 | if (RequestType !== 'Create') 95 | params.IdentityPoolId = PhysicalResourceId; 96 | 97 | // CloudFormation passes the value as a string, so it must be converted to a valid javascript object 98 | if (RequestType !== 'Delete') { 99 | const parseParams = [ 100 | 'AllowUnauthenticatedIdentities', 101 | 'CognitoIdentityProviders', 102 | 'OpenIdConnectProviderARNs', 103 | 'SamlProviderARNs', 104 | 'SupportedLoginProviders' 105 | ]; 106 | 107 | try { 108 | for (let param of parseParams) { 109 | if (params[param]) 110 | params[param] = JSON.parse(params[param]); 111 | } 112 | } catch (message) { 113 | return respond(FAILED, {message}); 114 | } 115 | } 116 | 117 | return cognitoidentity[`${RequestType.toLowerCase()}IdentityPool`](params) 118 | .promise() 119 | .then(data => respond(SUCCESS, data, data.IdentityPoolId)) 120 | .catch(message => respond(FAILED, {message})); 121 | case 'CognitoIdentityPoolRoles': 122 | switch (RequestType) { 123 | case 'Create': 124 | case 'Update': 125 | return cognitoidentity 126 | .setIdentityPoolRoles(params) 127 | .promise() 128 | .then(data => respond(SUCCESS, data)) 129 | .catch(message => respond(FAILED, {message})); 130 | case 'Delete': 131 | return respond(SUCCESS); 132 | } 133 | break; 134 | default: 135 | return respond(FAILED, UNKNOWN); 136 | } 137 | }; -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | ❗️**DEPRECATED as of 2017-04-28. Please use [AWS::Cognito::IdentityPool](https://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-cognito-identitypool.html)** 2 | 3 | # AWS CloudFormation Cognito Identity Pool 4 | 5 | > An [AWS Lambda-backed Custom Resource](https://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/template-custom-resources-lambda.html) for CRUD operations on Cognito Identity Pools 6 | 7 | [![Codacy Badge](https://api.codacy.com/project/badge/Grade/5149b6ed184b4775b3d0ef04c6a4e27f)](https://www.codacy.com/app/barrett-harber/aws-cloudformation-cognito-identity-pool?utm_source=github.com&utm_medium=referral&utm_content=binoculars/aws-cloudformation-cognito-identity-pool&utm_campaign=Badge_Grade) 8 | [![Dependency Status](https://david-dm.org/binoculars/aws-cloudformation-cognito-identity-pool.svg)](https://david-dm.org/binoculars/aws-cloudformation-cognito-identity-pool) 9 | [![devDependency Status](https://david-dm.org/binoculars/aws-cloudformation-cognito-identity-pool/dev-status.svg)](https://david-dm.org/binoculars/aws-cloudformation-cognito-identity-pool#info=devDependencies) 10 | [![Code Climate](https://codeclimate.com/github/binoculars/aws-cloudformation-cognito-identity-pool/badges/gpa.svg)](https://codeclimate.com/github/binoculars/aws-cloudformation-cognito-identity-pool) 11 | [![Test Coverage](https://codeclimate.com/github/binoculars/aws-cloudformation-cognito-identity-pool/badges/coverage.svg)](https://codeclimate.com/github/binoculars/aws-cloudformation-cognito-identity-pool/coverage) 12 | [![Issue Count](https://codeclimate.com/github/binoculars/aws-cloudformation-cognito-identity-pool/badges/issue_count.svg)](https://codeclimate.com/github/binoculars/aws-cloudformation-cognito-identity-pool) 13 | [![Known Vulnerabilities](https://snyk.io/test/github/binoculars/aws-cloudformation-cognito-identity-pool/badge.svg)](https://snyk.io/test/github/binoculars/aws-cloudformation-cognito-identity-pool) 14 | [![Greenkeeper badge](https://badges.greenkeeper.io/binoculars/aws-cloudformation-cognito-identity-pool.svg)](https://greenkeeper.io/) 15 | [![bitHound Code](https://www.bithound.io/github/binoculars/aws-cloudformation-cognito-identity-pool/badges/code.svg)](https://www.bithound.io/github/binoculars/aws-cloudformation-cognito-identity-pool) 16 | 17 | - Master: [![CircleCI](https://circleci.com/gh/binoculars/aws-cloudformation-cognito-identity-pool/tree/master.svg?style=svg)](https://circleci.com/gh/binoculars/aws-cloudformation-cognito-identity-pool/tree/master) 18 | - Develop: [![CircleCI](https://circleci.com/gh/binoculars/aws-cloudformation-cognito-identity-pool/tree/develop.svg?style=svg)](https://circleci.com/gh/binoculars/aws-cloudformation-cognito-identity-pool/tree/develop) 19 | 20 | ### Background 21 | Cognito Identity Pools are not currently supported within CloudFormation templates. However, CloudFormation provides extensibility via Custom Resources, which enable Create/Update/Delete operations. This is meant to replace having to manually create Cognito Identity Pools manually via the CLI or web console. 22 | 23 | > See the related [blog post](https://medium.com/@barrettharber/polyfilling-aws-cloudformation-with-a-lambda-backed-custom-resource-a907f65144d5#.fnl9giwg1) for more information. 24 | 25 | ### Quick Start 26 | 1. Ensure you have node.js >= 6 installed (preferably via nvm) 27 | 1. Install gulp globally (`yarn global add gulp`) 28 | 1. Clone this repository 29 | 1. Run `yarn` 30 | 1. Create an S3 bucket to hold your Lambda Function (skip this if you already have one) 31 | 1. Create `config.json` (see below) 32 | 1. Ensure you have the [AWS SDK for Node.js configured](https://docs.aws.amazon.com/AWSJavaScriptSDK/guide/node-configuring.html) correctly. Also, set the `AWS_REGION` environment variable. 33 | 1. Run `gulp` this will: 34 | 1. Build the Lambda function and place it in dist.zip 35 | 1. Upload the function to S3 36 | 1. Create the CloudFormation Stack 37 | 1. Create your IAM Role Policy(ies). Examples are provided in [cloudformation-role-policies-example.json](cloudformation-role-policies-example.json), which provides managed policies that are attached to the IAM roles. This is necessary for your users to be able to use their credentials to do anything. 38 | 39 | ### Example `config.json` 40 | Create a `config.json` file. See [The AWS-SDK for JavaScript docs on CognitoIdentity](https://docs.aws.amazon.com/AWSJavaScriptSDK/latest/AWS/CognitoIdentity.html#createIdentityPool-property) for options, or run `aws cloudformation get-template-summary --template-body file:///path/to/cloudformation.json` 41 | 42 | ```JSON 43 | { 44 | "IdentityPoolName": "IdentityPoolName", 45 | "AllowUnauthenticatedIdentities": false, 46 | "LambdaS3Bucket": "bucket-name", 47 | "LambdaS3Key": "CloudFormation-CustomResource-CognitoIdentityPool.zip", 48 | "DeveloperProviderName": "com.site" 49 | } 50 | ``` 51 | 52 | All non-string values will be stringified for the CloudFormation template. If you're going to use the template directly (instead of using gulp), keep this in mind. 53 | 54 | ### Testing 55 | 1. Configure your environment 56 | - Run yarn install (`yarn`) 57 | - Create your Lambda S3 Bucket 58 | - Configure the AWS SDK for Node.js (or just set the `AWS_ACCESS_KEY_ID`, `AWS_SECRET_ACCESS_KEY`, and `AWS_REGION` environment variables) 59 | - Create your `config.json` 60 | 1. Run `yarn test` 61 | -------------------------------------------------------------------------------- /gulpfile.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | const fs = require('fs'); 4 | const path = require('path'); 5 | const util = require('util'); 6 | const gulp = require('gulp'); 7 | const del = require('del'); 8 | const install = require('gulp-install'); 9 | const zip = require('gulp-zip'); 10 | const runSequence = require('run-sequence'); 11 | const AWS = require('aws-sdk'); 12 | const s3 = new AWS.S3(); 13 | const cloudFormation = new AWS.CloudFormation(); 14 | const lambda = new AWS.Lambda(); 15 | 16 | let config; 17 | try { 18 | config = require('./config.json'); 19 | } catch (ex) { 20 | console.error('Cannot load configuration'); 21 | config = {}; 22 | } 23 | 24 | const StackName = 'cognito-identity-pool'; 25 | 26 | gulp.task('clean', () => del([ 27 | './build/*', 28 | './dist/*', 29 | './dist.zip' 30 | ])); 31 | 32 | gulp.task('js', () => gulp 33 | .src([ 34 | 'index.js' 35 | ]) 36 | .pipe(gulp.dest('./dist')) 37 | ); 38 | 39 | gulp.task('npm', () => gulp 40 | .src('./package.json') 41 | .pipe(gulp.dest('./dist')) 42 | .pipe(install({production: true})) 43 | ); 44 | 45 | gulp.task('zip', () => gulp 46 | .src([ 47 | 'dist/**/*', 48 | '!dist/package.json', 49 | 'dist/.*' 50 | ]) 51 | .pipe(zip('dist.zip')) 52 | .pipe(gulp.dest('./')) 53 | ); 54 | 55 | const { 56 | LambdaS3Bucket, 57 | LambdaS3Key 58 | } = process.env; 59 | 60 | gulp.task('upload', () => s3 61 | .putObject({ 62 | Bucket: LambdaS3Bucket, 63 | Key: LambdaS3Key, 64 | Body: fs.createReadStream('./dist.zip') 65 | }) 66 | .promise() 67 | ); 68 | 69 | gulp.task('listStacks', () => cloudFormation 70 | .listStacks({ 71 | StackStatusFilter: [ 72 | 'CREATE_COMPLETE', 73 | 'UPDATE_COMPLETE' 74 | ] 75 | }) 76 | .promise() 77 | .then(console.log) 78 | .catch(console.error) 79 | ); 80 | 81 | function getCloudFormationOperation(StackName) { 82 | return cloudFormation 83 | .describeStacks({ 84 | StackName 85 | }) 86 | .promise() 87 | .then(() => 'updateStack') 88 | .catch(() => 'createStack'); 89 | } 90 | 91 | gulp.task('deployStack', () => getCloudFormationOperation(StackName) 92 | .then(operation => cloudFormation[operation]({ 93 | StackName, 94 | Capabilities: [ 95 | 'CAPABILITY_IAM' 96 | ], 97 | Parameters: Object 98 | .keys(config) 99 | .map(key => ({ 100 | ParameterKey: key, 101 | ParameterValue: typeof config[key] === 'string' ? config[key] : JSON.stringify(config[key]) 102 | })), 103 | TemplateBody: fs.readFileSync('./cloudformation.json', {encoding: 'utf8'}) 104 | }) 105 | .promise() 106 | ) 107 | .then(console.log) 108 | .catch(console.error) 109 | ); 110 | 111 | gulp.task('updateConfig', () => cloudFormation 112 | .waitFor( 113 | 'stackCreateComplete', 114 | { 115 | StackName 116 | } 117 | ) 118 | .promise() 119 | .then(data => { 120 | console.log(util.inspect(data, {depth:5})); 121 | 122 | const configParams = { 123 | 'AccessKey': 'accessKeyId', 124 | 'AccessSecret': 'secretAccessKey' 125 | }; 126 | 127 | for (const item of data.Stacks[0].Outputs) 128 | config[configParams[item.OutputKey]] = item.OutputValue; 129 | 130 | fs.writeFileSync( 131 | './config.json', 132 | JSON.stringify(config, null, '\t'), 133 | 'utf8' 134 | ); 135 | }) 136 | ); 137 | 138 | // Once the stack is deployed, this will update the function if the code is changed without recreating the stack 139 | gulp.task('updateCode', () => cloudFormation 140 | .describeStackResource({ 141 | StackName, 142 | LogicalResourceId: 'Lambda' 143 | }) 144 | .promise() 145 | .then(({StackResourceDetail: PhysicalResourceId}) => lambda 146 | .updateFunctionCode({ 147 | FunctionName: PhysicalResourceId, 148 | S3Bucket: LambdaS3Bucket, 149 | S3Key: LambdaS3Key 150 | }) 151 | .promise() 152 | ) 153 | ); 154 | 155 | gulp.task('build', cb => 156 | runSequence( 157 | 'clean', 158 | ['js', 'npm'], 159 | 'zip', 160 | cb 161 | ) 162 | ); 163 | 164 | // Builds the function and uploads 165 | gulp.task('build-upload', cb => 166 | runSequence( 167 | 'build', 168 | 'upload', 169 | cb 170 | ) 171 | ); 172 | 173 | // For an already created stack 174 | gulp.task('update', cb => 175 | runSequence( 176 | 'updateConfig', 177 | 'build-upload', 178 | 'updateCode', 179 | cb 180 | ) 181 | ); 182 | 183 | // For a new stack (or you change cloudformation.json) 184 | gulp.task('default', cb => 185 | runSequence( 186 | 'build-upload', 187 | 'deployStack', 188 | cb 189 | ) 190 | ); 191 | 192 | const ciStackName = `CI-for-${StackName}`; 193 | 194 | gulp.task('ci-bootstrap', () => { 195 | const StackName = ciStackName; 196 | 197 | const outputEnvMap = new Map([ 198 | ['CIUserAccessKey', 'AWS_ACCESS_KEY_ID'], 199 | ['CIUserSecretKey', 'AWS_SECRET_ACCESS_KEY'], 200 | ['CIRegion', 'AWS_REGION'], 201 | ['Bucket', 'CFN_S3_BUCKET'], 202 | ['CognitoRole', 'ROLE_ARN'] 203 | ]); 204 | 205 | return getCloudFormationOperation(StackName) 206 | .then((operation) => cloudFormation[operation]({ 207 | StackName, 208 | Capabilities: [ 209 | 'CAPABILITY_NAMED_IAM' 210 | ], 211 | TemplateBody: fs.readFileSync( 212 | path.join( 213 | __dirname, 214 | 'tests/bootstrap.template' 215 | ), 216 | { 217 | encoding: 'utf8' 218 | } 219 | ) 220 | }) 221 | .promise() 222 | .then(() => `stack${operation === 'createStack' ? 'Create' : 'Update'}Complete`) 223 | ) 224 | .then(condition => cloudFormation 225 | .waitFor(condition, { 226 | StackName 227 | }) 228 | .promise() 229 | ) 230 | .catch(console.error) 231 | .then(() => cloudFormation 232 | .describeStacks({ 233 | StackName 234 | }) 235 | .promise() 236 | ) 237 | .then(({Stacks: [{Outputs}]}) => console.log( 238 | Outputs 239 | .map(({OutputKey, OutputValue}) => `${outputEnvMap.get(OutputKey)}=${OutputValue}`) 240 | .join('\n') 241 | )); 242 | }); 243 | -------------------------------------------------------------------------------- /tests/unit/test.js: -------------------------------------------------------------------------------- 1 | /* eslint-env node, mocha */ 2 | 3 | 'use strict'; 4 | 5 | const packageInfo = require('./../../package.json'); 6 | const lambda = require('./../../index.js'); 7 | const assert = require('assert'); 8 | const AWS = require('aws-sdk'); 9 | const s3 = new AWS.S3(); 10 | const cognitoidentity = new AWS.CognitoIdentity(); 11 | const iam = new AWS.IAM(); 12 | 13 | const today = new Date(); 14 | const date = [ 15 | today.getUTCFullYear(), 16 | today.getUTCMonth() + 1, 17 | today.getUTCDate() 18 | ].join('/'); 19 | const StackId = `arn:aws:cloudformation:${process.env.AWS_REGION}:000000000000:stack/${packageInfo.name}/00000000-0000-0000-0000-000000000000`; 20 | const RequestId = 'TEST_REQUEST_ID'; 21 | const IdentityPoolName = 'test_id_pool'; 22 | const context = { 23 | logStreamName: `${date}/[$LATEST]aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa` 24 | }; 25 | 26 | let ResponseURL; 27 | 28 | const { 29 | CFN_S3_BUCKET: Bucket, 30 | ROLE_ARN 31 | } = process.env; 32 | 33 | beforeEach(cb => { 34 | s3.getSignedUrl( 35 | 'putObject', 36 | { 37 | Bucket, 38 | Key: `test/${packageInfo.name}.json` 39 | }, 40 | (error, url) => { 41 | ResponseURL = url; 42 | cb(); 43 | } 44 | ); 45 | }); 46 | 47 | /** 48 | * Note: This suite must run in order 49 | */ 50 | describe('Cognito Identity Pool', () => { 51 | const LogicalResourceId = 'CognitoIdentityPool'; 52 | const ResourceProperties = { 53 | Options: { 54 | IdentityPoolName, 55 | AllowUnauthenticatedIdentities: 'false', 56 | DeveloperProviderName: 'TEST_PROVIDER_NAME' 57 | } 58 | }; 59 | let PhysicalResourceId; 60 | 61 | describe('Create', () => { 62 | it('should create a Cognito Identity Pool', cb => { 63 | lambda.handler( 64 | // event 65 | { 66 | ResponseURL, 67 | StackId, 68 | RequestId, 69 | LogicalResourceId, 70 | RequestType: 'Create', 71 | ResourceProperties 72 | }, 73 | // context 74 | context, 75 | // callback 76 | (error, data) => { 77 | assert.ifError(error); 78 | assert.ok(data.IdentityPoolId); 79 | assert.strictEqual(data.IdentityPoolName, IdentityPoolName); 80 | assert.strictEqual(data.AllowUnauthenticatedIdentities, ResourceProperties.Options.DeveloperProviderName === 'true'); 81 | assert.strictEqual(data.DeveloperProviderName, ResourceProperties.Options.DeveloperProviderName); 82 | PhysicalResourceId = data.IdentityPoolId; 83 | cb(); 84 | } 85 | ); 86 | }); 87 | }); 88 | 89 | describe('Update', () => { 90 | it('should update a Cognito Identity Pool', cb => { 91 | lambda.handler( 92 | // event 93 | { 94 | ResponseURL, 95 | StackId, 96 | RequestId, 97 | LogicalResourceId, 98 | PhysicalResourceId, 99 | RequestType: 'Update', 100 | ResourceProperties 101 | }, 102 | // context 103 | context, 104 | // callback 105 | (error, data) => { 106 | assert.ifError(error); 107 | assert.ok(data.IdentityPoolId); 108 | assert.strictEqual(data.IdentityPoolName, IdentityPoolName); 109 | assert.strictEqual(data.AllowUnauthenticatedIdentities, ResourceProperties.Options.DeveloperProviderName === 'true'); 110 | assert.strictEqual(data.DeveloperProviderName, ResourceProperties.Options.DeveloperProviderName); 111 | cb(); 112 | } 113 | ); 114 | }); 115 | }); 116 | 117 | describe('Delete', () => { 118 | it('should delete a Cognito Identity Pool', cb => { 119 | lambda.handler( 120 | // event 121 | { 122 | ResponseURL, 123 | StackId, 124 | RequestId, 125 | LogicalResourceId, 126 | PhysicalResourceId, 127 | RequestType: 'Delete', 128 | ResourceProperties 129 | }, 130 | // context 131 | context, 132 | // callback 133 | (error, data) => { 134 | assert.ifError(error); 135 | cb(); 136 | } 137 | ); 138 | }); 139 | }); 140 | 141 | describe('Unknown', () => { 142 | it('should fail', cb => { 143 | lambda.handler( 144 | // event 145 | { 146 | ResponseURL, 147 | StackId, 148 | RequestId, 149 | LogicalResourceId, 150 | PhysicalResourceId, 151 | RequestType: 'UNKNOWN', 152 | ResourceProperties 153 | }, 154 | // context 155 | context, 156 | // callback 157 | (error, data) => { 158 | assert.ifError(!error); 159 | cb(); 160 | } 161 | ); 162 | }); 163 | }); 164 | }); 165 | 166 | describe('Cognito Identity Pool Roles', () => { 167 | const LogicalResourceId = 'CognitoIdentityPoolRoles'; 168 | const ResourceProperties = { 169 | Options: { 170 | Roles: { 171 | authenticated: ROLE_ARN 172 | } 173 | } 174 | }; 175 | const {Options} = ResourceProperties; 176 | const RoleName = 'TEST_ROLE'; 177 | 178 | before(() => Promise 179 | .all([ 180 | cognitoidentity 181 | .createIdentityPool({ 182 | IdentityPoolName, 183 | AllowUnauthenticatedIdentities: false, 184 | DeveloperProviderName: 'devauth' 185 | }) 186 | .promise() 187 | .then(({IdentityPoolId}) => Object.assign(ResourceProperties.Options, {IdentityPoolId})), 188 | ROLE_ARN ? Promise.resolve() : iam 189 | .createRole({ 190 | AssumeRolePolicyDocument: JSON.stringify({ 191 | Version: '2012-10-17', 192 | Statement: [ 193 | { 194 | Effect: 'Allow', 195 | Principal: { 196 | Federated: 'cognito-identity.amazonaws.com' 197 | }, 198 | Action: 'sts:AssumeRoleWithWebIdentity', 199 | Condition: { 200 | StringEquals: { 201 | 'cognito-identity.amazonaws.com:aud': '' 202 | }, 203 | 'ForAnyValue:StringLike': { 204 | 'cognito-identity.amazonaws.com:amr': 'authenticated' 205 | } 206 | } 207 | } 208 | ] 209 | }), 210 | RoleName 211 | }) 212 | .promise() 213 | .then(({Arn}) => Options.Roles.authenticated = Arn) 214 | ]) 215 | ); 216 | 217 | describe('Create', () => { 218 | it('should update a Cognito Identity Pool with Roles', cb => { 219 | lambda.handler( 220 | // event 221 | { 222 | ResponseURL, 223 | StackId, 224 | RequestId, 225 | LogicalResourceId, 226 | RequestType: 'Create', 227 | ResourceProperties 228 | }, 229 | // context 230 | context, 231 | // callback 232 | (error, data) => { 233 | assert.ifError(error); 234 | cb(); 235 | } 236 | ); 237 | }); 238 | }); 239 | 240 | describe('Update', () => { 241 | it('should update a Cognito Identity Pool with Roles', cb => { 242 | lambda.handler( 243 | // event 244 | { 245 | ResponseURL, 246 | StackId, 247 | RequestId, 248 | LogicalResourceId, 249 | RequestType: 'Update', 250 | ResourceProperties 251 | }, 252 | // context 253 | context, 254 | // callback 255 | (error, data) => { 256 | assert.ifError(error); 257 | cb(); 258 | } 259 | ); 260 | }); 261 | }); 262 | 263 | describe('Delete', () => { 264 | it('should do nothing and respond with success', cb => { 265 | lambda.handler( 266 | // event 267 | { 268 | ResponseURL, 269 | StackId, 270 | RequestId, 271 | LogicalResourceId, 272 | RequestType: 'Delete', 273 | ResourceProperties 274 | }, 275 | // context 276 | context, 277 | // callback 278 | (error, data) => { 279 | assert.ifError(error); 280 | cb(); 281 | } 282 | ); 283 | }); 284 | }); 285 | 286 | describe('Unknown', () => { 287 | it('should fail', cb => { 288 | lambda.handler( 289 | // event 290 | { 291 | ResponseURL, 292 | StackId, 293 | RequestId, 294 | LogicalResourceId, 295 | RequestType: 'UNKNOWN', 296 | ResourceProperties 297 | }, 298 | // context 299 | context, 300 | // callback 301 | (error, data) => { 302 | assert.ifError(!error); 303 | cb(); 304 | } 305 | ); 306 | }); 307 | }); 308 | 309 | after(() => Promise 310 | .all([ 311 | cognitoidentity 312 | .deleteIdentityPool({ 313 | IdentityPoolId: Options.IdentityPoolId 314 | }) 315 | .promise(), 316 | ROLE_ARN ? Promise.resolve() : iam 317 | .deleteRole({ 318 | RoleName 319 | }) 320 | .promise() 321 | ]) 322 | ); 323 | }); 324 | -------------------------------------------------------------------------------- /cloudformation.json: -------------------------------------------------------------------------------- 1 | { 2 | "AWSTemplateFormatVersion": "2010-09-09", 3 | "Description": "An Amazon Cognito Identity Pool", 4 | "Parameters": { 5 | "AllowUnauthenticatedIdentities": { 6 | "Type": "String", 7 | "Description": "TRUE if the identity pool supports unauthenticated logins.", 8 | "AllowedValues": [ 9 | "true", 10 | "false" 11 | ] 12 | }, 13 | "IdentityPoolName": { 14 | "Type": "String", 15 | "MinLength": 1, 16 | "MaxLength": 128, 17 | "AllowedPattern": "^\\w+$", 18 | "Description": "The name for the Cognito Identity Pool" 19 | }, 20 | "CognitoIdentityProviders": { 21 | "Type": "String", 22 | "AllowedPattern": "^$|^\\[(,?\\{\\\"ClientId\\\":\\\".*\\\",\\\"ProviderName\\\":\\\".*\\\"\\})+\\]$", 23 | "Default": "", 24 | "Description": "a JSON string in the format Array. A list representing a Cognito User Identity Pool and its client ID. E.g [{ProviderName: String, ClientId: String}], where ProviderName is The provider name for a Cognito User Identity Pool. For example, cognito-idp.us-east-1.amazonaws.com/us-east-1_123456789 and ClientId is The client ID for the Cognito User Identity Pool." 25 | }, 26 | "DeveloperProviderName": { 27 | "Type": "String", 28 | "AllowedPattern": "^$|^[\\w\\.\\-]+$", 29 | "Default": "", 30 | "Description": "The \"domain\" by which Cognito will refer to your users. This name acts as a placeholder that allows your backend and the Cognito service to communicate about the developer provider. Once you have set a developer provider name, you cannot change it. Please take care in setting this parameter." 31 | }, 32 | "OpenIdConnectProviderARNs": { 33 | "Type": "String", 34 | "AllowedPattern": "^$|^\\[(,?\\\"arn:aws:iam::\\d{12}:oidc-provider\\/[a-z0-9\\.]+\\\")+\\]$", 35 | "Default": "", 36 | "Description": "Array A list of OpendID Connect provider ARNs." 37 | }, 38 | "SamlProviderARNs": { 39 | "Type": "String", 40 | "AllowedPattern": "^$|^\\[(,?\\\"arn:aws:iam::\\d{12}:saml-provider\\/[a-z0-9\\.]+\\\")+\\]$", 41 | "Default": "", 42 | "Description": "Array An array of Amazon Resource Names (ARNs) of the SAML provider for your identity pool." 43 | }, 44 | "SupportedLoginProviders": { 45 | "Type": "String", 46 | "AllowedPattern": "^$|^\\{(,?\\\"[a-z0-9\\.]+\\\":\\\".+\\\")+\\}$", 47 | "Default": "", 48 | "Description": "map Optional key:value pairs mapping provider names to provider app IDs." 49 | }, 50 | "LambdaS3Bucket": { 51 | "Type": "String", 52 | "Description": "The S3 bucket in which the lambda function code is stored" 53 | }, 54 | "LambdaS3Key": { 55 | "Type": "String", 56 | "AllowedPattern": ".*\\.zip", 57 | "Description": "The S3 key for the lambda function code" 58 | } 59 | }, 60 | "Conditions": { 61 | "UseUnauthenticatedIdentities": { 62 | "Fn::Equals": [ 63 | { 64 | "Ref": "AllowUnauthenticatedIdentities" 65 | }, 66 | "true" 67 | ] 68 | }, 69 | "EMPTY_CognitoIdentityProviders": { 70 | "Fn::Equals": [ 71 | { 72 | "Ref": "CognitoIdentityProviders" 73 | }, 74 | "" 75 | ] 76 | }, 77 | "EMPTY_DeveloperProviderName": { 78 | "Fn::Equals": [ 79 | { 80 | "Ref": "DeveloperProviderName" 81 | }, 82 | "" 83 | ] 84 | }, 85 | "EMPTY_OpenIdConnectProviderARNs": { 86 | "Fn::Equals": [ 87 | { 88 | "Ref": "OpenIdConnectProviderARNs" 89 | }, 90 | "" 91 | ] 92 | }, 93 | "EMPTY_SamlProviderARNs": { 94 | "Fn::Equals": [ 95 | { 96 | "Ref": "OpenIdConnectProviderARNs" 97 | }, 98 | "" 99 | ] 100 | }, 101 | "EMPTY_SupportedLoginProviders": { 102 | "Fn::Equals": [ 103 | { 104 | "Ref": "SupportedLoginProviders" 105 | }, 106 | "" 107 | ] 108 | } 109 | }, 110 | "Resources": { 111 | "LambdaExecutionRole": { 112 | "Type": "AWS::IAM::Role", 113 | "Properties": { 114 | "AssumeRolePolicyDocument": { 115 | "Version": "2012-10-17", 116 | "Statement": { 117 | "Effect": "Allow", 118 | "Principal": { 119 | "Service": "lambda.amazonaws.com" 120 | }, 121 | "Action": "sts:AssumeRole" 122 | } 123 | }, 124 | "Path": "/", 125 | "Policies": [ 126 | { 127 | "PolicyName": "root", 128 | "PolicyDocument": { 129 | "Version": "2012-10-17", 130 | "Statement": [ 131 | { 132 | "Effect": "Allow", 133 | "Action": [ 134 | "logs:CreateLogGroup", 135 | "logs:CreateLogStream", 136 | "logs:PutLogEvents" 137 | ], 138 | "Resource": "arn:aws:logs:*:*:*" 139 | }, 140 | { 141 | "Effect": "Allow", 142 | "Action": [ 143 | "cognito-identity:CreateIdentityPool", 144 | "cognito-identity:DeleteIdentityPool", 145 | "cognito-identity:UpdateIdentityPool", 146 | "cognito-identity:SetIdentityPoolRoles" 147 | ], 148 | "Resource": "*" 149 | } 150 | ] 151 | } 152 | } 153 | ] 154 | } 155 | }, 156 | "Lambda": { 157 | "Type": "AWS::Lambda::Function", 158 | "Properties": { 159 | "Code": { 160 | "S3Bucket": { 161 | "Ref": "LambdaS3Bucket" 162 | }, 163 | "S3Key": { 164 | "Ref": "LambdaS3Key" 165 | } 166 | }, 167 | "Handler": "index.handler", 168 | "MemorySize": 128, 169 | "Role": { 170 | "Fn::GetAtt": [ 171 | "LambdaExecutionRole", 172 | "Arn" 173 | ] 174 | }, 175 | "Runtime": "nodejs6.10", 176 | "Timeout": 30 177 | } 178 | }, 179 | "CognitoIdentityPool": { 180 | "Type": "Custom::CognitoIdentityPool", 181 | "Properties": { 182 | "ServiceToken": { 183 | "Fn::GetAtt": [ 184 | "Lambda", 185 | "Arn" 186 | ] 187 | }, 188 | "Options": { 189 | "AllowUnauthenticatedIdentities": { 190 | "Ref": "AllowUnauthenticatedIdentities" 191 | }, 192 | "IdentityPoolName": { 193 | "Ref": "IdentityPoolName" 194 | }, 195 | "CognitoIdentityProviders": { 196 | "Fn::If": [ 197 | "EMPTY_CognitoIdentityProviders", 198 | { 199 | "Ref": "AWS::NoValue" 200 | }, 201 | { 202 | "Ref": "CognitoIdentityProviders" 203 | } 204 | ] 205 | }, 206 | "DeveloperProviderName": { 207 | "Fn::If": [ 208 | "EMPTY_DeveloperProviderName", 209 | { 210 | "Ref": "AWS::NoValue" 211 | }, 212 | { 213 | "Ref": "DeveloperProviderName" 214 | } 215 | ] 216 | }, 217 | "OpenIdConnectProviderARNs": { 218 | "Fn::If": [ 219 | "EMPTY_OpenIdConnectProviderARNs", 220 | { 221 | "Ref": "AWS::NoValue" 222 | }, 223 | { 224 | "Ref": "OpenIdConnectProviderARNs" 225 | } 226 | ] 227 | }, 228 | "SamlProviderARNs": { 229 | "Fn::If": [ 230 | "EMPTY_SamlProviderARNs", 231 | { 232 | "Ref": "AWS::NoValue" 233 | }, 234 | { 235 | "Ref": "SamlProviderARNs" 236 | } 237 | ] 238 | }, 239 | "SupportedLoginProviders": { 240 | "Fn::If": [ 241 | "EMPTY_SupportedLoginProviders", 242 | { 243 | "Ref": "AWS::NoValue" 244 | }, 245 | { 246 | "Ref": "SupportedLoginProviders" 247 | } 248 | ] 249 | } 250 | } 251 | } 252 | }, 253 | "CognitoAuthenticatedRole": { 254 | "Type": "AWS::IAM::Role", 255 | "Properties": { 256 | "AssumeRolePolicyDocument": { 257 | "Version": "2012-10-17", 258 | "Statement": [ 259 | { 260 | "Effect": "Allow", 261 | "Principal": { 262 | "Federated": "cognito-identity.amazonaws.com" 263 | }, 264 | "Action": "sts:AssumeRoleWithWebIdentity", 265 | "Condition": { 266 | "StringEquals": { 267 | "cognito-identity.amazonaws.com:aud": { 268 | "Fn::GetAtt": [ 269 | "CognitoIdentityPool", 270 | "IdentityPoolId" 271 | ] 272 | } 273 | }, 274 | "ForAnyValue:StringLike": { 275 | "cognito-identity.amazonaws.com:amr": "authenticated" 276 | } 277 | } 278 | } 279 | ] 280 | } 281 | } 282 | }, 283 | "CognitoUnauthenticatedRole": { 284 | "Type": "AWS::IAM::Role", 285 | "Condition": "UseUnauthenticatedIdentities", 286 | "Properties": { 287 | "AssumeRolePolicyDocument": { 288 | "Version": "2012-10-17", 289 | "Statement": [ 290 | { 291 | "Effect": "Allow", 292 | "Principal": { 293 | "Federated": "cognito-identity.amazonaws.com" 294 | }, 295 | "Action": "sts:AssumeRoleWithWebIdentity", 296 | "Condition": { 297 | "StringEquals": { 298 | "cognito-identity.amazonaws.com:aud": { 299 | "Fn::GetAtt": [ 300 | "CognitoIdentityPool", 301 | "IdentityPoolId" 302 | ] 303 | } 304 | }, 305 | "ForAnyValue:StringLike": { 306 | "cognito-identity.amazonaws.com:amr": "unauthenticated" 307 | } 308 | } 309 | } 310 | ] 311 | } 312 | } 313 | }, 314 | "CognitoIdentityPoolRoles": { 315 | "Type": "Custom::CognitoIdentityPoolRoles", 316 | "Properties": { 317 | "ServiceToken": { 318 | "Fn::GetAtt": [ 319 | "Lambda", 320 | "Arn" 321 | ] 322 | }, 323 | "Options": { 324 | "IdentityPoolId": { 325 | "Fn::GetAtt": [ 326 | "CognitoIdentityPool", 327 | "IdentityPoolId" 328 | ] 329 | }, 330 | "Roles": { 331 | "authenticated": { 332 | "Fn::GetAtt": [ 333 | "CognitoAuthenticatedRole", 334 | "Arn" 335 | ] 336 | }, 337 | "unauthenticated": { 338 | "Fn::If": [ 339 | "UseUnauthenticatedIdentities", 340 | { 341 | "Fn::GetAtt": [ 342 | "CognitoUnauthenticatedRole", 343 | "Arn" 344 | ] 345 | }, 346 | { 347 | "Ref" : "AWS::NoValue" 348 | } 349 | ] 350 | } 351 | } 352 | } 353 | } 354 | } 355 | }, 356 | "Outputs": { 357 | "IdentityPoolId": { 358 | "Description": "The Identity Pool ID", 359 | "Value": { 360 | "Fn::GetAtt": [ 361 | "CognitoIdentityPool", 362 | "IdentityPoolId" 363 | ] 364 | } 365 | }, 366 | "CognitoAuthenticatedRoleName": { 367 | "Description": "The name of the Cognito Authenticated Role", 368 | "Value": { 369 | "Ref": "CognitoAuthenticatedRole" 370 | } 371 | }, 372 | "CognitoAuthenticatedRoleArn": { 373 | "Description": "The ARN of the Cognito Authenticated Role", 374 | "Value": { 375 | "Fn::GetAtt": [ 376 | "CognitoAuthenticatedRole", 377 | "Arn" 378 | ] 379 | } 380 | }, 381 | "CognitoUnauthenticatedRoleName": { 382 | "Description": "The name of the Cognito Unauthenticated Role", 383 | "Value": { 384 | "Fn::If": [ 385 | "UseUnauthenticatedIdentities", 386 | { 387 | "Ref": "CognitoUnauthenticatedRole" 388 | }, 389 | "" 390 | ] 391 | } 392 | }, 393 | "CognitoUnauthenticatedRoleArn": { 394 | "Description": "The ARN of the Cognito Unauthenticated Role", 395 | "Value": { 396 | "Fn::If": [ 397 | "UseUnauthenticatedIdentities", 398 | { 399 | "Fn::GetAtt": [ 400 | "CognitoUnauthenticatedRole", 401 | "Arn" 402 | ] 403 | }, 404 | "" 405 | ] 406 | } 407 | } 408 | 409 | } 410 | } 411 | -------------------------------------------------------------------------------- /yarn.lock: -------------------------------------------------------------------------------- 1 | # THIS IS AN AUTOGENERATED FILE. DO NOT EDIT THIS FILE DIRECTLY. 2 | # yarn lockfile v1 3 | 4 | 5 | ansi-regex@^2.0.0: 6 | version "2.1.1" 7 | resolved "https://registry.yarnpkg.com/ansi-regex/-/ansi-regex-2.1.1.tgz#c3b33ab5ee360d86e0e628f0468ae7ef27d654df" 8 | 9 | ansi-styles@^2.2.1: 10 | version "2.2.1" 11 | resolved "https://registry.yarnpkg.com/ansi-styles/-/ansi-styles-2.2.1.tgz#b432dd3358b634cf75e1e4664368240533c1ddbe" 12 | 13 | archy@^1.0.0: 14 | version "1.0.0" 15 | resolved "https://registry.yarnpkg.com/archy/-/archy-1.0.0.tgz#f9c8c13757cc1dd7bc379ac77b2c62a5c2868c40" 16 | 17 | arr-diff@^2.0.0: 18 | version "2.0.0" 19 | resolved "https://registry.yarnpkg.com/arr-diff/-/arr-diff-2.0.0.tgz#8f3b827f955a8bd669697e4a4256ac3ceae356cf" 20 | dependencies: 21 | arr-flatten "^1.0.1" 22 | 23 | arr-flatten@^1.0.1: 24 | version "1.0.1" 25 | resolved "https://registry.yarnpkg.com/arr-flatten/-/arr-flatten-1.0.1.tgz#e5ffe54d45e19f32f216e91eb99c8ce892bb604b" 26 | 27 | array-differ@^1.0.0: 28 | version "1.0.0" 29 | resolved "https://registry.yarnpkg.com/array-differ/-/array-differ-1.0.0.tgz#eff52e3758249d33be402b8bb8e564bb2b5d4031" 30 | 31 | array-union@^1.0.1: 32 | version "1.0.2" 33 | resolved "https://registry.yarnpkg.com/array-union/-/array-union-1.0.2.tgz#9a34410e4f4e3da23dea375be5be70f24778ec39" 34 | dependencies: 35 | array-uniq "^1.0.1" 36 | 37 | array-uniq@^1.0.1, array-uniq@^1.0.2: 38 | version "1.0.3" 39 | resolved "https://registry.yarnpkg.com/array-uniq/-/array-uniq-1.0.3.tgz#af6ac877a25cc7f74e058894753858dfdb24fdb6" 40 | 41 | array-unique@^0.2.1: 42 | version "0.2.1" 43 | resolved "https://registry.yarnpkg.com/array-unique/-/array-unique-0.2.1.tgz#a1d97ccafcbc2625cc70fadceb36a50c58b01a53" 44 | 45 | arrify@^1.0.0: 46 | version "1.0.1" 47 | resolved "https://registry.yarnpkg.com/arrify/-/arrify-1.0.1.tgz#898508da2226f380df904728456849c1501a4b0d" 48 | 49 | aws-sdk-js-on-lambda@binoculars/aws-sdk-js-on-lambda: 50 | version "2.22.0" 51 | resolved "https://codeload.github.com/binoculars/aws-sdk-js-on-lambda/tar.gz/6ec243ac80769edf1fff8aaa98fb11334ce00c3f" 52 | dependencies: 53 | aws-sdk "2.22.0" 54 | 55 | aws-sdk@2.22.0: 56 | version "2.22.0" 57 | resolved "https://registry.yarnpkg.com/aws-sdk/-/aws-sdk-2.22.0.tgz#f7b67d5ece7e67c36f9d3d55e137872572e5c998" 58 | dependencies: 59 | buffer "4.9.1" 60 | crypto-browserify "1.0.9" 61 | jmespath "0.15.0" 62 | querystring "0.2.0" 63 | sax "1.1.5" 64 | url "0.10.3" 65 | uuid "3.0.0" 66 | xml2js "0.4.15" 67 | xmlbuilder "2.6.2" 68 | 69 | balanced-match@^0.4.1: 70 | version "0.4.2" 71 | resolved "https://registry.yarnpkg.com/balanced-match/-/balanced-match-0.4.2.tgz#cb3f3e3c732dc0f01ee70b403f302e61d7709838" 72 | 73 | base64-js@^1.0.2: 74 | version "1.2.0" 75 | resolved "https://registry.yarnpkg.com/base64-js/-/base64-js-1.2.0.tgz#a39992d723584811982be5e290bb6a53d86700f1" 76 | 77 | beeper@^1.0.0: 78 | version "1.1.1" 79 | resolved "https://registry.yarnpkg.com/beeper/-/beeper-1.1.1.tgz#e6d5ea8c5dad001304a70b22638447f69cb2f809" 80 | 81 | brace-expansion@^1.0.0: 82 | version "1.1.6" 83 | resolved "https://registry.yarnpkg.com/brace-expansion/-/brace-expansion-1.1.6.tgz#7197d7eaa9b87e648390ea61fc66c84427420df9" 84 | dependencies: 85 | balanced-match "^0.4.1" 86 | concat-map "0.0.1" 87 | 88 | braces@^1.8.2: 89 | version "1.8.5" 90 | resolved "https://registry.yarnpkg.com/braces/-/braces-1.8.5.tgz#ba77962e12dff969d6b76711e914b737857bf6a7" 91 | dependencies: 92 | expand-range "^1.8.1" 93 | preserve "^0.2.0" 94 | repeat-element "^1.1.2" 95 | 96 | browser-stdout@1.3.0: 97 | version "1.3.0" 98 | resolved "https://registry.yarnpkg.com/browser-stdout/-/browser-stdout-1.3.0.tgz#f351d32969d32fa5d7a5567154263d928ae3bd1f" 99 | 100 | buffer-crc32@~0.2.3: 101 | version "0.2.13" 102 | resolved "https://registry.yarnpkg.com/buffer-crc32/-/buffer-crc32-0.2.13.tgz#0d333e3f00eac50aa1454abd30ef8c2a5d9a7242" 103 | 104 | buffer-shims@^1.0.0: 105 | version "1.0.0" 106 | resolved "https://registry.yarnpkg.com/buffer-shims/-/buffer-shims-1.0.0.tgz#9978ce317388c649ad8793028c3477ef044a8b51" 107 | 108 | buffer@4.9.1: 109 | version "4.9.1" 110 | resolved "https://registry.yarnpkg.com/buffer/-/buffer-4.9.1.tgz#6d1bb601b07a4efced97094132093027c95bc298" 111 | dependencies: 112 | base64-js "^1.0.2" 113 | ieee754 "^1.1.4" 114 | isarray "^1.0.0" 115 | 116 | chalk@*, chalk@^1.0.0, chalk@^1.1.1: 117 | version "1.1.3" 118 | resolved "https://registry.yarnpkg.com/chalk/-/chalk-1.1.3.tgz#a8115c55e4a702fe4d150abd3872822a7e09fc98" 119 | dependencies: 120 | ansi-styles "^2.2.1" 121 | escape-string-regexp "^1.0.2" 122 | has-ansi "^2.0.0" 123 | strip-ansi "^3.0.0" 124 | supports-color "^2.0.0" 125 | 126 | clone-stats@^0.0.1: 127 | version "0.0.1" 128 | resolved "https://registry.yarnpkg.com/clone-stats/-/clone-stats-0.0.1.tgz#b88f94a82cf38b8791d58046ea4029ad88ca99d1" 129 | 130 | clone@^0.2.0: 131 | version "0.2.0" 132 | resolved "https://registry.yarnpkg.com/clone/-/clone-0.2.0.tgz#c6126a90ad4f72dbf5acdb243cc37724fe93fc1f" 133 | 134 | clone@^1.0.0, clone@^1.0.2: 135 | version "1.0.2" 136 | resolved "https://registry.yarnpkg.com/clone/-/clone-1.0.2.tgz#260b7a99ebb1edfe247538175f783243cb19d149" 137 | 138 | commander@2.9.0: 139 | version "2.9.0" 140 | resolved "https://registry.yarnpkg.com/commander/-/commander-2.9.0.tgz#9c99094176e12240cb22d6c5146098400fe0f7d4" 141 | dependencies: 142 | graceful-readlink ">= 1.0.0" 143 | 144 | concat-map@0.0.1: 145 | version "0.0.1" 146 | resolved "https://registry.yarnpkg.com/concat-map/-/concat-map-0.0.1.tgz#d8a96bd77fd68df7793a73036a3ba0d5405d477b" 147 | 148 | core-util-is@~1.0.0: 149 | version "1.0.2" 150 | resolved "https://registry.yarnpkg.com/core-util-is/-/core-util-is-1.0.2.tgz#b5fd54220aa2bc5ab57aab7140c940754503c1a7" 151 | 152 | crypto-browserify@1.0.9: 153 | version "1.0.9" 154 | resolved "https://registry.yarnpkg.com/crypto-browserify/-/crypto-browserify-1.0.9.tgz#cc5449685dfb85eb11c9828acc7cb87ab5bbfcc0" 155 | 156 | dargs@^5.1.0: 157 | version "5.1.0" 158 | resolved "https://registry.yarnpkg.com/dargs/-/dargs-5.1.0.tgz#ec7ea50c78564cd36c9d5ec18f66329fade27829" 159 | 160 | dateformat@^2.0.0: 161 | version "2.0.0" 162 | resolved "https://registry.yarnpkg.com/dateformat/-/dateformat-2.0.0.tgz#2743e3abb5c3fc2462e527dca445e04e9f4dee17" 163 | 164 | debug@2.2.0: 165 | version "2.2.0" 166 | resolved "https://registry.yarnpkg.com/debug/-/debug-2.2.0.tgz#f87057e995b1a1f6ae6a4960664137bc56f039da" 167 | dependencies: 168 | ms "0.7.1" 169 | 170 | defaults@^1.0.0: 171 | version "1.0.3" 172 | resolved "https://registry.yarnpkg.com/defaults/-/defaults-1.0.3.tgz#c656051e9817d9ff08ed881477f3fe4019f3ef7d" 173 | dependencies: 174 | clone "^1.0.2" 175 | 176 | del@^2.2.2: 177 | version "2.2.2" 178 | resolved "https://registry.yarnpkg.com/del/-/del-2.2.2.tgz#c12c981d067846c84bcaf862cff930d907ffd1a8" 179 | dependencies: 180 | globby "^5.0.0" 181 | is-path-cwd "^1.0.0" 182 | is-path-in-cwd "^1.0.0" 183 | object-assign "^4.0.1" 184 | pify "^2.0.0" 185 | pinkie-promise "^2.0.0" 186 | rimraf "^2.2.8" 187 | 188 | deprecated@^0.0.1: 189 | version "0.0.1" 190 | resolved "https://registry.yarnpkg.com/deprecated/-/deprecated-0.0.1.tgz#f9c9af5464afa1e7a971458a8bdef2aa94d5bb19" 191 | 192 | detect-file@^0.1.0: 193 | version "0.1.0" 194 | resolved "https://registry.yarnpkg.com/detect-file/-/detect-file-0.1.0.tgz#4935dedfd9488648e006b0129566e9386711ea63" 195 | dependencies: 196 | fs-exists-sync "^0.1.0" 197 | 198 | diff@1.4.0: 199 | version "1.4.0" 200 | resolved "https://registry.yarnpkg.com/diff/-/diff-1.4.0.tgz#7f28d2eb9ee7b15a97efd89ce63dcfdaa3ccbabf" 201 | 202 | duplexer2@0.0.2: 203 | version "0.0.2" 204 | resolved "https://registry.yarnpkg.com/duplexer2/-/duplexer2-0.0.2.tgz#c614dcf67e2fb14995a91711e5a617e8a60a31db" 205 | dependencies: 206 | readable-stream "~1.1.9" 207 | 208 | end-of-stream@~0.1.5: 209 | version "0.1.5" 210 | resolved "https://registry.yarnpkg.com/end-of-stream/-/end-of-stream-0.1.5.tgz#8e177206c3c80837d85632e8b9359dfe8b2f6eaf" 211 | dependencies: 212 | once "~1.3.0" 213 | 214 | escape-string-regexp@1.0.5, escape-string-regexp@^1.0.2: 215 | version "1.0.5" 216 | resolved "https://registry.yarnpkg.com/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz#1b61c0562190a8dff6ae3bb2cf0200ca130b86d4" 217 | 218 | expand-brackets@^0.1.4: 219 | version "0.1.5" 220 | resolved "https://registry.yarnpkg.com/expand-brackets/-/expand-brackets-0.1.5.tgz#df07284e342a807cd733ac5af72411e581d1177b" 221 | dependencies: 222 | is-posix-bracket "^0.1.0" 223 | 224 | expand-range@^1.8.1: 225 | version "1.8.2" 226 | resolved "https://registry.yarnpkg.com/expand-range/-/expand-range-1.8.2.tgz#a299effd335fe2721ebae8e257ec79644fc85337" 227 | dependencies: 228 | fill-range "^2.1.0" 229 | 230 | expand-tilde@^1.2.1, expand-tilde@^1.2.2: 231 | version "1.2.2" 232 | resolved "https://registry.yarnpkg.com/expand-tilde/-/expand-tilde-1.2.2.tgz#0b81eba897e5a3d31d1c3d102f8f01441e559449" 233 | dependencies: 234 | os-homedir "^1.0.1" 235 | 236 | extend@^3.0.0: 237 | version "3.0.0" 238 | resolved "https://registry.yarnpkg.com/extend/-/extend-3.0.0.tgz#5a474353b9f3353ddd8176dfd37b91c83a46f1d4" 239 | 240 | extglob@^0.3.1: 241 | version "0.3.2" 242 | resolved "https://registry.yarnpkg.com/extglob/-/extglob-0.3.2.tgz#2e18ff3d2f49ab2765cec9023f011daa8d8349a1" 243 | dependencies: 244 | is-extglob "^1.0.0" 245 | 246 | fancy-log@^1.1.0: 247 | version "1.3.0" 248 | resolved "https://registry.yarnpkg.com/fancy-log/-/fancy-log-1.3.0.tgz#45be17d02bb9917d60ccffd4995c999e6c8c9948" 249 | dependencies: 250 | chalk "^1.1.1" 251 | time-stamp "^1.0.0" 252 | 253 | filename-regex@^2.0.0: 254 | version "2.0.0" 255 | resolved "https://registry.yarnpkg.com/filename-regex/-/filename-regex-2.0.0.tgz#996e3e80479b98b9897f15a8a58b3d084e926775" 256 | 257 | fill-range@^2.1.0: 258 | version "2.2.3" 259 | resolved "https://registry.yarnpkg.com/fill-range/-/fill-range-2.2.3.tgz#50b77dfd7e469bc7492470963699fe7a8485a723" 260 | dependencies: 261 | is-number "^2.1.0" 262 | isobject "^2.0.0" 263 | randomatic "^1.1.3" 264 | repeat-element "^1.1.2" 265 | repeat-string "^1.5.2" 266 | 267 | find-index@^0.1.1: 268 | version "0.1.1" 269 | resolved "https://registry.yarnpkg.com/find-index/-/find-index-0.1.1.tgz#675d358b2ca3892d795a1ab47232f8b6e2e0dde4" 270 | 271 | findup-sync@^0.4.2: 272 | version "0.4.3" 273 | resolved "https://registry.yarnpkg.com/findup-sync/-/findup-sync-0.4.3.tgz#40043929e7bc60adf0b7f4827c4c6e75a0deca12" 274 | dependencies: 275 | detect-file "^0.1.0" 276 | is-glob "^2.0.1" 277 | micromatch "^2.3.7" 278 | resolve-dir "^0.1.0" 279 | 280 | fined@^1.0.1: 281 | version "1.0.2" 282 | resolved "https://registry.yarnpkg.com/fined/-/fined-1.0.2.tgz#5b28424b760d7598960b7ef8480dff8ad3660e97" 283 | dependencies: 284 | expand-tilde "^1.2.1" 285 | lodash.assignwith "^4.0.7" 286 | lodash.isempty "^4.2.1" 287 | lodash.isplainobject "^4.0.4" 288 | lodash.isstring "^4.0.1" 289 | lodash.pick "^4.2.1" 290 | parse-filepath "^1.0.1" 291 | 292 | first-chunk-stream@^1.0.0: 293 | version "1.0.0" 294 | resolved "https://registry.yarnpkg.com/first-chunk-stream/-/first-chunk-stream-1.0.0.tgz#59bfb50cd905f60d7c394cd3d9acaab4e6ad934e" 295 | 296 | flagged-respawn@^0.3.2: 297 | version "0.3.2" 298 | resolved "https://registry.yarnpkg.com/flagged-respawn/-/flagged-respawn-0.3.2.tgz#ff191eddcd7088a675b2610fffc976be9b8074b5" 299 | 300 | for-in@^1.0.1: 301 | version "1.0.2" 302 | resolved "https://registry.yarnpkg.com/for-in/-/for-in-1.0.2.tgz#81068d295a8142ec0ac726c6e2200c30fb6d5e80" 303 | 304 | for-own@^0.1.4: 305 | version "0.1.5" 306 | resolved "https://registry.yarnpkg.com/for-own/-/for-own-0.1.5.tgz#5265c681a4f294dabbf17c9509b6763aa84510ce" 307 | dependencies: 308 | for-in "^1.0.1" 309 | 310 | fs-exists-sync@^0.1.0: 311 | version "0.1.0" 312 | resolved "https://registry.yarnpkg.com/fs-exists-sync/-/fs-exists-sync-0.1.0.tgz#982d6893af918e72d08dec9e8673ff2b5a8d6add" 313 | 314 | fs.realpath@^1.0.0: 315 | version "1.0.0" 316 | resolved "https://registry.yarnpkg.com/fs.realpath/-/fs.realpath-1.0.0.tgz#1504ad2523158caa40db4a2787cb01411994ea4f" 317 | 318 | gaze@^0.5.1: 319 | version "0.5.2" 320 | resolved "https://registry.yarnpkg.com/gaze/-/gaze-0.5.2.tgz#40b709537d24d1d45767db5a908689dfe69ac44f" 321 | dependencies: 322 | globule "~0.1.0" 323 | 324 | get-stream@^3.0.0: 325 | version "3.0.0" 326 | resolved "https://registry.yarnpkg.com/get-stream/-/get-stream-3.0.0.tgz#8e943d1358dc37555054ecbe2edb05aa174ede14" 327 | 328 | glob-base@^0.3.0: 329 | version "0.3.0" 330 | resolved "https://registry.yarnpkg.com/glob-base/-/glob-base-0.3.0.tgz#dbb164f6221b1c0b1ccf82aea328b497df0ea3c4" 331 | dependencies: 332 | glob-parent "^2.0.0" 333 | is-glob "^2.0.0" 334 | 335 | glob-parent@^2.0.0: 336 | version "2.0.0" 337 | resolved "https://registry.yarnpkg.com/glob-parent/-/glob-parent-2.0.0.tgz#81383d72db054fcccf5336daa902f182f6edbb28" 338 | dependencies: 339 | is-glob "^2.0.0" 340 | 341 | glob-stream@^3.1.5: 342 | version "3.1.18" 343 | resolved "https://registry.yarnpkg.com/glob-stream/-/glob-stream-3.1.18.tgz#9170a5f12b790306fdfe598f313f8f7954fd143b" 344 | dependencies: 345 | glob "^4.3.1" 346 | glob2base "^0.0.12" 347 | minimatch "^2.0.1" 348 | ordered-read-streams "^0.1.0" 349 | through2 "^0.6.1" 350 | unique-stream "^1.0.0" 351 | 352 | glob-watcher@^0.0.6: 353 | version "0.0.6" 354 | resolved "https://registry.yarnpkg.com/glob-watcher/-/glob-watcher-0.0.6.tgz#b95b4a8df74b39c83298b0c05c978b4d9a3b710b" 355 | dependencies: 356 | gaze "^0.5.1" 357 | 358 | glob2base@^0.0.12: 359 | version "0.0.12" 360 | resolved "https://registry.yarnpkg.com/glob2base/-/glob2base-0.0.12.tgz#9d419b3e28f12e83a362164a277055922c9c0d56" 361 | dependencies: 362 | find-index "^0.1.1" 363 | 364 | glob@7.0.5, glob@^7.0.3, glob@^7.0.5: 365 | version "7.0.5" 366 | resolved "https://registry.yarnpkg.com/glob/-/glob-7.0.5.tgz#b4202a69099bbb4d292a7c1b95b6682b67ebdc95" 367 | dependencies: 368 | fs.realpath "^1.0.0" 369 | inflight "^1.0.4" 370 | inherits "2" 371 | minimatch "^3.0.2" 372 | once "^1.3.0" 373 | path-is-absolute "^1.0.0" 374 | 375 | glob@^4.3.1: 376 | version "4.5.3" 377 | resolved "https://registry.yarnpkg.com/glob/-/glob-4.5.3.tgz#c6cb73d3226c1efef04de3c56d012f03377ee15f" 378 | dependencies: 379 | inflight "^1.0.4" 380 | inherits "2" 381 | minimatch "^2.0.1" 382 | once "^1.3.0" 383 | 384 | glob@~3.1.21: 385 | version "3.1.21" 386 | resolved "https://registry.yarnpkg.com/glob/-/glob-3.1.21.tgz#d29e0a055dea5138f4d07ed40e8982e83c2066cd" 387 | dependencies: 388 | graceful-fs "~1.2.0" 389 | inherits "1" 390 | minimatch "~0.2.11" 391 | 392 | global-modules@^0.2.3: 393 | version "0.2.3" 394 | resolved "https://registry.yarnpkg.com/global-modules/-/global-modules-0.2.3.tgz#ea5a3bed42c6d6ce995a4f8a1269b5dae223828d" 395 | dependencies: 396 | global-prefix "^0.1.4" 397 | is-windows "^0.2.0" 398 | 399 | global-prefix@^0.1.4: 400 | version "0.1.5" 401 | resolved "https://registry.yarnpkg.com/global-prefix/-/global-prefix-0.1.5.tgz#8d3bc6b8da3ca8112a160d8d496ff0462bfef78f" 402 | dependencies: 403 | homedir-polyfill "^1.0.0" 404 | ini "^1.3.4" 405 | is-windows "^0.2.0" 406 | which "^1.2.12" 407 | 408 | globby@^5.0.0: 409 | version "5.0.0" 410 | resolved "https://registry.yarnpkg.com/globby/-/globby-5.0.0.tgz#ebd84667ca0dbb330b99bcfc68eac2bc54370e0d" 411 | dependencies: 412 | array-union "^1.0.1" 413 | arrify "^1.0.0" 414 | glob "^7.0.3" 415 | object-assign "^4.0.1" 416 | pify "^2.0.0" 417 | pinkie-promise "^2.0.0" 418 | 419 | globule@~0.1.0: 420 | version "0.1.0" 421 | resolved "https://registry.yarnpkg.com/globule/-/globule-0.1.0.tgz#d9c8edde1da79d125a151b79533b978676346ae5" 422 | dependencies: 423 | glob "~3.1.21" 424 | lodash "~1.0.1" 425 | minimatch "~0.2.11" 426 | 427 | glogg@^1.0.0: 428 | version "1.0.0" 429 | resolved "https://registry.yarnpkg.com/glogg/-/glogg-1.0.0.tgz#7fe0f199f57ac906cf512feead8f90ee4a284fc5" 430 | dependencies: 431 | sparkles "^1.0.0" 432 | 433 | graceful-fs@^3.0.0: 434 | version "3.0.11" 435 | resolved "https://registry.yarnpkg.com/graceful-fs/-/graceful-fs-3.0.11.tgz#7613c778a1afea62f25c630a086d7f3acbbdd818" 436 | dependencies: 437 | natives "^1.1.0" 438 | 439 | graceful-fs@~1.2.0: 440 | version "1.2.3" 441 | resolved "https://registry.yarnpkg.com/graceful-fs/-/graceful-fs-1.2.3.tgz#15a4806a57547cb2d2dbf27f42e89a8c3451b364" 442 | 443 | "graceful-readlink@>= 1.0.0": 444 | version "1.0.1" 445 | resolved "https://registry.yarnpkg.com/graceful-readlink/-/graceful-readlink-1.0.1.tgz#4cafad76bc62f02fa039b2f94e9a3dd3a391a725" 446 | 447 | growl@1.9.2: 448 | version "1.9.2" 449 | resolved "https://registry.yarnpkg.com/growl/-/growl-1.9.2.tgz#0ea7743715db8d8de2c5ede1775e1b45ac85c02f" 450 | 451 | gulp-install@^1.1.0: 452 | version "1.1.0" 453 | resolved "https://registry.yarnpkg.com/gulp-install/-/gulp-install-1.1.0.tgz#9386b46cb4669b47257b6adf4e3ea2e83c928a1a" 454 | dependencies: 455 | dargs "^5.1.0" 456 | gulp-util "^3.0.7" 457 | lodash.groupby "^4.6.0" 458 | p-queue "^1.0.0" 459 | through2 "^2.0.3" 460 | which "^1.2.14" 461 | 462 | gulp-util@*, gulp-util@^3.0.0, gulp-util@^3.0.7: 463 | version "3.0.8" 464 | resolved "https://registry.yarnpkg.com/gulp-util/-/gulp-util-3.0.8.tgz#0054e1e744502e27c04c187c3ecc505dd54bbb4f" 465 | dependencies: 466 | array-differ "^1.0.0" 467 | array-uniq "^1.0.2" 468 | beeper "^1.0.0" 469 | chalk "^1.0.0" 470 | dateformat "^2.0.0" 471 | fancy-log "^1.1.0" 472 | gulplog "^1.0.0" 473 | has-gulplog "^0.1.0" 474 | lodash._reescape "^3.0.0" 475 | lodash._reevaluate "^3.0.0" 476 | lodash._reinterpolate "^3.0.0" 477 | lodash.template "^3.0.0" 478 | minimist "^1.1.0" 479 | multipipe "^0.1.2" 480 | object-assign "^3.0.0" 481 | replace-ext "0.0.1" 482 | through2 "^2.0.0" 483 | vinyl "^0.5.0" 484 | 485 | gulp-zip@^4.0.0: 486 | version "4.0.0" 487 | resolved "https://registry.yarnpkg.com/gulp-zip/-/gulp-zip-4.0.0.tgz#1cefc08b4bf36df4b5b1e7c6b36ee55ebbe4a881" 488 | dependencies: 489 | get-stream "^3.0.0" 490 | gulp-util "^3.0.0" 491 | through2 "^2.0.1" 492 | yazl "^2.1.0" 493 | 494 | gulp@^3.9.1: 495 | version "3.9.1" 496 | resolved "https://registry.yarnpkg.com/gulp/-/gulp-3.9.1.tgz#571ce45928dd40af6514fc4011866016c13845b4" 497 | dependencies: 498 | archy "^1.0.0" 499 | chalk "^1.0.0" 500 | deprecated "^0.0.1" 501 | gulp-util "^3.0.0" 502 | interpret "^1.0.0" 503 | liftoff "^2.1.0" 504 | minimist "^1.1.0" 505 | orchestrator "^0.3.0" 506 | pretty-hrtime "^1.0.0" 507 | semver "^4.1.0" 508 | tildify "^1.0.0" 509 | v8flags "^2.0.2" 510 | vinyl-fs "^0.3.0" 511 | 512 | gulplog@^1.0.0: 513 | version "1.0.0" 514 | resolved "https://registry.yarnpkg.com/gulplog/-/gulplog-1.0.0.tgz#e28c4d45d05ecbbed818363ce8f9c5926229ffe5" 515 | dependencies: 516 | glogg "^1.0.0" 517 | 518 | has-ansi@^2.0.0: 519 | version "2.0.0" 520 | resolved "https://registry.yarnpkg.com/has-ansi/-/has-ansi-2.0.0.tgz#34f5049ce1ecdf2b0649af3ef24e45ed35416d91" 521 | dependencies: 522 | ansi-regex "^2.0.0" 523 | 524 | has-flag@^1.0.0: 525 | version "1.0.0" 526 | resolved "https://registry.yarnpkg.com/has-flag/-/has-flag-1.0.0.tgz#9d9e793165ce017a00f00418c43f942a7b1d11fa" 527 | 528 | has-gulplog@^0.1.0: 529 | version "0.1.0" 530 | resolved "https://registry.yarnpkg.com/has-gulplog/-/has-gulplog-0.1.0.tgz#6414c82913697da51590397dafb12f22967811ce" 531 | dependencies: 532 | sparkles "^1.0.0" 533 | 534 | homedir-polyfill@^1.0.0: 535 | version "1.0.1" 536 | resolved "https://registry.yarnpkg.com/homedir-polyfill/-/homedir-polyfill-1.0.1.tgz#4c2bbc8a758998feebf5ed68580f76d46768b4bc" 537 | dependencies: 538 | parse-passwd "^1.0.0" 539 | 540 | ieee754@^1.1.4: 541 | version "1.1.8" 542 | resolved "https://registry.yarnpkg.com/ieee754/-/ieee754-1.1.8.tgz#be33d40ac10ef1926701f6f08a2d86fbfd1ad3e4" 543 | 544 | inflight@^1.0.4: 545 | version "1.0.6" 546 | resolved "https://registry.yarnpkg.com/inflight/-/inflight-1.0.6.tgz#49bd6331d7d02d0c09bc910a1075ba8165b56df9" 547 | dependencies: 548 | once "^1.3.0" 549 | wrappy "1" 550 | 551 | inherits@1: 552 | version "1.0.2" 553 | resolved "https://registry.yarnpkg.com/inherits/-/inherits-1.0.2.tgz#ca4309dadee6b54cc0b8d247e8d7c7a0975bdc9b" 554 | 555 | inherits@2, inherits@~2.0.1: 556 | version "2.0.3" 557 | resolved "https://registry.yarnpkg.com/inherits/-/inherits-2.0.3.tgz#633c2c83e3da42a502f52466022480f4208261de" 558 | 559 | ini@^1.3.4: 560 | version "1.3.4" 561 | resolved "https://registry.yarnpkg.com/ini/-/ini-1.3.4.tgz#0537cb79daf59b59a1a517dff706c86ec039162e" 562 | 563 | interpret@^1.0.0: 564 | version "1.0.1" 565 | resolved "https://registry.yarnpkg.com/interpret/-/interpret-1.0.1.tgz#d579fb7f693b858004947af39fa0db49f795602c" 566 | 567 | is-absolute@^0.2.3: 568 | version "0.2.6" 569 | resolved "https://registry.yarnpkg.com/is-absolute/-/is-absolute-0.2.6.tgz#20de69f3db942ef2d87b9c2da36f172235b1b5eb" 570 | dependencies: 571 | is-relative "^0.2.1" 572 | is-windows "^0.2.0" 573 | 574 | is-buffer@^1.0.2: 575 | version "1.1.5" 576 | resolved "https://registry.yarnpkg.com/is-buffer/-/is-buffer-1.1.5.tgz#1f3b26ef613b214b88cbca23cc6c01d87961eecc" 577 | 578 | is-dotfile@^1.0.0: 579 | version "1.0.2" 580 | resolved "https://registry.yarnpkg.com/is-dotfile/-/is-dotfile-1.0.2.tgz#2c132383f39199f8edc268ca01b9b007d205cc4d" 581 | 582 | is-equal-shallow@^0.1.3: 583 | version "0.1.3" 584 | resolved "https://registry.yarnpkg.com/is-equal-shallow/-/is-equal-shallow-0.1.3.tgz#2238098fc221de0bcfa5d9eac4c45d638aa1c534" 585 | dependencies: 586 | is-primitive "^2.0.0" 587 | 588 | is-extendable@^0.1.1: 589 | version "0.1.1" 590 | resolved "https://registry.yarnpkg.com/is-extendable/-/is-extendable-0.1.1.tgz#62b110e289a471418e3ec36a617d472e301dfc89" 591 | 592 | is-extglob@^1.0.0: 593 | version "1.0.0" 594 | resolved "https://registry.yarnpkg.com/is-extglob/-/is-extglob-1.0.0.tgz#ac468177c4943405a092fc8f29760c6ffc6206c0" 595 | 596 | is-glob@^2.0.0, is-glob@^2.0.1: 597 | version "2.0.1" 598 | resolved "https://registry.yarnpkg.com/is-glob/-/is-glob-2.0.1.tgz#d096f926a3ded5600f3fdfd91198cb0888c2d863" 599 | dependencies: 600 | is-extglob "^1.0.0" 601 | 602 | is-number@^2.0.2, is-number@^2.1.0: 603 | version "2.1.0" 604 | resolved "https://registry.yarnpkg.com/is-number/-/is-number-2.1.0.tgz#01fcbbb393463a548f2f466cce16dece49db908f" 605 | dependencies: 606 | kind-of "^3.0.2" 607 | 608 | is-path-cwd@^1.0.0: 609 | version "1.0.0" 610 | resolved "https://registry.yarnpkg.com/is-path-cwd/-/is-path-cwd-1.0.0.tgz#d225ec23132e89edd38fda767472e62e65f1106d" 611 | 612 | is-path-in-cwd@^1.0.0: 613 | version "1.0.0" 614 | resolved "https://registry.yarnpkg.com/is-path-in-cwd/-/is-path-in-cwd-1.0.0.tgz#6477582b8214d602346094567003be8a9eac04dc" 615 | dependencies: 616 | is-path-inside "^1.0.0" 617 | 618 | is-path-inside@^1.0.0: 619 | version "1.0.0" 620 | resolved "https://registry.yarnpkg.com/is-path-inside/-/is-path-inside-1.0.0.tgz#fc06e5a1683fbda13de667aff717bbc10a48f37f" 621 | dependencies: 622 | path-is-inside "^1.0.1" 623 | 624 | is-posix-bracket@^0.1.0: 625 | version "0.1.1" 626 | resolved "https://registry.yarnpkg.com/is-posix-bracket/-/is-posix-bracket-0.1.1.tgz#3334dc79774368e92f016e6fbc0a88f5cd6e6bc4" 627 | 628 | is-primitive@^2.0.0: 629 | version "2.0.0" 630 | resolved "https://registry.yarnpkg.com/is-primitive/-/is-primitive-2.0.0.tgz#207bab91638499c07b2adf240a41a87210034575" 631 | 632 | is-relative@^0.2.1: 633 | version "0.2.1" 634 | resolved "https://registry.yarnpkg.com/is-relative/-/is-relative-0.2.1.tgz#d27f4c7d516d175fb610db84bbeef23c3bc97aa5" 635 | dependencies: 636 | is-unc-path "^0.1.1" 637 | 638 | is-unc-path@^0.1.1: 639 | version "0.1.2" 640 | resolved "https://registry.yarnpkg.com/is-unc-path/-/is-unc-path-0.1.2.tgz#6ab053a72573c10250ff416a3814c35178af39b9" 641 | dependencies: 642 | unc-path-regex "^0.1.0" 643 | 644 | is-utf8@^0.2.0: 645 | version "0.2.1" 646 | resolved "https://registry.yarnpkg.com/is-utf8/-/is-utf8-0.2.1.tgz#4b0da1442104d1b336340e80797e865cf39f7d72" 647 | 648 | is-windows@^0.2.0: 649 | version "0.2.0" 650 | resolved "https://registry.yarnpkg.com/is-windows/-/is-windows-0.2.0.tgz#de1aa6d63ea29dd248737b69f1ff8b8002d2108c" 651 | 652 | isarray@0.0.1: 653 | version "0.0.1" 654 | resolved "https://registry.yarnpkg.com/isarray/-/isarray-0.0.1.tgz#8a18acfca9a8f4177e09abfc6038939b05d1eedf" 655 | 656 | isarray@1.0.0, isarray@^1.0.0, isarray@~1.0.0: 657 | version "1.0.0" 658 | resolved "https://registry.yarnpkg.com/isarray/-/isarray-1.0.0.tgz#bb935d48582cba168c06834957a54a3e07124f11" 659 | 660 | isexe@^1.1.1: 661 | version "1.1.2" 662 | resolved "https://registry.yarnpkg.com/isexe/-/isexe-1.1.2.tgz#36f3e22e60750920f5e7241a476a8c6a42275ad0" 663 | 664 | isexe@^2.0.0: 665 | version "2.0.0" 666 | resolved "https://registry.yarnpkg.com/isexe/-/isexe-2.0.0.tgz#e8fbf374dc556ff8947a10dcb0572d633f2cfa10" 667 | 668 | isobject@^2.0.0: 669 | version "2.1.0" 670 | resolved "https://registry.yarnpkg.com/isobject/-/isobject-2.1.0.tgz#f065561096a3f1da2ef46272f815c840d87e0c89" 671 | dependencies: 672 | isarray "1.0.0" 673 | 674 | jmespath@0.15.0: 675 | version "0.15.0" 676 | resolved "https://registry.yarnpkg.com/jmespath/-/jmespath-0.15.0.tgz#a3f222a9aae9f966f5d27c796510e28091764217" 677 | 678 | json3@3.3.2: 679 | version "3.3.2" 680 | resolved "https://registry.yarnpkg.com/json3/-/json3-3.3.2.tgz#3c0434743df93e2f5c42aee7b19bcb483575f4e1" 681 | 682 | kind-of@^3.0.2: 683 | version "3.1.0" 684 | resolved "https://registry.yarnpkg.com/kind-of/-/kind-of-3.1.0.tgz#475d698a5e49ff5e53d14e3e732429dc8bf4cf47" 685 | dependencies: 686 | is-buffer "^1.0.2" 687 | 688 | liftoff@^2.1.0: 689 | version "2.3.0" 690 | resolved "https://registry.yarnpkg.com/liftoff/-/liftoff-2.3.0.tgz#a98f2ff67183d8ba7cfaca10548bd7ff0550b385" 691 | dependencies: 692 | extend "^3.0.0" 693 | findup-sync "^0.4.2" 694 | fined "^1.0.1" 695 | flagged-respawn "^0.3.2" 696 | lodash.isplainobject "^4.0.4" 697 | lodash.isstring "^4.0.1" 698 | lodash.mapvalues "^4.4.0" 699 | rechoir "^0.6.2" 700 | resolve "^1.1.7" 701 | 702 | lodash._baseassign@^3.0.0: 703 | version "3.2.0" 704 | resolved "https://registry.yarnpkg.com/lodash._baseassign/-/lodash._baseassign-3.2.0.tgz#8c38a099500f215ad09e59f1722fd0c52bfe0a4e" 705 | dependencies: 706 | lodash._basecopy "^3.0.0" 707 | lodash.keys "^3.0.0" 708 | 709 | lodash._basecopy@^3.0.0: 710 | version "3.0.1" 711 | resolved "https://registry.yarnpkg.com/lodash._basecopy/-/lodash._basecopy-3.0.1.tgz#8da0e6a876cf344c0ad8a54882111dd3c5c7ca36" 712 | 713 | lodash._basecreate@^3.0.0: 714 | version "3.0.3" 715 | resolved "https://registry.yarnpkg.com/lodash._basecreate/-/lodash._basecreate-3.0.3.tgz#1bc661614daa7fc311b7d03bf16806a0213cf821" 716 | 717 | lodash._basetostring@^3.0.0: 718 | version "3.0.1" 719 | resolved "https://registry.yarnpkg.com/lodash._basetostring/-/lodash._basetostring-3.0.1.tgz#d1861d877f824a52f669832dcaf3ee15566a07d5" 720 | 721 | lodash._basevalues@^3.0.0: 722 | version "3.0.0" 723 | resolved "https://registry.yarnpkg.com/lodash._basevalues/-/lodash._basevalues-3.0.0.tgz#5b775762802bde3d3297503e26300820fdf661b7" 724 | 725 | lodash._getnative@^3.0.0: 726 | version "3.9.1" 727 | resolved "https://registry.yarnpkg.com/lodash._getnative/-/lodash._getnative-3.9.1.tgz#570bc7dede46d61cdcde687d65d3eecbaa3aaff5" 728 | 729 | lodash._isiterateecall@^3.0.0: 730 | version "3.0.9" 731 | resolved "https://registry.yarnpkg.com/lodash._isiterateecall/-/lodash._isiterateecall-3.0.9.tgz#5203ad7ba425fae842460e696db9cf3e6aac057c" 732 | 733 | lodash._reescape@^3.0.0: 734 | version "3.0.0" 735 | resolved "https://registry.yarnpkg.com/lodash._reescape/-/lodash._reescape-3.0.0.tgz#2b1d6f5dfe07c8a355753e5f27fac7f1cde1616a" 736 | 737 | lodash._reevaluate@^3.0.0: 738 | version "3.0.0" 739 | resolved "https://registry.yarnpkg.com/lodash._reevaluate/-/lodash._reevaluate-3.0.0.tgz#58bc74c40664953ae0b124d806996daca431e2ed" 740 | 741 | lodash._reinterpolate@^3.0.0: 742 | version "3.0.0" 743 | resolved "https://registry.yarnpkg.com/lodash._reinterpolate/-/lodash._reinterpolate-3.0.0.tgz#0ccf2d89166af03b3663c796538b75ac6e114d9d" 744 | 745 | lodash._root@^3.0.0: 746 | version "3.0.1" 747 | resolved "https://registry.yarnpkg.com/lodash._root/-/lodash._root-3.0.1.tgz#fba1c4524c19ee9a5f8136b4609f017cf4ded692" 748 | 749 | lodash.assignwith@^4.0.7: 750 | version "4.2.0" 751 | resolved "https://registry.yarnpkg.com/lodash.assignwith/-/lodash.assignwith-4.2.0.tgz#127a97f02adc41751a954d24b0de17e100e038eb" 752 | 753 | lodash.create@3.1.1: 754 | version "3.1.1" 755 | resolved "https://registry.yarnpkg.com/lodash.create/-/lodash.create-3.1.1.tgz#d7f2849f0dbda7e04682bb8cd72ab022461debe7" 756 | dependencies: 757 | lodash._baseassign "^3.0.0" 758 | lodash._basecreate "^3.0.0" 759 | lodash._isiterateecall "^3.0.0" 760 | 761 | lodash.escape@^3.0.0: 762 | version "3.2.0" 763 | resolved "https://registry.yarnpkg.com/lodash.escape/-/lodash.escape-3.2.0.tgz#995ee0dc18c1b48cc92effae71a10aab5b487698" 764 | dependencies: 765 | lodash._root "^3.0.0" 766 | 767 | lodash.groupby@^4.6.0: 768 | version "4.6.0" 769 | resolved "https://registry.yarnpkg.com/lodash.groupby/-/lodash.groupby-4.6.0.tgz#0b08a1dcf68397c397855c3239783832df7403d1" 770 | 771 | lodash.isarguments@^3.0.0: 772 | version "3.1.0" 773 | resolved "https://registry.yarnpkg.com/lodash.isarguments/-/lodash.isarguments-3.1.0.tgz#2f573d85c6a24289ff00663b491c1d338ff3458a" 774 | 775 | lodash.isarray@^3.0.0: 776 | version "3.0.4" 777 | resolved "https://registry.yarnpkg.com/lodash.isarray/-/lodash.isarray-3.0.4.tgz#79e4eb88c36a8122af86f844aa9bcd851b5fbb55" 778 | 779 | lodash.isempty@^4.2.1: 780 | version "4.4.0" 781 | resolved "https://registry.yarnpkg.com/lodash.isempty/-/lodash.isempty-4.4.0.tgz#6f86cbedd8be4ec987be9aaf33c9684db1b31e7e" 782 | 783 | lodash.isplainobject@^4.0.4: 784 | version "4.0.6" 785 | resolved "https://registry.yarnpkg.com/lodash.isplainobject/-/lodash.isplainobject-4.0.6.tgz#7c526a52d89b45c45cc690b88163be0497f550cb" 786 | 787 | lodash.isstring@^4.0.1: 788 | version "4.0.1" 789 | resolved "https://registry.yarnpkg.com/lodash.isstring/-/lodash.isstring-4.0.1.tgz#d527dfb5456eca7cc9bb95d5daeaf88ba54a5451" 790 | 791 | lodash.keys@^3.0.0: 792 | version "3.1.2" 793 | resolved "https://registry.yarnpkg.com/lodash.keys/-/lodash.keys-3.1.2.tgz#4dbc0472b156be50a0b286855d1bd0b0c656098a" 794 | dependencies: 795 | lodash._getnative "^3.0.0" 796 | lodash.isarguments "^3.0.0" 797 | lodash.isarray "^3.0.0" 798 | 799 | lodash.mapvalues@^4.4.0: 800 | version "4.6.0" 801 | resolved "https://registry.yarnpkg.com/lodash.mapvalues/-/lodash.mapvalues-4.6.0.tgz#1bafa5005de9dd6f4f26668c30ca37230cc9689c" 802 | 803 | lodash.pick@^4.2.1: 804 | version "4.4.0" 805 | resolved "https://registry.yarnpkg.com/lodash.pick/-/lodash.pick-4.4.0.tgz#52f05610fff9ded422611441ed1fc123a03001b3" 806 | 807 | lodash.restparam@^3.0.0: 808 | version "3.6.1" 809 | resolved "https://registry.yarnpkg.com/lodash.restparam/-/lodash.restparam-3.6.1.tgz#936a4e309ef330a7645ed4145986c85ae5b20805" 810 | 811 | lodash.template@^3.0.0: 812 | version "3.6.2" 813 | resolved "https://registry.yarnpkg.com/lodash.template/-/lodash.template-3.6.2.tgz#f8cdecc6169a255be9098ae8b0c53d378931d14f" 814 | dependencies: 815 | lodash._basecopy "^3.0.0" 816 | lodash._basetostring "^3.0.0" 817 | lodash._basevalues "^3.0.0" 818 | lodash._isiterateecall "^3.0.0" 819 | lodash._reinterpolate "^3.0.0" 820 | lodash.escape "^3.0.0" 821 | lodash.keys "^3.0.0" 822 | lodash.restparam "^3.0.0" 823 | lodash.templatesettings "^3.0.0" 824 | 825 | lodash.templatesettings@^3.0.0: 826 | version "3.1.1" 827 | resolved "https://registry.yarnpkg.com/lodash.templatesettings/-/lodash.templatesettings-3.1.1.tgz#fb307844753b66b9f1afa54e262c745307dba8e5" 828 | dependencies: 829 | lodash._reinterpolate "^3.0.0" 830 | lodash.escape "^3.0.0" 831 | 832 | lodash@~1.0.1: 833 | version "1.0.2" 834 | resolved "https://registry.yarnpkg.com/lodash/-/lodash-1.0.2.tgz#8f57560c83b59fc270bd3d561b690043430e2551" 835 | 836 | lodash@~3.5.0: 837 | version "3.5.0" 838 | resolved "https://registry.yarnpkg.com/lodash/-/lodash-3.5.0.tgz#19bb3f4d51278f0b8c818ed145c74ecf9fe40e6d" 839 | 840 | lru-cache@2: 841 | version "2.7.3" 842 | resolved "https://registry.yarnpkg.com/lru-cache/-/lru-cache-2.7.3.tgz#6d4524e8b955f95d4f5b58851ce21dd72fb4e952" 843 | 844 | map-cache@^0.2.0: 845 | version "0.2.2" 846 | resolved "https://registry.yarnpkg.com/map-cache/-/map-cache-0.2.2.tgz#c32abd0bd6525d9b051645bb4f26ac5dc98a0dbf" 847 | 848 | micromatch@^2.3.7: 849 | version "2.3.11" 850 | resolved "https://registry.yarnpkg.com/micromatch/-/micromatch-2.3.11.tgz#86677c97d1720b363431d04d0d15293bd38c1565" 851 | dependencies: 852 | arr-diff "^2.0.0" 853 | array-unique "^0.2.1" 854 | braces "^1.8.2" 855 | expand-brackets "^0.1.4" 856 | extglob "^0.3.1" 857 | filename-regex "^2.0.0" 858 | is-extglob "^1.0.0" 859 | is-glob "^2.0.1" 860 | kind-of "^3.0.2" 861 | normalize-path "^2.0.1" 862 | object.omit "^2.0.0" 863 | parse-glob "^3.0.4" 864 | regex-cache "^0.4.2" 865 | 866 | minimatch@^2.0.1: 867 | version "2.0.10" 868 | resolved "https://registry.yarnpkg.com/minimatch/-/minimatch-2.0.10.tgz#8d087c39c6b38c001b97fca7ce6d0e1e80afbac7" 869 | dependencies: 870 | brace-expansion "^1.0.0" 871 | 872 | minimatch@^3.0.2: 873 | version "3.0.3" 874 | resolved "https://registry.yarnpkg.com/minimatch/-/minimatch-3.0.3.tgz#2a4e4090b96b2db06a9d7df01055a62a77c9b774" 875 | dependencies: 876 | brace-expansion "^1.0.0" 877 | 878 | minimatch@~0.2.11: 879 | version "0.2.14" 880 | resolved "https://registry.yarnpkg.com/minimatch/-/minimatch-0.2.14.tgz#c74e780574f63c6f9a090e90efbe6ef53a6a756a" 881 | dependencies: 882 | lru-cache "2" 883 | sigmund "~1.0.0" 884 | 885 | minimist@0.0.8: 886 | version "0.0.8" 887 | resolved "https://registry.yarnpkg.com/minimist/-/minimist-0.0.8.tgz#857fcabfc3397d2625b8228262e86aa7a011b05d" 888 | 889 | minimist@^1.1.0: 890 | version "1.2.0" 891 | resolved "https://registry.yarnpkg.com/minimist/-/minimist-1.2.0.tgz#a35008b20f41383eec1fb914f4cd5df79a264284" 892 | 893 | mkdirp@0.5.1, mkdirp@^0.5.0: 894 | version "0.5.1" 895 | resolved "https://registry.yarnpkg.com/mkdirp/-/mkdirp-0.5.1.tgz#30057438eac6cf7f8c4767f38648d6697d75c903" 896 | dependencies: 897 | minimist "0.0.8" 898 | 899 | mocha@^3.0.2: 900 | version "3.2.0" 901 | resolved "https://registry.yarnpkg.com/mocha/-/mocha-3.2.0.tgz#7dc4f45e5088075171a68896814e6ae9eb7a85e3" 902 | dependencies: 903 | browser-stdout "1.3.0" 904 | commander "2.9.0" 905 | debug "2.2.0" 906 | diff "1.4.0" 907 | escape-string-regexp "1.0.5" 908 | glob "7.0.5" 909 | growl "1.9.2" 910 | json3 "3.3.2" 911 | lodash.create "3.1.1" 912 | mkdirp "0.5.1" 913 | supports-color "3.1.2" 914 | 915 | ms@0.7.1: 916 | version "0.7.1" 917 | resolved "https://registry.yarnpkg.com/ms/-/ms-0.7.1.tgz#9cd13c03adbff25b65effde7ce864ee952017098" 918 | 919 | multipipe@^0.1.2: 920 | version "0.1.2" 921 | resolved "https://registry.yarnpkg.com/multipipe/-/multipipe-0.1.2.tgz#2a8f2ddf70eed564dff2d57f1e1a137d9f05078b" 922 | dependencies: 923 | duplexer2 "0.0.2" 924 | 925 | natives@^1.1.0: 926 | version "1.1.0" 927 | resolved "https://registry.yarnpkg.com/natives/-/natives-1.1.0.tgz#e9ff841418a6b2ec7a495e939984f78f163e6e31" 928 | 929 | normalize-path@^2.0.1: 930 | version "2.0.1" 931 | resolved "https://registry.yarnpkg.com/normalize-path/-/normalize-path-2.0.1.tgz#47886ac1662760d4261b7d979d241709d3ce3f7a" 932 | 933 | object-assign@^3.0.0: 934 | version "3.0.0" 935 | resolved "https://registry.yarnpkg.com/object-assign/-/object-assign-3.0.0.tgz#9bedd5ca0897949bca47e7ff408062d549f587f2" 936 | 937 | object-assign@^4.0.1: 938 | version "4.1.1" 939 | resolved "https://registry.yarnpkg.com/object-assign/-/object-assign-4.1.1.tgz#2109adc7965887cfc05cbbd442cac8bfbb360863" 940 | 941 | object.omit@^2.0.0: 942 | version "2.0.1" 943 | resolved "https://registry.yarnpkg.com/object.omit/-/object.omit-2.0.1.tgz#1a9c744829f39dbb858c76ca3579ae2a54ebd1fa" 944 | dependencies: 945 | for-own "^0.1.4" 946 | is-extendable "^0.1.1" 947 | 948 | once@^1.3.0: 949 | version "1.4.0" 950 | resolved "https://registry.yarnpkg.com/once/-/once-1.4.0.tgz#583b1aa775961d4b113ac17d9c50baef9dd76bd1" 951 | dependencies: 952 | wrappy "1" 953 | 954 | once@~1.3.0: 955 | version "1.3.3" 956 | resolved "https://registry.yarnpkg.com/once/-/once-1.3.3.tgz#b2e261557ce4c314ec8304f3fa82663e4297ca20" 957 | dependencies: 958 | wrappy "1" 959 | 960 | orchestrator@^0.3.0: 961 | version "0.3.8" 962 | resolved "https://registry.yarnpkg.com/orchestrator/-/orchestrator-0.3.8.tgz#14e7e9e2764f7315fbac184e506c7aa6df94ad7e" 963 | dependencies: 964 | end-of-stream "~0.1.5" 965 | sequencify "~0.0.7" 966 | stream-consume "~0.1.0" 967 | 968 | ordered-read-streams@^0.1.0: 969 | version "0.1.0" 970 | resolved "https://registry.yarnpkg.com/ordered-read-streams/-/ordered-read-streams-0.1.0.tgz#fd565a9af8eb4473ba69b6ed8a34352cb552f126" 971 | 972 | os-homedir@^1.0.0, os-homedir@^1.0.1: 973 | version "1.0.2" 974 | resolved "https://registry.yarnpkg.com/os-homedir/-/os-homedir-1.0.2.tgz#ffbc4988336e0e833de0c168c7ef152121aa7fb3" 975 | 976 | p-queue@^1.0.0: 977 | version "1.0.0" 978 | resolved "https://registry.yarnpkg.com/p-queue/-/p-queue-1.0.0.tgz#698cde72cc9f57aa3bc7d30ad8019cd736aaed3e" 979 | 980 | parse-filepath@^1.0.1: 981 | version "1.0.1" 982 | resolved "https://registry.yarnpkg.com/parse-filepath/-/parse-filepath-1.0.1.tgz#159d6155d43904d16c10ef698911da1e91969b73" 983 | dependencies: 984 | is-absolute "^0.2.3" 985 | map-cache "^0.2.0" 986 | path-root "^0.1.1" 987 | 988 | parse-glob@^3.0.4: 989 | version "3.0.4" 990 | resolved "https://registry.yarnpkg.com/parse-glob/-/parse-glob-3.0.4.tgz#b2c376cfb11f35513badd173ef0bb6e3a388391c" 991 | dependencies: 992 | glob-base "^0.3.0" 993 | is-dotfile "^1.0.0" 994 | is-extglob "^1.0.0" 995 | is-glob "^2.0.0" 996 | 997 | parse-passwd@^1.0.0: 998 | version "1.0.0" 999 | resolved "https://registry.yarnpkg.com/parse-passwd/-/parse-passwd-1.0.0.tgz#6d5b934a456993b23d37f40a382d6f1666a8e5c6" 1000 | 1001 | path-is-absolute@^1.0.0: 1002 | version "1.0.1" 1003 | resolved "https://registry.yarnpkg.com/path-is-absolute/-/path-is-absolute-1.0.1.tgz#174b9268735534ffbc7ace6bf53a5a9e1b5c5f5f" 1004 | 1005 | path-is-inside@^1.0.1: 1006 | version "1.0.2" 1007 | resolved "https://registry.yarnpkg.com/path-is-inside/-/path-is-inside-1.0.2.tgz#365417dede44430d1c11af61027facf074bdfc53" 1008 | 1009 | path-parse@^1.0.5: 1010 | version "1.0.5" 1011 | resolved "https://registry.yarnpkg.com/path-parse/-/path-parse-1.0.5.tgz#3c1adf871ea9cd6c9431b6ea2bd74a0ff055c4c1" 1012 | 1013 | path-root-regex@^0.1.0: 1014 | version "0.1.2" 1015 | resolved "https://registry.yarnpkg.com/path-root-regex/-/path-root-regex-0.1.2.tgz#bfccdc8df5b12dc52c8b43ec38d18d72c04ba96d" 1016 | 1017 | path-root@^0.1.1: 1018 | version "0.1.1" 1019 | resolved "https://registry.yarnpkg.com/path-root/-/path-root-0.1.1.tgz#9a4a6814cac1c0cd73360a95f32083c8ea4745b7" 1020 | dependencies: 1021 | path-root-regex "^0.1.0" 1022 | 1023 | pify@^2.0.0: 1024 | version "2.3.0" 1025 | resolved "https://registry.yarnpkg.com/pify/-/pify-2.3.0.tgz#ed141a6ac043a849ea588498e7dca8b15330e90c" 1026 | 1027 | pinkie-promise@^2.0.0: 1028 | version "2.0.1" 1029 | resolved "https://registry.yarnpkg.com/pinkie-promise/-/pinkie-promise-2.0.1.tgz#2135d6dfa7a358c069ac9b178776288228450ffa" 1030 | dependencies: 1031 | pinkie "^2.0.0" 1032 | 1033 | pinkie@^2.0.0: 1034 | version "2.0.4" 1035 | resolved "https://registry.yarnpkg.com/pinkie/-/pinkie-2.0.4.tgz#72556b80cfa0d48a974e80e77248e80ed4f7f870" 1036 | 1037 | preserve@^0.2.0: 1038 | version "0.2.0" 1039 | resolved "https://registry.yarnpkg.com/preserve/-/preserve-0.2.0.tgz#815ed1f6ebc65926f865b310c0713bcb3315ce4b" 1040 | 1041 | pretty-hrtime@^1.0.0: 1042 | version "1.0.3" 1043 | resolved "https://registry.yarnpkg.com/pretty-hrtime/-/pretty-hrtime-1.0.3.tgz#b7e3ea42435a4c9b2759d99e0f201eb195802ee1" 1044 | 1045 | process-nextick-args@~1.0.6: 1046 | version "1.0.7" 1047 | resolved "https://registry.yarnpkg.com/process-nextick-args/-/process-nextick-args-1.0.7.tgz#150e20b756590ad3f91093f25a4f2ad8bff30ba3" 1048 | 1049 | punycode@1.3.2: 1050 | version "1.3.2" 1051 | resolved "https://registry.yarnpkg.com/punycode/-/punycode-1.3.2.tgz#9653a036fb7c1ee42342f2325cceefea3926c48d" 1052 | 1053 | querystring@0.2.0: 1054 | version "0.2.0" 1055 | resolved "https://registry.yarnpkg.com/querystring/-/querystring-0.2.0.tgz#b209849203bb25df820da756e747005878521620" 1056 | 1057 | randomatic@^1.1.3: 1058 | version "1.1.6" 1059 | resolved "https://registry.yarnpkg.com/randomatic/-/randomatic-1.1.6.tgz#110dcabff397e9dcff7c0789ccc0a49adf1ec5bb" 1060 | dependencies: 1061 | is-number "^2.0.2" 1062 | kind-of "^3.0.2" 1063 | 1064 | "readable-stream@>=1.0.33-1 <1.1.0-0": 1065 | version "1.0.34" 1066 | resolved "https://registry.yarnpkg.com/readable-stream/-/readable-stream-1.0.34.tgz#125820e34bc842d2f2aaafafe4c2916ee32c157c" 1067 | dependencies: 1068 | core-util-is "~1.0.0" 1069 | inherits "~2.0.1" 1070 | isarray "0.0.1" 1071 | string_decoder "~0.10.x" 1072 | 1073 | readable-stream@^2.1.5: 1074 | version "2.2.6" 1075 | resolved "https://registry.yarnpkg.com/readable-stream/-/readable-stream-2.2.6.tgz#8b43aed76e71483938d12a8d46c6cf1a00b1f816" 1076 | dependencies: 1077 | buffer-shims "^1.0.0" 1078 | core-util-is "~1.0.0" 1079 | inherits "~2.0.1" 1080 | isarray "~1.0.0" 1081 | process-nextick-args "~1.0.6" 1082 | string_decoder "~0.10.x" 1083 | util-deprecate "~1.0.1" 1084 | 1085 | readable-stream@~1.1.9: 1086 | version "1.1.14" 1087 | resolved "https://registry.yarnpkg.com/readable-stream/-/readable-stream-1.1.14.tgz#7cf4c54ef648e3813084c636dd2079e166c081d9" 1088 | dependencies: 1089 | core-util-is "~1.0.0" 1090 | inherits "~2.0.1" 1091 | isarray "0.0.1" 1092 | string_decoder "~0.10.x" 1093 | 1094 | rechoir@^0.6.2: 1095 | version "0.6.2" 1096 | resolved "https://registry.yarnpkg.com/rechoir/-/rechoir-0.6.2.tgz#85204b54dba82d5742e28c96756ef43af50e3384" 1097 | dependencies: 1098 | resolve "^1.1.6" 1099 | 1100 | regex-cache@^0.4.2: 1101 | version "0.4.3" 1102 | resolved "https://registry.yarnpkg.com/regex-cache/-/regex-cache-0.4.3.tgz#9b1a6c35d4d0dfcef5711ae651e8e9d3d7114145" 1103 | dependencies: 1104 | is-equal-shallow "^0.1.3" 1105 | is-primitive "^2.0.0" 1106 | 1107 | repeat-element@^1.1.2: 1108 | version "1.1.2" 1109 | resolved "https://registry.yarnpkg.com/repeat-element/-/repeat-element-1.1.2.tgz#ef089a178d1483baae4d93eb98b4f9e4e11d990a" 1110 | 1111 | repeat-string@^1.5.2: 1112 | version "1.6.1" 1113 | resolved "https://registry.yarnpkg.com/repeat-string/-/repeat-string-1.6.1.tgz#8dcae470e1c88abc2d600fff4a776286da75e637" 1114 | 1115 | replace-ext@0.0.1: 1116 | version "0.0.1" 1117 | resolved "https://registry.yarnpkg.com/replace-ext/-/replace-ext-0.0.1.tgz#29bbd92078a739f0bcce2b4ee41e837953522924" 1118 | 1119 | resolve-dir@^0.1.0: 1120 | version "0.1.1" 1121 | resolved "https://registry.yarnpkg.com/resolve-dir/-/resolve-dir-0.1.1.tgz#b219259a5602fac5c5c496ad894a6e8cc430261e" 1122 | dependencies: 1123 | expand-tilde "^1.2.2" 1124 | global-modules "^0.2.3" 1125 | 1126 | resolve@^1.1.6, resolve@^1.1.7: 1127 | version "1.3.2" 1128 | resolved "https://registry.yarnpkg.com/resolve/-/resolve-1.3.2.tgz#1f0442c9e0cbb8136e87b9305f932f46c7f28235" 1129 | dependencies: 1130 | path-parse "^1.0.5" 1131 | 1132 | rimraf@^2.2.8: 1133 | version "2.6.1" 1134 | resolved "https://registry.yarnpkg.com/rimraf/-/rimraf-2.6.1.tgz#c2338ec643df7a1b7fe5c54fa86f57428a55f33d" 1135 | dependencies: 1136 | glob "^7.0.5" 1137 | 1138 | run-sequence@^1.2.2: 1139 | version "1.2.2" 1140 | resolved "https://registry.yarnpkg.com/run-sequence/-/run-sequence-1.2.2.tgz#5095a0bebe98733b0140bd08dd80ec030ddacdeb" 1141 | dependencies: 1142 | chalk "*" 1143 | gulp-util "*" 1144 | 1145 | sax@1.1.5, sax@>=0.6.0: 1146 | version "1.1.5" 1147 | resolved "https://registry.yarnpkg.com/sax/-/sax-1.1.5.tgz#1da50a8d00cdecd59405659f5ff85349fe773743" 1148 | 1149 | semver@^4.1.0: 1150 | version "4.3.6" 1151 | resolved "https://registry.yarnpkg.com/semver/-/semver-4.3.6.tgz#300bc6e0e86374f7ba61068b5b1ecd57fc6532da" 1152 | 1153 | sequencify@~0.0.7: 1154 | version "0.0.7" 1155 | resolved "https://registry.yarnpkg.com/sequencify/-/sequencify-0.0.7.tgz#90cff19d02e07027fd767f5ead3e7b95d1e7380c" 1156 | 1157 | sigmund@~1.0.0: 1158 | version "1.0.1" 1159 | resolved "https://registry.yarnpkg.com/sigmund/-/sigmund-1.0.1.tgz#3ff21f198cad2175f9f3b781853fd94d0d19b590" 1160 | 1161 | sparkles@^1.0.0: 1162 | version "1.0.0" 1163 | resolved "https://registry.yarnpkg.com/sparkles/-/sparkles-1.0.0.tgz#1acbbfb592436d10bbe8f785b7cc6f82815012c3" 1164 | 1165 | stream-consume@~0.1.0: 1166 | version "0.1.0" 1167 | resolved "https://registry.yarnpkg.com/stream-consume/-/stream-consume-0.1.0.tgz#a41ead1a6d6081ceb79f65b061901b6d8f3d1d0f" 1168 | 1169 | string_decoder@~0.10.x: 1170 | version "0.10.31" 1171 | resolved "https://registry.yarnpkg.com/string_decoder/-/string_decoder-0.10.31.tgz#62e203bc41766c6c28c9fc84301dab1c5310fa94" 1172 | 1173 | strip-ansi@^3.0.0: 1174 | version "3.0.1" 1175 | resolved "https://registry.yarnpkg.com/strip-ansi/-/strip-ansi-3.0.1.tgz#6a385fb8853d952d5ff05d0e8aaf94278dc63dcf" 1176 | dependencies: 1177 | ansi-regex "^2.0.0" 1178 | 1179 | strip-bom@^1.0.0: 1180 | version "1.0.0" 1181 | resolved "https://registry.yarnpkg.com/strip-bom/-/strip-bom-1.0.0.tgz#85b8862f3844b5a6d5ec8467a93598173a36f794" 1182 | dependencies: 1183 | first-chunk-stream "^1.0.0" 1184 | is-utf8 "^0.2.0" 1185 | 1186 | supports-color@3.1.2: 1187 | version "3.1.2" 1188 | resolved "https://registry.yarnpkg.com/supports-color/-/supports-color-3.1.2.tgz#72a262894d9d408b956ca05ff37b2ed8a6e2a2d5" 1189 | dependencies: 1190 | has-flag "^1.0.0" 1191 | 1192 | supports-color@^2.0.0: 1193 | version "2.0.0" 1194 | resolved "https://registry.yarnpkg.com/supports-color/-/supports-color-2.0.0.tgz#535d045ce6b6363fa40117084629995e9df324c7" 1195 | 1196 | through2@^0.6.1: 1197 | version "0.6.5" 1198 | resolved "https://registry.yarnpkg.com/through2/-/through2-0.6.5.tgz#41ab9c67b29d57209071410e1d7a7a968cd3ad48" 1199 | dependencies: 1200 | readable-stream ">=1.0.33-1 <1.1.0-0" 1201 | xtend ">=4.0.0 <4.1.0-0" 1202 | 1203 | through2@^2.0.0, through2@^2.0.1, through2@^2.0.3: 1204 | version "2.0.3" 1205 | resolved "https://registry.yarnpkg.com/through2/-/through2-2.0.3.tgz#0004569b37c7c74ba39c43f3ced78d1ad94140be" 1206 | dependencies: 1207 | readable-stream "^2.1.5" 1208 | xtend "~4.0.1" 1209 | 1210 | tildify@^1.0.0: 1211 | version "1.2.0" 1212 | resolved "https://registry.yarnpkg.com/tildify/-/tildify-1.2.0.tgz#dcec03f55dca9b7aa3e5b04f21817eb56e63588a" 1213 | dependencies: 1214 | os-homedir "^1.0.0" 1215 | 1216 | time-stamp@^1.0.0: 1217 | version "1.0.1" 1218 | resolved "https://registry.yarnpkg.com/time-stamp/-/time-stamp-1.0.1.tgz#9f4bd23559c9365966f3302dbba2b07c6b99b151" 1219 | 1220 | unc-path-regex@^0.1.0: 1221 | version "0.1.2" 1222 | resolved "https://registry.yarnpkg.com/unc-path-regex/-/unc-path-regex-0.1.2.tgz#e73dd3d7b0d7c5ed86fbac6b0ae7d8c6a69d50fa" 1223 | 1224 | unique-stream@^1.0.0: 1225 | version "1.0.0" 1226 | resolved "https://registry.yarnpkg.com/unique-stream/-/unique-stream-1.0.0.tgz#d59a4a75427447d9aa6c91e70263f8d26a4b104b" 1227 | 1228 | url@0.10.3: 1229 | version "0.10.3" 1230 | resolved "https://registry.yarnpkg.com/url/-/url-0.10.3.tgz#021e4d9c7705f21bbf37d03ceb58767402774c64" 1231 | dependencies: 1232 | punycode "1.3.2" 1233 | querystring "0.2.0" 1234 | 1235 | user-home@^1.1.1: 1236 | version "1.1.1" 1237 | resolved "https://registry.yarnpkg.com/user-home/-/user-home-1.1.1.tgz#2b5be23a32b63a7c9deb8d0f28d485724a3df190" 1238 | 1239 | util-deprecate@~1.0.1: 1240 | version "1.0.2" 1241 | resolved "https://registry.yarnpkg.com/util-deprecate/-/util-deprecate-1.0.2.tgz#450d4dc9fa70de732762fbd2d4a28981419a0ccf" 1242 | 1243 | uuid@3.0.0: 1244 | version "3.0.0" 1245 | resolved "https://registry.yarnpkg.com/uuid/-/uuid-3.0.0.tgz#6728fc0459c450d796a99c31837569bdf672d728" 1246 | 1247 | v8flags@^2.0.2: 1248 | version "2.0.11" 1249 | resolved "https://registry.yarnpkg.com/v8flags/-/v8flags-2.0.11.tgz#bca8f30f0d6d60612cc2c00641e6962d42ae6881" 1250 | dependencies: 1251 | user-home "^1.1.1" 1252 | 1253 | vinyl-fs@^0.3.0: 1254 | version "0.3.14" 1255 | resolved "https://registry.yarnpkg.com/vinyl-fs/-/vinyl-fs-0.3.14.tgz#9a6851ce1cac1c1cea5fe86c0931d620c2cfa9e6" 1256 | dependencies: 1257 | defaults "^1.0.0" 1258 | glob-stream "^3.1.5" 1259 | glob-watcher "^0.0.6" 1260 | graceful-fs "^3.0.0" 1261 | mkdirp "^0.5.0" 1262 | strip-bom "^1.0.0" 1263 | through2 "^0.6.1" 1264 | vinyl "^0.4.0" 1265 | 1266 | vinyl@^0.4.0: 1267 | version "0.4.6" 1268 | resolved "https://registry.yarnpkg.com/vinyl/-/vinyl-0.4.6.tgz#2f356c87a550a255461f36bbeb2a5ba8bf784847" 1269 | dependencies: 1270 | clone "^0.2.0" 1271 | clone-stats "^0.0.1" 1272 | 1273 | vinyl@^0.5.0: 1274 | version "0.5.3" 1275 | resolved "https://registry.yarnpkg.com/vinyl/-/vinyl-0.5.3.tgz#b0455b38fc5e0cf30d4325132e461970c2091cde" 1276 | dependencies: 1277 | clone "^1.0.0" 1278 | clone-stats "^0.0.1" 1279 | replace-ext "0.0.1" 1280 | 1281 | which@^1.2.12: 1282 | version "1.2.12" 1283 | resolved "https://registry.yarnpkg.com/which/-/which-1.2.12.tgz#de67b5e450269f194909ef23ece4ebe416fa1192" 1284 | dependencies: 1285 | isexe "^1.1.1" 1286 | 1287 | which@^1.2.14: 1288 | version "1.2.14" 1289 | resolved "https://registry.yarnpkg.com/which/-/which-1.2.14.tgz#9a87c4378f03e827cecaf1acdf56c736c01c14e5" 1290 | dependencies: 1291 | isexe "^2.0.0" 1292 | 1293 | wrappy@1: 1294 | version "1.0.2" 1295 | resolved "https://registry.yarnpkg.com/wrappy/-/wrappy-1.0.2.tgz#b5243d8f3ec1aa35f1364605bc0d1036e30ab69f" 1296 | 1297 | xml2js@0.4.15: 1298 | version "0.4.15" 1299 | resolved "https://registry.yarnpkg.com/xml2js/-/xml2js-0.4.15.tgz#95cd03ff2dd144ec28bc6273bf2b2890c581ad0c" 1300 | dependencies: 1301 | sax ">=0.6.0" 1302 | xmlbuilder ">=2.4.6" 1303 | 1304 | xmlbuilder@2.6.2, xmlbuilder@>=2.4.6: 1305 | version "2.6.2" 1306 | resolved "https://registry.yarnpkg.com/xmlbuilder/-/xmlbuilder-2.6.2.tgz#f916f6d10d45dc171b1be2e6e673fb6e0cc35d0a" 1307 | dependencies: 1308 | lodash "~3.5.0" 1309 | 1310 | "xtend@>=4.0.0 <4.1.0-0", xtend@~4.0.1: 1311 | version "4.0.1" 1312 | resolved "https://registry.yarnpkg.com/xtend/-/xtend-4.0.1.tgz#a5c6d532be656e23db820efb943a1f04998d63af" 1313 | 1314 | yazl@^2.1.0: 1315 | version "2.4.2" 1316 | resolved "https://registry.yarnpkg.com/yazl/-/yazl-2.4.2.tgz#14cb19083e1e25a70092c1588aabe0f4e4dd4d88" 1317 | dependencies: 1318 | buffer-crc32 "~0.2.3" 1319 | --------------------------------------------------------------------------------