From 6249ef2d8e4c6d9ef5e31f89a903c55f41eb0572 Mon Sep 17 00:00:00 2001 From: Jason Dobry Date: Wed, 10 May 2017 13:12:48 -0700 Subject: [PATCH] Bring Storage samples up to standard. --- package.json | 3 +- scripts/clean | 33 ++- storage/README.md | 4 +- storage/acl.js | 315 +++++++++++++------- storage/buckets.js | 80 ++++-- storage/encryption.js | 107 ++++--- storage/files.js | 346 +++++++++++++--------- storage/iam.js | 52 ++-- storage/package.json | 4 +- storage/quickstart.js | 9 +- storage/system-test/buckets.test.js | 7 +- storage/system-test/encryption.test.js | 2 +- storage/system-test/files.test.js | 21 +- storage/yarn.lock | 83 +++++- yarn.lock | 381 ++++++++++++++++++++++++- 15 files changed, 1079 insertions(+), 368 deletions(-) diff --git a/package.json b/package.json index 7541c1885dc..cc44adddc98 100644 --- a/package.json +++ b/package.json @@ -45,7 +45,7 @@ "check": "yarn check --strict-semver --integrity", "lint": "samples lint", "generate": "node ./scripts/generate", - "pretest": "npm run lint && ./scripts/clean", + "pretest": "npm run lint && node ./scripts/clean coverage", "unit-test": "ava --verbose -T 30s functions/**/test/**/*.test.js", "unit-cover": "nyc --cache npm test && nyc report --reporter=html", "system-test": "ava --verbose -T 30s vision/system-test/**/*.test.js", @@ -55,6 +55,7 @@ }, "devDependencies": { "@google-cloud/nodejs-repo-tools": "1.4.13", + "@google-cloud/storage": "1.1.0", "ava": "0.19.1", "nyc": "10.3.2", "shelljs": "0.7.7" diff --git a/scripts/clean b/scripts/clean index 17cdfb30fe4..ccc5a5d1cf6 100755 --- a/scripts/clean +++ b/scripts/clean @@ -15,4 +15,35 @@ require('shelljs/global'); -rm('-rf', 'coverage'); +const storage = require('@google-cloud/storage')(); + +const args = process.argv.slice(2); + +if (!args.length || args[0] === 'coverage') { + rm('-rf', 'coverage'); +} else if (args[0] === 'buckets') { + const NAME_REG_EXP = /^nodejs-docs-samples-test-[a-z0-9]{8}-[a-z0-9]{4}-[a-z0-9]{4}-[a-z0-9]{4}-[a-z0-9]{12}$/; + + storage + .getBuckets() + .then(([buckets]) => { + let promise = Promise.resolve(); + + buckets + .filter((bucket) => NAME_REG_EXP.test(bucket.name)) + .forEach((bucket) => { + promise = promise.then(() => { + return bucket.deleteFiles() + .then(() => bucket.deleteFiles(), console.error) + .then(() => { + console.log(`Deleting ${bucket.name}`); + return bucket.delete(); + }, console.error) + .catch(console.error); + }); + }); + }) + .catch((err) => { + console.error('ERROR:', err); + }); +} diff --git a/storage/README.md b/storage/README.md index 9356a2f8129..3b302bfd922 100644 --- a/storage/README.md +++ b/storage/README.md @@ -110,8 +110,8 @@ __Usage:__ `node encryption.js --help` ``` Commands: generate-encryption-key Generate a sample encryption key. - upload Encrypts and uploads a file. - download Decrypts and downloads a file. + upload Encrypts and uploads a file. + download Decrypts and downloads a file. rotate Rotates encryption keys for a file. Options: diff --git a/storage/acl.js b/storage/acl.js index 621f551f192..0c8ee63ee1d 100644 --- a/storage/acl.js +++ b/storage/acl.js @@ -1,5 +1,5 @@ /** - * Copyright 2016, Google, Inc. + * Copyright 2017, Google, Inc. * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at @@ -23,160 +23,247 @@ 'use strict'; -const Storage = require('@google-cloud/storage'); - -// [START storage_print_bucket_acl] function printBucketAcl (bucketName) { + // [START storage_print_bucket_acl] + // Imports the Google Cloud client library + const Storage = require('@google-cloud/storage'); + + // The name of the bucket to access, e.g. "my-bucket" + // const bucketName = "my-bucket"; + // Instantiates a client const storage = Storage(); - // References an existing bucket, e.g. "my-bucket" - const bucket = storage.bucket(bucketName); - // Gets the ACL for the bucket - return bucket.acl.get() + storage + .bucket(bucketName) + .acl + .get() .then((results) => { const acls = results[0]; - acls.forEach((acl) => console.log(`${acl.role}: ${acl.entity}`)); - - return acls; + acls.forEach((acl) => { + console.log(`${acl.role}: ${acl.entity}`); + }); + }) + .catch((err) => { + console.error('ERROR:', err); }); + // [END storage_print_bucket_acl] } -// [END storage_print_bucket_acl] -// [START storage_print_bucket_acl_for_user] function printBucketAclForUser (bucketName, userEmail) { + // [START storage_print_bucket_acl_for_user] + // Imports the Google Cloud client library + const Storage = require('@google-cloud/storage'); + + // The name of the bucket to access, e.g. "my-bucket" + // const bucketName = "my-bucket"; + + // The email of the user to check, e.g. "developer@company.com" + // const userEmail = "developer@company.com"; + // Instantiates a client const storage = Storage(); - // References an existing bucket, e.g. "my-bucket" - const bucket = storage.bucket(bucketName); - const options = { // Specify the user entity: `user-${userEmail}` }; // Gets the user's ACL for the bucket - return bucket.acl.get(options) + storage + .bucket(bucketName) + .acl + .get(options) .then((results) => { const aclObject = results[0]; console.log(`${aclObject.role}: ${aclObject.entity}`); - - return aclObject; + }) + .catch((err) => { + console.error('ERROR:', err); }); + // [END storage_print_bucket_acl_for_user] } -// [END storage_print_bucket_acl_for_user] -// [START storage_add_bucket_owner] function addBucketOwner (bucketName, userEmail) { + // [START storage_add_bucket_owner] + // Imports the Google Cloud client library + const Storage = require('@google-cloud/storage'); + + // The name of the bucket to access, e.g. "my-bucket" + // const bucketName = "my-bucket"; + + // The email of the user to add, e.g. "developer@company.com" + // const userEmail = "developer@company.com"; + // Instantiates a client const storage = Storage(); - // References an existing bucket, e.g. "my-bucket" - const bucket = storage.bucket(bucketName); - // Makes the user an owner of the bucket. You can use addAllUsers(), // addDomain(), addProject(), addGroup(), and addAllAuthenticatedUsers() // to grant access to different types of entities. You can also use "readers" // and "writers" to grant different roles. - return bucket.acl.owners.addUser(userEmail) + storage + .bucket(bucketName) + .acl + .owners + .addUser(userEmail) .then(() => { - console.log(`Added user ${userEmail} as an owner on bucket ${bucket.name}.`); + console.log(`Added user ${userEmail} as an owner on bucket ${bucketName}.`); + }) + .catch((err) => { + console.error('ERROR:', err); }); + // [END storage_add_bucket_owner] } -// [END storage_add_bucket_owner] -// [START storage_remove_bucket_owner] function removeBucketOwner (bucketName, userEmail) { + // [START storage_remove_bucket_owner] + // Imports the Google Cloud client library + const Storage = require('@google-cloud/storage'); + + // The name of the bucket to access, e.g. "my-bucket" + // const bucketName = "my-bucket"; + + // The email of the user to remove, e.g. "developer@company.com" + // const userEmail = "developer@company.com"; + // Instantiates a client const storage = Storage(); - // References an existing bucket, e.g. "my-bucket" - const bucket = storage.bucket(bucketName); - // Removes the user from the access control list of the bucket. You can use // deleteAllUsers(), deleteDomain(), deleteProject(), deleteGroup(), and // deleteAllAuthenticatedUsers() to remove access for different types of entities. - return bucket.acl.owners.deleteUser(userEmail) + storage + .bucket(bucketName) + .acl + .owners + .deleteUser(userEmail) .then(() => { - console.log(`Removed user ${userEmail} from bucket ${bucket.name}.`); + console.log(`Removed user ${userEmail} from bucket ${bucketName}.`); + }) + .catch((err) => { + console.error('ERROR:', err); }); + // [END storage_remove_bucket_owner] } -// [END storage_remove_bucket_owner] -// [START storage_add_bucket_default_owner] function addBucketDefaultOwner (bucketName, userEmail) { + // [START storage_add_bucket_default_owner] + // Imports the Google Cloud client library + const Storage = require('@google-cloud/storage'); + + // The name of the bucket to access, e.g. "my-bucket" + // const bucketName = "my-bucket"; + + // The email of the user to add, e.g. "developer@company.com" + // const userEmail = "developer@company.com"; + // Instantiates a client const storage = Storage(); - // References an existing bucket, e.g. "my-bucket" - const bucket = storage.bucket(bucketName); - // Makes the user an owner in the default ACL of the bucket. You can use // addAllUsers(), addDomain(), addProject(), addGroup(), and // addAllAuthenticatedUsers() to grant access to different types of entities. // You can also use "readers" and "writers" to grant different roles. - return bucket.acl.default.owners.addUser(userEmail) + storage + .bucket(bucketName) + .acl + .default + .owners + .addUser(userEmail) .then(() => { - console.log(`Added user ${userEmail} as an owner on bucket ${bucket.name}.`); + console.log(`Added user ${userEmail} as an owner on bucket ${bucketName}.`); + }) + .catch((err) => { + console.error('ERROR:', err); }); + // [END storage_add_bucket_default_owner] } -// [END storage_add_bucket_default_owner] -// [START storage_remove_bucket_default_owner] function removeBucketDefaultOwner (bucketName, userEmail) { + // [START storage_remove_bucket_default_owner] + // Imports the Google Cloud client library + const Storage = require('@google-cloud/storage'); + + // The name of the bucket to access, e.g. "my-bucket" + // const bucketName = "my-bucket"; + + // The email of the user to remove, e.g. "developer@company.com" + // const userEmail = "developer@company.com"; + // Instantiates a client const storage = Storage(); - // References an existing bucket, e.g. "my-bucket" - const bucket = storage.bucket(bucketName); - // Removes the user from the access control list of the bucket. You can use // deleteAllUsers(), deleteDomain(), deleteProject(), deleteGroup(), and // deleteAllAuthenticatedUsers() to remove access for different types of entities. - return bucket.acl.default.owners.deleteUser(userEmail) + storage + .bucket(bucketName) + .acl + .default + .owners + .deleteUser(userEmail) .then(() => { - console.log(`Removed user ${userEmail} from bucket ${bucket.name}.`); + console.log(`Removed user ${userEmail} from bucket ${bucketName}.`); + }) + .catch((err) => { + console.error('ERROR:', err); }); + // [END storage_remove_bucket_default_owner] } -// [END storage_remove_bucket_default_owner] -// [START storage_print_file_acl] -function printFileAcl (bucketName, fileName) { - // Instantiates a client - const storage = Storage(); +function printFileAcl (bucketName, filename) { + // [START storage_print_file_acl] + // Imports the Google Cloud client library + const Storage = require('@google-cloud/storage'); + + // The name of the bucket to access, e.g. "my-bucket" + // const bucketName = "my-bucket"; - // References an existing bucket, e.g. "my-bucket" - const bucket = storage.bucket(bucketName); + // The name of the file to access, e.g. "file.txt" + // const filename = "file.txt"; - // References an existing file, e.g. "file.txt" - const file = bucket.file(fileName); + // Instantiates a client + const storage = Storage(); // Gets the ACL for the file - return file.acl.get() + storage + .bucket(bucketName) + .file(filename) + .acl + .get() .then((results) => { const acls = results[0]; - acls.forEach((acl) => console.log(`${acl.role}: ${acl.entity}`)); - - return acls; + acls.forEach((acl) => { + console.log(`${acl.role}: ${acl.entity}`); + }); + }) + .catch((err) => { + console.error('ERROR:', err); }); + // [END storage_print_file_acl] } -// [END storage_print_file_acl] -// [START storage_print_file_acl_for_user] -function printFileAclForUser (bucketName, fileName, userEmail) { - // Instantiates a client - const storage = Storage(); +function printFileAclForUser (bucketName, filename, userEmail) { + // [START storage_print_file_acl_for_user] + // Imports the Google Cloud client library + const Storage = require('@google-cloud/storage'); - // References an existing bucket, e.g. "my-bucket" - const bucket = storage.bucket(bucketName); + // The name of the bucket to access, e.g. "my-bucket" + // const bucketName = "my-bucket"; - // References an existing file, e.g. "file.txt" - const file = bucket.file(fileName); + // The name of the file to access, e.g. "file.txt" + // const filename = "file.txt"; + + // The email of the user to check, e.g. "developer@company.com" + // const userEmail = "developer@company.com"; + + // Instantiates a client + const storage = Storage(); const options = { // Specify the user @@ -184,61 +271,94 @@ function printFileAclForUser (bucketName, fileName, userEmail) { }; // Gets the user's ACL for the file - return file.acl.get(options) + storage + .bucket(bucketName) + .file(filename) + .acl + .get(options) .then((results) => { const aclObject = results[0]; console.log(`${aclObject.role}: ${aclObject.entity}`); - - return aclObject; + }) + .catch((err) => { + console.error('ERROR:', err); }); + // [END storage_print_file_acl_for_user] } -// [END storage_print_file_acl_for_user] -// [START storage_add_file_owner] -function addFileOwner (bucketName, fileName, userEmail) { - // Instantiates a client - const storage = Storage(); +function addFileOwner (bucketName, filename, userEmail) { + // [START storage_add_file_owner] + // Imports the Google Cloud client library + const Storage = require('@google-cloud/storage'); + + // The name of the bucket to access, e.g. "my-bucket" + // const bucketName = "my-bucket"; - // References an existing bucket, e.g. "my-bucket" - const bucket = storage.bucket(bucketName); + // The name of the file to access, e.g. "file.txt" + // const filename = "file.txt"; - // References an existing file, e.g. "file.txt" - const file = bucket.file(fileName); + // The email of the user to add, e.g. "developer@company.com" + // const userEmail = "developer@company.com"; + + // Instantiates a client + const storage = Storage(); // Makes the user an owner of the file. You can use addAllUsers(), // addDomain(), addProject(), addGroup(), and addAllAuthenticatedUsers() // to grant access to different types of entities. You can also use "readers" // and "writers" to grant different roles. - return file.acl.owners.addUser(userEmail) + storage + .bucket(bucketName) + .file(filename) + .acl + .owners + .addUser(userEmail) .then(() => { - console.log(`Added user ${userEmail} as an owner on file ${file.name}.`); + console.log(`Added user ${userEmail} as an owner on file ${filename}.`); + }) + .catch((err) => { + console.error('ERROR:', err); }); + // [END storage_add_file_owner] } -// [END storage_add_file_owner] // [START storage_remove_file_owner] -function removeFileOwner (bucketName, fileName, userEmail) { - // Instantiates a client - const storage = Storage(); +function removeFileOwner (bucketName, filename, userEmail) { + // Imports the Google Cloud client library + const Storage = require('@google-cloud/storage'); - // References an existing bucket, e.g. "my-bucket" - const bucket = storage.bucket(bucketName); + // The name of the bucket to access, e.g. "my-bucket" + // const bucketName = "my-bucket"; - // References an existing file, e.g. "file.txt" - const file = bucket.file(fileName); + // The name of the file to access, e.g. "file.txt" + // const filename = "file.txt"; + + // The email of the user to remove, e.g. "developer@company.com" + // const userEmail = "developer@company.com"; + + // Instantiates a client + const storage = Storage(); // Removes the user from the access control list of the file. You can use // deleteAllUsers(), deleteDomain(), deleteProject(), deleteGroup(), and // deleteAllAuthenticatedUsers() to remove access for different types of entities. - return file.acl.owners.deleteUser(userEmail) + storage + .bucket(bucketName) + .file(filename) + .acl + .owners + .deleteUser(userEmail) .then(() => { - console.log(`Removed user ${userEmail} from file ${file.name}.`); + console.log(`Removed user ${userEmail} from file ${filename}.`); + }) + .catch((err) => { + console.error('ERROR:', err); }); } // [END storage_remove_file_owner] -require(`yargs`) // eslint-disable-line +const cli = require(`yargs`) .demand(1) .command( `print-bucket-acl `, @@ -314,5 +434,8 @@ require(`yargs`) // eslint-disable-line .recommendCommands() .epilogue(`For more information, see https://cloud.google.com/storage/docs/access-control/create-manage-lists`) .help() - .strict() - .argv; + .strict(); + +if (module === require.main) { + cli.parse(process.argv.slice(2)); +} diff --git a/storage/buckets.js b/storage/buckets.js index 3b3da13ac67..e14261d78c7 100644 --- a/storage/buckets.js +++ b/storage/buckets.js @@ -1,5 +1,5 @@ /** - * Copyright 2016, Google, Inc. + * Copyright 2017, Google, Inc. * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at @@ -23,60 +23,79 @@ 'use strict'; -const Storage = require('@google-cloud/storage'); - -// [START storage_create_bucket] function createBucket (bucketName) { - // Instantiates a client - const storage = Storage(); + // [START storage_create_bucket] + // Imports the Google Cloud client library + const Storage = require('@google-cloud/storage'); - // Creates a new bucket, e.g. "my-new-bucket" - return storage.createBucket(bucketName) - .then((results) => { - const bucket = results[0]; + // The name of the bucket to create, e.g. "my-bucket" + // const bucketName = "my-bucket"; - console.log(`Bucket ${bucket.name} created.`); + // Instantiates a client + const storage = Storage(); - return bucket; + // Creates a new bucket + storage + .createBucket(bucketName) + .then(() => { + console.log(`Bucket ${bucketName} created.`); + }) + .catch((err) => { + console.error('ERROR:', err); }); + // [END storage_create_bucket] } -// [END storage_create_bucket] -// [START storage_list_buckets] function listBuckets () { + // [START storage_list_buckets] + // Imports the Google Cloud client library + const Storage = require('@google-cloud/storage'); + // Instantiates a client const storage = Storage(); // Lists all buckets in the current project - return storage.getBuckets() + storage + .getBuckets() .then((results) => { const buckets = results[0]; console.log('Buckets:'); - buckets.forEach((bucket) => console.log(bucket.name)); - - return buckets; + buckets.forEach((bucket) => { + console.log(bucket.name); + }); + }) + .catch((err) => { + console.error('ERROR:', err); }); + // [END storage_list_buckets] } -// [END storage_list_buckets] -// [START storage_delete_bucket] function deleteBucket (bucketName) { + // [START storage_delete_bucket] + // Imports the Google Cloud client library + const Storage = require('@google-cloud/storage'); + + // The name of the bucket to delete, e.g. "my-bucket" + // const bucketName = "my-bucket"; + // Instantiates a client const storage = Storage(); - // References an existing bucket, e.g. "my-bucket" - const bucket = storage.bucket(bucketName); - // Deletes the bucket - return bucket.delete() + storage + .bucket(bucketName) + .delete() .then(() => { - console.log(`Bucket ${bucket.name} deleted.`); + console.log(`Bucket ${bucketName} deleted.`); + }) + .catch((err) => { + console.error('ERROR:', err); }); + // [END storage_delete_bucket] } -// [END storage_delete_bucket] -require(`yargs`) // eslint-disable-line +const cli = require(`yargs`) .demand(1) .command( `create `, @@ -103,5 +122,8 @@ require(`yargs`) // eslint-disable-line .recommendCommands() .epilogue(`For more information, see https://cloud.google.com/storage/docs`) .help() - .strict() - .argv; + .strict(); + +if (module === require.main) { + cli.parse(process.argv.slice(2)); +} diff --git a/storage/encryption.js b/storage/encryption.js index 22cbaac8468..d805d617bcb 100644 --- a/storage/encryption.js +++ b/storage/encryption.js @@ -1,5 +1,5 @@ /** - * Copyright 2016, Google, Inc. + * Copyright 2017, Google, Inc. * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at @@ -24,7 +24,6 @@ 'use strict'; const Buffer = require('safe-buffer').Buffer; -const Storage = require('@google-cloud/storage'); // [START storage_generate_encryption_key] const crypto = require('crypto'); @@ -49,61 +48,84 @@ function generateEncryptionKey () { } // [END storage_generate_encryption_key] -// [START storage_upload_encrypted_file] -function uploadEncryptedFile (bucketName, srcFileName, destFileName, key) { - // Instantiates a client - const storageClient = Storage(); +function uploadEncryptedFile (bucketName, srcFilename, destFilename, key) { + // [START storage_upload_encrypted_file] + // Imports the Google Cloud client library + const Storage = require('@google-cloud/storage'); + + // The name of the bucket to access, e.g. "my-bucket" + // const bucketName = "my-bucket"; + + // The name of the local file to upload, e.g. "./local/path/to/file.txt" + // const srcFilename = "./local/path/to/file.txt"; + + // The path to which the file should be uploaded, e.g. "file_encrypted.txt" + // const destFilename = "file.txt"; - // References an existing bucket, e.g. "my-bucket" - const bucket = storageClient.bucket(bucketName); + // Instantiates a client + const storage = Storage(); - const config = { + const options = { // The path to which the file should be uploaded, e.g. "file_encrypted.txt" - destination: destFileName, + destination: destFilename, // Encrypt the file with a customer-supplied key, e.g. "my-secret-key" - encryptionKey: new Buffer(key, 'base64') + encryptionKey: Buffer.from(key, 'base64') }; // Encrypts and uploads a local file, e.g. "./local/path/to/file.txt". // The file will only be retrievable using the key used to upload it. - return bucket.upload(srcFileName, config) - .then((results) => { - const file = results[0]; - - console.log(`File ${srcFileName} uploaded to ${file.name}.`); - - return file; + storage + .bucket(bucketName) + .upload(srcFilename, options) + .then(() => { + console.log(`File ${srcFilename} uploaded to gs://${bucketName}/${destFilename}.`); + }) + .catch((err) => { + console.error('ERROR:', err); }); + // [END storage_upload_encrypted_file] } -// [END storage_upload_encrypted_file] -// [START storage_download_encrypted_file] -function downloadEncryptedFile (bucketName, srcFileName, destFileName, key) { - // Instantiates a client - const storageClient = Storage(); +function downloadEncryptedFile (bucketName, srcFilename, destFilename, key) { + // [START storage_download_encrypted_file] + // Imports the Google Cloud client library + const Storage = require('@google-cloud/storage'); + + // The name of the bucket to access, e.g. "my-bucket" + // const bucketName = "my-bucket"; - // References an existing bucket, e.g. "my-bucket" - const bucket = storageClient.bucket(bucketName); + // The name of the remote file to download, e.g. "file_encrypted.txt" + // const srcFilename = "file_encrypted.txt"; - // References an existing file, e.g. "file_encrypted.txt" - const file = bucket.file(srcFileName); + // The path to which the file should be downloaded, e.g. "./file.txt" + // const destFilename = "./file.txt"; + + // Instantiates a client + const storage = Storage(); - const config = { + const options = { // The path to which the file should be downloaded, e.g. "./file.txt" - destination: destFileName + destination: destFilename }; - // Specifies the key that should be used to decrypt the file - file.setEncryptionKey(new Buffer(key, 'base64')); + const file = storage + .bucket(bucketName) + .file(srcFilename); + + file.setEncryptionKey(Buffer.from(key, 'base64')); // Descrypts and downloads the file. This can only be done with the key used // to encrypt and upload the file. - return file.download(config) + file + .download(options) .then(() => { - console.log(`File ${file.name} downloaded to ${destFileName}.`); + console.log(`File ${srcFilename} downloaded to ${destFilename}.`); + }) + .catch((err) => { + console.error('ERROR:', err); }); + // [END storage_download_encrypted_file] } -// [END storage_download_encrypted_file] // [START storage_rotate_encryption_key] function rotateEncryptionKey () { @@ -111,7 +133,7 @@ function rotateEncryptionKey () { } // [END storage_rotate_encryption_key] -require(`yargs`) // eslint-disable-line +const cli = require(`yargs`) .demand(1) .command( `generate-encryption-key`, @@ -120,16 +142,16 @@ require(`yargs`) // eslint-disable-line generateEncryptionKey ) .command( - `upload `, + `upload `, `Encrypts and uploads a file.`, {}, - (opts) => uploadEncryptedFile(opts.bucketName, opts.srcFileName, opts.destFileName, opts.key) + (opts) => uploadEncryptedFile(opts.bucketName, opts.srcFilename, opts.destFilename, opts.key) ) .command( - `download `, + `download `, `Decrypts and downloads a file.`, {}, - (opts) => downloadEncryptedFile(opts.bucketName, opts.srcFileName, opts.destFileName, opts.key) + (opts) => downloadEncryptedFile(opts.bucketName, opts.srcFilename, opts.destFilename, opts.key) ) .command( `rotate `, @@ -145,5 +167,8 @@ require(`yargs`) // eslint-disable-line .recommendCommands() .epilogue(`For more information, see https://cloud.google.com/storage/docs`) .help() - .strict() - .argv; + .strict(); + +if (module === require.main) { + cli.parse(process.argv.slice(2)); +} diff --git a/storage/files.js b/storage/files.js index f5e38a721af..5e4ad074d47 100644 --- a/storage/files.js +++ b/storage/files.js @@ -1,5 +1,5 @@ /** - * Copyright 2016, Google, Inc. + * Copyright 2017, Google, Inc. * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at @@ -23,37 +23,52 @@ 'use strict'; -const Storage = require('@google-cloud/storage'); - -// [START storage_list_files] function listFiles (bucketName) { + // [START storage_list_files] + // Imports the Google Cloud client library + const Storage = require('@google-cloud/storage'); + + // The name of the bucket to access, e.g. "my-bucket" + // const bucketName = "my-bucket"; + // Instantiates a client const storage = Storage(); - // References an existing bucket, e.g. "my-bucket" - const bucket = storage.bucket(bucketName); - // Lists files in the bucket - return bucket.getFiles() + storage + .bucket(bucketName) + .getFiles() .then((results) => { const files = results[0]; console.log('Files:'); - files.forEach((file) => console.log(file.name)); - - return files; + files.forEach((file) => { + console.log(file.name); + }); + }) + .catch((err) => { + console.error('ERROR:', err); }); + // [END storage_list_files] } -// [END storage_list_files] -// [START storage_list_files_with_prefix] function listFilesByPrefix (bucketName, prefix, delimiter) { + // [START storage_list_files_with_prefix] + // Imports the Google Cloud client library + const Storage = require('@google-cloud/storage'); + + // The name of the bucket to access, e.g. "my-bucket" + // const bucketName = "my-bucket"; + + // The prefix by which to filter files, e.g. "public/" + // const prefix = "public/"; + + // The delimiter to use, e.g. "/" + // const delimiter = "/"; + // Instantiates a client const storage = Storage(); - // References an existing bucket, e.g. "my-bucket" - const bucket = storage.bucket(bucketName); - /** * This can be used to list all blobs in a "folder", e.g. "public/". * @@ -76,99 +91,139 @@ function listFilesByPrefix (bucketName, prefix, delimiter) { const options = { prefix: prefix }; + if (delimiter) { options.delimiter = delimiter; } // Lists files in the bucket, filtered by a prefix - return bucket.getFiles(options) + storage + .bucket(bucketName) + .getFiles(options) .then((results) => { const files = results[0]; console.log('Files:'); - files.forEach((file) => console.log(file.name)); - - return files; + files.forEach((file) => { + console.log(file.name); + }); + }) + .catch((err) => { + console.error('ERROR:', err); }); + // [END storage_list_files_with_prefix] } -// [END storage_list_files_with_prefix] -// [START storage_upload_file] -function uploadFile (bucketName, fileName) { - // Instantiates a client - const storage = Storage(); +function uploadFile (bucketName, filename) { + // [START storage_upload_file] + // Imports the Google Cloud client library + const Storage = require('@google-cloud/storage'); - // References an existing bucket, e.g. "my-bucket" - const bucket = storage.bucket(bucketName); + // The name of the bucket to access, e.g. "my-bucket" + // const bucketName = "my-bucket"; - // Uploads a local file to the bucket, e.g. "./local/path/to/file.txt" - return bucket.upload(fileName) - .then((results) => { - const file = results[0]; + // The name of the local file to upload, e.g. "./local/path/to/file.txt" + // const filename = "./local/path/to/file.txt"; - console.log(`File ${file.name} uploaded.`); + // Instantiates a client + const storage = Storage(); - return file; + // Uploads a local file to the bucket + storage + .bucket(bucketName) + .upload(filename) + .then(() => { + console.log(`${filename} uploaded to ${bucketName}.`); + }) + .catch((err) => { + console.error('ERROR:', err); }); + // [END storage_upload_file] } -// [END storage_upload_file] -// [START storage_download_file] -function downloadFile (bucketName, srcFileName, destFileName) { - // Instantiates a client - const storage = Storage(); +function downloadFile (bucketName, srcFilename, destFilename) { + // [START storage_download_file] + // Imports the Google Cloud client library + const Storage = require('@google-cloud/storage'); - // References an existing bucket, e.g. "my-bucket" - const bucket = storage.bucket(bucketName); + // The name of the bucket to access, e.g. "my-bucket" + // const bucketName = "my-bucket"; - // References an existing file, e.g. "file.txt" - const file = bucket.file(srcFileName); + // The name of the remote file to download, e.g. "file.txt" + // const srcFilename = "file.txt"; + + // The path to which the file should be downloaded, e.g. "./local/path/to/file.txt" + // const destFilename = "./local/path/to/file.txt"; + + // Instantiates a client + const storage = Storage(); const options = { // The path to which the file should be downloaded, e.g. "./file.txt" - destination: destFileName + destination: destFilename }; // Downloads the file - return file.download(options) + storage + .bucket(bucketName) + .file(srcFilename) + .download(options) .then(() => { - console.log(`File ${file.name} downloaded to ${destFileName}.`); + console.log(`gs://${bucketName}/${srcFilename} downloaded to ${destFilename}.`); + }) + .catch((err) => { + console.error('ERROR:', err); }); + // [END storage_download_file] } -// [END storage_download_file] -// [START storage_delete_file] -function deleteFile (bucketName, fileName) { - // Instantiates a client - const storage = Storage(); +function deleteFile (bucketName, filename) { + // [START storage_delete_file] + // Imports the Google Cloud client library + const Storage = require('@google-cloud/storage'); - // References an existing bucket, e.g. "my-bucket" - const bucket = storage.bucket(bucketName); + // The name of the bucket to access, e.g. "my-bucket" + // const bucketName = "my-bucket"; - // References an existing file, e.g. "file.txt" - const file = bucket.file(fileName); + // The name of the file to delete, e.g. "file.txt" + // const filename = "file.txt"; + + // Instantiates a client + const storage = Storage(); // Deletes the file from the bucket - return file.delete() + storage + .bucket(bucketName) + .file(filename) + .delete() .then(() => { - console.log(`File ${fileName} deleted.`); + console.log(`gs://${bucketName}/${filename} deleted.`); + }) + .catch((err) => { + console.error('ERROR:', err); }); + // [END storage_delete_file] } -// [END storage_delete_file] -// [START storage_get_metadata] -function getMetadata (bucketName, fileName) { - // Instantiates a client - const storage = Storage(); +function getMetadata (bucketName, filename) { + // [START storage_get_metadata] + // Imports the Google Cloud client library + const Storage = require('@google-cloud/storage'); - // References an existing bucket, e.g. "my-bucket" - const bucket = storage.bucket(bucketName); + // The name of the bucket to access, e.g. "my-bucket" + // const bucketName = "my-bucket"; - // References an existing file, e.g. "file.txt" - const file = bucket.file(fileName); + // The name of the file to access, e.g. "file.txt" + // const filename = "file.txt"; + + // Instantiates a client + const storage = Storage(); // Gets the metadata for the file - return file.getMetadata() + storage + .bucket(bucketName) + .file(filename) + .getMetadata() .then((results) => { const metadata = results[0]; @@ -191,41 +246,54 @@ function getMetadata (bucketName, fileName) { console.log(`Content-encoding: ${metadata.contentEncoding}`); console.log(`Content-language: ${metadata.contentLanguage}`); console.log(`Metadata: ${metadata.metadata}`); - - return metadata; + }) + .catch((err) => { + console.error('ERROR:', err); }); + // [END storage_get_metadata] } -// [END storage_get_metadata] -// [START storage_make_public] -function makePublic (bucketName, fileName) { - // Instantiates a client - const storage = Storage(); +function makePublic (bucketName, filename) { + // [START storage_make_public] + // Imports the Google Cloud client library + const Storage = require('@google-cloud/storage'); + + // The name of the bucket to access, e.g. "my-bucket" + // const bucketName = "my-bucket"; - // References an existing bucket, e.g. "my-bucket" - const bucket = storage.bucket(bucketName); + // The name of the file to make public, e.g. "file.txt" + // const filename = "file.txt"; - // References an existing file, e.g. "file.txt" - const file = bucket.file(fileName); + // Instantiates a client + const storage = Storage(); // Makes the file public - return file.makePublic() + storage + .bucket(bucketName) + .file(filename) + .makePublic() .then(() => { - console.log(`File ${file.name} is now public.`); + console.log(`gs://${bucketName}/${filename} is now public.`); + }) + .catch((err) => { + console.error('ERROR:', err); }); + // [END storage_make_public] } -// [END storage_make_public] -// [START storage_generate_signed_url] -function generateSignedUrl (bucketName, fileName) { - // Instantiates a client - const storage = Storage(); +function generateSignedUrl (bucketName, filename) { + // [START storage_generate_signed_url] + // Imports the Google Cloud client library + const Storage = require('@google-cloud/storage'); - // References an existing bucket, e.g. "my-bucket" - const bucket = storage.bucket(bucketName); + // The name of the bucket to access, e.g. "my-bucket" + // const bucketName = "my-bucket"; - // References an existing file, e.g. "file.txt" - const file = bucket.file(fileName); + // The name of the file to access, e.g. "file.txt" + // const filename = "file.txt"; + + // Instantiates a client + const storage = Storage(); // These options will allow temporary read access to the file const options = { @@ -234,66 +302,87 @@ function generateSignedUrl (bucketName, fileName) { }; // Get a signed URL for the file - return file.getSignedUrl(options) + storage + .bucket(bucketName) + .file(filename) + .getSignedUrl(options) .then((results) => { const url = results[0]; - console.log(`The signed url for ${file.name} is ${url}.`); - - return url; + console.log(`The signed url for ${filename} is ${url}.`); + }) + .catch((err) => { + console.error('ERROR:', err); }); + // [END storage_generate_signed_url] } -// [END storage_generate_signed_url] -// [START storage_move_file] -function moveFile (bucketName, srcFileName, destFileName) { - // Instantiates a client - const storage = Storage(); +function moveFile (bucketName, srcFilename, destFilename) { + // [START storage_move_file] + // Imports the Google Cloud client library + const Storage = require('@google-cloud/storage'); - // References an existing bucket, e.g. "my-bucket" - const bucket = storage.bucket(bucketName); + // The name of the bucket to access, e.g. "my-bucket" + // const bucketName = "my-bucket"; - // References an existing file, e.g. "file.txt" - const file = bucket.file(srcFileName); + // The name of the file to move, e.g. "file.txt" + // const srcFilename = "file.txt"; + + // The destination path for the file, e.g. "moved.txt" + // const destFilename = "moved.txt"; + + // Instantiates a client + const storage = Storage(); // Moves the file within the bucket - return file.move(destFileName) + storage + .bucket(bucketName) + .file(srcFilename) + .move(destFilename) .then(() => { - console.log(`File ${file.name} moved to ${destFileName}.`); + console.log(`gs://${bucketName}/${srcFilename} moved to gs://${bucketName}/${destFilename}.`); + }) + .catch((err) => { + console.error('ERROR:', err); }); + // [END storage_move_file] } -// [END storage_move_file] -// [START storage_copy_file] -function copyFile (srcBucketName, srcFileName, destBucketName, destFileName) { - // Instantiates a client - const storage = Storage(); +function copyFile (srcBucketName, srcFilename, destBucketName, destFilename) { + // [START storage_copy_file] + // Imports the Google Cloud client library + const Storage = require('@google-cloud/storage'); - // References an existing bucket, e.g. "my-bucket" - const bucket = storage.bucket(srcBucketName); + // The name of the source bucket, e.g. "my-bucket" + // const srcBucketName = "my-bucket"; - // References an existing file, e.g. "file.txt" - const file = bucket.file(srcFileName); + // The name of the source file, e.g. "file.txt" + // const srcFilename = "file.txt"; - // References another existing bucket, e.g. "my-other-bucket" - const destBucket = storage.bucket(destBucketName); + // The destination bucket, e.g. "my-other-bucket" + // const destBucketName = "my-other-bucket"; - // Creates a reference to a destination file, e.g. "file.txt" - const destFile = destBucket.file(destFileName); + // The destination filename, e.g. "file.txt" + // const destFilename = "file.txt"; - // Copies the file to the other bucket - return file.copy(destFile) - .then((results) => { - const file = results[0]; - - console.log(`File ${srcFileName} copied to ${file.name} in ${destBucket.name}.`); + // Instantiates a client + const storage = Storage(); - return file; + // Copies the file to the other bucket + storage + .bucket(srcBucketName) + .file(srcFilename) + .copy(storage.bucket(destBucketName).file(destFilename)) + .then(() => { + console.log(`gs://${srcBucketName}/${srcFilename} copied to gs://${destBucketName}/${destFilename}.`); + }) + .catch((err) => { + console.error('ERROR:', err); }); + // [END storage_copy_file] } -// [END storage_copy_file] -require(`yargs`) // eslint-disable-line +const cli = require(`yargs`) .demand(1) .command( `list [prefix] [delimiter]`, @@ -368,5 +457,8 @@ require(`yargs`) // eslint-disable-line .recommendCommands() .epilogue(`For more information, see https://cloud.google.com/storage/docs`) .help() - .strict() - .argv; + .strict(); + +if (module === require.main) { + cli.parse(process.argv.slice(2)); +} diff --git a/storage/iam.js b/storage/iam.js index 20f3ec3c089..aa90cdd4f38 100644 --- a/storage/iam.js +++ b/storage/iam.js @@ -20,19 +20,19 @@ function viewBucketIamMembers (bucketName) { // Imports the Google Cloud client library const Storage = require('@google-cloud/storage'); - // Instantiates a client - const storage = Storage(); - - // Your Google Cloud Storage bucket name + // The name of the bucket to access, e.g. "my-bucket" // const bucketName = "my-bucket"; - // Get a reference to a Google Cloud Storage bucket - const bucket = storage.bucket(bucketName); + // Instantiates a client + const storage = Storage(); // Gets and displays the bucket's IAM policy - bucket.iam.getPolicy() - .then((data) => { - const policy = data[0].bindings; + storage + .bucket(bucketName) + .iam + .getPolicy() + .then((results) => { + const policy = results[0].bindings; // Displays the roles in the bucket's IAM policy console.log(`Roles for bucket ${bucketName}:`); @@ -47,7 +47,7 @@ function viewBucketIamMembers (bucketName) { }); }) .catch((err) => { - console.error('Error:', err); + console.error('ERROR:', err); }); // [END view_bucket_iam_members] } @@ -57,25 +57,25 @@ function addBucketIamMember (bucketName, roleName, members) { // Imports the Google Cloud client library const Storage = require('@google-cloud/storage'); - // Instantiates a client - const storage = Storage(); - - // Your Google Cloud Storage bucket name + // The name of the bucket to access, e.g. "my-bucket" // const bucketName = "my-bucket"; - // The bucket-level IAM role to grant + // The bucket-level IAM role to grant, e.g. "roles/storage.objectViewer" // const roleName = "roles/storage.objectViewer"; - // The list of IAM members to grant the role to + // The list of IAM members to grant the role to, e.g. ['user:jdoe@example.com', 'group:admins@example.com'] // const members = ['user:jdoe@example.com', 'group:admins@example.com']; + // Instantiates a client + const storage = Storage(); + // Get a reference to a Google Cloud Storage bucket const bucket = storage.bucket(bucketName); // Gets and updates the bucket's IAM policy bucket.iam.getPolicy() - .then((data) => { - const policy = data[0]; + .then((results) => { + const policy = results[0]; // Adds the new roles to the bucket's IAM policy policy.bindings.push({ @@ -93,7 +93,7 @@ function addBucketIamMember (bucketName, roleName, members) { }); }) .catch((err) => { - console.error('Error:', err); + console.error('ERROR:', err); }); // [END add_bucket_iam_member] } @@ -103,18 +103,18 @@ function removeBucketIamMember (bucketName, roleName, members) { // Imports the Google Cloud client library const Storage = require('@google-cloud/storage'); - // Instantiates a client - const storage = Storage(); - - // Your Google Cloud Storage bucket name + // The name of the bucket to access, e.g. "my-bucket" // const bucketName = "my-bucket"; - // The bucket-level IAM role to grant + // The bucket-level IAM role to grant, e.g. "roles/storage.objectViewer" // const roleName = "roles/storage.objectViewer"; - // The list of IAM members to grant the role to + // The list of IAM members to grant the role to, e.g. ['user:jdoe@example.com', 'group:admins@example.com'] // const members = ['user:jdoe@example.com', 'group:admins@example.com']; + // Instantiates a client + const storage = Storage(); + // Get a reference to a Google Cloud Storage bucket const bucket = storage.bucket(bucketName); @@ -150,7 +150,7 @@ function removeBucketIamMember (bucketName, roleName, members) { }); }) .catch((err) => { - console.error('Error:', err); + console.error('ERROR:', err); }); // [END remove_bucket_iam_member] } diff --git a/storage/package.json b/storage/package.json index 98eb07634ed..a1b50ae0d76 100644 --- a/storage/package.json +++ b/storage/package.json @@ -23,13 +23,13 @@ "googleapis": "19.0.0", "moment": "2.18.1", "safe-buffer": "5.0.1", - "yargs": "7.1.0" + "yargs": "8.0.1" }, "devDependencies": { "@google-cloud/nodejs-repo-tools": "1.4.13", "ava": "0.19.1", "proxyquire": "1.7.11", - "sinon": "2.1.0", + "sinon": "2.2.0", "uuid": "3.0.1" }, "cloud-repo-tools": { diff --git a/storage/quickstart.js b/storage/quickstart.js index c0cc56caff8..bc6e3b8b82b 100644 --- a/storage/quickstart.js +++ b/storage/quickstart.js @@ -23,7 +23,7 @@ const Storage = require('@google-cloud/storage'); const projectId = 'YOUR_PROJECT_ID'; // Instantiates a client -const storageClient = Storage({ +const storage = Storage({ projectId: projectId }); @@ -31,10 +31,9 @@ const storageClient = Storage({ const bucketName = 'my-new-bucket'; // Creates the new bucket -storageClient.createBucket(bucketName) - .then((results) => { - const bucket = results[0]; - console.log(`Bucket ${bucket.name} created.`); +storage.createBucket(bucketName) + .then(() => { + console.log(`Bucket ${bucketName} created.`); }) .catch((err) => { console.error('ERROR:', err); diff --git a/storage/system-test/buckets.test.js b/storage/system-test/buckets.test.js index c06af9ce44f..f017b2fec55 100644 --- a/storage/system-test/buckets.test.js +++ b/storage/system-test/buckets.test.js @@ -44,10 +44,11 @@ test.serial(`should create a bucket`, async (t) => { }); test.serial(`should list buckets`, async (t) => { - await tools.tryTest(async () => { + t.plan(0); + await tools.tryTest(async (assert) => { const output = await tools.runAsync(`${cmd} list`, cwd); - t.true(output.includes(`Buckets:`)); - t.true(output.includes(bucketName)); + assert(output.includes(`Buckets:`)); + assert(output.includes(bucketName)); }).start(); }); diff --git a/storage/system-test/encryption.test.js b/storage/system-test/encryption.test.js index 5ae8d4ebfd7..dc1419816ec 100644 --- a/storage/system-test/encryption.test.js +++ b/storage/system-test/encryption.test.js @@ -69,7 +69,7 @@ test.serial(`should generate a key`, async (t) => { test.serial(`should upload a file`, async (t) => { const output = await tools.runAsync(`${cmd} upload ${bucketName} ${filePath} ${fileName} ${key}`, cwd); - t.is(output, `File ${filePath} uploaded to ${fileName}.`); + t.is(output, `File ${filePath} uploaded to gs://${bucketName}/${fileName}.`); const [exists] = await bucket.file(fileName).exists(); t.true(exists); }); diff --git a/storage/system-test/files.test.js b/storage/system-test/files.test.js index 78076dd1aff..b8a2d199d61 100644 --- a/storage/system-test/files.test.js +++ b/storage/system-test/files.test.js @@ -60,37 +60,38 @@ test.afterEach.always(tools.restoreConsole); test.serial(`should upload a file`, async (t) => { const output = await tools.runAsync(`${cmd} upload ${bucketName} ${filePath}`, cwd); - t.is(output, `File ${fileName} uploaded.`); + t.is(output, `${filePath} uploaded to ${bucketName}.`); const [exists] = await bucket.file(fileName).exists(); t.true(exists); }); test.serial(`should download a file`, async (t) => { const output = await tools.runAsync(`${cmd} download ${bucketName} ${fileName} ${downloadFilePath}`, cwd); - t.is(output, `File ${fileName} downloaded to ${downloadFilePath}.`); + t.is(output, `gs://${bucketName}/${fileName} downloaded to ${downloadFilePath}.`); t.notThrows(() => fs.statSync(downloadFilePath)); }); test.serial(`should move a file`, async (t) => { const output = await tools.runAsync(`${cmd} move ${bucketName} ${fileName} ${movedFileName}`, cwd); - t.is(output, `File ${fileName} moved to ${movedFileName}.`); + t.is(output, `gs://${bucketName}/${fileName} moved to gs://${bucketName}/${movedFileName}.`); const [exists] = await bucket.file(movedFileName).exists(); t.true(exists); }); test.serial(`should copy a file`, async (t) => { const output = await tools.runAsync(`${cmd} copy ${bucketName} ${movedFileName} ${bucketName} ${copiedFileName}`, cwd); - t.is(output, `File ${movedFileName} copied to ${copiedFileName} in ${bucketName}.`); + t.is(output, `gs://${bucketName}/${movedFileName} copied to gs://${bucketName}/${copiedFileName}.`); const [exists] = await bucket.file(copiedFileName).exists(); t.true(exists); }); test.serial(`should list files`, async (t) => { - await tools.tryTest(async () => { + t.plan(0); + await tools.tryTest(async (assert) => { const output = await tools.runAsync(`${cmd} list ${bucketName}`, cwd); - t.true(output.includes(`Files:`)); - t.true(output.includes(movedFileName)); - t.true(output.includes(copiedFileName)); + assert(output.includes(`Files:`)); + assert(output.includes(movedFileName)); + assert(output.includes(copiedFileName)); }).start(); }); @@ -107,7 +108,7 @@ test.serial(`should list files by a prefix`, async (t) => { test.serial(`should make a file public`, async (t) => { const output = await tools.runAsync(`${cmd} make-public ${bucketName} ${copiedFileName}`, cwd); - t.is(output, `File ${copiedFileName} is now public.`); + t.is(output, `gs://${bucketName}/${copiedFileName} is now public.`); }); test.serial(`should generate a signed URL for a file`, async (t) => { @@ -123,7 +124,7 @@ test.serial(`should get metadata for a file`, async (t) => { test.serial(`should delete a file`, async (t) => { const output = await tools.runAsync(`${cmd} delete ${bucketName} ${copiedFileName}`, cwd); - t.is(output, `File ${copiedFileName} deleted.`); + t.is(output, `gs://${bucketName}/${copiedFileName} deleted.`); const [exists] = await bucket.file(copiedFileName).exists(); t.false(exists); }); diff --git a/storage/yarn.lock b/storage/yarn.lock index 365561592da..a3263501dbc 100644 --- a/storage/yarn.lock +++ b/storage/yarn.lock @@ -60,21 +60,21 @@ string-format-obj "^1.1.0" through2 "^2.0.3" -"@google-cloud/nodejs-repo-tools@1.4.5": - version "1.4.5" - resolved "https://registry.yarnpkg.com/@google-cloud/nodejs-repo-tools/-/nodejs-repo-tools-1.4.5.tgz#fa2f8fcf29969e05de184fa4b8f03363903566e3" +"@google-cloud/nodejs-repo-tools@1.4.13": + version "1.4.13" + resolved "https://registry.yarnpkg.com/@google-cloud/nodejs-repo-tools/-/nodejs-repo-tools-1.4.13.tgz#005556d8b93cb29f16018988e466cf0f9dc6d91f" dependencies: ava "0.19.1" colors "1.1.2" - fs-extra "3.0.0" + fs-extra "3.0.1" got "6.7.1" - handlebars "4.0.6" + handlebars "4.0.8" lodash "4.17.4" proxyquire "1.7.11" - sinon "2.1.0" + sinon "2.2.0" string "3.3.3" supertest "3.0.0" - yargs "7.1.0" + yargs "8.0.1" "@google-cloud/storage@1.1.0": version "1.1.0" @@ -778,7 +778,7 @@ camelcase@^3.0.0: version "3.0.0" resolved "https://registry.yarnpkg.com/camelcase/-/camelcase-3.0.0.tgz#32fc4b9fcdaf845fcdf7e73bb97cac2261f0ab0a" -camelcase@^4.0.0: +camelcase@^4.0.0, camelcase@^4.1.0: version "4.1.0" resolved "https://registry.yarnpkg.com/camelcase/-/camelcase-4.1.0.tgz#d545635be1e33c542649c69173e5de6acfae34dd" @@ -1343,9 +1343,9 @@ formidable@^1.1.1: version "1.1.1" resolved "https://registry.yarnpkg.com/formidable/-/formidable-1.1.1.tgz#96b8886f7c3c3508b932d6bd70c4d3a88f35f1a9" -fs-extra@3.0.0: - version "3.0.0" - resolved "https://registry.yarnpkg.com/fs-extra/-/fs-extra-3.0.0.tgz#244e0c4b0b8818f54040ec049d8a2bddc1202861" +fs-extra@3.0.1: + version "3.0.1" + resolved "https://registry.yarnpkg.com/fs-extra/-/fs-extra-3.0.1.tgz#3794f378c58b342ea7dbbb23095109c4b3b62291" dependencies: graceful-fs "^4.1.2" jsonfile "^3.0.0" @@ -1572,9 +1572,9 @@ gtoken@^1.1.0, gtoken@^1.2.1: mime "^1.2.11" request "^2.72.0" -handlebars@4.0.6: - version "4.0.6" - resolved "https://registry.yarnpkg.com/handlebars/-/handlebars-4.0.6.tgz#2ce4484850537f9c97a8026d5399b935c4ed4ed7" +handlebars@4.0.8: + version "4.0.8" + resolved "https://registry.yarnpkg.com/handlebars/-/handlebars-4.0.8.tgz#22b875cd3f0e6cbea30314f144e82bc7a72ff420" dependencies: async "^1.4.0" optimist "^0.6.1" @@ -2250,6 +2250,12 @@ md5-o-matic@^0.1.1: version "0.1.1" resolved "https://registry.yarnpkg.com/md5-o-matic/-/md5-o-matic-0.1.1.tgz#822bccd65e117c514fab176b25945d54100a03c3" +mem@^1.1.0: + version "1.1.0" + resolved "https://registry.yarnpkg.com/mem/-/mem-1.1.0.tgz#5edd52b485ca1d900fe64895505399a0dfa45f76" + dependencies: + mimic-fn "^1.0.0" + meow@^3.7.0: version "3.7.0" resolved "https://registry.yarnpkg.com/meow/-/meow-3.7.0.tgz#72cb668b425228290abbfa856892587308a801fb" @@ -2523,6 +2529,14 @@ os-locale@^1.4.0: dependencies: lcid "^1.0.0" +os-locale@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/os-locale/-/os-locale-2.0.0.tgz#15918ded510522b81ee7ae5a309d54f639fc39a4" + dependencies: + execa "^0.5.0" + lcid "^1.0.0" + mem "^1.1.0" + os-tmpdir@^1.0.0, os-tmpdir@^1.0.1: version "1.0.2" resolved "https://registry.yarnpkg.com/os-tmpdir/-/os-tmpdir-1.0.2.tgz#bbe67406c79aa85c5cfec766fe5734555dfa1274" @@ -3109,6 +3123,19 @@ sinon@2.1.0: text-encoding "0.6.4" type-detect "^4.0.0" +sinon@2.2.0: + version "2.2.0" + resolved "https://registry.yarnpkg.com/sinon/-/sinon-2.2.0.tgz#3b1b42ff5defcbf51a52a62aca6d61171b9fd262" + dependencies: + diff "^3.1.0" + formatio "1.2.0" + lolex "^1.6.0" + native-promise-only "^0.8.1" + path-to-regexp "^1.7.0" + samsam "^1.1.3" + text-encoding "0.6.4" + type-detect "^4.0.0" + slash@^1.0.0: version "1.0.0" resolved "https://registry.yarnpkg.com/slash/-/slash-1.0.0.tgz#c41f2f6c39fc16d1cd17ad4b5d896114ae470d55" @@ -3512,6 +3539,10 @@ which-module@^1.0.0: version "1.0.0" resolved "https://registry.yarnpkg.com/which-module/-/which-module-1.0.0.tgz#bba63ca861948994ff307736089e3b96026c2a4f" +which-module@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/which-module/-/which-module-2.0.0.tgz#d9ef07dce77b9902b8a3a8fa4b31c3e3f7e6e87a" + which@^1.2.8, which@^1.2.9: version "1.2.14" resolved "https://registry.yarnpkg.com/which/-/which-1.2.14.tgz#9a87c4378f03e827cecaf1acdf56c736c01c14e5" @@ -3606,6 +3637,12 @@ yargs-parser@^5.0.0: dependencies: camelcase "^3.0.0" +yargs-parser@^7.0.0: + version "7.0.0" + resolved "https://registry.yarnpkg.com/yargs-parser/-/yargs-parser-7.0.0.tgz#8d0ac42f16ea55debd332caf4c4038b3e3f5dfd9" + dependencies: + camelcase "^4.1.0" + yargs@7.1.0: version "7.1.0" resolved "https://registry.yarnpkg.com/yargs/-/yargs-7.1.0.tgz#6ba318eb16961727f5d284f8ea003e8d6154d0c8" @@ -3624,6 +3661,24 @@ yargs@7.1.0: y18n "^3.2.1" yargs-parser "^5.0.0" +yargs@8.0.1: + version "8.0.1" + resolved "https://registry.yarnpkg.com/yargs/-/yargs-8.0.1.tgz#420ef75e840c1457a80adcca9bc6fa3849de51aa" + dependencies: + camelcase "^4.1.0" + cliui "^3.2.0" + decamelize "^1.1.1" + get-caller-file "^1.0.1" + os-locale "^2.0.0" + read-pkg-up "^2.0.0" + require-directory "^2.1.1" + require-main-filename "^1.0.1" + set-blocking "^2.0.0" + string-width "^2.0.0" + which-module "^2.0.0" + y18n "^3.2.1" + yargs-parser "^7.0.0" + yargs@~3.10.0: version "3.10.0" resolved "https://registry.yarnpkg.com/yargs/-/yargs-3.10.0.tgz#f7ee7bd857dd7c1d2d38c0e74efbd681d1431fd1" diff --git a/yarn.lock b/yarn.lock index bb22c1db274..c5aebcb4e12 100644 --- a/yarn.lock +++ b/yarn.lock @@ -37,6 +37,29 @@ ansi-styles "^2.2.1" esutils "^2.0.2" +"@google-cloud/common@^0.13.0": + version "0.13.3" + resolved "https://registry.yarnpkg.com/@google-cloud/common/-/common-0.13.3.tgz#d73ee3fa511f29ffbcc44667898685709e9fec8c" + dependencies: + array-uniq "^1.0.3" + arrify "^1.0.1" + concat-stream "^1.6.0" + create-error-class "^3.0.2" + duplexify "^3.5.0" + ent "^2.2.0" + extend "^3.0.0" + google-auto-auth "^0.6.0" + is "^3.2.0" + log-driver "^1.2.5" + methmeth "^1.1.0" + modelo "^4.2.0" + request "^2.79.0" + retry-request "^2.0.0" + split-array-stream "^1.0.0" + stream-events "^1.0.1" + string-format-obj "^1.1.0" + through2 "^2.0.3" + "@google-cloud/nodejs-repo-tools@1.4.13": version "1.4.13" resolved "https://registry.yarnpkg.com/@google-cloud/nodejs-repo-tools/-/nodejs-repo-tools-1.4.13.tgz#005556d8b93cb29f16018988e466cf0f9dc6d91f" @@ -53,6 +76,27 @@ supertest "3.0.0" yargs "8.0.1" +"@google-cloud/storage@1.1.0": + version "1.1.0" + resolved "https://registry.yarnpkg.com/@google-cloud/storage/-/storage-1.1.0.tgz#5e905a1aed4c196d5ce75dcdb5e4cd7ce29a0860" + dependencies: + "@google-cloud/common" "^0.13.0" + arrify "^1.0.0" + async "^2.0.1" + concat-stream "^1.5.0" + create-error-class "^3.0.2" + duplexify "^3.2.0" + extend "^3.0.0" + gcs-resumable-upload "^0.7.1" + hash-stream-validation "^0.2.1" + is "^3.0.1" + mime-types "^2.0.8" + once "^1.3.1" + pumpify "^1.3.3" + stream-events "^1.0.1" + string-format-obj "^1.0.0" + through2 "^2.0.0" + abbrev@1: version "1.1.0" resolved "https://registry.yarnpkg.com/abbrev/-/abbrev-1.1.0.tgz#d0554c2256636e2f56e7c2e5ad183f859428d81f" @@ -162,7 +206,7 @@ array-union@^1.0.1: dependencies: array-uniq "^1.0.1" -array-uniq@^1.0.1, array-uniq@^1.0.2: +array-uniq@^1.0.1, array-uniq@^1.0.2, array-uniq@^1.0.3: version "1.0.3" resolved "https://registry.yarnpkg.com/array-uniq/-/array-uniq-1.0.3.tgz#af6ac877a25cc7f74e058894753858dfdb24fdb6" @@ -194,6 +238,12 @@ async@^1.4.0: version "1.5.2" resolved "https://registry.yarnpkg.com/async/-/async-1.5.2.tgz#ec6a61ae56480c0c3cb241c95618e20892f9672a" +async@^2.0.1, async@^2.1.2, async@^2.4.0: + version "2.4.0" + resolved "https://registry.yarnpkg.com/async/-/async-2.4.0.tgz#4990200f18ea5b837c2cc4f8c031a6985c385611" + dependencies: + lodash "^4.14.0" + asynckit@^0.4.0: version "0.4.0" resolved "https://registry.yarnpkg.com/asynckit/-/asynckit-0.4.0.tgz#c79ed97f7f34cb8f2ba1bc9790bcc366474b4b79" @@ -597,6 +647,10 @@ balanced-match@^0.4.1: version "0.4.2" resolved "https://registry.yarnpkg.com/balanced-match/-/balanced-match-0.4.2.tgz#cb3f3e3c732dc0f01ee70b403f302e61d7709838" +base64url@2.0.0, base64url@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/base64url/-/base64url-2.0.0.tgz#eac16e03ea1438eff9423d69baa36262ed1f70bb" + bcrypt-pbkdf@^1.0.0: version "1.0.1" resolved "https://registry.yarnpkg.com/bcrypt-pbkdf/-/bcrypt-pbkdf-1.0.1.tgz#63bc5dcb61331b92bc05fd528953c33462a06f8d" @@ -654,6 +708,14 @@ buf-compare@^1.0.0: version "1.0.1" resolved "https://registry.yarnpkg.com/buf-compare/-/buf-compare-1.0.1.tgz#fef28da8b8113a0a0db4430b0b6467b69730b34a" +buffer-equal-constant-time@1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/buffer-equal-constant-time/-/buffer-equal-constant-time-1.0.1.tgz#f8e71132f7ffe6e01a5c9697a4c6f3e48d5cc819" + +buffer-equal@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/buffer-equal/-/buffer-equal-1.0.0.tgz#59616b498304d556abd466966b22eeda3eca5fbe" + buffer-shims@^1.0.0: version "1.0.0" resolved "https://registry.yarnpkg.com/buffer-shims/-/buffer-shims-1.0.0.tgz#9978ce317388c649ad8793028c3477ef044a8b51" @@ -710,6 +772,10 @@ capture-stack-trace@^1.0.0: version "1.0.0" resolved "https://registry.yarnpkg.com/capture-stack-trace/-/capture-stack-trace-1.0.0.tgz#4a6fa07399c26bba47f0b2496b4d0fb408c5550d" +caseless@~0.11.0: + version "0.11.0" + resolved "https://registry.yarnpkg.com/caseless/-/caseless-0.11.0.tgz#715b96ea9841593cc33067923f5ec60ebda4f7d7" + caseless@~0.12.0: version "0.12.0" resolved "https://registry.yarnpkg.com/caseless/-/caseless-0.12.0.tgz#1b681c21ff84033c826543090689420d187151dc" @@ -843,6 +909,12 @@ combined-stream@^1.0.5, combined-stream@~1.0.5: dependencies: delayed-stream "~1.0.0" +commander@^2.9.0: + version "2.9.0" + resolved "https://registry.yarnpkg.com/commander/-/commander-2.9.0.tgz#9c99094176e12240cb22d6c5146098400fe0f7d4" + dependencies: + graceful-readlink ">= 1.0.0" + common-path-prefix@^1.0.0: version "1.0.0" resolved "https://registry.yarnpkg.com/common-path-prefix/-/common-path-prefix-1.0.0.tgz#cd52f6f0712e0baab97d6f9732874f22f47752c0" @@ -859,6 +931,14 @@ concat-map@0.0.1: version "0.0.1" resolved "https://registry.yarnpkg.com/concat-map/-/concat-map-0.0.1.tgz#d8a96bd77fd68df7793a73036a3ba0d5405d477b" +concat-stream@^1.5.0, concat-stream@^1.6.0: + version "1.6.0" + resolved "https://registry.yarnpkg.com/concat-stream/-/concat-stream-1.6.0.tgz#0aac662fd52be78964d5532f694784e70110acf7" + dependencies: + inherits "^2.0.3" + readable-stream "^2.2.2" + typedarray "^0.0.6" + configstore@^3.0.0: version "3.0.0" resolved "https://registry.yarnpkg.com/configstore/-/configstore-3.0.0.tgz#e1b8669c1803ccc50b545e92f8e6e79aa80e0196" @@ -901,7 +981,7 @@ core-util-is@~1.0.0: version "1.0.2" resolved "https://registry.yarnpkg.com/core-util-is/-/core-util-is-1.0.2.tgz#b5fd54220aa2bc5ab57aab7140c940754503c1a7" -create-error-class@^3.0.0: +create-error-class@^3.0.0, create-error-class@^3.0.2: version "3.0.2" resolved "https://registry.yarnpkg.com/create-error-class/-/create-error-class-3.0.2.tgz#06be7abef947a3f14a30fd610671d401bca8b7b6" dependencies: @@ -1013,12 +1093,28 @@ duplexer3@^0.1.4: version "0.1.4" resolved "https://registry.yarnpkg.com/duplexer3/-/duplexer3-0.1.4.tgz#ee01dd1cac0ed3cbc7fdbea37dc0a8f1ce002ce2" +duplexify@^3.1.2, duplexify@^3.2.0, duplexify@^3.5.0: + version "3.5.0" + resolved "https://registry.yarnpkg.com/duplexify/-/duplexify-3.5.0.tgz#1aa773002e1578457e9d9d4a50b0ccaaebcbd604" + dependencies: + end-of-stream "1.0.0" + inherits "^2.0.1" + readable-stream "^2.0.0" + stream-shift "^1.0.0" + ecc-jsbn@~0.1.1: version "0.1.1" resolved "https://registry.yarnpkg.com/ecc-jsbn/-/ecc-jsbn-0.1.1.tgz#0fc73a9ed5f0d53c38193398523ef7e543777505" dependencies: jsbn "~0.1.0" +ecdsa-sig-formatter@1.0.9: + version "1.0.9" + resolved "https://registry.yarnpkg.com/ecdsa-sig-formatter/-/ecdsa-sig-formatter-1.0.9.tgz#4bc926274ec3b5abb5016e7e1d60921ac262b2a1" + dependencies: + base64url "^2.0.0" + safe-buffer "^5.0.1" + empower-core@^0.6.1: version "0.6.1" resolved "https://registry.yarnpkg.com/empower-core/-/empower-core-0.6.1.tgz#6c187f502fcef7554d57933396aac655483772b1" @@ -1026,6 +1122,22 @@ empower-core@^0.6.1: call-signature "0.0.2" core-js "^2.0.0" +end-of-stream@1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/end-of-stream/-/end-of-stream-1.0.0.tgz#d4596e702734a93e40e9af864319eabd99ff2f0e" + dependencies: + once "~1.3.0" + +end-of-stream@^1.1.0: + version "1.4.0" + resolved "https://registry.yarnpkg.com/end-of-stream/-/end-of-stream-1.4.0.tgz#7a90d833efda6cfa6eac0f4949dbb0fad3a63206" + dependencies: + once "^1.4.0" + +ent@^2.2.0: + version "2.2.0" + resolved "https://registry.yarnpkg.com/ent/-/ent-2.2.0.tgz#e964219325a21d05f44466a2f686ed6ce5f5dd1d" + equal-length@^1.0.0: version "1.0.1" resolved "https://registry.yarnpkg.com/equal-length/-/equal-length-1.0.1.tgz#21ca112d48ab24b4e1e7ffc0e5339d31fdfc274c" @@ -1264,6 +1376,35 @@ gauge@~2.7.1: strip-ansi "^3.0.1" wide-align "^1.1.0" +gcp-metadata@^0.1.0: + version "0.1.0" + resolved "https://registry.yarnpkg.com/gcp-metadata/-/gcp-metadata-0.1.0.tgz#abe21f1ea324dd0b34a3f06ca81763fb1eee37d9" + dependencies: + extend "^3.0.0" + retry-request "^1.3.2" + +gcs-resumable-upload@^0.7.1: + version "0.7.6" + resolved "https://registry.yarnpkg.com/gcs-resumable-upload/-/gcs-resumable-upload-0.7.6.tgz#07bcec0656b0541bc6dd0afe0b81a9736ec82a3b" + dependencies: + buffer-equal "^1.0.0" + configstore "^3.0.0" + google-auto-auth "^0.6.0" + pumpify "^1.3.3" + request "^2.61.0" + stream-events "^1.0.1" + through2 "^2.0.0" + +generate-function@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/generate-function/-/generate-function-2.0.0.tgz#6858fe7c0969b7d4e9093337647ac79f60dfbe74" + +generate-object-property@^1.1.0: + version "1.2.0" + resolved "https://registry.yarnpkg.com/generate-object-property/-/generate-object-property-1.2.0.tgz#9c0e1c40308ce804f4783618b937fa88f99d50d0" + dependencies: + is-property "^1.0.0" + get-caller-file@^1.0.1: version "1.0.2" resolved "https://registry.yarnpkg.com/get-caller-file/-/get-caller-file-1.0.2.tgz#f702e63127e7e231c160a80c1554acb70d5047e5" @@ -1331,6 +1472,31 @@ globby@^6.0.0: pify "^2.0.0" pinkie-promise "^2.0.0" +google-auth-library@^0.10.0: + version "0.10.0" + resolved "https://registry.yarnpkg.com/google-auth-library/-/google-auth-library-0.10.0.tgz#6e15babee85fd1dd14d8d128a295b6838d52136e" + dependencies: + gtoken "^1.2.1" + jws "^3.1.4" + lodash.noop "^3.0.1" + request "^2.74.0" + +google-auto-auth@^0.6.0: + version "0.6.1" + resolved "https://registry.yarnpkg.com/google-auto-auth/-/google-auto-auth-0.6.1.tgz#c05d820e9454739ecf28a8892eeab3d1624f2cb3" + dependencies: + async "^2.1.2" + gcp-metadata "^0.1.0" + google-auth-library "^0.10.0" + object-assign "^3.0.0" + request "^2.79.0" + +google-p12-pem@^0.1.0: + version "0.1.2" + resolved "https://registry.yarnpkg.com/google-p12-pem/-/google-p12-pem-0.1.2.tgz#33c46ab021aa734fa0332b3960a9a3ffcb2f3177" + dependencies: + node-forge "^0.7.1" + got@6.7.1, got@^6.7.1: version "6.7.1" resolved "https://registry.yarnpkg.com/got/-/got-6.7.1.tgz#240cd05785a9a18e561dc1b44b41c763ef1e8db0" @@ -1351,6 +1517,19 @@ graceful-fs@^4.1.11, graceful-fs@^4.1.2, graceful-fs@^4.1.6: version "4.1.11" resolved "https://registry.yarnpkg.com/graceful-fs/-/graceful-fs-4.1.11.tgz#0e8bdfe4d1ddb8854d64e04ea7c00e2a026e5658" +"graceful-readlink@>= 1.0.0": + version "1.0.1" + resolved "https://registry.yarnpkg.com/graceful-readlink/-/graceful-readlink-1.0.1.tgz#4cafad76bc62f02fa039b2f94e9a3dd3a391a725" + +gtoken@^1.2.1: + version "1.2.2" + resolved "https://registry.yarnpkg.com/gtoken/-/gtoken-1.2.2.tgz#172776a1a9d96ac09fc22a00f5be83cee6de8820" + dependencies: + google-p12-pem "^0.1.0" + jws "^3.0.0" + mime "^1.2.11" + request "^2.72.0" + handlebars@4.0.8, handlebars@^4.0.3: version "4.0.8" resolved "https://registry.yarnpkg.com/handlebars/-/handlebars-4.0.8.tgz#22b875cd3f0e6cbea30314f144e82bc7a72ff420" @@ -1365,6 +1544,15 @@ har-schema@^1.0.5: version "1.0.5" resolved "https://registry.yarnpkg.com/har-schema/-/har-schema-1.0.5.tgz#d263135f43307c02c602afc8fe95970c0151369e" +har-validator@~2.0.6: + version "2.0.6" + resolved "https://registry.yarnpkg.com/har-validator/-/har-validator-2.0.6.tgz#cdcbc08188265ad119b6a5a7c8ab70eecfb5d27d" + dependencies: + chalk "^1.1.1" + commander "^2.9.0" + is-my-json-valid "^2.12.4" + pinkie-promise "^2.0.0" + har-validator@~4.2.1: version "4.2.1" resolved "https://registry.yarnpkg.com/har-validator/-/har-validator-4.2.1.tgz#33481d0f1bbff600dd203d75812a6a5fba002e2a" @@ -1398,6 +1586,12 @@ has-yarn@^1.0.0: version "1.0.0" resolved "https://registry.yarnpkg.com/has-yarn/-/has-yarn-1.0.0.tgz#89e25db604b725c8f5976fff0addc921b828a5a7" +hash-stream-validation@^0.2.1: + version "0.2.1" + resolved "https://registry.yarnpkg.com/hash-stream-validation/-/hash-stream-validation-0.2.1.tgz#ecc9b997b218be5bb31298628bb807869b73dcd1" + dependencies: + through2 "^2.0.0" + hawk@~3.1.3: version "3.1.3" resolved "https://registry.yarnpkg.com/hawk/-/hawk-3.1.3.tgz#078444bd7c1640b0fe540d2c9b73d59678e8e1c4" @@ -1473,7 +1667,7 @@ inflight@^1.0.4: once "^1.3.0" wrappy "1" -inherits@2, inherits@^2.0.1, inherits@~2.0.0, inherits@~2.0.1: +inherits@2, inherits@^2.0.1, inherits@^2.0.3, inherits@~2.0.0, inherits@~2.0.1: version "2.0.3" resolved "https://registry.yarnpkg.com/inherits/-/inherits-2.0.3.tgz#633c2c83e3da42a502f52466022480f4208261de" @@ -1573,6 +1767,15 @@ is-glob@^2.0.0, is-glob@^2.0.1: dependencies: is-extglob "^1.0.0" +is-my-json-valid@^2.12.4: + version "2.16.0" + resolved "https://registry.yarnpkg.com/is-my-json-valid/-/is-my-json-valid-2.16.0.tgz#f079dd9bfdae65ee2038aae8acbc86ab109e3693" + dependencies: + generate-function "^2.0.0" + generate-object-property "^1.1.0" + jsonpointer "^4.0.0" + xtend "^4.0.0" + is-npm@^1.0.0: version "1.0.0" resolved "https://registry.yarnpkg.com/is-npm/-/is-npm-1.0.0.tgz#f2fb63a65e4905b406c86072765a1a4dc793b9f4" @@ -1613,6 +1816,10 @@ is-promise@^2.1.0: version "2.1.0" resolved "https://registry.yarnpkg.com/is-promise/-/is-promise-2.1.0.tgz#79a2a9ece7f096e80f36d2b2f3bc16c1ff4bf3fa" +is-property@^1.0.0: + version "1.0.2" + resolved "https://registry.yarnpkg.com/is-property/-/is-property-1.0.2.tgz#57fe1c4e48474edd65b09911f26b1cd4095dda84" + is-redirect@^1.0.0: version "1.0.0" resolved "https://registry.yarnpkg.com/is-redirect/-/is-redirect-1.0.0.tgz#1d03dded53bd8db0f30c26e4f95d36fc7c87dc24" @@ -1621,6 +1828,10 @@ is-retry-allowed@^1.0.0: version "1.1.0" resolved "https://registry.yarnpkg.com/is-retry-allowed/-/is-retry-allowed-1.1.0.tgz#11a060568b67339444033d0125a61a20d564fb34" +is-stream-ended@^0.1.0: + version "0.1.3" + resolved "https://registry.yarnpkg.com/is-stream-ended/-/is-stream-ended-0.1.3.tgz#a0473b267c756635486beedc7e3344e549d152ac" + is-stream@^1.0.0, is-stream@^1.1.0: version "1.1.0" resolved "https://registry.yarnpkg.com/is-stream/-/is-stream-1.1.0.tgz#12d4a3dd4e68e0b79ceb8dbc84173ae80d91ca44" @@ -1637,6 +1848,10 @@ is-utf8@^0.2.0, is-utf8@^0.2.1: version "0.2.1" resolved "https://registry.yarnpkg.com/is-utf8/-/is-utf8-0.2.1.tgz#4b0da1442104d1b336340e80797e865cf39f7d72" +is@^3.0.1, is@^3.2.0: + version "3.2.1" + resolved "https://registry.yarnpkg.com/is/-/is-3.2.1.tgz#d0ac2ad55eb7b0bec926a5266f6c662aaa83dca5" + isarray@0.0.1: version "0.0.1" resolved "https://registry.yarnpkg.com/isarray/-/isarray-0.0.1.tgz#8a18acfca9a8f4177e09abfc6038939b05d1eedf" @@ -1828,6 +2043,10 @@ jsonify@~0.0.0: version "0.0.0" resolved "https://registry.yarnpkg.com/jsonify/-/jsonify-0.0.0.tgz#2c74b6ee41d93ca51b7b5aaee8f503631d252a73" +jsonpointer@^4.0.0: + version "4.0.1" + resolved "https://registry.yarnpkg.com/jsonpointer/-/jsonpointer-4.0.1.tgz#4fd92cb34e0e9db3c89c8622ecf51f9b978c6cb9" + jsprim@^1.2.2: version "1.4.0" resolved "https://registry.yarnpkg.com/jsprim/-/jsprim-1.4.0.tgz#a3b87e40298d8c380552d8cc7628a0bb95a22918" @@ -1837,6 +2056,23 @@ jsprim@^1.2.2: json-schema "0.2.3" verror "1.3.6" +jwa@^1.1.4: + version "1.1.5" + resolved "https://registry.yarnpkg.com/jwa/-/jwa-1.1.5.tgz#a0552ce0220742cd52e153774a32905c30e756e5" + dependencies: + base64url "2.0.0" + buffer-equal-constant-time "1.0.1" + ecdsa-sig-formatter "1.0.9" + safe-buffer "^5.0.1" + +jws@^3.0.0, jws@^3.1.4: + version "3.1.4" + resolved "https://registry.yarnpkg.com/jws/-/jws-3.1.4.tgz#f9e8b9338e8a847277d6444b1464f61880e050a2" + dependencies: + base64url "^2.0.0" + jwa "^1.1.4" + safe-buffer "^5.0.1" + kind-of@^3.0.2: version "3.1.0" resolved "https://registry.yarnpkg.com/kind-of/-/kind-of-3.1.0.tgz#475d698a5e49ff5e53d14e3e732429dc8bf4cf47" @@ -1931,10 +2167,18 @@ lodash.merge@^4.6.0: version "4.6.0" resolved "https://registry.yarnpkg.com/lodash.merge/-/lodash.merge-4.6.0.tgz#69884ba144ac33fe699737a6086deffadd0f89c5" -lodash@4.17.4, lodash@^4.2.0: +lodash.noop@^3.0.1: + version "3.0.1" + resolved "https://registry.yarnpkg.com/lodash.noop/-/lodash.noop-3.0.1.tgz#38188f4d650a3a474258439b96ec45b32617133c" + +lodash@4.17.4, lodash@^4.14.0, lodash@^4.2.0: version "4.17.4" resolved "https://registry.yarnpkg.com/lodash/-/lodash-4.17.4.tgz#78203a4d1c328ae1d86dca6460e369b57f4055ae" +log-driver@^1.2.5: + version "1.2.5" + resolved "https://registry.yarnpkg.com/log-driver/-/log-driver-1.2.5.tgz#7ae4ec257302fd790d557cb10c97100d857b0056" + lolex@^1.6.0: version "1.6.0" resolved "https://registry.yarnpkg.com/lolex/-/lolex-1.6.0.tgz#3a9a0283452a47d7439e72731b9e07d7386e49f6" @@ -2024,6 +2268,10 @@ merge-source-map@^1.0.2: dependencies: source-map "^0.5.3" +methmeth@^1.1.0: + version "1.1.0" + resolved "https://registry.yarnpkg.com/methmeth/-/methmeth-1.1.0.tgz#e80a26618e52f5c4222861bb748510bd10e29089" + methods@^1.1.1, methods@~1.1.2: version "1.1.2" resolved "https://registry.yarnpkg.com/methods/-/methods-1.1.2.tgz#5529a4d67654134edcc5266656835b0f851afcee" @@ -2050,13 +2298,13 @@ mime-db@~1.27.0: version "1.27.0" resolved "https://registry.yarnpkg.com/mime-db/-/mime-db-1.27.0.tgz#820f572296bbd20ec25ed55e5b5de869e5436eb1" -mime-types@^2.1.12, mime-types@~2.1.7: +mime-types@^2.0.8, mime-types@^2.1.12, mime-types@~2.1.7: version "2.1.15" resolved "https://registry.yarnpkg.com/mime-types/-/mime-types-2.1.15.tgz#a4ebf5064094569237b8cf70046776d09fc92aed" dependencies: mime-db "~1.27.0" -mime@^1.3.4: +mime@^1.2.11, mime@^1.3.4: version "1.3.4" resolved "https://registry.yarnpkg.com/mime/-/mime-1.3.4.tgz#115f9e3b6b3daf2959983cb38f149a2d40eb5d53" @@ -2084,6 +2332,10 @@ minimist@^1.1.3, minimist@^1.2.0: dependencies: minimist "0.0.8" +modelo@^4.2.0: + version "4.2.0" + resolved "https://registry.yarnpkg.com/modelo/-/modelo-4.2.0.tgz#3b4b420023a66ca7e32bdba16e710937e14d1b0b" + module-not-found-error@^1.0.0: version "1.0.1" resolved "https://registry.yarnpkg.com/module-not-found-error/-/module-not-found-error-1.0.1.tgz#cf8b4ff4f29640674d6cdd02b0e3bc523c2bbdc0" @@ -2117,6 +2369,10 @@ natural-compare@^1.4.0: version "1.4.0" resolved "https://registry.yarnpkg.com/natural-compare/-/natural-compare-1.4.0.tgz#4abebfeed7541f2c27acfb29bdbbd15c8d5ba4f7" +node-forge@^0.7.1: + version "0.7.1" + resolved "https://registry.yarnpkg.com/node-forge/-/node-forge-0.7.1.tgz#9da611ea08982f4b94206b3beb4cc9665f20c300" + node-pre-gyp@^0.6.29: version "0.6.34" resolved "https://registry.yarnpkg.com/node-pre-gyp/-/node-pre-gyp-0.6.34.tgz#94ad1c798a11d7fc67381b50d47f8cc18d9799f7" @@ -2131,6 +2387,10 @@ node-pre-gyp@^0.6.29: tar "^2.2.1" tar-pack "^3.4.0" +node-uuid@~1.4.7: + version "1.4.8" + resolved "https://registry.yarnpkg.com/node-uuid/-/node-uuid-1.4.8.tgz#b040eb0923968afabf8d32fb1f17f1167fdab907" + nopt@^4.0.1: version "4.0.1" resolved "https://registry.yarnpkg.com/nopt/-/nopt-4.0.1.tgz#d0d4685afd5415193c8c7505602d0d17cd64474d" @@ -2214,6 +2474,10 @@ oauth-sign@~0.8.1: version "0.8.2" resolved "https://registry.yarnpkg.com/oauth-sign/-/oauth-sign-0.8.2.tgz#46a6ab7f0aead8deae9ec0565780b7d4efeb9d43" +object-assign@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/object-assign/-/object-assign-3.0.0.tgz#9bedd5ca0897949bca47e7ff408062d549f587f2" + object-assign@^4.0.1, object-assign@^4.1.0: version "4.1.1" resolved "https://registry.yarnpkg.com/object-assign/-/object-assign-4.1.1.tgz#2109adc7965887cfc05cbbd442cac8bfbb360863" @@ -2232,12 +2496,18 @@ observable-to-promise@^0.5.0: is-observable "^0.2.0" symbol-observable "^1.0.4" -once@^1.3.0, once@^1.3.3: +once@^1.3.0, once@^1.3.1, once@^1.3.3, once@^1.4.0: version "1.4.0" resolved "https://registry.yarnpkg.com/once/-/once-1.4.0.tgz#583b1aa775961d4b113ac17d9c50baef9dd76bd1" dependencies: wrappy "1" +once@~1.3.0: + version "1.3.3" + resolved "https://registry.yarnpkg.com/once/-/once-1.3.3.tgz#b2e261557ce4c314ec8304f3fa82663e4297ca20" + dependencies: + wrappy "1" + onetime@^2.0.0: version "2.0.1" resolved "https://registry.yarnpkg.com/onetime/-/onetime-2.0.1.tgz#067428230fd67443b2794b22bba528b6867962d4" @@ -2492,6 +2762,21 @@ pseudomap@^1.0.1: version "1.0.2" resolved "https://registry.yarnpkg.com/pseudomap/-/pseudomap-1.0.2.tgz#f052a28da70e618917ef0a8ac34c1ae5a68286b3" +pump@^1.0.0: + version "1.0.2" + resolved "https://registry.yarnpkg.com/pump/-/pump-1.0.2.tgz#3b3ee6512f94f0e575538c17995f9f16990a5d51" + dependencies: + end-of-stream "^1.1.0" + once "^1.3.1" + +pumpify@^1.3.3: + version "1.3.5" + resolved "https://registry.yarnpkg.com/pumpify/-/pumpify-1.3.5.tgz#1b671c619940abcaeac0ad0e3a3c164be760993b" + dependencies: + duplexify "^3.1.2" + inherits "^2.0.1" + pump "^1.0.0" + punycode@^1.4.1: version "1.4.1" resolved "https://registry.yarnpkg.com/punycode/-/punycode-1.4.1.tgz#c0d5a63b2718800ad8e1eb0fa5269c84dd41845e" @@ -2500,6 +2785,10 @@ qs@^6.1.0, qs@~6.4.0: version "6.4.0" resolved "https://registry.yarnpkg.com/qs/-/qs-6.4.0.tgz#13e26d28ad6b0ffaa91312cd3bf708ed351e7233" +qs@~6.3.0: + version "6.3.2" + resolved "https://registry.yarnpkg.com/qs/-/qs-6.3.2.tgz#e75bd5f6e268122a2a0e0bda630b2550c166502c" + randomatic@^1.1.3: version "1.1.6" resolved "https://registry.yarnpkg.com/randomatic/-/randomatic-1.1.6.tgz#110dcabff397e9dcff7c0789ccc0a49adf1ec5bb" @@ -2546,7 +2835,7 @@ read-pkg@^2.0.0: normalize-package-data "^2.3.2" path-type "^2.0.0" -"readable-stream@^2.0.0 || ^1.1.13", readable-stream@^2.0.2, readable-stream@^2.0.5, readable-stream@^2.1.4, readable-stream@^2.1.5: +readable-stream@^2.0.0, "readable-stream@^2.0.0 || ^1.1.13", readable-stream@^2.0.2, readable-stream@^2.0.5, readable-stream@^2.1.4, readable-stream@^2.1.5, readable-stream@^2.2.2: version "2.2.6" resolved "https://registry.yarnpkg.com/readable-stream/-/readable-stream-2.2.6.tgz#8b43aed76e71483938d12a8d46c6cf1a00b1f816" dependencies: @@ -2649,7 +2938,32 @@ repeating@^2.0.0: dependencies: is-finite "^1.0.0" -request@^2.81.0: +request@2.76.0: + version "2.76.0" + resolved "https://registry.yarnpkg.com/request/-/request-2.76.0.tgz#be44505afef70360a0436955106be3945d95560e" + dependencies: + aws-sign2 "~0.6.0" + aws4 "^1.2.1" + caseless "~0.11.0" + combined-stream "~1.0.5" + extend "~3.0.0" + forever-agent "~0.6.1" + form-data "~2.1.1" + har-validator "~2.0.6" + hawk "~3.1.3" + http-signature "~1.1.0" + is-typedarray "~1.0.0" + isstream "~0.1.2" + json-stringify-safe "~5.0.1" + mime-types "~2.1.7" + node-uuid "~1.4.7" + oauth-sign "~0.8.1" + qs "~6.3.0" + stringstream "~0.0.4" + tough-cookie "~2.3.0" + tunnel-agent "~0.4.1" + +request@^2.61.0, request@^2.72.0, request@^2.74.0, request@^2.79.0, request@^2.81.0: version "2.81.0" resolved "https://registry.yarnpkg.com/request/-/request-2.81.0.tgz#c6928946a0e06c5f8d6f8a9333469ffda46298a0" dependencies: @@ -2709,6 +3023,20 @@ restore-cursor@^2.0.0: onetime "^2.0.0" signal-exit "^3.0.2" +retry-request@^1.3.2: + version "1.3.2" + resolved "https://registry.yarnpkg.com/retry-request/-/retry-request-1.3.2.tgz#59ad24e71f8ae3f312d5f7b4bcf467a5e5a57bd6" + dependencies: + request "2.76.0" + through2 "^2.0.0" + +retry-request@^2.0.0: + version "2.0.1" + resolved "https://registry.yarnpkg.com/retry-request/-/retry-request-2.0.1.tgz#fce3d5cc53e307c7dd1b4a6395bbfac1ea5ae664" + dependencies: + request "^2.81.0" + through2 "^2.0.0" + right-align@^0.1.1: version "0.1.3" resolved "https://registry.yarnpkg.com/right-align/-/right-align-0.1.3.tgz#61339b722fe6a3515689210d24e14c96148613ef" @@ -2841,6 +3169,13 @@ spdx-license-ids@^1.0.2: version "1.2.2" resolved "https://registry.yarnpkg.com/spdx-license-ids/-/spdx-license-ids-1.2.2.tgz#c9df7a3424594ade6bd11900d596696dc06bac57" +split-array-stream@^1.0.0: + version "1.0.3" + resolved "https://registry.yarnpkg.com/split-array-stream/-/split-array-stream-1.0.3.tgz#d2b75a8e5e0d824d52fdec8b8225839dc2e35dfa" + dependencies: + async "^2.4.0" + is-stream-ended "^0.1.0" + sprintf-js@~1.0.2: version "1.0.3" resolved "https://registry.yarnpkg.com/sprintf-js/-/sprintf-js-1.0.3.tgz#04e6926f662895354f3dd015203633b857297e2c" @@ -2864,6 +3199,20 @@ stack-utils@^1.0.0: version "1.0.0" resolved "https://registry.yarnpkg.com/stack-utils/-/stack-utils-1.0.0.tgz#2392cd8ddbd222492ed6c047960f7414b46c0f83" +stream-events@^1.0.1: + version "1.0.2" + resolved "https://registry.yarnpkg.com/stream-events/-/stream-events-1.0.2.tgz#abf39f66c0890a4eb795bc8d5e859b2615b590b2" + dependencies: + stubs "^3.0.0" + +stream-shift@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/stream-shift/-/stream-shift-1.0.0.tgz#d5c752825e5367e786f78e18e445ea223a155952" + +string-format-obj@^1.0.0, string-format-obj@^1.1.0: + version "1.1.0" + resolved "https://registry.yarnpkg.com/string-format-obj/-/string-format-obj-1.1.0.tgz#7635610b1ef397013e8478be98a170e04983d068" + string-width@^1.0.1, string-width@^1.0.2: version "1.0.2" resolved "https://registry.yarnpkg.com/string-width/-/string-width-1.0.2.tgz#118bdf5b8cdc51a2a7e70d211e07e2b0b9b107d3" @@ -2931,6 +3280,10 @@ strip-json-comments@~2.0.1: version "2.0.1" resolved "https://registry.yarnpkg.com/strip-json-comments/-/strip-json-comments-2.0.1.tgz#3c531942e908c2697c0ec344858c286c7ca0a60a" +stubs@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/stubs/-/stubs-3.0.0.tgz#e8d2ba1fa9c90570303c030b6900f7d5f89abe5b" + superagent@^3.0.0: version "3.5.2" resolved "https://registry.yarnpkg.com/superagent/-/superagent-3.5.2.tgz#3361a3971567504c351063abeaae0faa23dbf3f8" @@ -3016,7 +3369,7 @@ text-table@^0.2.0: version "0.2.0" resolved "https://registry.yarnpkg.com/text-table/-/text-table-0.2.0.tgz#7f5ee823ae805207c00af2df4a84ec3fcfa570b4" -through2@^2.0.0: +through2@^2.0.0, through2@^2.0.3: version "2.0.3" resolved "https://registry.yarnpkg.com/through2/-/through2-2.0.3.tgz#0004569b37c7c74ba39c43f3ced78d1ad94140be" dependencies: @@ -3060,6 +3413,10 @@ tunnel-agent@^0.6.0: dependencies: safe-buffer "^5.0.1" +tunnel-agent@~0.4.1: + version "0.4.3" + resolved "https://registry.yarnpkg.com/tunnel-agent/-/tunnel-agent-0.4.3.tgz#6373db76909fe570e08d73583365ed828a74eeeb" + tweetnacl@^0.14.3, tweetnacl@~0.14.0: version "0.14.5" resolved "https://registry.yarnpkg.com/tweetnacl/-/tweetnacl-0.14.5.tgz#5ae68177f192d4456269d108afa93ff8743f4f64" @@ -3068,6 +3425,10 @@ type-detect@^4.0.0: version "4.0.0" resolved "https://registry.yarnpkg.com/type-detect/-/type-detect-4.0.0.tgz#62053883542a321f2f7b25746dc696478b18ff6b" +typedarray@^0.0.6: + version "0.0.6" + resolved "https://registry.yarnpkg.com/typedarray/-/typedarray-0.0.6.tgz#867ac74e3864187b1d3d47d996a78ec5c8830777" + uglify-js@^2.6: version "2.8.22" resolved "https://registry.yarnpkg.com/uglify-js/-/uglify-js-2.8.22.tgz#d54934778a8da14903fa29a326fb24c0ab51a1a0"