From 07cbaae2a584d1c6a87742e11e93eb3415f97f6f Mon Sep 17 00:00:00 2001 From: Jeff Stieler Date: Fri, 18 Jan 2019 14:35:43 -0700 Subject: [PATCH 01/53] Add customers report stats endpoint. --- ...est-reports-customers-stats-controller.php | 352 ++++++++++++++++++ .../includes/class-wc-admin-api-init.php | 5 + ...wc-admin-reports-customers-stats-query.php | 54 +++ ...min-reports-customers-stats-data-store.php | 123 ++++++ 4 files changed, 534 insertions(+) create mode 100644 plugins/woocommerce-admin/includes/api/class-wc-admin-rest-reports-customers-stats-controller.php create mode 100644 plugins/woocommerce-admin/includes/class-wc-admin-reports-customers-stats-query.php create mode 100644 plugins/woocommerce-admin/includes/data-stores/class-wc-admin-reports-customers-stats-data-store.php diff --git a/plugins/woocommerce-admin/includes/api/class-wc-admin-rest-reports-customers-stats-controller.php b/plugins/woocommerce-admin/includes/api/class-wc-admin-rest-reports-customers-stats-controller.php new file mode 100644 index 00000000000..bd28daa23f8 --- /dev/null +++ b/plugins/woocommerce-admin/includes/api/class-wc-admin-rest-reports-customers-stats-controller.php @@ -0,0 +1,352 @@ +prepare_reports_query( $request ); + $customers_query = new WC_Admin_Reports_Customers_Stats_Query( $query_args ); + $report_data = $customers_query->get_data(); + $out_data = array( + 'totals' => $report_data, + 'intervals' => array(), // TODO: is this needed? + ); + + return rest_ensure_response( $out_data ); + } + + /** + * Prepare a report object for serialization. + * + * @param Array $report Report data. + * @param WP_REST_Request $request Request object. + * @return WP_REST_Response + */ + public function prepare_item_for_response( $report, $request ) { + $data = $report; + + $context = ! empty( $request['context'] ) ? $request['context'] : 'view'; + $data = $this->add_additional_fields_to_object( $data, $request ); + $data = $this->filter_response_by_context( $data, $context ); + + // Wrap the data in a response object. + $response = rest_ensure_response( $data ); + + /** + * Filter a report returned from the API. + * + * Allows modification of the report data right before it is returned. + * + * @param WP_REST_Response $response The response object. + * @param object $report The original report object. + * @param WP_REST_Request $request Request used to generate the response. + */ + return apply_filters( 'woocommerce_rest_prepare_report_customers_stats', $response, $report, $request ); + } + + /** + * Get the Report's schema, conforming to JSON Schema. + * + * @return array + */ + public function get_item_schema() { + // TODO: should any of these be 'indicator's? + $totals = array( + 'customers_count' => array( + 'description' => __( 'Number of customers.', 'wc-admin' ), + 'type' => 'integer', + 'context' => array( 'view', 'edit' ), + 'readonly' => true, + ), + 'avg_orders_count' => array( + 'description' => __( 'Average number of orders.', 'wc-admin' ), + 'type' => 'integer', + 'context' => array( 'view', 'edit' ), + 'readonly' => true, + ), + 'avg_total_spend' => array( + 'description' => __( 'Average total spend per customer.', 'wc-admin' ), + 'type' => 'number', + 'context' => array( 'view', 'edit' ), + 'readonly' => true, + 'format' => 'currency', + ), + 'avg_avg_order_value' => array( + 'description' => __( 'Average AOV per customer.', 'wc-admin' ), + 'type' => 'number', + 'context' => array( 'view', 'edit' ), + 'readonly' => true, + 'format' => 'currency', + ), + ); + + $schema = array( + '$schema' => 'http://json-schema.org/draft-04/schema#', + 'title' => 'report_customers_stats', + 'type' => 'object', + 'properties' => array( + 'totals' => array( + 'description' => __( 'Totals data.', 'wc-admin' ), + 'type' => 'object', + 'context' => array( 'view', 'edit' ), + 'readonly' => true, + 'properties' => $totals, + ), + 'intervals' => array( // TODO: remove this? + 'description' => __( 'Reports data grouped by intervals.', 'wc-admin' ), + 'type' => 'array', + 'context' => array( 'view', 'edit' ), + 'readonly' => true, + 'items' => array( + 'type' => 'object', + 'properties' => array( + 'interval' => array( + 'description' => __( 'Type of interval.', 'wc-admin' ), + 'type' => 'string', + 'context' => array( 'view', 'edit' ), + 'readonly' => true, + 'enum' => array( 'day', 'week', 'month', 'year' ), + ), + 'date_start' => array( + 'description' => __( "The date the report start, in the site's timezone.", 'wc-admin' ), + 'type' => 'date-time', + 'context' => array( 'view', 'edit' ), + 'readonly' => true, + ), + 'date_start_gmt' => array( + 'description' => __( 'The date the report start, as GMT.', 'wc-admin' ), + 'type' => 'date-time', + 'context' => array( 'view', 'edit' ), + 'readonly' => true, + ), + 'date_end' => array( + 'description' => __( "The date the report end, in the site's timezone.", 'wc-admin' ), + 'type' => 'date-time', + 'context' => array( 'view', 'edit' ), + 'readonly' => true, + ), + 'date_end_gmt' => array( + 'description' => __( 'The date the report end, as GMT.', 'wc-admin' ), + 'type' => 'date-time', + 'context' => array( 'view', 'edit' ), + 'readonly' => true, + ), + 'subtotals' => array( + 'description' => __( 'Interval subtotals.', 'wc-admin' ), + 'type' => 'object', + 'context' => array( 'view', 'edit' ), + 'readonly' => true, + 'properties' => $totals, + ), + ), + ), + ), + ), + ); + + return $this->add_additional_fields_schema( $schema ); + } + + /** + * Get the query params for collections. + * + * @return array + */ + public function get_collection_params() { + $params = array(); + $params['context'] = $this->get_context_param( array( 'default' => 'view' ) ); + $params['registered_before'] = array( + 'description' => __( 'Limit response to objects registered before (or at) a given ISO8601 compliant datetime.', 'wc-admin' ), + 'type' => 'string', + 'format' => 'date-time', + 'validate_callback' => 'rest_validate_request_arg', + ); + $params['registered_after'] = array( + 'description' => __( 'Limit response to objects registered after (or at) a given ISO8601 compliant datetime.', 'wc-admin' ), + 'type' => 'string', + 'format' => 'date-time', + 'validate_callback' => 'rest_validate_request_arg', + ); + $params['match'] = array( + 'description' => __( 'Indicates whether all the conditions should be true for the resulting set, or if any one of them is sufficient. Match affects the following parameters: status_is, status_is_not, product_includes, product_excludes, coupon_includes, coupon_excludes, customer, categories', 'wc-admin' ), + 'type' => 'string', + 'default' => 'all', + 'enum' => array( + 'all', + 'any', + ), + 'validate_callback' => 'rest_validate_request_arg', + ); + $params['name'] = array( + 'description' => __( 'Limit response to objects with a specfic customer name.', 'wc-admin' ), + 'type' => 'string', + 'validate_callback' => 'rest_validate_request_arg', + ); + $params['username'] = array( + 'description' => __( 'Limit response to objects with a specfic username.', 'wc-admin' ), + 'type' => 'string', + 'validate_callback' => 'rest_validate_request_arg', + ); + $params['email'] = array( + 'description' => __( 'Limit response to objects equal to an email.', 'wc-admin' ), + 'type' => 'string', + 'validate_callback' => 'rest_validate_request_arg', + ); + $params['country'] = array( + 'description' => __( 'Limit response to objects with a specfic country.', 'wc-admin' ), + 'type' => 'string', + 'validate_callback' => 'rest_validate_request_arg', + ); + $params['last_active_before'] = array( + 'description' => __( 'Limit response to objects last active before (or at) a given ISO8601 compliant datetime.', 'wc-admin' ), + 'type' => 'string', + 'format' => 'date-time', + 'validate_callback' => 'rest_validate_request_arg', + ); + $params['last_active_after'] = array( + 'description' => __( 'Limit response to objects last active after (or at) a given ISO8601 compliant datetime.', 'wc-admin' ), + 'type' => 'string', + 'format' => 'date-time', + 'validate_callback' => 'rest_validate_request_arg', + ); + $params['registered_before'] = array( + 'description' => __( 'Limit response to objects registered before (or at) a given ISO8601 compliant datetime.', 'wc-admin' ), + 'type' => 'string', + 'format' => 'date-time', + 'validate_callback' => 'rest_validate_request_arg', + ); + $params['registered_after'] = array( + 'description' => __( 'Limit response to objects registered after (or at) a given ISO8601 compliant datetime.', 'wc-admin' ), + 'type' => 'string', + 'format' => 'date-time', + 'validate_callback' => 'rest_validate_request_arg', + ); + $params['orders_count_min'] = array( + 'description' => __( 'Limit response to objects with an order count greater than or equal to given integer.', 'wc-admin' ), + 'type' => 'integer', + 'sanitize_callback' => 'absint', + 'validate_callback' => 'rest_validate_request_arg', + ); + $params['orders_count_max'] = array( + 'description' => __( 'Limit response to objects with an order count less than or equal to given integer.', 'wc-admin' ), + 'type' => 'integer', + 'sanitize_callback' => 'absint', + 'validate_callback' => 'rest_validate_request_arg', + ); + $params['orders_count_between'] = array( + 'description' => __( 'Limit response to objects with an order count between two given integers.', 'wc-admin' ), + 'type' => 'array', + 'validate_callback' => array( 'WC_Admin_Reports_Interval', 'rest_validate_between_arg' ), + ); + $params['total_spend_min'] = array( + 'description' => __( 'Limit response to objects with a total order spend greater than or equal to given number.', 'wc-admin' ), + 'type' => 'number', + 'validate_callback' => 'rest_validate_request_arg', + ); + $params['total_spend_max'] = array( + 'description' => __( 'Limit response to objects with a total order spend less than or equal to given number.', 'wc-admin' ), + 'type' => 'number', + 'validate_callback' => 'rest_validate_request_arg', + ); + $params['total_spend_between'] = array( + 'description' => __( 'Limit response to objects with a total order spend between two given numbers.', 'wc-admin' ), + 'type' => 'array', + 'validate_callback' => array( 'WC_Admin_Reports_Interval', 'rest_validate_between_arg' ), + ); + $params['avg_order_value_min'] = array( + 'description' => __( 'Limit response to objects with an average order spend greater than or equal to given number.', 'wc-admin' ), + 'type' => 'number', + 'validate_callback' => 'rest_validate_request_arg', + ); + $params['avg_order_value_max'] = array( + 'description' => __( 'Limit response to objects with an average order spend less than or equal to given number.', 'wc-admin' ), + 'type' => 'number', + 'validate_callback' => 'rest_validate_request_arg', + ); + $params['avg_order_value_between'] = array( + 'description' => __( 'Limit response to objects with an average order spend between two given numbers.', 'wc-admin' ), + 'type' => 'array', + 'validate_callback' => array( 'WC_Admin_Reports_Interval', 'rest_validate_between_arg' ), + ); + $params['last_order_before'] = array( + 'description' => __( 'Limit response to objects with last order before (or at) a given ISO8601 compliant datetime.', 'wc-admin' ), + 'type' => 'string', + 'format' => 'date-time', + 'validate_callback' => 'rest_validate_request_arg', + ); + $params['last_order_after'] = array( + 'description' => __( 'Limit response to objects with last order after (or at) a given ISO8601 compliant datetime.', 'wc-admin' ), + 'type' => 'string', + 'format' => 'date-time', + 'validate_callback' => 'rest_validate_request_arg', + ); + + return $params; + } +} diff --git a/plugins/woocommerce-admin/includes/class-wc-admin-api-init.php b/plugins/woocommerce-admin/includes/class-wc-admin-api-init.php index 4cfdffd9ff2..5af36a6cbdc 100644 --- a/plugins/woocommerce-admin/includes/class-wc-admin-api-init.php +++ b/plugins/woocommerce-admin/includes/class-wc-admin-api-init.php @@ -125,6 +125,7 @@ class WC_Admin_Api_Init { require_once dirname( __FILE__ ) . '/class-wc-admin-reports-downloads-query.php'; require_once dirname( __FILE__ ) . '/class-wc-admin-reports-downloads-stats-query.php'; require_once dirname( __FILE__ ) . '/class-wc-admin-reports-customers-query.php'; + require_once dirname( __FILE__ ) . '/class-wc-admin-reports-customers-stats-query.php'; // Data stores. require_once dirname( __FILE__ ) . '/data-stores/class-wc-admin-reports-data-store.php'; @@ -141,6 +142,7 @@ class WC_Admin_Api_Init { require_once dirname( __FILE__ ) . '/data-stores/class-wc-admin-reports-downloads-data-store.php'; require_once dirname( __FILE__ ) . '/data-stores/class-wc-admin-reports-downloads-stats-data-store.php'; require_once dirname( __FILE__ ) . '/data-stores/class-wc-admin-reports-customers-data-store.php'; + require_once dirname( __FILE__ ) . '/data-stores/class-wc-admin-reports-customers-stats-data-store.php'; // Data triggers. require_once dirname( __FILE__ ) . '/data-stores/class-wc-admin-notes-data-store.php'; @@ -169,6 +171,7 @@ class WC_Admin_Api_Init { require_once dirname( __FILE__ ) . '/api/class-wc-admin-rest-reports-coupons-controller.php'; require_once dirname( __FILE__ ) . '/api/class-wc-admin-rest-reports-coupons-stats-controller.php'; require_once dirname( __FILE__ ) . '/api/class-wc-admin-rest-reports-customers-controller.php'; + require_once dirname( __FILE__ ) . '/api/class-wc-admin-rest-reports-customers-stats-controller.php'; require_once dirname( __FILE__ ) . '/api/class-wc-admin-rest-reports-downloads-controller.php'; require_once dirname( __FILE__ ) . '/api/class-wc-admin-rest-reports-downloads-files-controller.php'; require_once dirname( __FILE__ ) . '/api/class-wc-admin-rest-reports-downloads-stats-controller.php'; @@ -212,6 +215,7 @@ class WC_Admin_Api_Init { 'WC_Admin_REST_Reports_Downloads_Controller', 'WC_Admin_REST_Reports_Downloads_Stats_Controller', 'WC_Admin_REST_Reports_Customers_Controller', + 'WC_Admin_REST_Reports_Customers_Stats_Controller', ) ); @@ -618,6 +622,7 @@ class WC_Admin_Api_Init { 'report-downloads-stats' => 'WC_Admin_Reports_Downloads_Stats_Data_Store', 'admin-note' => 'WC_Admin_Notes_Data_Store', 'report-customers' => 'WC_Admin_Reports_Customers_Data_Store', + 'report-customers-stats' => 'WC_Admin_Reports_Customers_Stats_Data_Store', ) ); } diff --git a/plugins/woocommerce-admin/includes/class-wc-admin-reports-customers-stats-query.php b/plugins/woocommerce-admin/includes/class-wc-admin-reports-customers-stats-query.php new file mode 100644 index 00000000000..c9c34b0ba84 --- /dev/null +++ b/plugins/woocommerce-admin/includes/class-wc-admin-reports-customers-stats-query.php @@ -0,0 +1,54 @@ + '2018-07-19 00:00:00', + * 'registered_after' => '2018-07-05 00:00:00', + * 'page' => 2, + * 'avg_order_value_min' => 100, + * 'country' => 'GB', + * ); + * $report = new WC_Admin_Reports_Customers_Stats_Query( $args ); + * $mydata = $report->get_data(); + * + * @package WooCommerce Admin/Classes + */ + +defined( 'ABSPATH' ) || exit; + +/** + * WC_Admin_Reports_Customers_Stats_Query + */ +class WC_Admin_Reports_Customers_Stats_Query extends WC_Admin_Reports_Query { + + /** + * Valid fields for Customers report. + * + * @return array + */ + protected function get_default_query_vars() { + return array( + 'per_page' => get_option( 'posts_per_page' ), // not sure if this should be the default. + 'page' => 1, + 'order' => 'DESC', + 'orderby' => 'date_registered', + 'fields' => '*', // TODO: needed? + ); + } + + /** + * Get product data based on the current query vars. + * + * @return array + */ + public function get_data() { + $args = apply_filters( 'woocommerce_reports_customers_stats_query_args', $this->get_query_vars() ); + + $data_store = WC_Data_Store::load( 'report-customers-stats' ); + $results = $data_store->get_data( $args ); + return apply_filters( 'woocommerce_reports_customers_stats_select_query', $results, $args ); + } + +} diff --git a/plugins/woocommerce-admin/includes/data-stores/class-wc-admin-reports-customers-stats-data-store.php b/plugins/woocommerce-admin/includes/data-stores/class-wc-admin-reports-customers-stats-data-store.php new file mode 100644 index 00000000000..dbf4392c899 --- /dev/null +++ b/plugins/woocommerce-admin/includes/data-stores/class-wc-admin-reports-customers-stats-data-store.php @@ -0,0 +1,123 @@ + 'intval', + 'avg_orders_count' => 'floatval', + 'avg_total_spend' => 'floatval', + 'avg_avg_order_value' => 'floatval', + ); + + /** + * SQL columns to select in the db query and their mapping to SQL code. + * + * @var array + */ + protected $report_columns = array( + 'customers_count' => 'COUNT( * ) as customers_count', + 'avg_orders_count' => 'AVG( orders_count ) as avg_orders_count', + 'avg_total_spend' => 'AVG( total_spend ) as avg_total_spend', + 'avg_avg_order_value' => 'AVG( avg_order_value ) as avg_avg_order_value', + ); + + /** + * Constructor. + */ + public function __construct() { + // This space intentionally left blank (to avoid parent constructor). + } + + /** + * Returns the report data based on parameters supplied by the user. + * + * @param array $query_args Query parameters. + * @return stdClass|WP_Error Data. + */ + public function get_data( $query_args ) { + global $wpdb; + + $customers_table_name = $wpdb->prefix . self::TABLE_NAME; + + // These defaults are only partially applied when used via REST API, as that has its own defaults. + $defaults = array( + 'per_page' => get_option( 'posts_per_page' ), + 'page' => 1, + 'order' => 'DESC', + 'orderby' => 'date_registered', + 'fields' => '*', + ); + $query_args = wp_parse_args( $query_args, $defaults ); + $cache_key = $this->get_cache_key( $query_args ); + $data = wp_cache_get( $cache_key, $this->cache_group ); + + if ( false === $data ) { + $data = (object) array( + 'customers_count' => 0, + 'avg_orders_count' => 0, + 'avg_total_spend' => 0.0, + 'avg_avg_order_value' => 0.0, + ); + + $selections = $this->selected_columns( $query_args ); + $sql_query_params = $this->get_sql_query_params( $query_args ); + + $report_data = $wpdb->get_results( + "SELECT {$selections} FROM + ( + SELECT + COUNT( order_id ) as orders_count, + SUM( gross_total ) as total_spend, + ( SUM( gross_total ) / COUNT( order_id ) ) as avg_order_value + FROM + {$customers_table_name} + {$sql_query_params['from_clause']} + WHERE + 1=1 + {$sql_query_params['where_time_clause']} + {$sql_query_params['where_clause']} + GROUP BY + {$customers_table_name}.customer_id + HAVING + 1=1 + {$sql_query_params['having_clause']} + ) as tt", + ARRAY_A + ); // WPCS: cache ok, DB call ok, unprepared SQL ok. + + if ( null === $report_data ) { + return $data; + } + + $data = (object) $this->cast_numbers( $report_data[0] ); + + wp_cache_set( $cache_key, $data, $this->cache_group ); + } + + return $data; + } + + /** + * Returns string to be used as cache key for the data. + * + * @param array $params Query parameters. + * @return string + */ + protected function get_cache_key( $params ) { + return 'woocommerce_' . self::TABLE_NAME . '_stats_' . md5( wp_json_encode( $params ) ); + } +} From 4a6f2652b603e9287420d6b4c99ca79001640bb3 Mon Sep 17 00:00:00 2001 From: Jeff Stieler Date: Mon, 21 Jan 2019 08:46:21 -0700 Subject: [PATCH 02/53] Hook customers report table summary up to stats endpoint. --- .../analytics/report/customers/table.js | 26 +++++++++++++++++++ .../client/wc-api/reports/stats/operations.js | 11 +++++++- ...est-reports-customers-stats-controller.php | 3 ++- 3 files changed, 38 insertions(+), 2 deletions(-) diff --git a/plugins/woocommerce-admin/client/analytics/report/customers/table.js b/plugins/woocommerce-admin/client/analytics/report/customers/table.js index 497cdb53631..3d58782d0cd 100644 --- a/plugins/woocommerce-admin/client/analytics/report/customers/table.js +++ b/plugins/woocommerce-admin/client/analytics/report/customers/table.js @@ -25,6 +25,7 @@ export default class CustomersReportTable extends Component { this.getHeadersContent = this.getHeadersContent.bind( this ); this.getRowsContent = this.getRowsContent.bind( this ); + this.getSummary = this.getSummary.bind( this ); } getHeadersContent() { @@ -187,6 +188,30 @@ export default class CustomersReportTable extends Component { } ); } + getSummary( totals ) { + if ( ! totals ) { + return []; + } + return [ + { + label: __( 'customers', 'wc-admin' ), + value: numberFormat( totals.customers_count ), + }, + { + label: __( 'average orders', 'wc-admin' ), + value: numberFormat( totals.avg_orders_count ), + }, + { + label: __( 'average lifetime spend', 'wc-admin' ), + value: formatCurrency( totals.avg_total_spend ), + }, + { + label: __( 'average order value', 'wc-admin' ), + value: formatCurrency( totals.avg_avg_order_value ), + }, + ]; + } + render() { const { query } = this.props; @@ -195,6 +220,7 @@ export default class CustomersReportTable extends Component { endpoint="customers" getHeadersContent={ this.getHeadersContent } getRowsContent={ this.getRowsContent } + getSummary={ this.getSummary } itemIdField="id" query={ query } labels={ { placeholder: __( 'Search by customer name', 'wc-admin' ) } } diff --git a/plugins/woocommerce-admin/client/wc-api/reports/stats/operations.js b/plugins/woocommerce-admin/client/wc-api/reports/stats/operations.js index 5d0d8876be3..97193986cd9 100644 --- a/plugins/woocommerce-admin/client/wc-api/reports/stats/operations.js +++ b/plugins/woocommerce-admin/client/wc-api/reports/stats/operations.js @@ -16,7 +16,15 @@ import { getResourceIdentifier, getResourcePrefix } from '../../utils'; import { NAMESPACE } from '../../constants'; import { SWAGGERNAMESPACE } from 'store/constants'; -const statEndpoints = [ 'coupons', 'downloads', 'orders', 'products', 'revenue', 'taxes' ]; +const statEndpoints = [ + 'coupons', + 'downloads', + 'orders', + 'products', + 'revenue', + 'taxes', + 'customers', +]; // TODO: Remove once swagger endpoints are phased out. const swaggerEndpoints = [ 'categories' ]; @@ -28,6 +36,7 @@ const typeEndpointMap = { 'report-stats-query-downloads': 'downloads', 'report-stats-query-coupons': 'coupons', 'report-stats-query-taxes': 'taxes', + 'report-stats-query-customers': 'customers', }; function read( resourceNames, fetch = apiFetch ) { diff --git a/plugins/woocommerce-admin/includes/api/class-wc-admin-rest-reports-customers-stats-controller.php b/plugins/woocommerce-admin/includes/api/class-wc-admin-rest-reports-customers-stats-controller.php index bd28daa23f8..af24ea6119d 100644 --- a/plugins/woocommerce-admin/includes/api/class-wc-admin-rest-reports-customers-stats-controller.php +++ b/plugins/woocommerce-admin/includes/api/class-wc-admin-rest-reports-customers-stats-controller.php @@ -75,7 +75,8 @@ class WC_Admin_REST_Reports_Customers_Stats_Controller extends WC_REST_Reports_C $report_data = $customers_query->get_data(); $out_data = array( 'totals' => $report_data, - 'intervals' => array(), // TODO: is this needed? + // TODO: is this needed? the single element array tricks the isReportDataEmpty() selector. + 'intervals' => array( (object) array() ), ); return rest_ensure_response( $out_data ); From 2d4aea19713b05d456fe66bc9af0db08ac944d95 Mon Sep 17 00:00:00 2001 From: Jeff Stieler Date: Tue, 22 Jan 2019 10:44:00 -0700 Subject: [PATCH 03/53] Only install/activate Gutenberg plugin if WP version under test is earlier than 5.0. --- plugins/woocommerce-admin/bin/install-wp-tests.sh | 8 ++++++-- plugins/woocommerce-admin/tests/bootstrap.php | 4 +++- 2 files changed, 9 insertions(+), 3 deletions(-) diff --git a/plugins/woocommerce-admin/bin/install-wp-tests.sh b/plugins/woocommerce-admin/bin/install-wp-tests.sh index 2f4867f336e..b88529cd819 100755 --- a/plugins/woocommerce-admin/bin/install-wp-tests.sh +++ b/plugins/woocommerce-admin/bin/install-wp-tests.sh @@ -168,8 +168,12 @@ install_deps() { php wp-cli.phar core config --dbname=$DB_NAME --dbuser=$DB_USER --dbpass=$DB_PASS --dbhost=$DB_HOST --dbprefix=wptests_ php wp-cli.phar core install --url="$WP_SITE_URL" --title="Example" --admin_user=admin --admin_password=password --admin_email=info@example.com --path=$WP_CORE_DIR --skip-email - # Install Gutenberg - php wp-cli.phar plugin install gutenberg --activate + # Install Gutenberg if WP < 5 + if [[ $WP_VERSION =~ ^([0-9]+)[0-9\.]+\-? ]]; then + if [ "5" -gt "${BASH_REMATCH[1]}" ]; then + php wp-cli.phar plugin install gutenberg --activate + fi + fi # Install WooCommerce cd "wp-content/plugins/" diff --git a/plugins/woocommerce-admin/tests/bootstrap.php b/plugins/woocommerce-admin/tests/bootstrap.php index 616c248cb18..bc8866a4c6b 100755 --- a/plugins/woocommerce-admin/tests/bootstrap.php +++ b/plugins/woocommerce-admin/tests/bootstrap.php @@ -94,7 +94,9 @@ function wc_test_includes() { * Manually load the plugin being tested. */ function _manually_load_plugin() { - require dirname( dirname( dirname( __FILE__ ) ) ) . '/gutenberg/gutenberg.php'; + if ( version_compare( $GLOBALS['wp_version'], '4.9.9', '<=' ) ) { // < 5.0 fails for "5.0-alpha-12345-src + require dirname( dirname( dirname( __FILE__ ) ) ) . '/gutenberg/gutenberg.php'; + } define( 'WC_TAX_ROUNDING_MODE', 'auto' ); define( 'WC_USE_TRANSACTIONS', false ); From e7a20b421697159079376fde6b1f57d3245ff8e4 Mon Sep 17 00:00:00 2001 From: David Levin Date: Wed, 23 Jan 2019 09:51:12 -0800 Subject: [PATCH 04/53] update column lifetime spend column label, and re-order columns --- .../analytics/report/customers/table.js | 22 +++++++++---------- 1 file changed, 11 insertions(+), 11 deletions(-) diff --git a/plugins/woocommerce-admin/client/analytics/report/customers/table.js b/plugins/woocommerce-admin/client/analytics/report/customers/table.js index 497cdb53631..1e62051e76a 100644 --- a/plugins/woocommerce-admin/client/analytics/report/customers/table.js +++ b/plugins/woocommerce-admin/client/analytics/report/customers/table.js @@ -41,10 +41,15 @@ export default class CustomersReportTable extends Component { key: 'username', hiddenByDefault: true, }, + { + label: __( 'Last Active', 'wc-admin' ), + key: 'date_last_active', + defaultSort: true, + isSortable: true, + }, { label: __( 'Sign Up', 'wc-admin' ), key: 'date_registered', - defaultSort: true, isSortable: true, }, { @@ -58,7 +63,7 @@ export default class CustomersReportTable extends Component { isNumeric: true, }, { - label: __( 'Lifetime Spend', 'wc-admin' ), + label: __( 'Total Spend', 'wc-admin' ), key: 'total_spend', isSortable: true, isNumeric: true, @@ -69,11 +74,6 @@ export default class CustomersReportTable extends Component { key: 'avg_order_value', isNumeric: true, }, - { - label: __( 'Last Active', 'wc-admin' ), - key: 'date_last_active', - isSortable: true, - }, { label: __( 'Country', 'wc-admin' ), key: 'country', @@ -147,6 +147,10 @@ export default class CustomersReportTable extends Component { display: username, value: username, }, + { + display: , + value: date_last_active, + }, { display: dateRegistered, value: date_registered, @@ -167,10 +171,6 @@ export default class CustomersReportTable extends Component { display: formatCurrency( avg_order_value ), value: getCurrencyFormatDecimal( avg_order_value ), }, - { - display: , - value: date_last_active, - }, { display: countryDisplay, value: country, From 4c1826740879d305781a0ec7fc35f3b4da7829c7 Mon Sep 17 00:00:00 2001 From: David Levin Date: Wed, 23 Jan 2019 10:08:27 -0800 Subject: [PATCH 05/53] update orderby in index --- .../client/analytics/report/customers/index.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/plugins/woocommerce-admin/client/analytics/report/customers/index.js b/plugins/woocommerce-admin/client/analytics/report/customers/index.js index 7b68ebaee8b..1641d6a6aab 100644 --- a/plugins/woocommerce-admin/client/analytics/report/customers/index.js +++ b/plugins/woocommerce-admin/client/analytics/report/customers/index.js @@ -20,7 +20,7 @@ export default class CustomersReport extends Component { render() { const { query, path } = this.props; const tableQuery = { - orderby: 'date_registered', + orderby: 'date_last_active', order: 'desc', ...query, }; From 4cfa082d0f9185527b1134ac80f2e459663d7d03 Mon Sep 17 00:00:00 2001 From: Jeff Stieler Date: Wed, 23 Jan 2019 16:59:10 -0700 Subject: [PATCH 06/53] Load gutenberg from test plugins directory if required. --- plugins/woocommerce-admin/tests/bootstrap.php | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/plugins/woocommerce-admin/tests/bootstrap.php b/plugins/woocommerce-admin/tests/bootstrap.php index bc8866a4c6b..55caa41ce7d 100755 --- a/plugins/woocommerce-admin/tests/bootstrap.php +++ b/plugins/woocommerce-admin/tests/bootstrap.php @@ -95,7 +95,13 @@ function wc_test_includes() { */ function _manually_load_plugin() { if ( version_compare( $GLOBALS['wp_version'], '4.9.9', '<=' ) ) { // < 5.0 fails for "5.0-alpha-12345-src - require dirname( dirname( dirname( __FILE__ ) ) ) . '/gutenberg/gutenberg.php'; + $_tests_wp_core_dir = getenv( 'WP_CORE_DIR' ); + + if ( ! $_tests_wp_core_dir ) { + $_tests_wp_core_dir = rtrim( sys_get_temp_dir(), '/\\' ) . '/wordpress'; + } + + require $_tests_wp_core_dir . '/wp-content/plugins/gutenberg/gutenberg.php'; } define( 'WC_TAX_ROUNDING_MODE', 'auto' ); From 6a215ceca959255562c8f21c8feacf1c8cee623d Mon Sep 17 00:00:00 2001 From: Jeff Stieler Date: Wed, 23 Jan 2019 17:47:44 -0700 Subject: [PATCH 07/53] Exclude customers with no orders from average orders count calculation. --- .../class-wc-admin-reports-customers-stats-data-store.php | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/plugins/woocommerce-admin/includes/data-stores/class-wc-admin-reports-customers-stats-data-store.php b/plugins/woocommerce-admin/includes/data-stores/class-wc-admin-reports-customers-stats-data-store.php index dbf4392c899..66133fe0edd 100644 --- a/plugins/woocommerce-admin/includes/data-stores/class-wc-admin-reports-customers-stats-data-store.php +++ b/plugins/woocommerce-admin/includes/data-stores/class-wc-admin-reports-customers-stats-data-store.php @@ -80,7 +80,12 @@ class WC_Admin_Reports_Customers_Stats_Data_Store extends WC_Admin_Reports_Custo "SELECT {$selections} FROM ( SELECT - COUNT( order_id ) as orders_count, + ( + CASE WHEN COUNT( order_id ) = 0 + THEN NULL + ELSE COUNT( order_id ) + END + ) as orders_count, SUM( gross_total ) as total_spend, ( SUM( gross_total ) / COUNT( order_id ) ) as avg_order_value FROM From 8207bd7649bd2bec93b31d3a52b40b70ac40878f Mon Sep 17 00:00:00 2001 From: Jeff Stieler Date: Wed, 23 Jan 2019 17:48:22 -0700 Subject: [PATCH 08/53] Add tests for customers report stats endpoint. --- .../tests/api/reports-customers-stats.php | 171 ++++++++++++++++++ 1 file changed, 171 insertions(+) create mode 100644 plugins/woocommerce-admin/tests/api/reports-customers-stats.php diff --git a/plugins/woocommerce-admin/tests/api/reports-customers-stats.php b/plugins/woocommerce-admin/tests/api/reports-customers-stats.php new file mode 100644 index 00000000000..316cf2613b8 --- /dev/null +++ b/plugins/woocommerce-admin/tests/api/reports-customers-stats.php @@ -0,0 +1,171 @@ +user = $this->factory->user->create( + array( + 'role' => 'administrator', + ) + ); + } + + /** + * Test route registration. + * + * @since 3.5.0 + */ + public function _test_register_routes() { + $routes = $this->server->get_routes(); + + $this->assertArrayHasKey( $this->endpoint, $routes ); + } + + /** + * Test reports schema. + * + * @since 3.5.0 + */ + public function test_reports_schema() { + wp_set_current_user( $this->user ); + + $request = new WP_REST_Request( 'OPTIONS', $this->endpoint ); + $response = $this->server->dispatch( $request ); + $data = $response->get_data(); + $properties = $data['schema']['properties']; + + $this->assertCount( 2, $properties ); + $this->assertArrayHasKey( 'totals', $properties ); + $this->assertArrayHasKey( 'intervals', $properties ); + $this->assertCount( 4, $properties['totals']['properties'] ); + $this->assertArrayHasKey( 'customers_count', $properties['totals']['properties'] ); + $this->assertArrayHasKey( 'avg_orders_count', $properties['totals']['properties'] ); + $this->assertArrayHasKey( 'avg_total_spend', $properties['totals']['properties'] ); + $this->assertArrayHasKey( 'avg_avg_order_value', $properties['totals']['properties'] ); + } + + /** + * Test getting reports without valid permissions. + * + * @since 3.5.0 + */ + public function test_get_reports_without_permission() { + wp_set_current_user( 0 ); + $response = $this->server->dispatch( new WP_REST_Request( 'GET', $this->endpoint ) ); + $this->assertEquals( 401, $response->get_status() ); + } + + /** + * Test getting reports. + * + * @since 3.5.0 + */ + public function test_get_reports() { + wp_set_current_user( $this->user ); + WC_Helper_Reports::reset_stats_dbs(); + + $test_customers = array(); + + // Create 10 test customers. + for ( $i = 1; $i <= 10; $i++ ) { + $test_customers[] = WC_Helper_Customer::create_customer( "customer{$i}", 'password', "customer{$i}@example.com" ); + } + // One differing name. + $test_customers[2]->set_first_name( 'Jeff' ); + $test_customers[2]->save(); + + // Create a test product for use in an order. + $product = new WC_Product_Simple(); + $product->set_name( 'Test Product' ); + $product->set_regular_price( 25 ); + $product->save(); + + // Place some test orders. + $order = WC_Helper_Order::create_order( $test_customers[0]->get_id(), $product ); + $order->set_status( 'completed' ); + $order->set_total( 100 ); + $order->save(); + + $order = WC_Helper_Order::create_order( $test_customers[0]->get_id(), $product ); + $order->set_status( 'completed' ); + $order->set_total( 234 ); + $order->save(); + + $order = WC_Helper_Order::create_order( $test_customers[1]->get_id(), $product ); + $order->set_status( 'completed' ); + $order->set_total( 55 ); + $order->save(); + + $order = WC_Helper_Order::create_order( $test_customers[2]->get_id(), $product ); + $order->set_status( 'completed' ); + $order->set_total( 9.12 ); + $order->save(); + + $request = new WP_REST_Request( 'GET', $this->endpoint ); + $response = $this->server->dispatch( $request ); + $reports = $response->get_data(); + $headers = $response->get_headers(); + + $this->assertEquals( 200, $response->get_status() ); + $this->assertEquals( 10, $reports['totals']->customers_count ); + $this->assertEquals( 1.333, round( $reports['totals']->avg_orders_count, 3 ) ); + $this->assertEquals( 132.707, round( $reports['totals']->avg_total_spend, 3 ) ); + $this->assertEquals( 77.04, $reports['totals']->avg_avg_order_value ); + + // Test name parameter (case with no matches). + $request->set_query_params( + array( + 'name' => 'Nota Customername', + ) + ); + $response = $this->server->dispatch( $request ); + $reports = $response->get_data(); + + $this->assertEquals( 200, $response->get_status() ); + $this->assertEquals( 0, $reports['totals']->customers_count ); + $this->assertEquals( 0, $reports['totals']->avg_orders_count ); + $this->assertEquals( 0, $reports['totals']->avg_total_spend ); + $this->assertEquals( 0, $reports['totals']->avg_avg_order_value ); + + // Test name and last_order parameters. + $request->set_query_params( + array( + 'name' => 'Jeff', + 'last_order_after' => date( 'Y-m-d' ) . 'T00:00:00Z', + ) + ); + $response = $this->server->dispatch( $request ); + $reports = $response->get_data(); + + $this->assertEquals( 200, $response->get_status() ); + $this->assertEquals( 1, $reports['totals']->customers_count ); + $this->assertEquals( 1, $reports['totals']->avg_orders_count ); + $this->assertEquals( 9.12, $reports['totals']->avg_total_spend ); + $this->assertEquals( 9.12, $reports['totals']->avg_avg_order_value ); + } +} From 050438a11c8fdcd4def10ef9fb759070e3045743 Mon Sep 17 00:00:00 2001 From: Paul Sealock Date: Tue, 22 Jan 2019 15:18:55 +1300 Subject: [PATCH 09/53] Add emoji flags --- .../header/activity-panel/panels/orders.js | 2 +- plugins/woocommerce-admin/package-lock.json | 107 ++++++++++++++---- plugins/woocommerce-admin/package.json | 2 +- .../packages/components/src/flag/example.md | 20 +++- .../packages/components/src/flag/index.js | 56 ++++----- .../packages/components/src/flag/style.scss | 15 ++- .../src/search/autocompleters/countries.js | 4 +- .../packages/components/src/search/style.scss | 5 +- plugins/woocommerce-admin/wc-admin.php | 6 + 9 files changed, 140 insertions(+), 77 deletions(-) diff --git a/plugins/woocommerce-admin/client/header/activity-panel/panels/orders.js b/plugins/woocommerce-admin/client/header/activity-panel/panels/orders.js index 5dd9d83787b..c1c4b2b4b62 100644 --- a/plugins/woocommerce-admin/client/header/activity-panel/panels/orders.js +++ b/plugins/woocommerce-admin/client/header/activity-panel/panels/orders.js @@ -85,7 +85,7 @@ function OrdersPanel( { orders, isRequesting, isError } ) { orderLink: , // @TODO: Hook up customer name link customerLink: , - destinationFlag: , + destinationFlag: , }, } ) } diff --git a/plugins/woocommerce-admin/package-lock.json b/plugins/woocommerce-admin/package-lock.json index 75e91db1f65..326cca17a77 100644 --- a/plugins/woocommerce-admin/package-lock.json +++ b/plugins/woocommerce-admin/package-lock.json @@ -5081,8 +5081,7 @@ "clone": { "version": "1.0.4", "resolved": "https://registry.npmjs.org/clone/-/clone-1.0.4.tgz", - "integrity": "sha1-2jCcwmPfFZlMaIypAheco8fNfH4=", - "dev": true + "integrity": "sha1-2jCcwmPfFZlMaIypAheco8fNfH4=" }, "clone-deep": { "version": "2.0.2", @@ -6808,7 +6807,6 @@ "version": "1.0.3", "resolved": "https://registry.npmjs.org/defaults/-/defaults-1.0.3.tgz", "integrity": "sha1-xlYFHpgX2f8I7YgUd/P+QBnz730=", - "dev": true, "requires": { "clone": "^1.0.2" } @@ -7375,6 +7373,39 @@ "minimalistic-crypto-utils": "^1.0.0" } }, + "emoji-flags": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/emoji-flags/-/emoji-flags-1.2.0.tgz", + "integrity": "sha1-VrZGKUwYmoo/jRIjOfqIJqSgDO8=", + "requires": { + "columnify": "1.5.1", + "lodash.find": "3.2.1" + }, + "dependencies": { + "ansi-regex": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-1.1.1.tgz", + "integrity": "sha1-QchHGUZGN15qGl0Qw8oFTvn8mA0=" + }, + "columnify": { + "version": "1.5.1", + "resolved": "https://registry.npmjs.org/columnify/-/columnify-1.5.1.tgz", + "integrity": "sha1-Ff3agDo4dfh/nTArO8goky1mQAM=", + "requires": { + "strip-ansi": "^2.0.1", + "wcwidth": "^1.0.0" + } + }, + "strip-ansi": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-2.0.1.tgz", + "integrity": "sha1-32LBqpTtLxFOHQ8h/R1QSCt5pg4=", + "requires": { + "ansi-regex": "^1.0.0" + } + } + } + }, "emoji-regex": { "version": "6.5.1", "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-6.5.1.tgz", @@ -12920,6 +12951,35 @@ "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.11.tgz", "integrity": "sha512-cQKh8igo5QUhZ7lg38DYWAxMvjSAKG0A8wGSVimP07SIUEK2UO+arSRKbRZWtelMtN5V0Hkwh5ryOto/SshYIg==" }, + "lodash._basecallback": { + "version": "3.3.1", + "resolved": "https://registry.npmjs.org/lodash._basecallback/-/lodash._basecallback-3.3.1.tgz", + "integrity": "sha1-t7K7Q9whYEJKIczybFfkQ3cqjic=", + "requires": { + "lodash._baseisequal": "^3.0.0", + "lodash._bindcallback": "^3.0.0", + "lodash.isarray": "^3.0.0", + "lodash.pairs": "^3.0.0" + } + }, + "lodash._baseeach": { + "version": "3.0.4", + "resolved": "https://registry.npmjs.org/lodash._baseeach/-/lodash._baseeach-3.0.4.tgz", + "integrity": "sha1-z4cGVyyhROjZ11InyZDamC+TKvM=", + "requires": { + "lodash.keys": "^3.0.0" + } + }, + "lodash._basefind": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/lodash._basefind/-/lodash._basefind-3.0.0.tgz", + "integrity": "sha1-srugXMZF+XLeLPkl+iv2Og9gyK4=" + }, + "lodash._basefindindex": { + "version": "3.6.0", + "resolved": "https://registry.npmjs.org/lodash._basefindindex/-/lodash._basefindindex-3.6.0.tgz", + "integrity": "sha1-8IM2ChsCJBjtgbyJm+sxLiHnSk8=" + }, "lodash._baseisequal": { "version": "3.0.7", "resolved": "https://registry.npmjs.org/lodash._baseisequal/-/lodash._baseisequal-3.0.7.tgz", @@ -12974,6 +13034,19 @@ "resolved": "https://registry.npmjs.org/lodash.escape/-/lodash.escape-4.0.1.tgz", "integrity": "sha1-yQRGkMIeBClL6qUXcS/e0fqI3pg=" }, + "lodash.find": { + "version": "3.2.1", + "resolved": "https://registry.npmjs.org/lodash.find/-/lodash.find-3.2.1.tgz", + "integrity": "sha1-BG4xnzrOkSrGySRsf2g8XsB7Nq0=", + "requires": { + "lodash._basecallback": "^3.0.0", + "lodash._baseeach": "^3.0.0", + "lodash._basefind": "^3.0.0", + "lodash._basefindindex": "^3.0.0", + "lodash.isarray": "^3.0.0", + "lodash.keys": "^3.0.0" + } + }, "lodash.flattendeep": { "version": "4.4.0", "resolved": "https://registry.npmjs.org/lodash.flattendeep/-/lodash.flattendeep-4.4.0.tgz", @@ -13015,6 +13088,14 @@ "integrity": "sha512-eWw5r+PYICtEBgrBE5hhlT6aAa75f411bgDz/ZL2KZqYV03USvucsxcHUIlGTDTECs1eunpI7HOV7U+WLDvNdQ==", "dev": true }, + "lodash.pairs": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/lodash.pairs/-/lodash.pairs-3.0.1.tgz", + "integrity": "sha1-u+CNV4bu6qCaFckevw3LfSvjJqk=", + "requires": { + "lodash.keys": "^3.0.0" + } + }, "lodash.sortby": { "version": "4.7.0", "resolved": "https://registry.npmjs.org/lodash.sortby/-/lodash.sortby-4.7.0.tgz", @@ -16571,15 +16652,6 @@ "global-cache": "^1.2.1" } }, - "react-world-flags": { - "version": "1.2.4", - "resolved": "https://registry.npmjs.org/react-world-flags/-/react-world-flags-1.2.4.tgz", - "integrity": "sha512-7WVe6w8SsKo3ySnzZHEZaqBogizU/u952YeQF19AyQ2EItxb4xzgBkUaMuSEXa8AxpK0id/hvJslNhSYdIWMMg==", - "requires": { - "svg-country-flags": "^1.2.3", - "world-countries": "^2.0.0" - } - }, "read": { "version": "1.0.7", "resolved": "https://registry.npmjs.org/read/-/read-1.0.7.tgz", @@ -19640,11 +19712,6 @@ "has-flag": "^3.0.0" } }, - "svg-country-flags": { - "version": "1.2.6", - "resolved": "https://registry.npmjs.org/svg-country-flags/-/svg-country-flags-1.2.6.tgz", - "integrity": "sha512-loHSF5qIEXoUgcXxLBlGG2eczDvqjzhyjdu2cIxcuHbJDGPUFBIsKnlp3N/+KBhaIZWbpksoczghkJsyJxbSGQ==" - }, "svg-tags": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/svg-tags/-/svg-tags-1.0.0.tgz", @@ -20714,7 +20781,6 @@ "version": "1.0.1", "resolved": "https://registry.npmjs.org/wcwidth/-/wcwidth-1.0.1.tgz", "integrity": "sha1-8LDc+RW8X/FSivrbLA4XtTLaL+g=", - "dev": true, "requires": { "defaults": "^1.0.3" } @@ -21356,11 +21422,6 @@ "errno": "~0.1.7" } }, - "world-countries": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/world-countries/-/world-countries-2.1.0.tgz", - "integrity": "sha512-g8DRgoH7UJiF5L0xjj+RP/GFH4fOVlD3J5CxkJ+PZYH1PNl0i5JrstBOX53Ub8ObTZ6lCx0V7nIA8BuCvxMoSg==" - }, "wrap-ansi": { "version": "2.1.0", "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-2.1.0.tgz", diff --git a/plugins/woocommerce-admin/package.json b/plugins/woocommerce-admin/package.json index 772c2f6f500..d7011710654 100644 --- a/plugins/woocommerce-admin/package.json +++ b/plugins/woocommerce-admin/package.json @@ -131,6 +131,7 @@ "d3-shape": "^1.2.2", "d3-time-format": "^2.1.3", "dompurify": "1.0.9", + "emoji-flags": "^1.2.0", "gfm-code-blocks": "1.0.0", "gridicons": "3.1.1", "history": "4.7.2", @@ -147,7 +148,6 @@ "react-router-dom": "4.3.1", "react-slot-fill": "^2.0.1", "react-transition-group": "^2.4.0", - "react-world-flags": "1.2.4", "redux": "^4.0.0" }, "husky": { diff --git a/plugins/woocommerce-admin/packages/components/src/flag/example.md b/plugins/woocommerce-admin/packages/components/src/flag/example.md index 6376b35dc94..ddf919c4df6 100644 --- a/plugins/woocommerce-admin/packages/components/src/flag/example.md +++ b/plugins/woocommerce-admin/packages/components/src/flag/example.md @@ -2,9 +2,21 @@ import { Flag } from '@woocommerce/components'; const MyFlag = () => ( - +
+ Default (inherits parent font size) +
+ +
+ + Large +
+ +
+ + Invalid Country Code +
+ +
+
); ``` diff --git a/plugins/woocommerce-admin/packages/components/src/flag/index.js b/plugins/woocommerce-admin/packages/components/src/flag/index.js index 7d53386bef0..0990d9e42f7 100644 --- a/plugins/woocommerce-admin/packages/components/src/flag/index.js +++ b/plugins/woocommerce-admin/packages/components/src/flag/index.js @@ -3,40 +3,36 @@ /** * External dependencies */ -import ReactFlag from 'react-world-flags'; import classnames from 'classnames'; import PropTypes from 'prop-types'; +import emojiFlags from 'emoji-flags'; +import { get } from 'lodash'; /** - * Use the `Flag` component to display a country's flag. + * Use the `Flag` component to display a country's flag using the operating system's emojis. * - * @return { object } - + * @return { object } - React component. */ -const Flag = ( { code, order, round, height, width, className } ) => { - const classes = classnames( 'woocommerce-flag', className, { - 'is-round': round, - } ); +const Flag = ( { code, order, className, size, hideFromScreenReader } ) => { + const classes = classnames( 'woocommerce-flag', className ); let _code = code || 'unknown'; - if ( order && order.shipping ) { + if ( order && order.shipping && order.shipping.country ) { _code = order.shipping.country; } else if ( order && order.billing && order.billing.country ) { _code = order.billing.country; } - const _height = round ? height * 2 : height; - const _width = round ? width * 2 : width; - const inlineStyles = round ? { height, width } : {}; + const inlineStyles = { + fontSize: size, + }; + + const emoji = get( emojiFlags.countryCode( _code ), 'emoji' ); return ( -
- } - height={ _height } - width={ _width } - alt="" - /> +
+ { emoji && { emoji } } + { ! emoji && Invalid country flag }
); }; @@ -50,28 +46,14 @@ Flag.propTypes = { * An order can be passed instead of `code` and the code will automatically be pulled from the billing or shipping data. */ order: PropTypes.object, - /** - * True to display a rounded flag. - */ - round: PropTypes.bool, - /** - * Flag image height. - */ - height: PropTypes.number, - /** - * Flag image width. - */ - width: PropTypes.number, /** * Additional CSS classes. */ className: PropTypes.string, -}; - -Flag.defaultProps = { - height: 24, - width: 24, - round: true, + /** + * Supply a font size to be applied to the emoji flag. + */ + size: PropTypes.number, }; export default Flag; diff --git a/plugins/woocommerce-admin/packages/components/src/flag/style.scss b/plugins/woocommerce-admin/packages/components/src/flag/style.scss index ca633768b41..9727addfc5e 100644 --- a/plugins/woocommerce-admin/packages/components/src/flag/style.scss +++ b/plugins/woocommerce-admin/packages/components/src/flag/style.scss @@ -1,16 +1,15 @@ /** @format */ .woocommerce-flag { - &.is-round { - overflow: hidden; - border-radius: 50%; - - img { - width: auto; - height: 100%; - } + span { + vertical-align: middle; } .woocommerce-flag__fallback { background: $core-grey-light-500; + color: transparent; + width: 24px; + height: 18px; + display: block; + overflow: hidden; } } diff --git a/plugins/woocommerce-admin/packages/components/src/search/autocompleters/countries.js b/plugins/woocommerce-admin/packages/components/src/search/autocompleters/countries.js index 55555ad3084..874d9ba5d0e 100644 --- a/plugins/woocommerce-admin/packages/components/src/search/autocompleters/countries.js +++ b/plugins/woocommerce-admin/packages/components/src/search/autocompleters/countries.js @@ -37,8 +37,8 @@ export default { key="thumbnail" className="woocommerce-search__result-thumbnail" code={ country.code } - width={ 18 } - height={ 18 } + size={ 18 } + hideFromScreenReader />, { match.suggestionBeforeMatch } diff --git a/plugins/woocommerce-admin/packages/components/src/search/style.scss b/plugins/woocommerce-admin/packages/components/src/search/style.scss index 8c6edea5076..008f48390fe 100644 --- a/plugins/woocommerce-admin/packages/components/src/search/style.scss +++ b/plugins/woocommerce-admin/packages/components/src/search/style.scss @@ -96,7 +96,6 @@ align-items: center; padding: $gap-small; color: $woocommerce; - text-decoration: underline; // @todo Not actually a link, should underline? text-align: left; background: $core-grey-light-100; border-bottom: 1px solid $core-grey-light-500; @@ -124,3 +123,7 @@ } } } + +.woocommerce-search__result-name { + text-decoration: underline; // @todo Not actually a link, should underline? +} diff --git a/plugins/woocommerce-admin/wc-admin.php b/plugins/woocommerce-admin/wc-admin.php index aaa90ff465c..b324db51027 100755 --- a/plugins/woocommerce-admin/wc-admin.php +++ b/plugins/woocommerce-admin/wc-admin.php @@ -192,3 +192,9 @@ function wc_admin_woocommerce_updated() { WC_Admin_Notes_Settings_Notes::add_notes_for_settings_that_have_moved(); } add_action( 'woocommerce_updated', 'wc_admin_woocommerce_updated' ); + +/* + * Remove the emoji script as it always defaults to replacing emojis with Twemoji images. + * Gutenberg has also disabled emojis. More on that here -> https://github.com/WordPress/gutenberg/pull/6151 + */ +remove_action( 'admin_print_scripts', 'print_emoji_detection_script' ); From 1c09b6836de66b0354fd5b6bdf865c8bacd94cdd Mon Sep 17 00:00:00 2001 From: Peter Fabian Date: Fri, 25 Jan 2019 13:14:41 +0100 Subject: [PATCH 10/53] Adjusted default return value when page is out of range. --- .../class-wc-admin-reports-taxes-stats-data-store.php | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) diff --git a/plugins/woocommerce-admin/includes/data-stores/class-wc-admin-reports-taxes-stats-data-store.php b/plugins/woocommerce-admin/includes/data-stores/class-wc-admin-reports-taxes-stats-data-store.php index 5dc32c70506..8231bee89e3 100644 --- a/plugins/woocommerce-admin/includes/data-stores/class-wc-admin-reports-taxes-stats-data-store.php +++ b/plugins/woocommerce-admin/includes/data-stores/class-wc-admin-reports-taxes-stats-data-store.php @@ -132,6 +132,14 @@ class WC_Admin_Reports_Taxes_Stats_Data_Store extends WC_Admin_Reports_Data_Stor $data = wp_cache_get( $cache_key, $this->cache_group ); if ( false === $data ) { + $data = (object) array( + 'totals' => (object) array(), + 'intervals' => (object) array(), + 'total' => 0, + 'pages' => 0, + 'page_no' => 0, + ); + $selections = $this->selected_columns( $query_args ); $totals_query = array(); $intervals_query = array(); @@ -155,7 +163,7 @@ class WC_Admin_Reports_Taxes_Stats_Data_Store extends WC_Admin_Reports_Data_Stor $total_pages = (int) ceil( $db_records_count / $intervals_query['per_page'] ); if ( $query_args['page'] < 1 || $query_args['page'] > $total_pages ) { - return array(); + return $data; } $totals = $wpdb->get_results( From 4c8a95cb899372f56e695f0a33effc8866d3861b Mon Sep 17 00:00:00 2001 From: Peter Fabian Date: Fri, 25 Jan 2019 13:29:59 +0100 Subject: [PATCH 11/53] Added fetching of db intervals for later use in zero-filling. --- ...c-admin-reports-taxes-stats-data-store.php | 33 ++++++++++--------- 1 file changed, 17 insertions(+), 16 deletions(-) diff --git a/plugins/woocommerce-admin/includes/data-stores/class-wc-admin-reports-taxes-stats-data-store.php b/plugins/woocommerce-admin/includes/data-stores/class-wc-admin-reports-taxes-stats-data-store.php index 8231bee89e3..c09f65a3351 100644 --- a/plugins/woocommerce-admin/includes/data-stores/class-wc-admin-reports-taxes-stats-data-store.php +++ b/plugins/woocommerce-admin/includes/data-stores/class-wc-admin-reports-taxes-stats-data-store.php @@ -145,23 +145,24 @@ class WC_Admin_Reports_Taxes_Stats_Data_Store extends WC_Admin_Reports_Data_Stor $intervals_query = array(); $this->update_sql_query_params( $query_args, $totals_query, $intervals_query ); - $db_records_count = (int) $wpdb->get_var( - "SELECT COUNT(*) FROM ( - SELECT - {$intervals_query['select_clause']} AS time_interval - FROM - {$table_name} - {$intervals_query['from_clause']} - WHERE - 1=1 - {$intervals_query['where_time_clause']} - {$intervals_query['where_clause']} - GROUP BY - time_interval - ) AS t" + $db_intervals = $wpdb->get_col( + "SELECT + {$intervals_query['select_clause']} AS time_interval + FROM + {$table_name} + {$intervals_query['from_clause']} + WHERE + 1=1 + {$intervals_query['where_time_clause']} + {$intervals_query['where_clause']} + GROUP BY + time_interval" ); // WPCS: cache ok, DB call ok, unprepared SQL ok. - $total_pages = (int) ceil( $db_records_count / $intervals_query['per_page'] ); + $db_interval_count = count( $db_intervals ); + $expected_interval_count = WC_Admin_Reports_Interval::intervals_between( $query_args['after'], $query_args['before'], $query_args['interval'] ); + $total_pages = (int) ceil( $expected_interval_count / $intervals_query['per_page'] ); + if ( $query_args['page'] < 1 || $query_args['page'] > $total_pages ) { return $data; } @@ -219,7 +220,7 @@ class WC_Admin_Reports_Taxes_Stats_Data_Store extends WC_Admin_Reports_Data_Stor $data = (object) array( 'totals' => $totals, 'intervals' => $intervals, - 'total' => $db_records_count, + 'total' => $expected_interval_count, 'pages' => $total_pages, 'page_no' => (int) $query_args['page'], ); From c8c9cd4943af14e3567c0306247610a2b3b1d227 Mon Sep 17 00:00:00 2001 From: Peter Fabian Date: Fri, 25 Jan 2019 13:30:27 +0100 Subject: [PATCH 12/53] Updated error message to point to the correct report. --- .../class-wc-admin-reports-taxes-stats-data-store.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/plugins/woocommerce-admin/includes/data-stores/class-wc-admin-reports-taxes-stats-data-store.php b/plugins/woocommerce-admin/includes/data-stores/class-wc-admin-reports-taxes-stats-data-store.php index c09f65a3351..5837f2901b1 100644 --- a/plugins/woocommerce-admin/includes/data-stores/class-wc-admin-reports-taxes-stats-data-store.php +++ b/plugins/woocommerce-admin/includes/data-stores/class-wc-admin-reports-taxes-stats-data-store.php @@ -209,7 +209,7 @@ class WC_Admin_Reports_Taxes_Stats_Data_Store extends WC_Admin_Reports_Data_Stor ); // WPCS: cache ok, DB call ok, unprepared SQL ok. if ( null === $intervals ) { - return new WP_Error( 'woocommerce_reports_taxes_stats_result_failed', __( 'Sorry, fetching revenue data failed.', 'wc-admin' ) ); + return new WP_Error( 'woocommerce_reports_taxes_stats_result_failed', __( 'Sorry, fetching tax data failed.', 'wc-admin' ) ); } $totals = (object) $this->cast_numbers( $totals[0] ); From b87ca4f6aa55d4e158b8aff3e687ebfd2f445a9a Mon Sep 17 00:00:00 2001 From: Peter Fabian Date: Fri, 25 Jan 2019 14:54:14 +0100 Subject: [PATCH 13/53] Added filling in zeros for interval not having records in the database. --- ...s-wc-admin-reports-taxes-stats-data-store.php | 16 ++++++++++++---- 1 file changed, 12 insertions(+), 4 deletions(-) diff --git a/plugins/woocommerce-admin/includes/data-stores/class-wc-admin-reports-taxes-stats-data-store.php b/plugins/woocommerce-admin/includes/data-stores/class-wc-admin-reports-taxes-stats-data-store.php index 5837f2901b1..365febbfba0 100644 --- a/plugins/woocommerce-admin/includes/data-stores/class-wc-admin-reports-taxes-stats-data-store.php +++ b/plugins/woocommerce-admin/includes/data-stores/class-wc-admin-reports-taxes-stats-data-store.php @@ -184,6 +184,8 @@ class WC_Admin_Reports_Taxes_Stats_Data_Store extends WC_Admin_Reports_Data_Stor return new WP_Error( 'woocommerce_reports_taxes_stats_result_failed', __( 'Sorry, fetching revenue data failed.', 'wc-admin' ) ); } + $this->update_intervals_sql_params( $intervals_query, $query_args, $db_interval_count, $expected_interval_count, $table_name ); + if ( '' !== $selections ) { $selections = ', ' . $selections; } @@ -214,10 +216,7 @@ class WC_Admin_Reports_Taxes_Stats_Data_Store extends WC_Admin_Reports_Data_Stor $totals = (object) $this->cast_numbers( $totals[0] ); - $this->update_interval_boundary_dates( $query_args['after'], $query_args['before'], $query_args['interval'], $intervals ); - $this->create_interval_subtotals( $intervals ); - - $data = (object) array( + $data = (object) array( 'totals' => $totals, 'intervals' => $intervals, 'total' => $expected_interval_count, @@ -225,6 +224,15 @@ class WC_Admin_Reports_Taxes_Stats_Data_Store extends WC_Admin_Reports_Data_Stor 'page_no' => (int) $query_args['page'], ); + if ( WC_Admin_Reports_Interval::intervals_missing( $expected_interval_count, $db_interval_count, $intervals_query['per_page'], $query_args['page'], $query_args['order'], $query_args['orderby'], count( $intervals ) ) ) { + $this->fill_in_missing_intervals( $db_intervals, $query_args['adj_after'], $query_args['adj_before'], $query_args['interval'], $data ); + $this->sort_intervals( $data, $query_args['orderby'], $query_args['order'] ); + $this->remove_extra_records( $data, $query_args['page'], $intervals_query['per_page'], $db_interval_count, $expected_interval_count, $query_args['orderby'] ); + } else { + $this->update_interval_boundary_dates( $query_args['after'], $query_args['before'], $query_args['interval'], $data->intervals ); + } + $this->create_interval_subtotals( $data->intervals ); + wp_cache_set( $cache_key, $data, $this->cache_group ); } From 40602efd895bfe0e4bb79f7cc71a3b18a3a48db3 Mon Sep 17 00:00:00 2001 From: Timmy Crawford Date: Fri, 25 Jan 2019 09:17:09 -0800 Subject: [PATCH 14/53] Components; Fix SummaryNumber example (https://github.com/woocommerce/woocommerce-admin/pull/1392) --- .../packages/components/CHANGELOG.md | 1 + .../components/src/summary/example.md | 43 +++++++++++-------- 2 files changed, 26 insertions(+), 18 deletions(-) diff --git a/plugins/woocommerce-admin/packages/components/CHANGELOG.md b/plugins/woocommerce-admin/packages/components/CHANGELOG.md index 71066dfcf12..7234f23da80 100644 --- a/plugins/woocommerce-admin/packages/components/CHANGELOG.md +++ b/plugins/woocommerce-admin/packages/components/CHANGELOG.md @@ -1,6 +1,7 @@ # 1.4.1 (unreleased) - Chart component: format numbers and prices using store currency settings. - Make `href`/linking optional in SummaryNumber. +- Fix SummaryNumber example code. # 1.4.0 - Add download log ip address autocompleter to search component diff --git a/plugins/woocommerce-admin/packages/components/src/summary/example.md b/plugins/woocommerce-admin/packages/components/src/summary/example.md index 0b1333d1b41..af417e4270c 100644 --- a/plugins/woocommerce-admin/packages/components/src/summary/example.md +++ b/plugins/woocommerce-admin/packages/components/src/summary/example.md @@ -3,24 +3,31 @@ import { SummaryList, SummaryNumber } from '@woocommerce/components'; const MySummaryList = () => ( - - - + { () => { + return [ + , + , + + ]; + } } ); ``` From 9c9ff13c2bfd7e974eeb766d7084fa2c512961e3 Mon Sep 17 00:00:00 2001 From: Joshua T Flowers Date: Sat, 26 Jan 2019 01:37:50 +0800 Subject: [PATCH 15/53] Allow customer date_last_active to be null (https://github.com/woocommerce/woocommerce-admin/pull/1377) * Allow customer date_last_active to be null * Only show last active in customers report table if set --- .../client/analytics/report/customers/table.js | 6 ++++-- .../woocommerce-admin/includes/class-wc-admin-api-init.php | 2 +- .../class-wc-admin-reports-customers-data-store.php | 2 +- 3 files changed, 6 insertions(+), 4 deletions(-) diff --git a/plugins/woocommerce-admin/client/analytics/report/customers/table.js b/plugins/woocommerce-admin/client/analytics/report/customers/table.js index 1e62051e76a..d4751504ec3 100644 --- a/plugins/woocommerce-admin/client/analytics/report/customers/table.js +++ b/plugins/woocommerce-admin/client/analytics/report/customers/table.js @@ -148,7 +148,9 @@ export default class CustomersReportTable extends Component { value: username, }, { - display: , + display: date_last_active && ( + + ), value: date_last_active, }, { @@ -205,4 +207,4 @@ export default class CustomersReportTable extends Component { /> ); } -} +} \ No newline at end of file diff --git a/plugins/woocommerce-admin/includes/class-wc-admin-api-init.php b/plugins/woocommerce-admin/includes/class-wc-admin-api-init.php index c7277a546fb..32efad2730f 100644 --- a/plugins/woocommerce-admin/includes/class-wc-admin-api-init.php +++ b/plugins/woocommerce-admin/includes/class-wc-admin-api-init.php @@ -754,7 +754,7 @@ class WC_Admin_Api_Init { first_name varchar(255) NOT NULL, last_name varchar(255) NOT NULL, email varchar(100) NOT NULL, - date_last_active timestamp DEFAULT '0000-00-00 00:00:00' NOT NULL, + date_last_active timestamp NULL default null, date_registered timestamp NULL default null, country char(2) DEFAULT '' NOT NULL, postcode varchar(20) DEFAULT '' NOT NULL, diff --git a/plugins/woocommerce-admin/includes/data-stores/class-wc-admin-reports-customers-data-store.php b/plugins/woocommerce-admin/includes/data-stores/class-wc-admin-reports-customers-data-store.php index 05e4c5d94b4..17e88cba209 100644 --- a/plugins/woocommerce-admin/includes/data-stores/class-wc-admin-reports-customers-data-store.php +++ b/plugins/woocommerce-admin/includes/data-stores/class-wc-admin-reports-customers-data-store.php @@ -534,7 +534,7 @@ class WC_Admin_Reports_Customers_Data_Store extends WC_Admin_Reports_Data_Store 'postcode' => $customer->get_billing_postcode( 'edit' ), 'country' => $customer->get_billing_country( 'edit' ), 'date_registered' => date( 'Y-m-d H:i:s', $customer->get_date_created( 'edit' )->getTimestamp() ), - 'date_last_active' => $last_active ? date( 'Y-m-d H:i:s', $last_active ) : '', + 'date_last_active' => $last_active ? date( 'Y-m-d H:i:s', $last_active ) : null, ); $format = array( '%d', From 066daa4b6a98176e1228f77600b696fbc59ac959 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Albert=20Juh=C3=A9=20Lluveras?= Date: Fri, 25 Jan 2019 18:59:53 +0100 Subject: [PATCH 16/53] Add Top Coupons Block (https://github.com/woocommerce/woocommerce-admin/pull/1397) * Add Top Coupons Block * Order coupons by orders_count by default * Fix wrong variable name --- .../client/analytics/report/coupons/table.js | 24 ++-- .../client/dashboard/leaderboards/index.js | 5 +- .../dashboard/leaderboards/top-coupons.js | 122 ++++++++++++++++++ 3 files changed, 142 insertions(+), 9 deletions(-) create mode 100644 plugins/woocommerce-admin/client/dashboard/leaderboards/top-coupons.js diff --git a/plugins/woocommerce-admin/client/analytics/report/coupons/table.js b/plugins/woocommerce-admin/client/analytics/report/coupons/table.js index 1fa0d30bbbc..50fba9e655c 100644 --- a/plugins/woocommerce-admin/client/analytics/report/coupons/table.js +++ b/plugins/woocommerce-admin/client/analytics/report/coupons/table.js @@ -12,6 +12,7 @@ import { map } from 'lodash'; import { Date, Link } from '@woocommerce/components'; import { defaultTableDateFormat } from '@woocommerce/date'; import { formatCurrency, getCurrencyFormatDecimal } from '@woocommerce/currency'; +import { getNewPath, getPersistedQuery } from '@woocommerce/navigation'; /** * Internal dependencies @@ -67,22 +68,29 @@ export default class CouponsReportTable extends Component { } getRowsContent( coupons ) { + const { query } = this.props; + const persistedQuery = getPersistedQuery( query ); + return map( coupons, coupon => { const { amount, coupon_id, extended_info, orders_count } = coupon; const { code, date_created, date_expires, discount_type } = extended_info; - // @TODO must link to the coupon detail report + const couponUrl = getNewPath( persistedQuery, '/analytics/coupons', { + filter: 'single_coupon', + coupons: coupon_id, + } ); const couponLink = ( - + { code } ); + const ordersUrl = getNewPath( persistedQuery, '/analytics/orders', { + filter: 'advanced', + coupon_includes: coupon_id, + } ); const ordersLink = ( - + { numberFormat( orders_count ) } ); @@ -162,8 +170,8 @@ export default class CouponsReportTable extends Component { itemIdField="coupon_id" query={ query } tableQuery={ { - orderby: query.orderby || 'coupon_id', - order: query.order || 'asc', + orderby: query.orderby || 'orders_count', + order: query.order || 'desc', extended_info: true, } } title={ __( 'Coupons', 'wc-admin' ) } diff --git a/plugins/woocommerce-admin/client/dashboard/leaderboards/index.js b/plugins/woocommerce-admin/client/dashboard/leaderboards/index.js index 70e71ab788a..9e3c1a8e6a3 100644 --- a/plugins/woocommerce-admin/client/dashboard/leaderboards/index.js +++ b/plugins/woocommerce-admin/client/dashboard/leaderboards/index.js @@ -21,6 +21,7 @@ import { EllipsisMenu, MenuItem, MenuTitle, SectionHeader } from '@woocommerce/c import withSelect from 'wc-api/with-select'; import TopSellingCategories from './top-selling-categories'; import TopSellingProducts from './top-selling-products'; +import TopCoupons from './top-coupons'; import './style.scss'; class Leaderboards extends Component { @@ -134,10 +135,12 @@ class Leaderboards extends Component { { ! hiddenLeaderboardKeys.includes( 'top-products' ) && ( ) } - { ! hiddenLeaderboardKeys.includes( 'top-categories' ) && ( ) } + { ! hiddenLeaderboardKeys.includes( 'top-coupons' ) && ( + + ) }
diff --git a/plugins/woocommerce-admin/client/dashboard/leaderboards/top-coupons.js b/plugins/woocommerce-admin/client/dashboard/leaderboards/top-coupons.js new file mode 100644 index 00000000000..afc05275c19 --- /dev/null +++ b/plugins/woocommerce-admin/client/dashboard/leaderboards/top-coupons.js @@ -0,0 +1,122 @@ +/** @format */ +/** + * External dependencies + */ +import { __ } from '@wordpress/i18n'; +import { Component } from '@wordpress/element'; +import { map } from 'lodash'; + +/** + * WooCommerce dependencies + */ +import { formatCurrency, getCurrencyFormatDecimal } from '@woocommerce/currency'; +import { getNewPath, getPersistedQuery } from '@woocommerce/navigation'; +import { Link } from '@woocommerce/components'; + +/** + * Internal dependencies + */ +import { numberFormat } from 'lib/number'; +import Leaderboard from 'analytics/components/leaderboard'; + +export class TopCoupons extends Component { + constructor( props ) { + super( props ); + + this.getRowsContent = this.getRowsContent.bind( this ); + this.getHeadersContent = this.getHeadersContent.bind( this ); + } + + getHeadersContent() { + return [ + { + label: __( 'Coupon Code', 'wc-admin' ), + key: 'code', + required: true, + isLeftAligned: true, + isSortable: false, + }, + { + label: __( 'Orders', 'wc-admin' ), + key: 'orders_count', + required: true, + defaultSort: true, + isSortable: false, + isNumeric: true, + }, + { + label: __( 'Amount Discounted', 'wc-admin' ), + key: 'amount', + isSortable: false, + isNumeric: true, + }, + ]; + } + + getRowsContent( data ) { + const { query } = this.props; + const persistedQuery = getPersistedQuery( query ); + return map( data, row => { + const { amount, coupon_id, extended_info, orders_count } = row; + const { code } = extended_info; + + const couponUrl = getNewPath( persistedQuery, 'analytics/coupons', { + filter: 'single_coupon', + coupons: coupon_id, + } ); + const couponLink = ( + + { code } + + ); + + const ordersUrl = getNewPath( persistedQuery, 'analytics/orders', { + filter: 'advanced', + coupon_includes: coupon_id, + } ); + const ordersLink = ( + + { numberFormat( orders_count ) } + + ); + + return [ + { + display: couponLink, + value: code, + }, + { + display: ordersLink, + value: orders_count, + }, + { + display: formatCurrency( amount ), + value: getCurrencyFormatDecimal( amount ), + }, + ]; + } ); + } + + render() { + const { query, totalRows } = this.props; + const tableQuery = { + orderby: 'orders_count', + order: 'desc', + per_page: totalRows, + extended_info: true, + }; + + return ( + + ); + } +} + +export default TopCoupons; From 833345dfeebde154911367c1c4bbfc403195a1c9 Mon Sep 17 00:00:00 2001 From: Kevin Killingsworth Date: Mon, 28 Jan 2019 13:18:21 -0600 Subject: [PATCH 17/53] Remove 'wc-admin' client/store implementation (https://github.com/woocommerce/woocommerce-admin/pull/1344) This has been replaced by the `wc-api` store, under client/wc-api --- plugins/woocommerce-admin/client/embedded.js | 1 - plugins/woocommerce-admin/client/index.js | 1 - .../woocommerce-admin/client/store/index.js | 41 -- .../client/store/middleware.js | 16 - .../client/store/notes/actions.js | 17 - .../client/store/notes/index.js | 15 - .../client/store/notes/reducer.js | 31 - .../client/store/notes/resolvers.js | 32 - .../client/store/notes/selectors.js | 49 -- .../client/store/notes/test/reducer.js | 80 --- .../client/store/notes/test/resolvers.js | 53 -- .../client/store/notes/test/selectors.js | 92 --- .../client/store/orders/actions.js | 17 - .../client/store/orders/index.js | 15 - .../client/store/orders/reducer.js | 32 - .../client/store/orders/resolvers.js | 32 - .../client/store/orders/selectors.js | 49 -- .../client/store/orders/test/reducer.js | 80 --- .../client/store/orders/test/resolvers.js | 53 -- .../client/store/orders/test/selectors.js | 92 --- .../client/store/reports/index.js | 31 - .../client/store/reports/items/actions.js | 20 - .../client/store/reports/items/index.js | 15 - .../client/store/reports/items/reducer.js | 39 -- .../client/store/reports/items/resolvers.js | 36 -- .../client/store/reports/items/selectors.js | 51 -- .../store/reports/items/test/reducer.js | 104 --- .../store/reports/items/test/resolvers.js | 74 --- .../store/reports/items/test/selectors.js | 106 ---- .../client/store/reports/stats/actions.js | 21 - .../client/store/reports/stats/index.js | 16 - .../client/store/reports/stats/reducer.js | 40 -- .../client/store/reports/stats/resolvers.js | 63 -- .../client/store/reports/stats/selectors.js | 52 -- .../store/reports/stats/test/reducer.js | 164 ----- .../store/reports/stats/test/resolvers.js | 107 ---- .../store/reports/stats/test/selectors.js | 102 --- .../client/store/reports/test/utils.js | 598 ------------------ 38 files changed, 2437 deletions(-) delete mode 100644 plugins/woocommerce-admin/client/store/index.js delete mode 100644 plugins/woocommerce-admin/client/store/middleware.js delete mode 100644 plugins/woocommerce-admin/client/store/notes/actions.js delete mode 100644 plugins/woocommerce-admin/client/store/notes/index.js delete mode 100644 plugins/woocommerce-admin/client/store/notes/reducer.js delete mode 100644 plugins/woocommerce-admin/client/store/notes/resolvers.js delete mode 100644 plugins/woocommerce-admin/client/store/notes/selectors.js delete mode 100644 plugins/woocommerce-admin/client/store/notes/test/reducer.js delete mode 100644 plugins/woocommerce-admin/client/store/notes/test/resolvers.js delete mode 100644 plugins/woocommerce-admin/client/store/notes/test/selectors.js delete mode 100644 plugins/woocommerce-admin/client/store/orders/actions.js delete mode 100644 plugins/woocommerce-admin/client/store/orders/index.js delete mode 100644 plugins/woocommerce-admin/client/store/orders/reducer.js delete mode 100644 plugins/woocommerce-admin/client/store/orders/resolvers.js delete mode 100644 plugins/woocommerce-admin/client/store/orders/selectors.js delete mode 100644 plugins/woocommerce-admin/client/store/orders/test/reducer.js delete mode 100644 plugins/woocommerce-admin/client/store/orders/test/resolvers.js delete mode 100644 plugins/woocommerce-admin/client/store/orders/test/selectors.js delete mode 100644 plugins/woocommerce-admin/client/store/reports/index.js delete mode 100644 plugins/woocommerce-admin/client/store/reports/items/actions.js delete mode 100644 plugins/woocommerce-admin/client/store/reports/items/index.js delete mode 100644 plugins/woocommerce-admin/client/store/reports/items/reducer.js delete mode 100644 plugins/woocommerce-admin/client/store/reports/items/resolvers.js delete mode 100644 plugins/woocommerce-admin/client/store/reports/items/selectors.js delete mode 100644 plugins/woocommerce-admin/client/store/reports/items/test/reducer.js delete mode 100644 plugins/woocommerce-admin/client/store/reports/items/test/resolvers.js delete mode 100644 plugins/woocommerce-admin/client/store/reports/items/test/selectors.js delete mode 100644 plugins/woocommerce-admin/client/store/reports/stats/actions.js delete mode 100644 plugins/woocommerce-admin/client/store/reports/stats/index.js delete mode 100644 plugins/woocommerce-admin/client/store/reports/stats/reducer.js delete mode 100644 plugins/woocommerce-admin/client/store/reports/stats/resolvers.js delete mode 100644 plugins/woocommerce-admin/client/store/reports/stats/selectors.js delete mode 100644 plugins/woocommerce-admin/client/store/reports/stats/test/reducer.js delete mode 100644 plugins/woocommerce-admin/client/store/reports/stats/test/resolvers.js delete mode 100644 plugins/woocommerce-admin/client/store/reports/stats/test/selectors.js delete mode 100644 plugins/woocommerce-admin/client/store/reports/test/utils.js diff --git a/plugins/woocommerce-admin/client/embedded.js b/plugins/woocommerce-admin/client/embedded.js index 230e6548dcc..4cd027349aa 100644 --- a/plugins/woocommerce-admin/client/embedded.js +++ b/plugins/woocommerce-admin/client/embedded.js @@ -10,7 +10,6 @@ import { Provider as SlotFillProvider } from 'react-slot-fill'; */ import './stylesheets/_embedded.scss'; import { EmbedLayout } from './layout'; -import 'store'; import 'wc-api/wp-data-store'; render( diff --git a/plugins/woocommerce-admin/client/index.js b/plugins/woocommerce-admin/client/index.js index f57ca37af21..2bd3841f7af 100644 --- a/plugins/woocommerce-admin/client/index.js +++ b/plugins/woocommerce-admin/client/index.js @@ -10,7 +10,6 @@ import { Provider as SlotFillProvider } from 'react-slot-fill'; */ import './stylesheets/_index.scss'; import { PageLayout } from './layout'; -import 'store'; import 'wc-api/wp-data-store'; render( diff --git a/plugins/woocommerce-admin/client/store/index.js b/plugins/woocommerce-admin/client/store/index.js deleted file mode 100644 index b87f00b4258..00000000000 --- a/plugins/woocommerce-admin/client/store/index.js +++ /dev/null @@ -1,41 +0,0 @@ -/** @format */ -/** - * External dependencies - */ -import { combineReducers, registerStore } from '@wordpress/data'; - -/** - * Internal dependencies - */ -import { applyMiddleware, addThunks } from './middleware'; -import orders from 'store/orders'; -import reports from 'store/reports'; -import notes from 'store/notes'; - -const store = registerStore( 'wc-admin', { - reducer: combineReducers( { - orders: orders.reducer, - reports: reports.reducer, - notes: notes.reducer, - } ), - - actions: { - ...orders.actions, - ...reports.actions, - ...notes.actions, - }, - - selectors: { - ...orders.selectors, - ...reports.selectors, - ...notes.selectors, - }, - - resolvers: { - ...orders.resolvers, - ...reports.resolvers, - ...notes.resolvers, - }, -} ); - -applyMiddleware( store, [ addThunks ] ); diff --git a/plugins/woocommerce-admin/client/store/middleware.js b/plugins/woocommerce-admin/client/store/middleware.js deleted file mode 100644 index 82fa299bb33..00000000000 --- a/plugins/woocommerce-admin/client/store/middleware.js +++ /dev/null @@ -1,16 +0,0 @@ -/** @format */ - -export function applyMiddleware( store, middlewares ) { - middlewares = middlewares.slice(); - middlewares.reverse(); - let dispatch = store.dispatch; - middlewares.forEach( middleware => ( dispatch = middleware( store )( dispatch ) ) ); - return Object.assign( store, { dispatch } ); -} - -export const addThunks = ( { getState } ) => next => action => { - if ( 'function' === typeof action ) { - return action( getState ); - } - return next( action ); -}; diff --git a/plugins/woocommerce-admin/client/store/notes/actions.js b/plugins/woocommerce-admin/client/store/notes/actions.js deleted file mode 100644 index 7a66e9f3baf..00000000000 --- a/plugins/woocommerce-admin/client/store/notes/actions.js +++ /dev/null @@ -1,17 +0,0 @@ -/** @format */ - -export default { - setNotes( notes, query ) { - return { - type: 'SET_NOTES', - notes, - query: query || {}, - }; - }, - setNotesError( query ) { - return { - type: 'SET_NOTES_ERROR', - query: query || {}, - }; - }, -}; diff --git a/plugins/woocommerce-admin/client/store/notes/index.js b/plugins/woocommerce-admin/client/store/notes/index.js deleted file mode 100644 index 5d2b89160cc..00000000000 --- a/plugins/woocommerce-admin/client/store/notes/index.js +++ /dev/null @@ -1,15 +0,0 @@ -/** @format */ -/** - * Internal dependencies - */ -import actions from './actions'; -import reducer from './reducer'; -import resolvers from './resolvers'; -import selectors from './selectors'; - -export default { - actions, - reducer, - resolvers, - selectors, -}; diff --git a/plugins/woocommerce-admin/client/store/notes/reducer.js b/plugins/woocommerce-admin/client/store/notes/reducer.js deleted file mode 100644 index 42aa2b4555f..00000000000 --- a/plugins/woocommerce-admin/client/store/notes/reducer.js +++ /dev/null @@ -1,31 +0,0 @@ -/** @format */ - -/** - * External dependencies - */ -import { merge } from 'lodash'; - -/** - * Internal dependencies - */ -import { ERROR } from 'store/constants'; -import { getJsonString } from 'store/utils'; - -const DEFAULT_STATE = {}; - -export default function notesReducer( state = DEFAULT_STATE, action ) { - const queryKey = getJsonString( action.query ); - - switch ( action.type ) { - case 'SET_NOTES': - return merge( {}, state, { - [ queryKey ]: action.notes, - } ); - case 'SET_NOTES_ERROR': - return merge( {}, state, { - [ queryKey ]: ERROR, - } ); - } - - return state; -} diff --git a/plugins/woocommerce-admin/client/store/notes/resolvers.js b/plugins/woocommerce-admin/client/store/notes/resolvers.js deleted file mode 100644 index 93b0c619408..00000000000 --- a/plugins/woocommerce-admin/client/store/notes/resolvers.js +++ /dev/null @@ -1,32 +0,0 @@ -/** @format */ -/** - * External dependencies - */ -import { dispatch } from '@wordpress/data'; -import apiFetch from '@wordpress/api-fetch'; - -/** - * WooCommerce dependencies - */ -import { stringifyQuery } from '@woocommerce/navigation'; - -/** - * Internal dependencies - */ -import { NAMESPACE } from 'store/constants'; - -export default { - // TODO: Use controls data plugin or fresh-data instead of async - async getNotes( ...args ) { - // This is interim code to work with either 2.x or 3.x version of @wordpress/data - // TODO: Change to just `getNotes( query )` after Gutenberg plugin uses @wordpress/data 3+ - const query = args.length === 1 ? args[ 0 ] : args[ 1 ]; - - try { - const notes = await apiFetch( { path: NAMESPACE + 'admin/notes' + stringifyQuery( query ) } ); - dispatch( 'wc-admin' ).setNotes( notes, query ); - } catch ( error ) { - dispatch( 'wc-admin' ).setNotesError( query ); - } - }, -}; diff --git a/plugins/woocommerce-admin/client/store/notes/selectors.js b/plugins/woocommerce-admin/client/store/notes/selectors.js deleted file mode 100644 index 93013f9f1c8..00000000000 --- a/plugins/woocommerce-admin/client/store/notes/selectors.js +++ /dev/null @@ -1,49 +0,0 @@ -/** @format */ - -/** - * External dependencies - */ -import { get } from 'lodash'; -import { select } from '@wordpress/data'; - -/** - * Internal dependencies - */ -import { getJsonString } from 'store/utils'; -import { ERROR } from 'store/constants'; - -/** - * Returns notes for a specific query. - * - * @param {Object} state Current state - * @param {Object} query Note query parameters - * @return {Array} Notes - */ -function getNotes( state, query = {} ) { - return get( state, [ 'notes', getJsonString( query ) ], [] ); -} - -export default { - getNotes, - - /** - * Returns true if a query is pending. - * - * @param {Object} state Current state - * @return {Boolean} True if the `getNotes` request is pending, false otherwise - */ - isGetNotesRequesting( state, ...args ) { - return select( 'core/data' ).isResolving( 'wc-admin', 'getNotes', args ); - }, - - /** - * Returns true if a get notes request has returned an error. - * - * @param {Object} state Current state - * @param {Object} query Query parameters - * @return {Boolean} True if the `getNotes` request has failed, false otherwise - */ - isGetNotesError( state, query ) { - return ERROR === getNotes( state, query ); - }, -}; diff --git a/plugins/woocommerce-admin/client/store/notes/test/reducer.js b/plugins/woocommerce-admin/client/store/notes/test/reducer.js deleted file mode 100644 index bc037aa7033..00000000000 --- a/plugins/woocommerce-admin/client/store/notes/test/reducer.js +++ /dev/null @@ -1,80 +0,0 @@ -/** - * @format - */ - -/** - * External dependencies - */ -import deepFreeze from 'deep-freeze'; - -/** - * Internal dependencies - */ -import { ERROR } from 'store/constants'; -import notesReducer from '../reducer'; -import { getJsonString } from 'store/utils'; - -describe( 'notesReducer()', () => { - it( 'returns an empty data object by default', () => { - const state = notesReducer( undefined, {} ); - expect( state ).toEqual( {} ); - } ); - - it( 'returns with received notes data', () => { - const originalState = deepFreeze( {} ); - const query = { - page: 2, - }; - const notes = [ { id: 1214 }, { id: 1215 }, { id: 1216 } ]; - - const state = notesReducer( originalState, { - type: 'SET_NOTES', - query, - notes, - } ); - - const queryKey = getJsonString( query ); - expect( state[ queryKey ] ).toEqual( notes ); - } ); - - it( 'tracks multiple queries in notes data', () => { - const otherQuery = { - page: 3, - }; - const otherQueryKey = getJsonString( otherQuery ); - const otherNotes = [ { id: 1 }, { id: 2 }, { id: 3 } ]; - const otherQueryState = { - [ otherQueryKey ]: otherNotes, - }; - const originalState = deepFreeze( otherQueryState ); - const query = { - page: 2, - }; - const notes = [ { id: 1214 }, { id: 1215 }, { id: 1216 } ]; - - const state = notesReducer( originalState, { - type: 'SET_NOTES', - query, - notes, - } ); - - const queryKey = getJsonString( query ); - expect( state[ queryKey ] ).toEqual( notes ); - expect( state[ otherQueryKey ] ).toEqual( otherNotes ); - } ); - - it( 'returns with received error data', () => { - const originalState = deepFreeze( {} ); - const query = { - page: 2, - }; - - const state = notesReducer( originalState, { - type: 'SET_NOTES_ERROR', - query, - } ); - - const queryKey = getJsonString( query ); - expect( state[ queryKey ] ).toEqual( ERROR ); - } ); -} ); diff --git a/plugins/woocommerce-admin/client/store/notes/test/resolvers.js b/plugins/woocommerce-admin/client/store/notes/test/resolvers.js deleted file mode 100644 index 5ffad3292a5..00000000000 --- a/plugins/woocommerce-admin/client/store/notes/test/resolvers.js +++ /dev/null @@ -1,53 +0,0 @@ -/* -* @format -*/ - -/** - * External dependencies - */ -import apiFetch from '@wordpress/api-fetch'; -import { dispatch } from '@wordpress/data'; - -/** - * Internal dependencies - */ -import { NAMESPACE } from 'store/constants'; -import resolvers from '../resolvers'; - -const { getNotes } = resolvers; - -jest.mock( '@wordpress/data', () => ( { - dispatch: jest.fn().mockReturnValue( { - setNotes: jest.fn(), - } ), -} ) ); -jest.mock( '@wordpress/api-fetch', () => jest.fn() ); - -describe( 'getNotes', () => { - const NOTES_1 = [ { id: 1214 }, { id: 1215 }, { id: 1216 } ]; - - const NOTES_2 = [ { id: 1 }, { id: 2 }, { id: 3 } ]; - - beforeAll( () => { - apiFetch.mockImplementation( options => { - if ( options.path === NAMESPACE + 'admin/notes' ) { - return Promise.resolve( NOTES_1 ); - } - if ( options.path === NAMESPACE + 'admin/notes?page=2' ) { - return Promise.resolve( NOTES_2 ); - } - } ); - } ); - - it( 'returns requested data', async () => { - expect.assertions( 1 ); - await getNotes(); - expect( dispatch().setNotes ).toHaveBeenCalledWith( NOTES_1, undefined ); - } ); - - it( 'returns requested data for a specific query', async () => { - expect.assertions( 1 ); - await getNotes( { page: 2 } ); - expect( dispatch().setNotes ).toHaveBeenCalledWith( NOTES_2, { page: 2 } ); - } ); -} ); diff --git a/plugins/woocommerce-admin/client/store/notes/test/selectors.js b/plugins/woocommerce-admin/client/store/notes/test/selectors.js deleted file mode 100644 index 974cf7640e1..00000000000 --- a/plugins/woocommerce-admin/client/store/notes/test/selectors.js +++ /dev/null @@ -1,92 +0,0 @@ -/* -* @format -*/ - -/** - * External dependencies - */ -import deepFreeze from 'deep-freeze'; - -/** - * Internal dependencies - */ -import { ERROR } from 'store/constants'; -import selectors from '../selectors'; -import { select } from '@wordpress/data'; -import { getJsonString } from 'store/utils'; - -const { getNotes, isGetNotesRequesting, isGetNotesError } = selectors; -jest.mock( '@wordpress/data', () => ( { - ...require.requireActual( '@wordpress/data' ), - select: jest.fn().mockReturnValue( {} ), -} ) ); - -const query = { page: 1 }; -const queryKey = getJsonString( query ); - -describe( 'getNotes()', () => { - it( 'returns an empty array when no notes are available', () => { - const state = deepFreeze( {} ); - expect( getNotes( state, query ) ).toEqual( [] ); - } ); - - it( 'returns stored notes for current query', () => { - const notes = [ { id: 1214 }, { id: 1215 }, { id: 1216 } ]; - const state = deepFreeze( { - notes: { - [ queryKey ]: notes, - }, - } ); - expect( getNotes( state, query ) ).toEqual( notes ); - } ); -} ); - -describe( 'isGetNotesRequesting()', () => { - beforeAll( () => { - select( 'core/data' ).isResolving = jest.fn().mockReturnValue( false ); - } ); - - afterAll( () => { - select( 'core/data' ).isResolving.mockRestore(); - } ); - - function setIsResolving( isResolving ) { - select( 'core/data' ).isResolving.mockImplementation( - ( reducerKey, selectorName ) => - isResolving && reducerKey === 'wc-admin' && selectorName === 'getNotes' - ); - } - - it( 'returns false if never requested', () => { - const result = isGetNotesRequesting( query ); - expect( result ).toBe( false ); - } ); - - it( 'returns false if request finished', () => { - setIsResolving( false ); - const result = isGetNotesRequesting( query ); - expect( result ).toBe( false ); - } ); - - it( 'returns true if requesting', () => { - setIsResolving( true ); - const result = isGetNotesRequesting( query ); - expect( result ).toBe( true ); - } ); -} ); - -describe( 'isGetNotesError()', () => { - it( 'returns false by default', () => { - const state = deepFreeze( {} ); - expect( isGetNotesError( state, query ) ).toEqual( false ); - } ); - - it( 'returns true if ERROR constant is found', () => { - const state = deepFreeze( { - notes: { - [ queryKey ]: ERROR, - }, - } ); - expect( isGetNotesError( state, query ) ).toEqual( true ); - } ); -} ); diff --git a/plugins/woocommerce-admin/client/store/orders/actions.js b/plugins/woocommerce-admin/client/store/orders/actions.js deleted file mode 100644 index a149f85f509..00000000000 --- a/plugins/woocommerce-admin/client/store/orders/actions.js +++ /dev/null @@ -1,17 +0,0 @@ -/** @format */ - -export default { - setOrders( orders, query ) { - return { - type: 'SET_ORDERS', - orders, - query: query || {}, - }; - }, - setOrdersError( query ) { - return { - type: 'SET_ORDERS_ERROR', - query: query || {}, - }; - }, -}; diff --git a/plugins/woocommerce-admin/client/store/orders/index.js b/plugins/woocommerce-admin/client/store/orders/index.js deleted file mode 100644 index 5d2b89160cc..00000000000 --- a/plugins/woocommerce-admin/client/store/orders/index.js +++ /dev/null @@ -1,15 +0,0 @@ -/** @format */ -/** - * Internal dependencies - */ -import actions from './actions'; -import reducer from './reducer'; -import resolvers from './resolvers'; -import selectors from './selectors'; - -export default { - actions, - reducer, - resolvers, - selectors, -}; diff --git a/plugins/woocommerce-admin/client/store/orders/reducer.js b/plugins/woocommerce-admin/client/store/orders/reducer.js deleted file mode 100644 index 64f28e2e541..00000000000 --- a/plugins/woocommerce-admin/client/store/orders/reducer.js +++ /dev/null @@ -1,32 +0,0 @@ -/** @format */ - -/** - * External dependencies - */ -import { merge } from 'lodash'; - -/** - * Internal dependencies - */ -import { ERROR } from 'store/constants'; -import { getJsonString } from 'store/utils'; - -const DEFAULT_STATE = {}; - -export default function ordersReducer( state = DEFAULT_STATE, action ) { - const queryKey = getJsonString( action.query ); - - switch ( action.type ) { - case 'SET_ORDERS': - return merge( {}, state, { - [ queryKey ]: action.orders, - } ); - - case 'SET_ORDERS_ERROR': - return merge( {}, state, { - [ queryKey ]: ERROR, - } ); - } - - return state; -} diff --git a/plugins/woocommerce-admin/client/store/orders/resolvers.js b/plugins/woocommerce-admin/client/store/orders/resolvers.js deleted file mode 100644 index 8eac9d8f493..00000000000 --- a/plugins/woocommerce-admin/client/store/orders/resolvers.js +++ /dev/null @@ -1,32 +0,0 @@ -/** @format */ -/** - * External dependencies - */ -import { dispatch } from '@wordpress/data'; -import apiFetch from '@wordpress/api-fetch'; - -/** - * WooCommerce dependencies - */ -import { stringifyQuery } from '@woocommerce/navigation'; - -/** - * Internal dependencies - */ -import { NAMESPACE } from 'store/constants'; - -export default { - // TODO: Use controls data plugin or fresh-data instead of async - async getOrders( ...args ) { - // This is interim code to work with either 2.x or 3.x version of @wordpress/data - // TODO: Change to just `getNotes( query )` after Gutenberg plugin uses @wordpress/data 3+ - const query = args.length === 1 ? args[ 0 ] : args[ 1 ]; - - try { - const orders = await apiFetch( { path: NAMESPACE + 'orders' + stringifyQuery( query ) } ); - dispatch( 'wc-admin' ).setOrders( orders, query ); - } catch ( error ) { - dispatch( 'wc-admin' ).setOrdersError( query ); - } - }, -}; diff --git a/plugins/woocommerce-admin/client/store/orders/selectors.js b/plugins/woocommerce-admin/client/store/orders/selectors.js deleted file mode 100644 index 25eec87f802..00000000000 --- a/plugins/woocommerce-admin/client/store/orders/selectors.js +++ /dev/null @@ -1,49 +0,0 @@ -/** @format */ - -/** - * External dependencies - */ -import { get } from 'lodash'; -import { select } from '@wordpress/data'; - -/** - * Internal dependencies - */ -import { getJsonString } from 'store/utils'; -import { ERROR } from 'store/constants'; - -/** - * Returns orders for a specific query. - * - * @param {Object} state Current state - * @param {Object} query Report query parameters - * @return {Array} Report details - */ -function getOrders( state, query = {} ) { - return get( state, [ 'orders', getJsonString( query ) ], [] ); -} - -export default { - getOrders, - - /** - * Returns true if a getOrders request is pending. - * - * @param {Object} state Current state - * @return {Boolean} True if the `getOrders` request is pending, false otherwise - */ - isGetOrdersRequesting( state, ...args ) { - return select( 'core/data' ).isResolving( 'wc-admin', 'getOrders', args ); - }, - - /** - * Returns true if a getOrders request has returned an error. - * - * @param {Object} state Current state - * @param {Object} query Query parameters - * @return {Boolean} True if the `getOrders` request has failed, false otherwise - */ - isGetOrdersError( state, query ) { - return ERROR === getOrders( state, query ); - }, -}; diff --git a/plugins/woocommerce-admin/client/store/orders/test/reducer.js b/plugins/woocommerce-admin/client/store/orders/test/reducer.js deleted file mode 100644 index 0af59e78779..00000000000 --- a/plugins/woocommerce-admin/client/store/orders/test/reducer.js +++ /dev/null @@ -1,80 +0,0 @@ -/** - * @format - */ - -/** - * External dependencies - */ -import deepFreeze from 'deep-freeze'; - -/** - * Internal dependencies - */ -import { ERROR } from 'store/constants'; -import ordersReducer from '../reducer'; -import { getJsonString } from 'store/utils'; - -describe( 'ordersReducer()', () => { - it( 'returns an empty data object by default', () => { - const state = ordersReducer( undefined, {} ); - expect( state ).toEqual( {} ); - } ); - - it( 'returns with received orders data', () => { - const originalState = deepFreeze( {} ); - const query = { - orderby: 'date', - }; - const orders = [ { id: 1214 }, { id: 1215 }, { id: 1216 } ]; - - const state = ordersReducer( originalState, { - type: 'SET_ORDERS', - query, - orders, - } ); - - const queryKey = getJsonString( query ); - expect( state[ queryKey ] ).toEqual( orders ); - } ); - - it( 'tracks multiple queries in orders data', () => { - const otherQuery = { - orderby: 'id', - }; - const otherQueryKey = getJsonString( otherQuery ); - const otherOrders = [ { id: 1 }, { id: 2 }, { id: 3 } ]; - const otherQueryState = { - [ otherQueryKey ]: otherOrders, - }; - const originalState = deepFreeze( otherQueryState ); - const query = { - orderby: 'date', - }; - const orders = [ { id: 1214 }, { id: 1215 }, { id: 1216 } ]; - - const state = ordersReducer( originalState, { - type: 'SET_ORDERS', - query, - orders, - } ); - - const queryKey = getJsonString( query ); - expect( state[ queryKey ] ).toEqual( orders ); - expect( state[ otherQueryKey ] ).toEqual( otherOrders ); - } ); - - it( 'returns with received error data', () => { - const originalState = deepFreeze( {} ); - const query = { - orderby: 'date', - }; - - const state = ordersReducer( originalState, { - type: 'SET_ORDERS_ERROR', - query, - } ); - - const queryKey = getJsonString( query ); - expect( state[ queryKey ] ).toEqual( ERROR ); - } ); -} ); diff --git a/plugins/woocommerce-admin/client/store/orders/test/resolvers.js b/plugins/woocommerce-admin/client/store/orders/test/resolvers.js deleted file mode 100644 index fbfe382c7da..00000000000 --- a/plugins/woocommerce-admin/client/store/orders/test/resolvers.js +++ /dev/null @@ -1,53 +0,0 @@ -/* -* @format -*/ - -/** - * External dependencies - */ -import apiFetch from '@wordpress/api-fetch'; -import { dispatch } from '@wordpress/data'; - -/** - * Internal dependencies - */ -import { NAMESPACE } from 'store/constants'; -import resolvers from '../resolvers'; - -const { getOrders } = resolvers; - -jest.mock( '@wordpress/data', () => ( { - dispatch: jest.fn().mockReturnValue( { - setOrders: jest.fn(), - } ), -} ) ); -jest.mock( '@wordpress/api-fetch', () => jest.fn() ); - -describe( 'getOrders', () => { - const ORDERS_1 = [ { id: 1214 }, { id: 1215 }, { id: 1216 } ]; - - const ORDERS_2 = [ { id: 1 }, { id: 2 }, { id: 3 } ]; - - beforeAll( () => { - apiFetch.mockImplementation( options => { - if ( options.path === NAMESPACE + 'orders' ) { - return Promise.resolve( ORDERS_1 ); - } - if ( options.path === NAMESPACE + 'orders?orderby=id' ) { - return Promise.resolve( ORDERS_2 ); - } - } ); - } ); - - it( 'returns requested report data', async () => { - expect.assertions( 1 ); - await getOrders(); - expect( dispatch().setOrders ).toHaveBeenCalledWith( ORDERS_1, undefined ); - } ); - - it( 'returns requested report data for a specific query', async () => { - expect.assertions( 1 ); - await getOrders( { orderby: 'id' } ); - expect( dispatch().setOrders ).toHaveBeenCalledWith( ORDERS_2, { orderby: 'id' } ); - } ); -} ); diff --git a/plugins/woocommerce-admin/client/store/orders/test/selectors.js b/plugins/woocommerce-admin/client/store/orders/test/selectors.js deleted file mode 100644 index 93737096e7f..00000000000 --- a/plugins/woocommerce-admin/client/store/orders/test/selectors.js +++ /dev/null @@ -1,92 +0,0 @@ -/* -* @format -*/ - -/** - * External dependencies - */ -import deepFreeze from 'deep-freeze'; -import { select } from '@wordpress/data'; - -/** - * Internal dependencies - */ -import { ERROR } from 'store/constants'; -import selectors from '../selectors'; -import { getJsonString } from 'store/utils'; - -const { getOrders, isGetOrdersRequesting, isGetOrdersError } = selectors; -jest.mock( '@wordpress/data', () => ( { - ...require.requireActual( '@wordpress/data' ), - select: jest.fn().mockReturnValue( {} ), -} ) ); - -const query = { orderby: 'date' }; -const queryKey = getJsonString( query ); - -describe( 'getOrders()', () => { - it( 'returns an empty array when no orders are available', () => { - const state = deepFreeze( {} ); - expect( getOrders( state, query ) ).toEqual( [] ); - } ); - - it( 'returns stored orders for current query', () => { - const orders = [ { id: 1214 }, { id: 1215 }, { id: 1216 } ]; - const state = deepFreeze( { - orders: { - [ queryKey ]: orders, - }, - } ); - expect( getOrders( state, query ) ).toEqual( orders ); - } ); -} ); - -describe( 'isGetOrdersRequesting()', () => { - beforeAll( () => { - select( 'core/data' ).isResolving = jest.fn().mockReturnValue( false ); - } ); - - afterAll( () => { - select( 'core/data' ).isResolving.mockRestore(); - } ); - - function setIsResolving( isResolving ) { - select( 'core/data' ).isResolving.mockImplementation( - ( reducerKey, selectorName ) => - isResolving && reducerKey === 'wc-admin' && selectorName === 'getOrders' - ); - } - - it( 'returns false if never requested', () => { - const result = isGetOrdersRequesting( query ); - expect( result ).toBe( false ); - } ); - - it( 'returns false if request finished', () => { - setIsResolving( false ); - const result = isGetOrdersRequesting( query ); - expect( result ).toBe( false ); - } ); - - it( 'returns true if requesting', () => { - setIsResolving( true ); - const result = isGetOrdersRequesting( query ); - expect( result ).toBe( true ); - } ); -} ); - -describe( 'isGetOrdersError()', () => { - it( 'returns false by default', () => { - const state = deepFreeze( {} ); - expect( isGetOrdersError( state, query ) ).toEqual( false ); - } ); - - it( 'returns true if ERROR constant is found', () => { - const state = deepFreeze( { - orders: { - [ queryKey ]: ERROR, - }, - } ); - expect( isGetOrdersError( state, query ) ).toEqual( true ); - } ); -} ); diff --git a/plugins/woocommerce-admin/client/store/reports/index.js b/plugins/woocommerce-admin/client/store/reports/index.js deleted file mode 100644 index 751b8f16e46..00000000000 --- a/plugins/woocommerce-admin/client/store/reports/index.js +++ /dev/null @@ -1,31 +0,0 @@ -/** @format */ - -/** - * External dependencies - */ -import { combineReducers } from '@wordpress/data'; - -/** - * Internal dependencies - */ -import items from './items'; -import stats from './stats'; - -export default { - reducer: combineReducers( { - items: items.reducer, - stats: stats.reducer, - } ), - actions: { - ...items.actions, - ...stats.actions, - }, - selectors: { - ...items.selectors, - ...stats.selectors, - }, - resolvers: { - ...items.resolvers, - ...stats.resolvers, - }, -}; diff --git a/plugins/woocommerce-admin/client/store/reports/items/actions.js b/plugins/woocommerce-admin/client/store/reports/items/actions.js deleted file mode 100644 index 579290e4203..00000000000 --- a/plugins/woocommerce-admin/client/store/reports/items/actions.js +++ /dev/null @@ -1,20 +0,0 @@ -/** @format */ - -export default { - setReportItems( endpoint, query, data, totalCount ) { - return { - type: 'SET_REPORT_ITEMS', - endpoint, - query: query || {}, - data, - totalCount, - }; - }, - setReportItemsError( endpoint, query ) { - return { - type: 'SET_REPORT_ITEMS_ERROR', - endpoint, - query: query || {}, - }; - }, -}; diff --git a/plugins/woocommerce-admin/client/store/reports/items/index.js b/plugins/woocommerce-admin/client/store/reports/items/index.js deleted file mode 100644 index 5d2b89160cc..00000000000 --- a/plugins/woocommerce-admin/client/store/reports/items/index.js +++ /dev/null @@ -1,15 +0,0 @@ -/** @format */ -/** - * Internal dependencies - */ -import actions from './actions'; -import reducer from './reducer'; -import resolvers from './resolvers'; -import selectors from './selectors'; - -export default { - actions, - reducer, - resolvers, - selectors, -}; diff --git a/plugins/woocommerce-admin/client/store/reports/items/reducer.js b/plugins/woocommerce-admin/client/store/reports/items/reducer.js deleted file mode 100644 index ac75b509c1f..00000000000 --- a/plugins/woocommerce-admin/client/store/reports/items/reducer.js +++ /dev/null @@ -1,39 +0,0 @@ -/** @format */ - -/** - * External dependencies - */ -import { merge } from 'lodash'; - -/** - * Internal dependencies - */ -import { ERROR } from 'store/constants'; -import { getJsonString } from 'store/utils'; - -const DEFAULT_STATE = {}; - -export default function reportItemsReducer( state = DEFAULT_STATE, action ) { - const queryKey = getJsonString( action.query ); - - switch ( action.type ) { - case 'SET_REPORT_ITEMS': - return merge( {}, state, { - [ action.endpoint ]: { - [ queryKey ]: { - data: action.data, - totalCount: action.totalCount, - }, - }, - } ); - - case 'SET_REPORT_ITEMS_ERROR': - return merge( {}, state, { - [ action.endpoint ]: { - [ queryKey ]: ERROR, - }, - } ); - } - - return state; -} diff --git a/plugins/woocommerce-admin/client/store/reports/items/resolvers.js b/plugins/woocommerce-admin/client/store/reports/items/resolvers.js deleted file mode 100644 index 811604ef1d0..00000000000 --- a/plugins/woocommerce-admin/client/store/reports/items/resolvers.js +++ /dev/null @@ -1,36 +0,0 @@ -/** @format */ - -/** - * External dependencies - */ -import apiFetch from '@wordpress/api-fetch'; -import { dispatch } from '@wordpress/data'; - -/** - * WooCommerce dependencies - */ -import { stringifyQuery } from '@woocommerce/navigation'; - -/** - * Internal dependencies - */ -import { NAMESPACE } from 'store/constants'; - -export default { - async getReportItems( ...args ) { - const [ endpoint, query ] = args.slice( -2 ); - - try { - const response = await apiFetch( { - parse: false, - path: NAMESPACE + 'reports/' + endpoint + stringifyQuery( query ), - } ); - - const itemsData = await response.json(); - const totalCount = parseInt( response.headers.get( 'x-wp-total' ) ); - dispatch( 'wc-admin' ).setReportItems( endpoint, query, itemsData, totalCount ); - } catch ( error ) { - dispatch( 'wc-admin' ).setReportItemsError( endpoint, query ); - } - }, -}; diff --git a/plugins/woocommerce-admin/client/store/reports/items/selectors.js b/plugins/woocommerce-admin/client/store/reports/items/selectors.js deleted file mode 100644 index cb4fd0e64d5..00000000000 --- a/plugins/woocommerce-admin/client/store/reports/items/selectors.js +++ /dev/null @@ -1,51 +0,0 @@ -/** @format */ - -/** - * External dependencies - */ -import { get } from 'lodash'; -import { select } from '@wordpress/data'; - -/** - * Internal dependencies - */ -import { ERROR } from 'store/constants'; -import { getJsonString } from 'store/utils'; - -/** - * Returns report items for a specific endpoint query. - * - * @param {Object} state Current state - * @param {String} endpoint Stats endpoint - * @param {Object} query Report query parameters - * @return {Object} Report details - */ -function getReportItems( state, endpoint, query = {} ) { - return get( state, [ 'reports', 'items', endpoint, getJsonString( query ) ], { data: [] } ); -} - -export default { - getReportItems, - - /** - * Returns true if a getReportItems request is pending. - * - * @param {Object} state Current state - * @return {Boolean} True if the `getReportItems` request is pending, false otherwise - */ - isGetReportItemsRequesting( state, ...args ) { - return select( 'core/data' ).isResolving( 'wc-admin', 'getReportItems', args ); - }, - - /** - * Returns true if a getReportItems request has returned an error. - * - * @param {Object} state Current state - * @param {String} endpoint Items endpoint - * @param {Object} query Report query parameters - * @return {Boolean} True if the `getReportItems` request has failed, false otherwise - */ - isGetReportItemsError( state, endpoint, query ) { - return ERROR === getReportItems( state, endpoint, query ); - }, -}; diff --git a/plugins/woocommerce-admin/client/store/reports/items/test/reducer.js b/plugins/woocommerce-admin/client/store/reports/items/test/reducer.js deleted file mode 100644 index d743b2cf77c..00000000000 --- a/plugins/woocommerce-admin/client/store/reports/items/test/reducer.js +++ /dev/null @@ -1,104 +0,0 @@ -/** - * @format - */ - -/** - * External dependencies - */ -import deepFreeze from 'deep-freeze'; - -/** - * Internal dependencies - */ -import { ERROR } from 'store/constants'; -import reportItemsReducer from '../reducer'; -import { getJsonString } from 'store/utils'; - -describe( 'reportItemsReducer()', () => { - const endpoint = 'coupons'; - - it( 'returns an empty object by default', () => { - const state = reportItemsReducer( undefined, {} ); - expect( state ).toEqual( {} ); - } ); - - it( 'returns with received items data', () => { - const originalState = deepFreeze( {} ); - const query = { - orderby: 'orders_count', - }; - const itemsData = [ { id: 1214 }, { id: 1215 }, { id: 1216 } ]; - const itemsTotalCount = 50; - - const state = reportItemsReducer( originalState, { - type: 'SET_REPORT_ITEMS', - endpoint, - query, - data: itemsData, - totalCount: itemsTotalCount, - } ); - - const queryKey = getJsonString( query ); - expect( state[ endpoint ][ queryKey ] ).toEqual( { - data: itemsData, - totalCount: itemsTotalCount, - } ); - } ); - - it( 'tracks multiple queries in items data', () => { - const otherQuery = { - orderby: 'id', - }; - const otherQueryKey = getJsonString( otherQuery ); - const otherItemsData = [ { id: 1 }, { id: 2 }, { id: 3 } ]; - const otherItemsTotalCount = 70; - const otherQueryState = { - [ endpoint ]: { - [ otherQueryKey ]: { - data: otherItemsData, - totalCount: otherItemsTotalCount, - }, - }, - }; - const originalState = deepFreeze( otherQueryState ); - const query = { - orderby: 'orders_count', - }; - const itemsData = [ { id: 1214 }, { id: 1215 }, { id: 1216 } ]; - const itemsTotalCount = 50; - - const state = reportItemsReducer( originalState, { - type: 'SET_REPORT_ITEMS', - endpoint, - query, - data: itemsData, - totalCount: itemsTotalCount, - } ); - - const queryKey = getJsonString( query ); - expect( state[ endpoint ][ queryKey ] ).toEqual( { - data: itemsData, - totalCount: itemsTotalCount, - } ); - expect( state[ endpoint ][ otherQueryKey ] ).toEqual( { - data: otherItemsData, - totalCount: otherItemsTotalCount, - } ); - } ); - - it( 'returns with received error data', () => { - const originalState = deepFreeze( {} ); - const query = { - orderby: 'orders_count', - }; - - const state = reportItemsReducer( originalState, { - type: 'SET_REPORT_ITEMS_ERROR', - endpoint, - query, - } ); - - const queryKey = getJsonString( query ); - expect( state[ endpoint ][ queryKey ] ).toEqual( ERROR ); - } ); -} ); diff --git a/plugins/woocommerce-admin/client/store/reports/items/test/resolvers.js b/plugins/woocommerce-admin/client/store/reports/items/test/resolvers.js deleted file mode 100644 index 1e544bc6f5b..00000000000 --- a/plugins/woocommerce-admin/client/store/reports/items/test/resolvers.js +++ /dev/null @@ -1,74 +0,0 @@ -/* -* @format -*/ - -/** - * External dependencies - */ -import apiFetch from '@wordpress/api-fetch'; -import { dispatch } from '@wordpress/data'; - -/** - * Internal dependencies - */ -import resolvers from '../resolvers'; - -const { getReportItems } = resolvers; - -jest.mock( '@wordpress/data', () => ( { - dispatch: jest.fn().mockReturnValue( { - setReportItems: jest.fn(), - } ), -} ) ); -jest.mock( '@wordpress/api-fetch', () => jest.fn() ); - -describe( 'getReportItems', () => { - const ITEMS_1 = [ { id: 1214 }, { id: 1215 }, { id: 1216 } ]; - const ITEMS_1_COUNT = 50; - const ITEMS_2 = [ { id: 1 }, { id: 2 }, { id: 3 } ]; - const ITEMS_2_COUNT = 75; - const endpoint = 'products'; - - beforeAll( () => { - apiFetch.mockImplementation( options => { - if ( options.path === `/wc/v4/reports/${ endpoint }` ) { - return Promise.resolve( { - headers: { - get: () => ITEMS_1_COUNT, - }, - json: () => Promise.resolve( ITEMS_1 ), - } ); - } - if ( options.path === `/wc/v4/reports/${ endpoint }?orderby=id` ) { - return Promise.resolve( { - headers: { - get: () => ITEMS_2_COUNT, - }, - json: () => Promise.resolve( ITEMS_2 ), - } ); - } - } ); - } ); - - it( 'returns requested report data', async () => { - expect.assertions( 1 ); - await getReportItems( endpoint ); - expect( dispatch().setReportItems ).toHaveBeenCalledWith( - endpoint, - undefined, - ITEMS_1, - ITEMS_1_COUNT - ); - } ); - - it( 'returns requested report data for a specific query', async () => { - expect.assertions( 1 ); - await getReportItems( endpoint, { orderby: 'id' } ); - expect( dispatch().setReportItems ).toHaveBeenCalledWith( - endpoint, - { orderby: 'id' }, - ITEMS_2, - ITEMS_2_COUNT - ); - } ); -} ); diff --git a/plugins/woocommerce-admin/client/store/reports/items/test/selectors.js b/plugins/woocommerce-admin/client/store/reports/items/test/selectors.js deleted file mode 100644 index 504217506cb..00000000000 --- a/plugins/woocommerce-admin/client/store/reports/items/test/selectors.js +++ /dev/null @@ -1,106 +0,0 @@ -/* -* @format -*/ - -/** - * External dependencies - */ -import deepFreeze from 'deep-freeze'; -import { select } from '@wordpress/data'; - -/** - * Internal dependencies - */ -import { ERROR } from 'store/constants'; -import { getJsonString } from 'store/utils'; -import selectors from '../selectors'; - -const { getReportItems, isGetReportItemsRequesting, isGetReportItemsError } = selectors; -jest.mock( '@wordpress/data', () => ( { - ...require.requireActual( '@wordpress/data' ), - select: jest.fn().mockReturnValue( {} ), -} ) ); - -const query = { orderby: 'date' }; -const queryKey = getJsonString( query ); -const endpoint = 'coupons'; - -describe( 'getReportItems()', () => { - it( 'returns an empty object when no items are available', () => { - const state = deepFreeze( {} ); - expect( getReportItems( state, endpoint, query ) ).toEqual( { data: [] } ); - } ); - - it( 'returns stored items for current query', () => { - const itemsData = [ { id: 1214 }, { id: 1215 }, { id: 1216 } ]; - const itemsTotalCount = 50; - const queryState = { - data: itemsData, - totalCount: itemsTotalCount, - }; - const state = deepFreeze( { - reports: { - items: { - [ endpoint ]: { - [ queryKey ]: queryState, - }, - }, - }, - } ); - expect( getReportItems( state, endpoint, query ) ).toEqual( queryState ); - } ); -} ); - -describe( 'isGetReportItemsRequesting()', () => { - beforeAll( () => { - select( 'core/data' ).isResolving = jest.fn().mockReturnValue( false ); - } ); - - afterAll( () => { - select( 'core/data' ).isResolving.mockRestore(); - } ); - - function setIsResolving( isResolving ) { - select( 'core/data' ).isResolving.mockImplementation( - ( reducerKey, selectorName ) => - isResolving && reducerKey === 'wc-admin' && selectorName === 'getReportItems' - ); - } - - it( 'returns false if never requested', () => { - const result = isGetReportItemsRequesting( endpoint ); - expect( result ).toBe( false ); - } ); - - it( 'returns false if request finished', () => { - setIsResolving( false ); - const result = isGetReportItemsRequesting( endpoint ); - expect( result ).toBe( false ); - } ); - - it( 'returns true if requesting', () => { - setIsResolving( true ); - const result = isGetReportItemsRequesting( endpoint ); - expect( result ).toBe( true ); - } ); -} ); - -describe( 'isGetReportItemsError()', () => { - it( 'returns false by default', () => { - const state = deepFreeze( {} ); - expect( isGetReportItemsError( state, endpoint, query ) ).toEqual( false ); - } ); - - it( 'returns true if ERROR constant is found', () => { - const state = deepFreeze( { - reports: { - items: { - [ endpoint ]: { - [ queryKey ]: ERROR, - }, - }, - }, - } ); - expect( isGetReportItemsError( state, endpoint, query ) ).toEqual( true ); - } ); -} ); diff --git a/plugins/woocommerce-admin/client/store/reports/stats/actions.js b/plugins/woocommerce-admin/client/store/reports/stats/actions.js deleted file mode 100644 index 94a7bf06d57..00000000000 --- a/plugins/woocommerce-admin/client/store/reports/stats/actions.js +++ /dev/null @@ -1,21 +0,0 @@ -/** @format */ - -export default { - setReportStats( endpoint, report, query, totalResults, totalPages ) { - return { - type: 'SET_REPORT_STATS', - endpoint, - report, - totalResults, - totalPages, - query: query || {}, - }; - }, - setReportStatsError( endpoint, query ) { - return { - type: 'SET_REPORT_STATS_ERROR', - endpoint, - query: query || {}, - }; - }, -}; diff --git a/plugins/woocommerce-admin/client/store/reports/stats/index.js b/plugins/woocommerce-admin/client/store/reports/stats/index.js deleted file mode 100644 index 2f5bda3abaa..00000000000 --- a/plugins/woocommerce-admin/client/store/reports/stats/index.js +++ /dev/null @@ -1,16 +0,0 @@ -/** @format */ - -/** - * Internal dependencies - */ -import actions from './actions'; -import reducer from './reducer'; -import resolvers from './resolvers'; -import selectors from './selectors'; - -export default { - actions, - reducer, - resolvers, - selectors, -}; diff --git a/plugins/woocommerce-admin/client/store/reports/stats/reducer.js b/plugins/woocommerce-admin/client/store/reports/stats/reducer.js deleted file mode 100644 index f733db1f92f..00000000000 --- a/plugins/woocommerce-admin/client/store/reports/stats/reducer.js +++ /dev/null @@ -1,40 +0,0 @@ -/** @format */ - -/** - * External dependencies - */ -import { merge } from 'lodash'; - -/** - * Internal dependencies - */ -import { ERROR } from 'store/constants'; -import { getJsonString } from 'store/utils'; - -const DEFAULT_STATE = {}; - -export default function reportStatsReducer( state = DEFAULT_STATE, action ) { - if ( 'SET_REPORT_STATS' === action.type ) { - const queryKey = getJsonString( action.query ); - return merge( {}, state, { - [ action.endpoint ]: { - [ queryKey ]: { - data: action.report, - totalResults: action.totalResults, - totalPages: action.totalPages, - }, - }, - } ); - } - - if ( 'SET_REPORT_STATS_ERROR' === action.type ) { - const queryKey = getJsonString( action.query ); - return merge( {}, state, { - [ action.endpoint ]: { - [ queryKey ]: ERROR, - }, - } ); - } - - return state; -} diff --git a/plugins/woocommerce-admin/client/store/reports/stats/resolvers.js b/plugins/woocommerce-admin/client/store/reports/stats/resolvers.js deleted file mode 100644 index 83f35864089..00000000000 --- a/plugins/woocommerce-admin/client/store/reports/stats/resolvers.js +++ /dev/null @@ -1,63 +0,0 @@ -/** @format */ - -/** - * External dependencies - */ -import apiFetch from '@wordpress/api-fetch'; -import { dispatch } from '@wordpress/data'; - -/** - * WooCommerce dependencies - */ -import { stringifyQuery } from '@woocommerce/navigation'; - -/** - * Internal dependencies - */ -import { NAMESPACE, SWAGGERNAMESPACE } from 'store/constants'; - -export default { - // TODO: Use controls data plugin or fresh-data instead of async - async getReportStats( ...args ) { - // This is interim code to work with either 2.x or 3.x version of @wordpress/data - // TODO: Change to just `getNotes( endpoint, query )` - // after Gutenberg plugin uses @wordpress/data 3+ - const [ endpoint, query ] = args.length === 2 ? args : args.slice( 1, 3 ); - const statEndpoints = [ 'orders', 'revenue', 'products', 'taxes' ]; - - let apiPath = endpoint + stringifyQuery( query ); - - // TODO: Remove once swagger endpoints are phased out. - const swaggerEndpoints = [ 'categories' ]; - if ( swaggerEndpoints.indexOf( endpoint ) >= 0 ) { - apiPath = SWAGGERNAMESPACE + 'reports/' + endpoint + '/stats' + stringifyQuery( query ); - try { - const response = await fetch( apiPath ); - - const report = await response.json(); - dispatch( 'wc-admin' ).setReportStats( endpoint, report, query ); - } catch ( error ) { - dispatch( 'wc-admin' ).setReportStatsError( endpoint, query ); - } - return; - } - - if ( statEndpoints.indexOf( endpoint ) >= 0 ) { - apiPath = NAMESPACE + 'reports/' + endpoint + '/stats' + stringifyQuery( query ); - } - - try { - const response = await apiFetch( { - path: apiPath, - parse: false, - } ); - - const report = await response.json(); - const totalResults = parseInt( response.headers.get( 'x-wp-total' ) ); - const totalPages = parseInt( response.headers.get( 'x-wp-totalpages' ) ); - dispatch( 'wc-admin' ).setReportStats( endpoint, report, query, totalResults, totalPages ); - } catch ( error ) { - dispatch( 'wc-admin' ).setReportStatsError( endpoint, query ); - } - }, -}; diff --git a/plugins/woocommerce-admin/client/store/reports/stats/selectors.js b/plugins/woocommerce-admin/client/store/reports/stats/selectors.js deleted file mode 100644 index 76bca5db212..00000000000 --- a/plugins/woocommerce-admin/client/store/reports/stats/selectors.js +++ /dev/null @@ -1,52 +0,0 @@ -/** @format */ - -/** - * External dependencies - */ -import { get } from 'lodash'; -import { select } from '@wordpress/data'; - -/** - * Internal dependencies - */ -import { ERROR } from 'store/constants'; -import { getJsonString } from 'store/utils'; - -/** - * Returns report stats details for a specific endpoint query. - * - * @param {Object} state Current state - * @param {String} endpoint Stats endpoint - * @param {Object} query Report query parameters - * @return {Object} Report details - */ -function getReportStats( state, endpoint, query = {} ) { - const queries = get( state, [ 'reports', 'stats', endpoint ], {} ); - return queries[ getJsonString( query ) ] || null; -} - -export default { - getReportStats, - - /** - * Returns true if a stats query is pending. - * - * @param {Object} state Current state - * @return {Boolean} True if the `getReportStats` request is pending, false otherwise - */ - isReportStatsRequesting( state, ...args ) { - return select( 'core/data' ).isResolving( 'wc-admin', 'getReportStats', args ); - }, - - /** - * Returns true if a report stat request has returned an error. - * - * @param {Object} state Current state - * @param {String} endpoint Stats endpoint - * @param {Object} query Report query parameters - * @return {Boolean} True if the `getReportStats` request has failed, false otherwise - */ - isReportStatsError( state, endpoint, query ) { - return ERROR === getReportStats( state, endpoint, query ); - }, -}; diff --git a/plugins/woocommerce-admin/client/store/reports/stats/test/reducer.js b/plugins/woocommerce-admin/client/store/reports/stats/test/reducer.js deleted file mode 100644 index ea8dc82552a..00000000000 --- a/plugins/woocommerce-admin/client/store/reports/stats/test/reducer.js +++ /dev/null @@ -1,164 +0,0 @@ -/** - * @format - */ - -/** - * External dependencies - */ -import deepFreeze from 'deep-freeze'; - -/** - * Internal dependencies - */ -import { ERROR } from 'store/constants'; -import reportStatsReducer from '../reducer'; -import { getJsonString } from 'store/utils'; - -describe( 'reportStatsReducer()', () => { - it( 'returns an empty data object by default', () => { - const state = reportStatsReducer( undefined, {} ); - expect( state ).toEqual( {} ); - } ); - - it( 'returns with received report data', () => { - const originalState = deepFreeze( {} ); - const query = { - after: '2018-01-04T00:00:00+00:00', - before: '2018-07-14T00:00:00+00:00', - interval: 'day', - }; - const report = { - totals: { - orders_count: 10, - num_items_sold: 9, - }, - interval: [ 0, 1, 2 ], - }; - const endpoint = 'revenue'; - - const state = reportStatsReducer( originalState, { - type: 'SET_REPORT_STATS', - endpoint, - query, - report, - totalResults: 3, - totalPages: 1, - } ); - - const queryKey = getJsonString( query ); - expect( state[ endpoint ][ queryKey ] ).toEqual( { - data: { ...report }, - totalResults: 3, - totalPages: 1, - } ); - } ); - - it( 'tracks multiple queries per endpoint in report data', () => { - const otherQuery = { - after: '2018-01-04T00:00:00+00:00', - before: '2018-07-14T00:00:00+00:00', - interval: 'week', - }; - const otherQueryKey = getJsonString( otherQuery ); - const otherQueryState = { - revenue: { - [ otherQueryKey ]: { data: { totals: 1000 } }, - }, - }; - const originalState = deepFreeze( otherQueryState ); - const query = { - after: '2018-01-04T00:00:00+00:00', - before: '2018-07-14T00:00:00+00:00', - interval: 'day', - }; - const report = { - totals: { - orders_count: 10, - num_items_sold: 9, - }, - interval: [ 0, 1, 2 ], - }; - const endpoint = 'revenue'; - - const state = reportStatsReducer( originalState, { - type: 'SET_REPORT_STATS', - endpoint, - query, - report, - totalResults: 3, - totalPages: 1, - } ); - - const queryKey = getJsonString( query ); - expect( state[ endpoint ][ queryKey ] ).toEqual( { - data: { ...report }, - totalResults: 3, - totalPages: 1, - } ); - expect( state[ endpoint ][ otherQueryKey ].data.totals ).toEqual( 1000 ); - } ); - - it( 'tracks multiple endpoints in report data', () => { - const productsQuery = { - after: '2018-01-04T00:00:00+00:00', - before: '2018-07-14T00:00:00+00:00', - interval: 'week', - }; - const productsQueryKey = getJsonString( productsQuery ); - const productsQueryState = { - products: { - [ productsQueryKey ]: { data: { totals: 1999 } }, - }, - }; - const originalState = deepFreeze( productsQueryState ); - const query = { - after: '2018-01-04T00:00:00+00:00', - before: '2018-07-14T00:00:00+00:00', - interval: 'day', - }; - const report = { - totals: { - orders_count: 10, - num_items_sold: 9, - }, - interval: [ 0, 1, 2 ], - }; - const endpoint = 'revenue'; - - const state = reportStatsReducer( originalState, { - type: 'SET_REPORT_STATS', - endpoint, - query, - report, - totalResults: 3, - totalPages: 1, - } ); - - const queryKey = getJsonString( query ); - expect( state[ endpoint ][ queryKey ] ).toEqual( { - data: { ...report }, - totalResults: 3, - totalPages: 1, - } ); - expect( state.products[ productsQueryKey ].data.totals ).toEqual( 1999 ); - } ); - - it( 'returns with received error data', () => { - const originalState = deepFreeze( {} ); - const query = { - after: '2018-01-04T00:00:00+00:00', - before: '2018-07-14T00:00:00+00:00', - interval: 'day', - }; - const endpoint = 'revenue'; - - const state = reportStatsReducer( originalState, { - type: 'SET_REPORT_STATS_ERROR', - endpoint, - query, - } ); - - const queryKey = getJsonString( query ); - expect( state[ endpoint ][ queryKey ] ).toEqual( ERROR ); - } ); -} ); diff --git a/plugins/woocommerce-admin/client/store/reports/stats/test/resolvers.js b/plugins/woocommerce-admin/client/store/reports/stats/test/resolvers.js deleted file mode 100644 index 66bde02d99e..00000000000 --- a/plugins/woocommerce-admin/client/store/reports/stats/test/resolvers.js +++ /dev/null @@ -1,107 +0,0 @@ -/* -* @format -*/ - -/** - * External dependencies - */ -import apiFetch from '@wordpress/api-fetch'; -import { dispatch } from '@wordpress/data'; - -/** - * Internal dependencies - */ -import resolvers from '../resolvers'; - -const { getReportStats } = resolvers; - -jest.mock( '@wordpress/data', () => ( { - dispatch: jest.fn().mockReturnValue( { - setReportStats: jest.fn(), - } ), -} ) ); -jest.mock( '@wordpress/api-fetch', () => jest.fn() ); - -describe( 'getReportStats', () => { - const REPORT_1 = { - totals: { - orders_count: 10, - num_items_sold: 9, - }, - interval: [ 0, 1, 2 ], - }; - const REPORT_1_TOTALS = { - 'x-wp-total': 10, - 'x-wp-totalpages': 2, - }; - - const REPORT_2 = { - totals: { - orders_count: 5, - items_sold: 5, - gross_revenue: 999.99, - }, - intervals: [ - { - interval: 'week', - subtotals: {}, - }, - ], - }; - const REPORT_2_TOTALS = { - 'x-wp-total': 20, - 'x-wp-totalpages': 4, - }; - - beforeAll( () => { - apiFetch.mockImplementation( options => { - if ( options.path === '/wc/v4/reports/revenue/stats' ) { - return Promise.resolve( { - headers: { - get: header => REPORT_1_TOTALS[ header ], - }, - json: () => Promise.resolve( REPORT_1 ), - } ); - } - if ( options.path === '/wc/v4/reports/products/stats?interval=week' ) { - return Promise.resolve( { - headers: { - get: header => REPORT_2_TOTALS[ header ], - }, - json: () => Promise.resolve( REPORT_2 ), - } ); - } - } ); - } ); - - it( 'returns requested report data', async () => { - expect.assertions( 1 ); - const endpoint = 'revenue'; - - await getReportStats( endpoint, undefined ); - - expect( dispatch().setReportStats ).toHaveBeenCalledWith( - endpoint, - REPORT_1, - undefined, - REPORT_1_TOTALS[ 'x-wp-total' ], - REPORT_1_TOTALS[ 'x-wp-totalpages' ] - ); - } ); - - it( 'returns requested report data for a specific query', async () => { - expect.assertions( 1 ); - const endpoint = 'products'; - const query = { interval: 'week' }; - - await getReportStats( endpoint, query ); - - expect( dispatch().setReportStats ).toHaveBeenCalledWith( - endpoint, - REPORT_2, - query, - REPORT_2_TOTALS[ 'x-wp-total' ], - REPORT_2_TOTALS[ 'x-wp-totalpages' ] - ); - } ); -} ); diff --git a/plugins/woocommerce-admin/client/store/reports/stats/test/selectors.js b/plugins/woocommerce-admin/client/store/reports/stats/test/selectors.js deleted file mode 100644 index b48d4e75c74..00000000000 --- a/plugins/woocommerce-admin/client/store/reports/stats/test/selectors.js +++ /dev/null @@ -1,102 +0,0 @@ -/* -* @format -*/ - -/** - * External dependencies - */ -import deepFreeze from 'deep-freeze'; -import { select } from '@wordpress/data'; - -/** - * Internal dependencies - */ -import { ERROR } from 'store/constants'; -import selectors from '../selectors'; - -const { getReportStats, isReportStatsRequesting, isReportStatsError } = selectors; -jest.mock( '@wordpress/data', () => ( { - ...require.requireActual( '@wordpress/data' ), - select: jest.fn().mockReturnValue( {} ), -} ) ); - -const endpointName = 'revenue'; - -describe( 'getReportStats()', () => { - it( 'returns null when no report data is available', () => { - const state = deepFreeze( {} ); - expect( getReportStats( state, endpointName ) ).toEqual( null ); - } ); - it( 'returns stored report information by endpoint and query combination', () => { - const report = { - totals: { - orders_count: 10, - num_items_sold: 9, - }, - interval: [ 0, 1, 2 ], - }; - const state = deepFreeze( { - reports: { - stats: { - revenue: { - '{}': { ...report }, - }, - }, - }, - } ); - expect( getReportStats( state, endpointName ) ).toEqual( report ); - } ); -} ); - -describe( 'isReportStatsRequesting()', () => { - beforeAll( () => { - select( 'core/data' ).isResolving = jest.fn().mockReturnValue( false ); - } ); - - afterAll( () => { - select( 'core/data' ).isResolving.mockRestore(); - } ); - - function setIsResolving( isResolving ) { - select( 'core/data' ).isResolving.mockImplementation( - ( reducerKey, selectorName ) => - isResolving && reducerKey === 'wc-admin' && selectorName === 'getReportStats' - ); - } - - it( 'returns false if never requested', () => { - const result = isReportStatsRequesting( endpointName ); - expect( result ).toBe( false ); - } ); - - it( 'returns false if request finished', () => { - setIsResolving( false ); - const result = isReportStatsRequesting( endpointName ); - expect( result ).toBe( false ); - } ); - - it( 'returns true if requesting', () => { - setIsResolving( true ); - const result = isReportStatsRequesting( endpointName ); - expect( result ).toBe( true ); - } ); -} ); - -describe( 'isReportStatsError()', () => { - it( 'returns false by default', () => { - const state = deepFreeze( {} ); - expect( isReportStatsError( state, endpointName ) ).toEqual( false ); - } ); - it( 'returns true if ERROR constant is found', () => { - const state = deepFreeze( { - reports: { - stats: { - revenue: { - '{}': ERROR, - }, - }, - }, - } ); - expect( isReportStatsError( state, endpointName ) ).toEqual( true ); - } ); -} ); diff --git a/plugins/woocommerce-admin/client/store/reports/test/utils.js b/plugins/woocommerce-admin/client/store/reports/test/utils.js deleted file mode 100644 index 707588bc3f1..00000000000 --- a/plugins/woocommerce-admin/client/store/reports/test/utils.js +++ /dev/null @@ -1,598 +0,0 @@ -/* -* @format -*/ - -/** - * Internal dependencies - */ -import { - isReportDataEmpty, - getReportChartData, - getSummaryNumbers, - getFilterQuery, - getReportTableData, - timeStampFilterDates, -} from '../utils'; -import * as ordersConfig from 'analytics/report/orders/config'; - -jest.mock( '../utils', () => ( { - ...require.requireActual( '../utils' ), - getReportTableQuery: () => ( { - after: '2018-10-10', - before: '2018-10-10', - } ), -} ) ); - -describe( 'isReportDataEmpty()', () => { - it( 'returns false if report is valid', () => { - const report = { - data: { - totals: { - orders_count: 10, - num_items_sold: 9, - }, - intervals: [ 0, 1, 2 ], - }, - }; - expect( isReportDataEmpty( report ) ).toEqual( false ); - } ); - it( 'returns true if report object is undefined', () => { - expect( isReportDataEmpty( undefined ) ).toEqual( true ); - } ); - it( 'returns true if data response object is missing', () => { - expect( isReportDataEmpty( {} ) ).toEqual( true ); - } ); - it( 'returns true if totals response object is missing', () => { - expect( isReportDataEmpty( { data: {} } ) ).toEqual( true ); - } ); - it( 'returns true if intervals response object is empty', () => { - expect( isReportDataEmpty( { data: { intervals: [], totals: 2 } } ) ).toEqual( true ); - } ); -} ); - -describe( 'getReportChartData()', () => { - const select = jest.fn().mockReturnValue( {} ); - const response = { - isEmpty: false, - isError: false, - isRequesting: false, - data: { - totals: null, - intervals: [], - }, - }; - - beforeAll( () => { - select( 'wc-api' ).getReportStats = jest.fn().mockReturnValue( {} ); - select( 'wc-api' ).isReportStatsRequesting = jest.fn().mockReturnValue( false ); - select( 'wc-api' ).getReportStatsError = jest.fn().mockReturnValue( false ); - } ); - - afterAll( () => { - select( 'wc-api' ).getReportStats.mockRestore(); - select( 'wc-api' ).isReportStatsRequesting.mockRestore(); - select( 'wc-api' ).getReportStatsError.mockRestore(); - } ); - - function setGetReportStats( func ) { - select( 'wc-api' ).getReportStats.mockImplementation( ( ...args ) => func( ...args ) ); - } - - function setIsReportStatsRequesting( func ) { - select( 'wc-api' ).isReportStatsRequesting.mockImplementation( ( ...args ) => func( ...args ) ); - } - - function setGetReportStatsError( func ) { - select( 'wc-api' ).getReportStatsError.mockImplementation( ( ...args ) => func( ...args ) ); - } - - it( 'returns isRequesting if first request is in progress', () => { - setIsReportStatsRequesting( () => { - return true; - } ); - const result = getReportChartData( 'revenue', 'primary', {}, select ); - expect( result ).toEqual( { ...response, isRequesting: true } ); - } ); - - it( 'returns isError if first request errors', () => { - setIsReportStatsRequesting( () => { - return false; - } ); - setGetReportStatsError( () => { - return { error: 'Error' }; - } ); - const result = getReportChartData( 'revenue', 'primary', {}, select ); - expect( result ).toEqual( { ...response, isError: true } ); - } ); - - it( 'returns results after single page of data', () => { - const data = { - totals: { - orders_count: 115, - gross_revenue: 13966.92, - }, - intervals: [ - { - interval: 'day', - date_start: '2018-07-01 00:00:00', - subtotals: { - orders_count: 115, - gross_revenue: 13966.92, - }, - }, - ], - }; - - setIsReportStatsRequesting( () => { - return false; - } ); - setGetReportStatsError( () => { - return undefined; - } ); - setGetReportStats( () => { - return { - totalResults: 1, - data, - }; - } ); - - const result = getReportChartData( 'revenue', 'primary', {}, select ); - expect( result ).toEqual( { ...response, data: { ...data } } ); - } ); - - it( 'returns combined results for multiple pages of data', () => { - const totalResults = 110; - const orders_count = 115; - const gross_revenue = 13966.92; - const intervals = []; - for ( let i = 0; i < totalResults; i++ ) { - intervals.push( { - interval: 'day', - date_start: '2018-07-01 00:00:00', - subtotals: { orders_count, gross_revenue }, - } ); - } - const totals = { - orders_count: orders_count * totalResults, - gross_revenue: gross_revenue * totalResults, - }; - - setIsReportStatsRequesting( () => { - return false; - } ); - setGetReportStatsError( () => { - return undefined; - } ); - setGetReportStats( ( endpoint, query ) => { - if ( 2 === query.page ) { - return { - totalResults, - data: { - totals, - intervals: intervals.slice( 100, 110 ), - }, - }; - } - return { - totalResults, - data: { - totals, - intervals: intervals.slice( 0, 100 ), - }, - }; - } ); - - const actualResponse = getReportChartData( 'revenue', 'primary', {}, select ); - const expectedResponse = { - ...response, - data: { - totals, - intervals, - }, - }; - - expect( actualResponse ).toEqual( expectedResponse ); - } ); - - it( 'returns isRequesting if additional requests are in progress', () => { - setIsReportStatsRequesting( ( endpoint, query ) => { - if ( 2 === query.page ) { - return true; - } - return false; - } ); - setGetReportStatsError( () => { - return undefined; - } ); - - const result = getReportChartData( 'revenue', 'primary', {}, select ); - expect( result ).toEqual( { ...response, isRequesting: true } ); - } ); - - it( 'returns isError if additional requests return an error', () => { - setIsReportStatsRequesting( () => { - return false; - } ); - setGetReportStatsError( ( endpoint, query ) => { - if ( 2 === query.page ) { - return { error: 'Error' }; - } - return undefined; - } ); - const result = getReportChartData( 'revenue', 'primary', {}, select ); - expect( result ).toEqual( { ...response, isError: true } ); - } ); - - it( 'returns empty state if a query returns no data', () => { - setIsReportStatsRequesting( () => { - return false; - } ); - setGetReportStatsError( () => { - return undefined; - } ); - setGetReportStats( () => { - return { - totalResults: undefined, - data: {}, - }; - } ); - - const result = getReportChartData( 'revenue', 'primary', {}, select ); - expect( result ).toEqual( { ...response, isEmpty: true } ); - } ); -} ); - -describe( 'getSummaryNumbers()', () => { - const select = jest.fn().mockReturnValue( {} ); - const response = { - isError: false, - isRequesting: false, - totals: { - primary: null, - secondary: null, - }, - }; - - const query = { - after: '2018-10-10', - before: '2018-10-10', - period: 'custom', - compare: 'previous_period', - }; - - beforeAll( () => { - select( 'wc-api' ).getReportStats = jest.fn().mockReturnValue( {} ); - select( 'wc-api' ).isReportStatsRequesting = jest.fn().mockReturnValue( false ); - select( 'wc-api' ).getReportStatsError = jest.fn().mockReturnValue( false ); - } ); - - afterAll( () => { - select( 'wc-api' ).getReportStats.mockRestore(); - select( 'wc-api' ).isReportStatsRequesting.mockRestore(); - select( 'wc-api' ).getReportStatsError.mockRestore(); - } ); - - function setGetReportStats( func ) { - select( 'wc-api' ).getReportStats.mockImplementation( ( ...args ) => func( ...args ) ); - } - - function setIsReportStatsRequesting( func ) { - select( 'wc-api' ).isReportStatsRequesting.mockImplementation( ( ...args ) => func( ...args ) ); - } - - function setGetReportStatsError( func ) { - select( 'wc-api' ).getReportStatsError.mockImplementation( ( ...args ) => func( ...args ) ); - } - - it( 'returns isRequesting if a request is in progress', () => { - setIsReportStatsRequesting( () => { - return true; - } ); - const result = getSummaryNumbers( 'revenue', query, select ); - expect( result ).toEqual( { ...response, isRequesting: true } ); - } ); - - it( 'returns isError if request errors', () => { - setIsReportStatsRequesting( () => { - return false; - } ); - setGetReportStatsError( () => { - return { error: 'Error' }; - } ); - const result = getSummaryNumbers( 'revenue', query, select ); - expect( result ).toEqual( { ...response, isError: true } ); - } ); - - it( 'returns results after queries finish', () => { - const totals = { - primary: { - orders_count: 115, - gross_revenue: 13966.92, - }, - secondary: { - orders_count: 85, - gross_revenue: 10406.1, - }, - }; - - setIsReportStatsRequesting( () => { - return false; - } ); - setGetReportStatsError( () => { - return undefined; - } ); - setGetReportStats( () => { - return { - totals, - }; - } ); - - setGetReportStats( ( endpoint, _query ) => { - if ( '2018-10-10T00:00:00+00:00' === _query.after ) { - return { - data: { - totals: totals.primary, - intervals: [], - }, - }; - } - return { - data: { - totals: totals.secondary, - intervals: [], - }, - }; - } ); - - const result = getSummaryNumbers( 'revenue', query, select ); - expect( result ).toEqual( { ...response, totals } ); - } ); -} ); - -describe( 'getFilterQuery', () => { - /** - * Mock the orders config - */ - const filters = [ - { - param: 'filter', - filters: [ - { value: 'top_meal', query: { lunch: 'burritos' } }, - { value: 'top_dessert', query: { dinner: 'ice_cream' } }, - { value: 'compare-cuisines', settings: { param: 'region' } }, - { - value: 'food_destination', - subFilters: [ - { value: 'choose_a_european_city', settings: { param: 'european_cities' } }, - ], - }, - ], - }, - ]; - - const advancedFilters = { - filters: { - mexican: { - rules: [ { value: 'is' }, { value: 'is_not' } ], - }, - french: { - rules: [ { value: 'includes' }, { value: 'excludes' } ], - }, - }, - }; - - ordersConfig.filters = filters; - ordersConfig.advancedFilters = advancedFilters; - - it( 'should return an empty object if no filter param is given', () => { - const query = {}; - const filterQuery = getFilterQuery( 'orders', query ); - - expect( filterQuery ).toEqual( {} ); - } ); - - it( 'should return an empty object if filter parameter is not in configs', () => { - const query = { filter: 'canned_meat' }; - const filterQuery = getFilterQuery( 'orders', query ); - - expect( filterQuery ).toEqual( {} ); - } ); - - it( 'should return the query for an advanced filter', () => { - const query = { filter: 'advanced', mexican_is: 'delicious' }; - const filterQuery = getFilterQuery( 'orders', query ); - - expect( filterQuery ).toEqual( { mexican_is: 'delicious', match: 'all' } ); - } ); - - it( 'should ignore other queries not defined by filter configs', () => { - const query = { - filter: 'advanced', - mexican_is_not: 'healthy', - orderby: 'calories', - topping: 'salsa-verde', - }; - const filterQuery = getFilterQuery( 'orders', query ); - - expect( filterQuery ).toEqual( { mexican_is_not: 'healthy', match: 'all' } ); - } ); - - it( 'should apply the match parameter advanced filters', () => { - const query = { - filter: 'advanced', - french_includes: 'le-fromage', - match: 'any', - }; - const filterQuery = getFilterQuery( 'orders', query ); - - expect( filterQuery ).toEqual( { french_includes: 'le-fromage', match: 'any' } ); - } ); - - it( 'should return the query for compare filters', () => { - const query = { filter: 'compare-cuisines', region: 'vietnam,malaysia,thailand' }; - const filterQuery = getFilterQuery( 'orders', query ); - - expect( filterQuery ).toEqual( { region: 'vietnam,malaysia,thailand' } ); - } ); - - it( 'should return the query for subFilters', () => { - const query = { filter: 'choose_a_european_city', european_cities: 'paris,rome,barcelona' }; - const filterQuery = getFilterQuery( 'orders', query ); - - expect( filterQuery ).toEqual( { european_cities: 'paris,rome,barcelona' } ); - } ); -} ); - -describe( 'getReportTableData()', () => { - const select = jest.fn().mockReturnValue( {} ); - const response = { - isError: false, - isRequesting: false, - items: { - data: [], - }, - }; - - const query = { - after: '2018-10-10', - before: '2018-10-10', - }; - - beforeAll( () => { - select( 'wc-api' ).getReportItems = jest.fn().mockReturnValue( {} ); - select( 'wc-api' ).isReportItemsRequesting = jest.fn().mockReturnValue( false ); - select( 'wc-api' ).getReportItemsError = jest.fn().mockReturnValue( undefined ); - } ); - - afterAll( () => { - select( 'wc-api' ).getReportItems.mockRestore(); - select( 'wc-api' ).isReportItemsRequesting.mockRestore(); - select( 'wc-api' ).getReportItemsError.mockRestore(); - } ); - - function setGetReportItems( func ) { - select( 'wc-api' ).getReportItems.mockImplementation( ( ...args ) => func( ...args ) ); - } - - function setIsReportItemsRequesting( func ) { - select( 'wc-api' ).isReportItemsRequesting.mockImplementation( ( ...args ) => func( ...args ) ); - } - - function setGetReportItemsError( func ) { - select( 'wc-api' ).getReportItemsError.mockImplementation( ( ...args ) => func( ...args ) ); - } - - it( 'returns isRequesting if a request is in progress', () => { - setIsReportItemsRequesting( () => true ); - - const result = getReportTableData( 'coupons', query, select ); - - expect( result ).toEqual( { ...response, query, isRequesting: true } ); - expect( select( 'wc-api' ).getReportItems ).toHaveBeenLastCalledWith( 'coupons', query ); - expect( select( 'wc-api' ).isReportItemsRequesting ).toHaveBeenLastCalledWith( - 'coupons', - query - ); - expect( select( 'wc-api' ).getReportItemsError ).toHaveBeenCalledTimes( 0 ); - } ); - - it( 'returns isError if request errors', () => { - setIsReportItemsRequesting( () => false ); - setGetReportItemsError( () => ( { error: 'Error' } ) ); - - const result = getReportTableData( 'coupons', query, select ); - - expect( result ).toEqual( { ...response, query, isError: true } ); - expect( select( 'wc-api' ).getReportItems ).toHaveBeenLastCalledWith( 'coupons', query ); - expect( select( 'wc-api' ).isReportItemsRequesting ).toHaveBeenLastCalledWith( - 'coupons', - query - ); - expect( select( 'wc-api' ).getReportItemsError ).toHaveBeenLastCalledWith( 'coupons', query ); - } ); - - it( 'returns results after queries finish', () => { - const items = [ { id: 1 }, { id: 2 }, { id: 3 } ]; - setIsReportItemsRequesting( () => false ); - setGetReportItemsError( () => undefined ); - setGetReportItems( () => items ); - - const result = getReportTableData( 'coupons', query, select ); - - expect( result ).toEqual( { ...response, query, items } ); - expect( select( 'wc-api' ).getReportItems ).toHaveBeenLastCalledWith( 'coupons', query ); - expect( select( 'wc-api' ).isReportItemsRequesting ).toHaveBeenLastCalledWith( - 'coupons', - query - ); - expect( select( 'wc-api' ).getReportItemsError ).toHaveBeenLastCalledWith( 'coupons', query ); - } ); -} ); - -describe( 'timeStampFilterDates', () => { - const advancedFilters = { - filters: { - city: { - input: { component: 'Search' }, - }, - my_date: { - input: { component: 'Date' }, - }, - }, - }; - - it( 'should not change activeFilters not using the Date component', () => { - const activeFilter = { - key: 'name', - rule: 'is', - value: 'New York', - }; - const timeStampedActiveFilter = timeStampFilterDates( advancedFilters, activeFilter ); - - expect( timeStampedActiveFilter ).toMatchObject( activeFilter ); - } ); - - it( 'should append timestamps to activeFilters using the Date component', () => { - const activeFilter = { - key: 'my_date', - rule: 'after', - value: '2018-04-04', - }; - const timeStampedActiveFilter = timeStampFilterDates( advancedFilters, activeFilter ); - - expect( timeStampedActiveFilter.value ).toBe( '2018-04-04T00:00:00+00:00' ); - } ); - - it( 'should append start of day for "after" rule', () => { - const activeFilter = { - key: 'my_date', - rule: 'after', - value: '2018-04-04', - }; - const timeStampedActiveFilter = timeStampFilterDates( advancedFilters, activeFilter ); - expect( timeStampedActiveFilter.value ).toBe( '2018-04-04T00:00:00+00:00' ); - } ); - - it( 'should append end of day for "before" rule', () => { - const activeFilter = { - key: 'my_date', - rule: 'before', - value: '2018-04-04', - }; - const timeStampedActiveFilter = timeStampFilterDates( advancedFilters, activeFilter ); - expect( timeStampedActiveFilter.value ).toBe( '2018-04-04T23:59:59+00:00' ); - } ); - - it( 'should handle "between" values', () => { - const activeFilter = { - key: 'my_date', - rule: 'before', - value: [ '2018-04-04', '2018-04-10' ], - }; - const timeStampedActiveFilter = timeStampFilterDates( advancedFilters, activeFilter ); - expect( Array.isArray( timeStampedActiveFilter.value ) ).toBe( true ); - expect( timeStampedActiveFilter.value ).toHaveLength( 2 ); - expect( timeStampedActiveFilter.value[ 0 ] ).toContain( 'T00:00:00+00:00' ); - expect( timeStampedActiveFilter.value[ 1 ] ).toContain( 'T23:59:59+00:00' ); - } ); -} ); From bca0785e642dada42d8bc791137ed018a20e038c Mon Sep 17 00:00:00 2001 From: Paul Sealock Date: Tue, 29 Jan 2019 08:58:07 +1300 Subject: [PATCH 18/53] Customers Report: support between args for dates --- ...dmin-rest-reports-customers-controller.php | 33 +++++++++++-------- ...est-reports-customers-stats-controller.php | 24 +++++++------- .../class-wc-admin-reports-interval.php | 33 ++++++++++++++++++- ...-wc-admin-reports-customers-data-store.php | 26 +++++++-------- .../tests/api/reports-interval.php | 8 ++--- 5 files changed, 81 insertions(+), 43 deletions(-) diff --git a/plugins/woocommerce-admin/includes/api/class-wc-admin-rest-reports-customers-controller.php b/plugins/woocommerce-admin/includes/api/class-wc-admin-rest-reports-customers-controller.php index 8c01d455a69..4b5883d06e0 100644 --- a/plugins/woocommerce-admin/includes/api/class-wc-admin-rest-reports-customers-controller.php +++ b/plugins/woocommerce-admin/includes/api/class-wc-admin-rest-reports-customers-controller.php @@ -52,6 +52,8 @@ class WC_Admin_REST_Reports_Customers_Controller extends WC_REST_Reports_Control $args['country'] = $request['country']; $args['last_active_before'] = $request['last_active_before']; $args['last_active_after'] = $request['last_active_after']; + $args['last_active_min'] = $request['last_active_min']; + $args['last_active_max'] = $request['last_active_max']; $args['orders_count_min'] = $request['orders_count_min']; $args['orders_count_max'] = $request['orders_count_max']; $args['total_spend_min'] = $request['total_spend_min']; @@ -61,7 +63,7 @@ class WC_Admin_REST_Reports_Customers_Controller extends WC_REST_Reports_Control $args['last_order_before'] = $request['last_order_before']; $args['last_order_after'] = $request['last_order_after']; - $between_params = array( 'orders_count', 'total_spend', 'avg_order_value' ); + $between_params = array( 'orders_count', 'total_spend', 'avg_order_value', 'last_active' ); $normalized = WC_Admin_Reports_Interval::normalize_between_params( $request, $between_params ); $args = array_merge( $args, $normalized ); @@ -296,14 +298,14 @@ class WC_Admin_REST_Reports_Customers_Controller extends WC_REST_Reports_Control 'sanitize_callback' => 'absint', 'validate_callback' => 'rest_validate_request_arg', ); - $params['order'] = array( + $params['order'] = array( 'description' => __( 'Order sort attribute ascending or descending.', 'wc-admin' ), 'type' => 'string', 'default' => 'desc', 'enum' => array( 'asc', 'desc' ), 'validate_callback' => 'rest_validate_request_arg', ); - $params['orderby'] = array( + $params['orderby'] = array( 'description' => __( 'Sort collection by object attribute.', 'wc-admin' ), 'type' => 'string', 'default' => 'date_registered', @@ -321,7 +323,7 @@ class WC_Admin_REST_Reports_Customers_Controller extends WC_REST_Reports_Control ), 'validate_callback' => 'rest_validate_request_arg', ); - $params['match'] = array( + $params['match'] = array( 'description' => __( 'Indicates whether all the conditions should be true for the resulting set, or if any one of them is sufficient. Match affects the following parameters: status_is, status_is_not, product_includes, product_excludes, coupon_includes, coupon_excludes, customer, categories', 'wc-admin' ), 'type' => 'string', 'default' => 'all', @@ -331,7 +333,7 @@ class WC_Admin_REST_Reports_Customers_Controller extends WC_REST_Reports_Control ), 'validate_callback' => 'rest_validate_request_arg', ); - $params['name'] = array( + $params['name'] = array( 'description' => __( 'Limit response to objects with a specfic customer name.', 'wc-admin' ), 'type' => 'string', 'validate_callback' => 'rest_validate_request_arg', @@ -363,34 +365,39 @@ class WC_Admin_REST_Reports_Customers_Controller extends WC_REST_Reports_Control 'format' => 'date-time', 'validate_callback' => 'rest_validate_request_arg', ); - $params['registered_before'] = array( + $params['last_active_between'] = array( + 'description' => __( 'Limit response to objects last active between two given ISO8601 compliant datetime.', 'wc-admin' ), + 'type' => 'array', + 'validate_callback' => array( 'WC_Admin_Reports_Interval', 'rest_validate_between_date_arg' ), + ); + $params['registered_before'] = array( 'description' => __( 'Limit response to objects registered before (or at) a given ISO8601 compliant datetime.', 'wc-admin' ), 'type' => 'string', 'format' => 'date-time', 'validate_callback' => 'rest_validate_request_arg', ); - $params['registered_after'] = array( + $params['registered_after'] = array( 'description' => __( 'Limit response to objects registered after (or at) a given ISO8601 compliant datetime.', 'wc-admin' ), 'type' => 'string', 'format' => 'date-time', 'validate_callback' => 'rest_validate_request_arg', ); - $params['orders_count_min'] = array( + $params['orders_count_min'] = array( 'description' => __( 'Limit response to objects with an order count greater than or equal to given integer.', 'wc-admin' ), 'type' => 'integer', 'sanitize_callback' => 'absint', 'validate_callback' => 'rest_validate_request_arg', ); - $params['orders_count_max'] = array( + $params['orders_count_max'] = array( 'description' => __( 'Limit response to objects with an order count less than or equal to given integer.', 'wc-admin' ), 'type' => 'integer', 'sanitize_callback' => 'absint', 'validate_callback' => 'rest_validate_request_arg', ); - $params['orders_count_between'] = array( + $params['orders_count_between'] = array( 'description' => __( 'Limit response to objects with an order count between two given integers.', 'wc-admin' ), 'type' => 'array', - 'validate_callback' => array( 'WC_Admin_Reports_Interval', 'rest_validate_between_arg' ), + 'validate_callback' => array( 'WC_Admin_Reports_Interval', 'rest_validate_between_numeric_arg' ), ); $params['total_spend_min'] = array( 'description' => __( 'Limit response to objects with a total order spend greater than or equal to given number.', 'wc-admin' ), @@ -405,7 +412,7 @@ class WC_Admin_REST_Reports_Customers_Controller extends WC_REST_Reports_Control $params['total_spend_between'] = array( 'description' => __( 'Limit response to objects with a total order spend between two given numbers.', 'wc-admin' ), 'type' => 'array', - 'validate_callback' => array( 'WC_Admin_Reports_Interval', 'rest_validate_between_arg' ), + 'validate_callback' => array( 'WC_Admin_Reports_Interval', 'rest_validate_between_numeric_arg' ), ); $params['avg_order_value_min'] = array( 'description' => __( 'Limit response to objects with an average order spend greater than or equal to given number.', 'wc-admin' ), @@ -420,7 +427,7 @@ class WC_Admin_REST_Reports_Customers_Controller extends WC_REST_Reports_Control $params['avg_order_value_between'] = array( 'description' => __( 'Limit response to objects with an average order spend between two given numbers.', 'wc-admin' ), 'type' => 'array', - 'validate_callback' => array( 'WC_Admin_Reports_Interval', 'rest_validate_between_arg' ), + 'validate_callback' => array( 'WC_Admin_Reports_Interval', 'rest_validate_between_numeric_arg' ), ); $params['last_order_before'] = array( 'description' => __( 'Limit response to objects with last order before (or at) a given ISO8601 compliant datetime.', 'wc-admin' ), diff --git a/plugins/woocommerce-admin/includes/api/class-wc-admin-rest-reports-customers-stats-controller.php b/plugins/woocommerce-admin/includes/api/class-wc-admin-rest-reports-customers-stats-controller.php index af24ea6119d..2b906f6c049 100644 --- a/plugins/woocommerce-admin/includes/api/class-wc-admin-rest-reports-customers-stats-controller.php +++ b/plugins/woocommerce-admin/includes/api/class-wc-admin-rest-reports-customers-stats-controller.php @@ -119,7 +119,7 @@ class WC_Admin_REST_Reports_Customers_Stats_Controller extends WC_REST_Reports_C public function get_item_schema() { // TODO: should any of these be 'indicator's? $totals = array( - 'customers_count' => array( + 'customers_count' => array( 'description' => __( 'Number of customers.', 'wc-admin' ), 'type' => 'integer', 'context' => array( 'view', 'edit' ), @@ -131,7 +131,7 @@ class WC_Admin_REST_Reports_Customers_Stats_Controller extends WC_REST_Reports_C 'context' => array( 'view', 'edit' ), 'readonly' => true, ), - 'avg_total_spend' => array( + 'avg_total_spend' => array( 'description' => __( 'Average total spend per customer.', 'wc-admin' ), 'type' => 'number', 'context' => array( 'view', 'edit' ), @@ -234,7 +234,7 @@ class WC_Admin_REST_Reports_Customers_Stats_Controller extends WC_REST_Reports_C 'format' => 'date-time', 'validate_callback' => 'rest_validate_request_arg', ); - $params['match'] = array( + $params['match'] = array( 'description' => __( 'Indicates whether all the conditions should be true for the resulting set, or if any one of them is sufficient. Match affects the following parameters: status_is, status_is_not, product_includes, product_excludes, coupon_includes, coupon_excludes, customer, categories', 'wc-admin' ), 'type' => 'string', 'default' => 'all', @@ -244,7 +244,7 @@ class WC_Admin_REST_Reports_Customers_Stats_Controller extends WC_REST_Reports_C ), 'validate_callback' => 'rest_validate_request_arg', ); - $params['name'] = array( + $params['name'] = array( 'description' => __( 'Limit response to objects with a specfic customer name.', 'wc-admin' ), 'type' => 'string', 'validate_callback' => 'rest_validate_request_arg', @@ -276,34 +276,34 @@ class WC_Admin_REST_Reports_Customers_Stats_Controller extends WC_REST_Reports_C 'format' => 'date-time', 'validate_callback' => 'rest_validate_request_arg', ); - $params['registered_before'] = array( + $params['registered_before'] = array( 'description' => __( 'Limit response to objects registered before (or at) a given ISO8601 compliant datetime.', 'wc-admin' ), 'type' => 'string', 'format' => 'date-time', 'validate_callback' => 'rest_validate_request_arg', ); - $params['registered_after'] = array( + $params['registered_after'] = array( 'description' => __( 'Limit response to objects registered after (or at) a given ISO8601 compliant datetime.', 'wc-admin' ), 'type' => 'string', 'format' => 'date-time', 'validate_callback' => 'rest_validate_request_arg', ); - $params['orders_count_min'] = array( + $params['orders_count_min'] = array( 'description' => __( 'Limit response to objects with an order count greater than or equal to given integer.', 'wc-admin' ), 'type' => 'integer', 'sanitize_callback' => 'absint', 'validate_callback' => 'rest_validate_request_arg', ); - $params['orders_count_max'] = array( + $params['orders_count_max'] = array( 'description' => __( 'Limit response to objects with an order count less than or equal to given integer.', 'wc-admin' ), 'type' => 'integer', 'sanitize_callback' => 'absint', 'validate_callback' => 'rest_validate_request_arg', ); - $params['orders_count_between'] = array( + $params['orders_count_between'] = array( 'description' => __( 'Limit response to objects with an order count between two given integers.', 'wc-admin' ), 'type' => 'array', - 'validate_callback' => array( 'WC_Admin_Reports_Interval', 'rest_validate_between_arg' ), + 'validate_callback' => array( 'WC_Admin_Reports_Interval', 'rest_validate_between_numeric_arg' ), ); $params['total_spend_min'] = array( 'description' => __( 'Limit response to objects with a total order spend greater than or equal to given number.', 'wc-admin' ), @@ -318,7 +318,7 @@ class WC_Admin_REST_Reports_Customers_Stats_Controller extends WC_REST_Reports_C $params['total_spend_between'] = array( 'description' => __( 'Limit response to objects with a total order spend between two given numbers.', 'wc-admin' ), 'type' => 'array', - 'validate_callback' => array( 'WC_Admin_Reports_Interval', 'rest_validate_between_arg' ), + 'validate_callback' => array( 'WC_Admin_Reports_Interval', 'rest_validate_between_numeric_arg' ), ); $params['avg_order_value_min'] = array( 'description' => __( 'Limit response to objects with an average order spend greater than or equal to given number.', 'wc-admin' ), @@ -333,7 +333,7 @@ class WC_Admin_REST_Reports_Customers_Stats_Controller extends WC_REST_Reports_C $params['avg_order_value_between'] = array( 'description' => __( 'Limit response to objects with an average order spend between two given numbers.', 'wc-admin' ), 'type' => 'array', - 'validate_callback' => array( 'WC_Admin_Reports_Interval', 'rest_validate_between_arg' ), + 'validate_callback' => array( 'WC_Admin_Reports_Interval', 'rest_validate_between_numeric_arg' ), ); $params['last_order_before'] = array( 'description' => __( 'Limit response to objects with last order before (or at) a given ISO8601 compliant datetime.', 'wc-admin' ), diff --git a/plugins/woocommerce-admin/includes/class-wc-admin-reports-interval.php b/plugins/woocommerce-admin/includes/class-wc-admin-reports-interval.php index 27e576e6065..166bd8484e5 100644 --- a/plugins/woocommerce-admin/includes/class-wc-admin-reports-interval.php +++ b/plugins/woocommerce-admin/includes/class-wc-admin-reports-interval.php @@ -538,7 +538,7 @@ class WC_Admin_Reports_Interval { * @param string $param Parameter name. * @return WP_Error|boolean */ - public static function rest_validate_between_arg( $value, $request, $param ) { + public static function rest_validate_between_numeric_arg( $value, $request, $param ) { if ( ! wp_is_numeric_array( $value ) ) { return new WP_Error( 'rest_invalid_param', @@ -561,4 +561,35 @@ class WC_Admin_Reports_Interval { return true; } + + /** + * Validate a "*_between" range argument (an array with 2 date items). + * + * @param mixed $value Parameter value. + * @param WP_REST_Request $request REST Request. + * @param string $param Parameter name. + * @return WP_Error|boolean + */ + public static function rest_validate_between_date_arg( $value, $request, $param ) { + if ( ! wp_is_numeric_array( $value ) ) { + return new WP_Error( + 'rest_invalid_param', + /* translators: 1: parameter name */ + sprintf( __( '%1$s is not a numerically indexed array.', 'wc-admin' ), $param ) + ); + } + + // check for dates here. + if ( + 2 !== count( $value ) + ) { + return new WP_Error( + 'rest_invalid_param', + /* translators: %s: parameter name */ + sprintf( __( '%s must contain 2 dates.', 'wc-admin' ), $param ) + ); + } + + return true; + } } diff --git a/plugins/woocommerce-admin/includes/data-stores/class-wc-admin-reports-customers-data-store.php b/plugins/woocommerce-admin/includes/data-stores/class-wc-admin-reports-customers-data-store.php index 17e88cba209..1c0d3cba50f 100644 --- a/plugins/woocommerce-admin/includes/data-stores/class-wc-admin-reports-customers-data-store.php +++ b/plugins/woocommerce-admin/includes/data-stores/class-wc-admin-reports-customers-data-store.php @@ -25,11 +25,11 @@ class WC_Admin_Reports_Customers_Data_Store extends WC_Admin_Reports_Data_Store * @var array */ protected $column_types = array( - 'customer_id' => 'intval', - 'user_id' => 'intval', - 'orders_count' => 'intval', - 'total_spend' => 'floatval', - 'avg_order_value' => 'floatval', + 'customer_id' => 'intval', + 'user_id' => 'intval', + 'orders_count' => 'intval', + 'total_spend' => 'floatval', + 'avg_order_value' => 'floatval', ); /** @@ -60,7 +60,7 @@ class WC_Admin_Reports_Customers_Data_Store extends WC_Admin_Reports_Data_Store global $wpdb; // Initialize some report columns that need disambiguation. - $this->report_columns['customer_id'] = $wpdb->prefix . self::TABLE_NAME . '.customer_id'; + $this->report_columns['customer_id'] = $wpdb->prefix . self::TABLE_NAME . '.customer_id'; $this->report_columns['date_last_order'] = "MAX( {$wpdb->prefix}wc_order_stats.date_created ) as date_last_order"; } @@ -274,7 +274,7 @@ class WC_Admin_Reports_Customers_Data_Store extends WC_Admin_Reports_Data_Store } if ( $where_clauses ) { - $preceding_match = empty( $sql_query_params['where_time_clause'] ) ? ' AND ' : " {$match_operator} "; + $preceding_match = empty( $sql_query_params['where_time_clause'] ) ? ' AND ' : " {$match_operator} "; $sql_query_params['where_clause'] = $preceding_match . implode( " {$match_operator} ", $where_clauses ); } @@ -284,7 +284,7 @@ class WC_Admin_Reports_Customers_Data_Store extends WC_Admin_Reports_Data_Store } if ( $having_clauses ) { - $preceding_match = empty( $sql_query_params['having_clause'] ) ? ' AND ' : " {$match_operator} "; + $preceding_match = empty( $sql_query_params['having_clause'] ) ? ' AND ' : " {$match_operator} "; $sql_query_params['having_clause'] .= $preceding_match . implode( " {$match_operator} ", $having_clauses ); } @@ -304,7 +304,7 @@ class WC_Admin_Reports_Customers_Data_Store extends WC_Admin_Reports_Data_Store $order_stats_table_name = $wpdb->prefix . 'wc_order_stats'; // These defaults are only partially applied when used via REST API, as that has its own defaults. - $defaults = array( + $defaults = array( 'per_page' => get_option( 'posts_per_page' ), 'page' => 1, 'order' => 'DESC', @@ -442,7 +442,7 @@ class WC_Admin_Reports_Customers_Data_Store extends WC_Admin_Reports_Data_Store * Retrieve a guest (no user_id) customer row by email. * * @param string $email Email address. - * @returns false|array Customer array if found, boolean false if not. + * @return false|array Customer array if found, boolean false if not. */ public function get_guest_by_email( $email ) { global $wpdb; @@ -467,7 +467,7 @@ class WC_Admin_Reports_Customers_Data_Store extends WC_Admin_Reports_Data_Store * Retrieve a registered customer row by user_id. * * @param string|int $user_id User ID. - * @returns false|array Customer array if found, boolean false if not. + * @return false|array Customer array if found, boolean false if not. */ public function get_customer_by_user_id( $user_id ) { global $wpdb; @@ -492,7 +492,7 @@ class WC_Admin_Reports_Customers_Data_Store extends WC_Admin_Reports_Data_Store * Retrieve a registered customer row id by user_id. * * @param string|int $user_id User ID. - * @returns false|int Customer ID if found, boolean false if not. + * @return false|int Customer ID if found, boolean false if not. */ public static function get_customer_id_by_user_id( $user_id ) { global $wpdb; @@ -554,7 +554,7 @@ class WC_Admin_Reports_Customers_Data_Store extends WC_Admin_Reports_Data_Store if ( $customer_id ) { // Preserve customer_id for existing user_id. $data['customer_id'] = $customer_id; - $format[] = '%d'; + $format[] = '%d'; } return $wpdb->replace( $wpdb->prefix . self::TABLE_NAME, $data, $format ); diff --git a/plugins/woocommerce-admin/tests/api/reports-interval.php b/plugins/woocommerce-admin/tests/api/reports-interval.php index 566153a0796..78db9e8c26c 100644 --- a/plugins/woocommerce-admin/tests/api/reports-interval.php +++ b/plugins/woocommerce-admin/tests/api/reports-interval.php @@ -836,19 +836,19 @@ class WC_Tests_Reports_Interval_Stats extends WC_Unit_Test_Case { /** * Test function that validates *_between query parameters. */ - public function test_rest_validate_between_arg() { + public function test_rest_validate_between_numeric_arg() { $this->assertIsWPError( - WC_Admin_Reports_Interval::rest_validate_between_arg( 'not array', null, 'param' ), + WC_Admin_Reports_Interval::rest_validate_between_numeric_arg( 'not array', null, 'param' ), 'param is not a numerically indexed array.' ); $this->assertIsWPError( - WC_Admin_Reports_Interval::rest_validate_between_arg( array( 1 ), null, 'param' ), + WC_Admin_Reports_Interval::rest_validate_between_numeric_arg( array( 1 ), null, 'param' ), 'param must contain 2 numbers.' ); $this->assertTrue( - WC_Admin_Reports_Interval::rest_validate_between_arg( array( 1, 2 ), null, 'param' ) + WC_Admin_Reports_Interval::rest_validate_between_numeric_arg( array( 1, 2 ), null, 'param' ) ); } } From 3d0890a704d1f9631c41264904832d52db409f90 Mon Sep 17 00:00:00 2001 From: Paul Sealock Date: Tue, 29 Jan 2019 09:21:11 +1300 Subject: [PATCH 19/53] basic working --- ...dmin-rest-reports-customers-controller.php | 8 ++-- ...est-reports-customers-stats-controller.php | 2 +- .../class-wc-admin-reports-interval.php | 39 ++++++++++++++++++- .../tests/api/reports-interval.php | 4 +- 4 files changed, 46 insertions(+), 7 deletions(-) diff --git a/plugins/woocommerce-admin/includes/api/class-wc-admin-rest-reports-customers-controller.php b/plugins/woocommerce-admin/includes/api/class-wc-admin-rest-reports-customers-controller.php index 4b5883d06e0..3d1c2421286 100644 --- a/plugins/woocommerce-admin/includes/api/class-wc-admin-rest-reports-customers-controller.php +++ b/plugins/woocommerce-admin/includes/api/class-wc-admin-rest-reports-customers-controller.php @@ -63,9 +63,11 @@ class WC_Admin_REST_Reports_Customers_Controller extends WC_REST_Reports_Control $args['last_order_before'] = $request['last_order_before']; $args['last_order_after'] = $request['last_order_after']; - $between_params = array( 'orders_count', 'total_spend', 'avg_order_value', 'last_active' ); - $normalized = WC_Admin_Reports_Interval::normalize_between_params( $request, $between_params ); - $args = array_merge( $args, $normalized ); + $numeric_between_params = array( 'orders_count', 'total_spend', 'avg_order_value' ); + $date_between_params = array( 'last_active' ); + $normalized = WC_Admin_Reports_Interval::normalize_numeric_between_params( $request, $numeric_between_params ); + $normalized_dates = WC_Admin_Reports_Interval::normalize_date_between_params( $request, $date_between_params ); + $args = array_merge( $args, $normalized, $normalized_dates ); return $args; } diff --git a/plugins/woocommerce-admin/includes/api/class-wc-admin-rest-reports-customers-stats-controller.php b/plugins/woocommerce-admin/includes/api/class-wc-admin-rest-reports-customers-stats-controller.php index 2b906f6c049..8946ddeddd0 100644 --- a/plugins/woocommerce-admin/includes/api/class-wc-admin-rest-reports-customers-stats-controller.php +++ b/plugins/woocommerce-admin/includes/api/class-wc-admin-rest-reports-customers-stats-controller.php @@ -57,7 +57,7 @@ class WC_Admin_REST_Reports_Customers_Stats_Controller extends WC_REST_Reports_C $args['last_order_after'] = $request['last_order_after']; $between_params = array( 'orders_count', 'total_spend', 'avg_order_value' ); - $normalized = WC_Admin_Reports_Interval::normalize_between_params( $request, $between_params ); + $normalized = WC_Admin_Reports_Interval::normalize_numeric_between_params( $request, $between_params ); $args = array_merge( $args, $normalized ); return $args; diff --git a/plugins/woocommerce-admin/includes/class-wc-admin-reports-interval.php b/plugins/woocommerce-admin/includes/class-wc-admin-reports-interval.php index 166bd8484e5..bf868b473cc 100644 --- a/plugins/woocommerce-admin/includes/class-wc-admin-reports-interval.php +++ b/plugins/woocommerce-admin/includes/class-wc-admin-reports-interval.php @@ -500,7 +500,7 @@ class WC_Admin_Reports_Interval { * @param string|array $param_names One or more param names to handle. Should not include "_between" suffix. * @return array Normalized query values. */ - public static function normalize_between_params( $request, $param_names ) { + public static function normalize_numeric_between_params( $request, $param_names ) { if ( ! is_array( $param_names ) ) { $param_names = array( $param_names ); } @@ -530,6 +530,43 @@ class WC_Admin_Reports_Interval { return $normalized; } + /** + * Normalize "*_between" parameters to "*_after" and "*_before". + * + * @param array $request Query params from REST API request. + * @param string|array $param_names One or more param names to handle. Should not include "_between" suffix. + * @return array Normalized query values. + */ + public static function normalize_date_between_params( $request, $param_names ) { + if ( ! is_array( $param_names ) ) { + $param_names = array( $param_names ); + } + + $normalized = array(); + + foreach ( $param_names as $param_name ) { + if ( ! is_array( $request[ $param_name . '_between' ] ) ) { + continue; + } + + $range = $request[ $param_name . '_between' ]; + + if ( 2 !== count( $range ) ) { + continue; + } + + if ( $range[0] < $range[1] ) { + $normalized[ $param_name . '_after' ] = $range[0]; + $normalized[ $param_name . '_before' ] = $range[1]; + } else { + $normalized[ $param_name . '_after' ] = $range[1]; + $normalized[ $param_name . '_before' ] = $range[0]; + } + } + + return $normalized; + } + /** * Validate a "*_between" range argument (an array with 2 numeric items). * diff --git a/plugins/woocommerce-admin/tests/api/reports-interval.php b/plugins/woocommerce-admin/tests/api/reports-interval.php index 78db9e8c26c..bcce5694f55 100644 --- a/plugins/woocommerce-admin/tests/api/reports-interval.php +++ b/plugins/woocommerce-admin/tests/api/reports-interval.php @@ -813,7 +813,7 @@ class WC_Tests_Reports_Interval_Stats extends WC_Unit_Test_Case { /** * Test function that normalizes *_between query parameters to *_min & *_max. */ - public function test_normalize_between_params() { + public function test_normalize_numeric_between_params() { $request = array( 'a_between' => 'malformed', // won't be normalized (not an array). 'b_between' => array( 1, 5 ), // results in min=1, max=5. @@ -822,7 +822,7 @@ class WC_Tests_Reports_Interval_Stats extends WC_Unit_Test_Case { 'f_between' => array( 10, 12 ), // not in params, skipped. ); $params = array( 'a', 'b', 'c', 'd' ); - $result = WC_Admin_Reports_Interval::normalize_between_params( $request, $params ); + $result = WC_Admin_Reports_Interval::normalize_numeric_between_params( $request, $params ); $expected = array( 'b_min' => 1, 'b_max' => 5, From 2f022ffdba1c8ce01b81a999c3d5df62a3da2f1a Mon Sep 17 00:00:00 2001 From: Paul Sealock Date: Tue, 29 Jan 2019 10:23:44 +1300 Subject: [PATCH 20/53] dry interval.php --- ...dmin-rest-reports-customers-controller.php | 10 ++-- ...est-reports-customers-stats-controller.php | 2 +- .../class-wc-admin-reports-interval.php | 49 +++---------------- .../tests/api/reports-interval.php | 4 +- 4 files changed, 15 insertions(+), 50 deletions(-) diff --git a/plugins/woocommerce-admin/includes/api/class-wc-admin-rest-reports-customers-controller.php b/plugins/woocommerce-admin/includes/api/class-wc-admin-rest-reports-customers-controller.php index 3d1c2421286..c46e8c84afd 100644 --- a/plugins/woocommerce-admin/includes/api/class-wc-admin-rest-reports-customers-controller.php +++ b/plugins/woocommerce-admin/includes/api/class-wc-admin-rest-reports-customers-controller.php @@ -52,8 +52,6 @@ class WC_Admin_REST_Reports_Customers_Controller extends WC_REST_Reports_Control $args['country'] = $request['country']; $args['last_active_before'] = $request['last_active_before']; $args['last_active_after'] = $request['last_active_after']; - $args['last_active_min'] = $request['last_active_min']; - $args['last_active_max'] = $request['last_active_max']; $args['orders_count_min'] = $request['orders_count_min']; $args['orders_count_max'] = $request['orders_count_max']; $args['total_spend_min'] = $request['total_spend_min']; @@ -64,10 +62,10 @@ class WC_Admin_REST_Reports_Customers_Controller extends WC_REST_Reports_Control $args['last_order_after'] = $request['last_order_after']; $numeric_between_params = array( 'orders_count', 'total_spend', 'avg_order_value' ); - $date_between_params = array( 'last_active' ); - $normalized = WC_Admin_Reports_Interval::normalize_numeric_between_params( $request, $numeric_between_params ); - $normalized_dates = WC_Admin_Reports_Interval::normalize_date_between_params( $request, $date_between_params ); - $args = array_merge( $args, $normalized, $normalized_dates ); + $date_between_params = array( 'last_active' ); + $normalized = WC_Admin_Reports_Interval::normalize_between_params( $request, $numeric_between_params, false ); + $normalized_dates = WC_Admin_Reports_Interval::normalize_between_params( $request, $date_between_params, true ); + $args = array_merge( $args, $normalized, $normalized_dates ); return $args; } diff --git a/plugins/woocommerce-admin/includes/api/class-wc-admin-rest-reports-customers-stats-controller.php b/plugins/woocommerce-admin/includes/api/class-wc-admin-rest-reports-customers-stats-controller.php index 8946ddeddd0..2b906f6c049 100644 --- a/plugins/woocommerce-admin/includes/api/class-wc-admin-rest-reports-customers-stats-controller.php +++ b/plugins/woocommerce-admin/includes/api/class-wc-admin-rest-reports-customers-stats-controller.php @@ -57,7 +57,7 @@ class WC_Admin_REST_Reports_Customers_Stats_Controller extends WC_REST_Reports_C $args['last_order_after'] = $request['last_order_after']; $between_params = array( 'orders_count', 'total_spend', 'avg_order_value' ); - $normalized = WC_Admin_Reports_Interval::normalize_numeric_between_params( $request, $between_params ); + $normalized = WC_Admin_Reports_Interval::normalize_between_params( $request, $between_params ); $args = array_merge( $args, $normalized ); return $args; diff --git a/plugins/woocommerce-admin/includes/class-wc-admin-reports-interval.php b/plugins/woocommerce-admin/includes/class-wc-admin-reports-interval.php index bf868b473cc..dcb90e23daf 100644 --- a/plugins/woocommerce-admin/includes/class-wc-admin-reports-interval.php +++ b/plugins/woocommerce-admin/includes/class-wc-admin-reports-interval.php @@ -498,9 +498,10 @@ class WC_Admin_Reports_Interval { * * @param array $request Query params from REST API request. * @param string|array $param_names One or more param names to handle. Should not include "_between" suffix. + * @param bool $is_date Boolean if the param is date is related. * @return array Normalized query values. */ - public static function normalize_numeric_between_params( $request, $param_names ) { + public static function normalize_between_params( $request, $param_names, $is_date ) { if ( ! is_array( $param_names ) ) { $param_names = array( $param_names ); } @@ -518,49 +519,15 @@ class WC_Admin_Reports_Interval { continue; } - if ( $range[0] < $range[1] ) { - $normalized[ $param_name . '_min' ] = $range[0]; - $normalized[ $param_name . '_max' ] = $range[1]; - } else { - $normalized[ $param_name . '_min' ] = $range[1]; - $normalized[ $param_name . '_max' ] = $range[0]; - } - } - - return $normalized; - } - - /** - * Normalize "*_between" parameters to "*_after" and "*_before". - * - * @param array $request Query params from REST API request. - * @param string|array $param_names One or more param names to handle. Should not include "_between" suffix. - * @return array Normalized query values. - */ - public static function normalize_date_between_params( $request, $param_names ) { - if ( ! is_array( $param_names ) ) { - $param_names = array( $param_names ); - } - - $normalized = array(); - - foreach ( $param_names as $param_name ) { - if ( ! is_array( $request[ $param_name . '_between' ] ) ) { - continue; - } - - $range = $request[ $param_name . '_between' ]; - - if ( 2 !== count( $range ) ) { - continue; - } + $min = $is_date ? '_after' : '_min'; + $max = $is_date ? '_before' : '_max'; if ( $range[0] < $range[1] ) { - $normalized[ $param_name . '_after' ] = $range[0]; - $normalized[ $param_name . '_before' ] = $range[1]; + $normalized[ $param_name . $min ] = $range[0]; + $normalized[ $param_name . $max ] = $range[1]; } else { - $normalized[ $param_name . '_after' ] = $range[1]; - $normalized[ $param_name . '_before' ] = $range[0]; + $normalized[ $param_name . $min ] = $range[1]; + $normalized[ $param_name . $max ] = $range[0]; } } diff --git a/plugins/woocommerce-admin/tests/api/reports-interval.php b/plugins/woocommerce-admin/tests/api/reports-interval.php index bcce5694f55..78db9e8c26c 100644 --- a/plugins/woocommerce-admin/tests/api/reports-interval.php +++ b/plugins/woocommerce-admin/tests/api/reports-interval.php @@ -813,7 +813,7 @@ class WC_Tests_Reports_Interval_Stats extends WC_Unit_Test_Case { /** * Test function that normalizes *_between query parameters to *_min & *_max. */ - public function test_normalize_numeric_between_params() { + public function test_normalize_between_params() { $request = array( 'a_between' => 'malformed', // won't be normalized (not an array). 'b_between' => array( 1, 5 ), // results in min=1, max=5. @@ -822,7 +822,7 @@ class WC_Tests_Reports_Interval_Stats extends WC_Unit_Test_Case { 'f_between' => array( 10, 12 ), // not in params, skipped. ); $params = array( 'a', 'b', 'c', 'd' ); - $result = WC_Admin_Reports_Interval::normalize_numeric_between_params( $request, $params ); + $result = WC_Admin_Reports_Interval::normalize_between_params( $request, $params ); $expected = array( 'b_min' => 1, 'b_max' => 5, From c6d1ce98c0179e4877856f1a9f95660dc3c4d798 Mon Sep 17 00:00:00 2001 From: Paul Sealock Date: Tue, 29 Jan 2019 10:45:49 +1300 Subject: [PATCH 21/53] rest_validate_between_date_arg --- .../includes/class-wc-admin-reports-interval.php | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/plugins/woocommerce-admin/includes/class-wc-admin-reports-interval.php b/plugins/woocommerce-admin/includes/class-wc-admin-reports-interval.php index dcb90e23daf..5036d2fcab4 100644 --- a/plugins/woocommerce-admin/includes/class-wc-admin-reports-interval.php +++ b/plugins/woocommerce-admin/includes/class-wc-admin-reports-interval.php @@ -583,14 +583,15 @@ class WC_Admin_Reports_Interval { ); } - // check for dates here. if ( - 2 !== count( $value ) + 2 !== count( $value ) || + ! rest_parse_date( $value[0] ) || + ! rest_parse_date( $value[1] ) ) { return new WP_Error( 'rest_invalid_param', /* translators: %s: parameter name */ - sprintf( __( '%s must contain 2 dates.', 'wc-admin' ), $param ) + sprintf( __( '%s must contain 2 valid dates.', 'wc-admin' ), $param ) ); } From 483c199fbf735b24932eb48fd0aba30eeadd8c5c Mon Sep 17 00:00:00 2001 From: Paul Sealock Date: Tue, 29 Jan 2019 10:53:56 +1300 Subject: [PATCH 22/53] tests working --- ...dmin-rest-reports-customers-stats-controller.php | 13 ++++++++++--- .../tests/api/reports-interval.php | 2 +- 2 files changed, 11 insertions(+), 4 deletions(-) diff --git a/plugins/woocommerce-admin/includes/api/class-wc-admin-rest-reports-customers-stats-controller.php b/plugins/woocommerce-admin/includes/api/class-wc-admin-rest-reports-customers-stats-controller.php index 2b906f6c049..c05b5d237c9 100644 --- a/plugins/woocommerce-admin/includes/api/class-wc-admin-rest-reports-customers-stats-controller.php +++ b/plugins/woocommerce-admin/includes/api/class-wc-admin-rest-reports-customers-stats-controller.php @@ -56,9 +56,11 @@ class WC_Admin_REST_Reports_Customers_Stats_Controller extends WC_REST_Reports_C $args['last_order_before'] = $request['last_order_before']; $args['last_order_after'] = $request['last_order_after']; - $between_params = array( 'orders_count', 'total_spend', 'avg_order_value' ); - $normalized = WC_Admin_Reports_Interval::normalize_between_params( $request, $between_params ); - $args = array_merge( $args, $normalized ); + $numeric_between_params = array( 'orders_count', 'total_spend', 'avg_order_value' ); + $date_between_params = array( 'last_active' ); + $normalized = WC_Admin_Reports_Interval::normalize_between_params( $request, $numeric_between_params, false ); + $normalized_dates = WC_Admin_Reports_Interval::normalize_between_params( $request, $date_between_params, true ); + $args = array_merge( $args, $normalized, $normalized_dates ); return $args; } @@ -276,6 +278,11 @@ class WC_Admin_REST_Reports_Customers_Stats_Controller extends WC_REST_Reports_C 'format' => 'date-time', 'validate_callback' => 'rest_validate_request_arg', ); + $params['last_active_between'] = array( + 'description' => __( 'Limit response to objects last active between two given ISO8601 compliant datetime.', 'wc-admin' ), + 'type' => 'array', + 'validate_callback' => array( 'WC_Admin_Reports_Interval', 'rest_validate_between_date_arg' ), + ); $params['registered_before'] = array( 'description' => __( 'Limit response to objects registered before (or at) a given ISO8601 compliant datetime.', 'wc-admin' ), 'type' => 'string', diff --git a/plugins/woocommerce-admin/tests/api/reports-interval.php b/plugins/woocommerce-admin/tests/api/reports-interval.php index 78db9e8c26c..f6b094cfcde 100644 --- a/plugins/woocommerce-admin/tests/api/reports-interval.php +++ b/plugins/woocommerce-admin/tests/api/reports-interval.php @@ -822,7 +822,7 @@ class WC_Tests_Reports_Interval_Stats extends WC_Unit_Test_Case { 'f_between' => array( 10, 12 ), // not in params, skipped. ); $params = array( 'a', 'b', 'c', 'd' ); - $result = WC_Admin_Reports_Interval::normalize_between_params( $request, $params ); + $result = WC_Admin_Reports_Interval::normalize_between_params( $request, $params, false ); $expected = array( 'b_min' => 1, 'b_max' => 5, From 3e16a37be08b94dcba016d6d614e49730a387241 Mon Sep 17 00:00:00 2001 From: Paul Sealock Date: Tue, 29 Jan 2019 11:01:25 +1300 Subject: [PATCH 23/53] add tests --- .../tests/api/reports-interval.php | 49 ++++++++++++++++++- 1 file changed, 48 insertions(+), 1 deletion(-) diff --git a/plugins/woocommerce-admin/tests/api/reports-interval.php b/plugins/woocommerce-admin/tests/api/reports-interval.php index f6b094cfcde..112891efe6d 100644 --- a/plugins/woocommerce-admin/tests/api/reports-interval.php +++ b/plugins/woocommerce-admin/tests/api/reports-interval.php @@ -834,7 +834,30 @@ class WC_Tests_Reports_Interval_Stats extends WC_Unit_Test_Case { } /** - * Test function that validates *_between query parameters. + * Test function that normalizes *_between query parameters for dates to *_after & *_before. + */ + public function test_normalize_between_date_params() { + $request = array( + 'a_between' => 'malformed', // won't be normalized (not an array). + 'b_between' => array( 1, 5 ), // results in after=1, before=5. + 'c_between' => array( 4, 2 ), // results in after=2, before=4. + 'd_between' => array( 7 ), // won't be normalized (only 1 item). + 'f_between' => array( 10, 12 ), // not in params, skipped. + ); + $params = array( 'a', 'b', 'c', 'd' ); + $result = WC_Admin_Reports_Interval::normalize_between_params( $request, $params, true ); + $expected = array( + 'b_after' => 1, + 'b_before' => 5, + 'c_after' => 2, + 'c_before' => 4, + ); + + $this->assertEquals( $result, $expected ); + } + + /** + * Test function that validates *_between query parameters for numeric values. */ public function test_rest_validate_between_numeric_arg() { $this->assertIsWPError( @@ -851,4 +874,28 @@ class WC_Tests_Reports_Interval_Stats extends WC_Unit_Test_Case { WC_Admin_Reports_Interval::rest_validate_between_numeric_arg( array( 1, 2 ), null, 'param' ) ); } + + /** + * Test function that validates *_between query parameters for date values. + */ + public function rest_validate_between_date_arg() { + $this->assertIsWPError( + WC_Admin_Reports_Interval::rest_validate_between_date_arg( 'not array', null, 'param' ), + 'param is not a numerically indexed array.' + ); + + $this->assertIsWPError( + WC_Admin_Reports_Interval::rest_validate_between_date_arg( array( '2019-01-01T00:00:00' ), null, 'param' ), + 'param must contain 2 valid dates.' + ); + + $this->assertIsWPError( + WC_Admin_Reports_Interval::rest_validate_between_date_arg( array( 'not a valid date' ), null, 'param' ), + 'param must contain 2 valid dates.' + ); + + $this->assertTrue( + WC_Admin_Reports_Interval::rest_validate_between_date_arg( array( '2019-01-01T00:00:00', '2019-01-15T00:00:00' ), null, 'param' ) + ); + } } From 370a747c2b7cc9e4ece0923a7875f27b58005de6 Mon Sep 17 00:00:00 2001 From: Paul Sealock Date: Tue, 29 Jan 2019 11:05:27 +1300 Subject: [PATCH 24/53] add registered --- .../class-wc-admin-rest-reports-customers-controller.php | 7 ++++++- ...ss-wc-admin-rest-reports-customers-stats-controller.php | 7 ++++++- 2 files changed, 12 insertions(+), 2 deletions(-) diff --git a/plugins/woocommerce-admin/includes/api/class-wc-admin-rest-reports-customers-controller.php b/plugins/woocommerce-admin/includes/api/class-wc-admin-rest-reports-customers-controller.php index c46e8c84afd..99c093f587f 100644 --- a/plugins/woocommerce-admin/includes/api/class-wc-admin-rest-reports-customers-controller.php +++ b/plugins/woocommerce-admin/includes/api/class-wc-admin-rest-reports-customers-controller.php @@ -62,7 +62,7 @@ class WC_Admin_REST_Reports_Customers_Controller extends WC_REST_Reports_Control $args['last_order_after'] = $request['last_order_after']; $numeric_between_params = array( 'orders_count', 'total_spend', 'avg_order_value' ); - $date_between_params = array( 'last_active' ); + $date_between_params = array( 'last_active', 'registered' ); $normalized = WC_Admin_Reports_Interval::normalize_between_params( $request, $numeric_between_params, false ); $normalized_dates = WC_Admin_Reports_Interval::normalize_between_params( $request, $date_between_params, true ); $args = array_merge( $args, $normalized, $normalized_dates ); @@ -382,6 +382,11 @@ class WC_Admin_REST_Reports_Customers_Controller extends WC_REST_Reports_Control 'format' => 'date-time', 'validate_callback' => 'rest_validate_request_arg', ); + $params['registered_between'] = array( + 'description' => __( 'Limit response to objects last active between two given ISO8601 compliant datetime.', 'wc-admin' ), + 'type' => 'array', + 'validate_callback' => array( 'WC_Admin_Reports_Interval', 'rest_validate_between_date_arg' ), + ); $params['orders_count_min'] = array( 'description' => __( 'Limit response to objects with an order count greater than or equal to given integer.', 'wc-admin' ), 'type' => 'integer', diff --git a/plugins/woocommerce-admin/includes/api/class-wc-admin-rest-reports-customers-stats-controller.php b/plugins/woocommerce-admin/includes/api/class-wc-admin-rest-reports-customers-stats-controller.php index c05b5d237c9..fadb5b8736f 100644 --- a/plugins/woocommerce-admin/includes/api/class-wc-admin-rest-reports-customers-stats-controller.php +++ b/plugins/woocommerce-admin/includes/api/class-wc-admin-rest-reports-customers-stats-controller.php @@ -57,7 +57,7 @@ class WC_Admin_REST_Reports_Customers_Stats_Controller extends WC_REST_Reports_C $args['last_order_after'] = $request['last_order_after']; $numeric_between_params = array( 'orders_count', 'total_spend', 'avg_order_value' ); - $date_between_params = array( 'last_active' ); + $date_between_params = array( 'last_active', 'registered' ); $normalized = WC_Admin_Reports_Interval::normalize_between_params( $request, $numeric_between_params, false ); $normalized_dates = WC_Admin_Reports_Interval::normalize_between_params( $request, $date_between_params, true ); $args = array_merge( $args, $normalized, $normalized_dates ); @@ -295,6 +295,11 @@ class WC_Admin_REST_Reports_Customers_Stats_Controller extends WC_REST_Reports_C 'format' => 'date-time', 'validate_callback' => 'rest_validate_request_arg', ); + $params['registered_between'] = array( + 'description' => __( 'Limit response to objects last active between two given ISO8601 compliant datetime.', 'wc-admin' ), + 'type' => 'array', + 'validate_callback' => array( 'WC_Admin_Reports_Interval', 'rest_validate_between_date_arg' ), + ); $params['orders_count_min'] = array( 'description' => __( 'Limit response to objects with an order count greater than or equal to given integer.', 'wc-admin' ), 'type' => 'integer', From 41bec03880e9456fdfc55a76583c33abdc2ed692 Mon Sep 17 00:00:00 2001 From: Paul Sealock Date: Tue, 29 Jan 2019 11:28:58 +1300 Subject: [PATCH 25/53] tweeks --- .../class-wc-admin-rest-reports-customers-controller.php | 8 ++++---- ...s-wc-admin-rest-reports-customers-stats-controller.php | 8 ++++---- .../includes/class-wc-admin-reports-interval.php | 3 ++- 3 files changed, 10 insertions(+), 9 deletions(-) diff --git a/plugins/woocommerce-admin/includes/api/class-wc-admin-rest-reports-customers-controller.php b/plugins/woocommerce-admin/includes/api/class-wc-admin-rest-reports-customers-controller.php index 99c093f587f..33c67a1fd39 100644 --- a/plugins/woocommerce-admin/includes/api/class-wc-admin-rest-reports-customers-controller.php +++ b/plugins/woocommerce-admin/includes/api/class-wc-admin-rest-reports-customers-controller.php @@ -61,10 +61,10 @@ class WC_Admin_REST_Reports_Customers_Controller extends WC_REST_Reports_Control $args['last_order_before'] = $request['last_order_before']; $args['last_order_after'] = $request['last_order_after']; - $numeric_between_params = array( 'orders_count', 'total_spend', 'avg_order_value' ); - $date_between_params = array( 'last_active', 'registered' ); - $normalized = WC_Admin_Reports_Interval::normalize_between_params( $request, $numeric_between_params, false ); - $normalized_dates = WC_Admin_Reports_Interval::normalize_between_params( $request, $date_between_params, true ); + $between_params_numeric = array( 'orders_count', 'total_spend', 'avg_order_value' ); + $between_params_date = array( 'last_active', 'registered' ); + $normalized = WC_Admin_Reports_Interval::normalize_between_params( $request, $between_params_numeric, false ); + $normalized_dates = WC_Admin_Reports_Interval::normalize_between_params( $request, $between_params_date, true ); $args = array_merge( $args, $normalized, $normalized_dates ); return $args; diff --git a/plugins/woocommerce-admin/includes/api/class-wc-admin-rest-reports-customers-stats-controller.php b/plugins/woocommerce-admin/includes/api/class-wc-admin-rest-reports-customers-stats-controller.php index fadb5b8736f..aa9a7f163ca 100644 --- a/plugins/woocommerce-admin/includes/api/class-wc-admin-rest-reports-customers-stats-controller.php +++ b/plugins/woocommerce-admin/includes/api/class-wc-admin-rest-reports-customers-stats-controller.php @@ -56,10 +56,10 @@ class WC_Admin_REST_Reports_Customers_Stats_Controller extends WC_REST_Reports_C $args['last_order_before'] = $request['last_order_before']; $args['last_order_after'] = $request['last_order_after']; - $numeric_between_params = array( 'orders_count', 'total_spend', 'avg_order_value' ); - $date_between_params = array( 'last_active', 'registered' ); - $normalized = WC_Admin_Reports_Interval::normalize_between_params( $request, $numeric_between_params, false ); - $normalized_dates = WC_Admin_Reports_Interval::normalize_between_params( $request, $date_between_params, true ); + $between_params_numeric = array( 'orders_count', 'total_spend', 'avg_order_value' ); + $between_params_date = array( 'last_active', 'registered' ); + $normalized = WC_Admin_Reports_Interval::normalize_between_params( $request, $between_params_numeric, false ); + $normalized_dates = WC_Admin_Reports_Interval::normalize_between_params( $request, $between_params_date, true ); $args = array_merge( $args, $normalized, $normalized_dates ); return $args; diff --git a/plugins/woocommerce-admin/includes/class-wc-admin-reports-interval.php b/plugins/woocommerce-admin/includes/class-wc-admin-reports-interval.php index 5036d2fcab4..2bc1465c147 100644 --- a/plugins/woocommerce-admin/includes/class-wc-admin-reports-interval.php +++ b/plugins/woocommerce-admin/includes/class-wc-admin-reports-interval.php @@ -494,7 +494,8 @@ class WC_Admin_Reports_Interval { } /** - * Normalize "*_between" parameters to "*_min" and "*_max". + * Normalize "*_between" parameters to "*_min" and "*_max" for numeric values + * and "*_after" and "*_before" for date values. * * @param array $request Query params from REST API request. * @param string|array $param_names One or more param names to handle. Should not include "_between" suffix. From e6b42631f38faa524a62990fbe2493588d54c62b Mon Sep 17 00:00:00 2001 From: Paul Sealock Date: Tue, 29 Jan 2019 11:48:40 +1300 Subject: [PATCH 26/53] formatting --- ...ss-wc-admin-rest-reports-customers-controller.php | 12 ++++++------ ...admin-rest-reports-customers-stats-controller.php | 12 ++++++------ 2 files changed, 12 insertions(+), 12 deletions(-) diff --git a/plugins/woocommerce-admin/includes/api/class-wc-admin-rest-reports-customers-controller.php b/plugins/woocommerce-admin/includes/api/class-wc-admin-rest-reports-customers-controller.php index 33c67a1fd39..800e44b0e1f 100644 --- a/plugins/woocommerce-admin/includes/api/class-wc-admin-rest-reports-customers-controller.php +++ b/plugins/woocommerce-admin/includes/api/class-wc-admin-rest-reports-customers-controller.php @@ -61,11 +61,11 @@ class WC_Admin_REST_Reports_Customers_Controller extends WC_REST_Reports_Control $args['last_order_before'] = $request['last_order_before']; $args['last_order_after'] = $request['last_order_after']; - $between_params_numeric = array( 'orders_count', 'total_spend', 'avg_order_value' ); - $between_params_date = array( 'last_active', 'registered' ); - $normalized = WC_Admin_Reports_Interval::normalize_between_params( $request, $between_params_numeric, false ); - $normalized_dates = WC_Admin_Reports_Interval::normalize_between_params( $request, $between_params_date, true ); - $args = array_merge( $args, $normalized, $normalized_dates ); + $between_params_numeric = array( 'orders_count', 'total_spend', 'avg_order_value' ); + $normalized_numeric_params = WC_Admin_Reports_Interval::normalize_between_params( $request, $between_params_numeric, false ); + $between_params_date = array( 'last_active', 'registered' ); + $normalized_date_params = WC_Admin_Reports_Interval::normalize_between_params( $request, $between_params_date, true ); + $args = array_merge( $args, $normalized_numeric_params, $normalized_date_params ); return $args; } @@ -382,7 +382,7 @@ class WC_Admin_REST_Reports_Customers_Controller extends WC_REST_Reports_Control 'format' => 'date-time', 'validate_callback' => 'rest_validate_request_arg', ); - $params['registered_between'] = array( + $params['registered_between'] = array( 'description' => __( 'Limit response to objects last active between two given ISO8601 compliant datetime.', 'wc-admin' ), 'type' => 'array', 'validate_callback' => array( 'WC_Admin_Reports_Interval', 'rest_validate_between_date_arg' ), diff --git a/plugins/woocommerce-admin/includes/api/class-wc-admin-rest-reports-customers-stats-controller.php b/plugins/woocommerce-admin/includes/api/class-wc-admin-rest-reports-customers-stats-controller.php index aa9a7f163ca..3265e26f2ad 100644 --- a/plugins/woocommerce-admin/includes/api/class-wc-admin-rest-reports-customers-stats-controller.php +++ b/plugins/woocommerce-admin/includes/api/class-wc-admin-rest-reports-customers-stats-controller.php @@ -56,11 +56,11 @@ class WC_Admin_REST_Reports_Customers_Stats_Controller extends WC_REST_Reports_C $args['last_order_before'] = $request['last_order_before']; $args['last_order_after'] = $request['last_order_after']; - $between_params_numeric = array( 'orders_count', 'total_spend', 'avg_order_value' ); - $between_params_date = array( 'last_active', 'registered' ); - $normalized = WC_Admin_Reports_Interval::normalize_between_params( $request, $between_params_numeric, false ); - $normalized_dates = WC_Admin_Reports_Interval::normalize_between_params( $request, $between_params_date, true ); - $args = array_merge( $args, $normalized, $normalized_dates ); + $between_params_numeric = array( 'orders_count', 'total_spend', 'avg_order_value' ); + $normalized_numeric_params = WC_Admin_Reports_Interval::normalize_between_params( $request, $between_params_numeric, false ); + $between_params_date = array( 'last_active', 'registered' ); + $normalized_date_params = WC_Admin_Reports_Interval::normalize_between_params( $request, $between_params_date, true ); + $args = array_merge( $args, $normalized_numeric_params, $normalized_date_params ); return $args; } @@ -295,7 +295,7 @@ class WC_Admin_REST_Reports_Customers_Stats_Controller extends WC_REST_Reports_C 'format' => 'date-time', 'validate_callback' => 'rest_validate_request_arg', ); - $params['registered_between'] = array( + $params['registered_between'] = array( 'description' => __( 'Limit response to objects last active between two given ISO8601 compliant datetime.', 'wc-admin' ), 'type' => 'array', 'validate_callback' => array( 'WC_Admin_Reports_Interval', 'rest_validate_between_date_arg' ), From 765a0074918f803f2b87c302b9b85e06d1f36f52 Mon Sep 17 00:00:00 2001 From: Paul Sealock Date: Tue, 29 Jan 2019 12:08:44 +1300 Subject: [PATCH 27/53] tweeek --- .../class-wc-admin-rest-reports-customers-controller.php | 6 +++--- ...ass-wc-admin-rest-reports-customers-stats-controller.php | 6 +++--- 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/plugins/woocommerce-admin/includes/api/class-wc-admin-rest-reports-customers-controller.php b/plugins/woocommerce-admin/includes/api/class-wc-admin-rest-reports-customers-controller.php index 800e44b0e1f..f599cbe5455 100644 --- a/plugins/woocommerce-admin/includes/api/class-wc-admin-rest-reports-customers-controller.php +++ b/plugins/woocommerce-admin/includes/api/class-wc-admin-rest-reports-customers-controller.php @@ -62,10 +62,10 @@ class WC_Admin_REST_Reports_Customers_Controller extends WC_REST_Reports_Control $args['last_order_after'] = $request['last_order_after']; $between_params_numeric = array( 'orders_count', 'total_spend', 'avg_order_value' ); - $normalized_numeric_params = WC_Admin_Reports_Interval::normalize_between_params( $request, $between_params_numeric, false ); + $normalized_params_numeric = WC_Admin_Reports_Interval::normalize_between_params( $request, $between_params_numeric, false ); $between_params_date = array( 'last_active', 'registered' ); - $normalized_date_params = WC_Admin_Reports_Interval::normalize_between_params( $request, $between_params_date, true ); - $args = array_merge( $args, $normalized_numeric_params, $normalized_date_params ); + $normalized_params_date = WC_Admin_Reports_Interval::normalize_between_params( $request, $between_params_date, true ); + $args = array_merge( $args, $normalized_params_numeric, $normalized_params_date ); return $args; } diff --git a/plugins/woocommerce-admin/includes/api/class-wc-admin-rest-reports-customers-stats-controller.php b/plugins/woocommerce-admin/includes/api/class-wc-admin-rest-reports-customers-stats-controller.php index 3265e26f2ad..d500b888ff7 100644 --- a/plugins/woocommerce-admin/includes/api/class-wc-admin-rest-reports-customers-stats-controller.php +++ b/plugins/woocommerce-admin/includes/api/class-wc-admin-rest-reports-customers-stats-controller.php @@ -57,10 +57,10 @@ class WC_Admin_REST_Reports_Customers_Stats_Controller extends WC_REST_Reports_C $args['last_order_after'] = $request['last_order_after']; $between_params_numeric = array( 'orders_count', 'total_spend', 'avg_order_value' ); - $normalized_numeric_params = WC_Admin_Reports_Interval::normalize_between_params( $request, $between_params_numeric, false ); + $normalized_params_numeric = WC_Admin_Reports_Interval::normalize_between_params( $request, $between_params_numeric, false ); $between_params_date = array( 'last_active', 'registered' ); - $normalized_date_params = WC_Admin_Reports_Interval::normalize_between_params( $request, $between_params_date, true ); - $args = array_merge( $args, $normalized_numeric_params, $normalized_date_params ); + $normalized_params_date = WC_Admin_Reports_Interval::normalize_between_params( $request, $between_params_date, true ); + $args = array_merge( $args, $normalized_params_numeric, $normalized_params_date ); return $args; } From e136036ef9b941503d3b324ed58197e6cbf29931 Mon Sep 17 00:00:00 2001 From: Timmy Crawford Date: Mon, 28 Jan 2019 15:34:56 -0800 Subject: [PATCH 28/53] Build: Create new number package (https://github.com/woocommerce/woocommerce-admin/pull/1399) * Create new number package * Updates per feedback. * Update README. --- .../packages/currency/package.json | 3 +- .../packages/currency/src/index.js | 4 +- .../woocommerce-admin/packages/number/.npmrc | 1 + .../packages/number/CHANGELOG.md | 3 + .../packages/number/README.md | 31 ++++++++ .../packages/number/package.json | 30 ++++++++ .../packages/number/src/index.js | 74 +++++++++++++++++++ .../packages/number/src/test/index.js | 39 ++++++++++ 8 files changed, 182 insertions(+), 3 deletions(-) create mode 100644 plugins/woocommerce-admin/packages/number/.npmrc create mode 100644 plugins/woocommerce-admin/packages/number/CHANGELOG.md create mode 100644 plugins/woocommerce-admin/packages/number/README.md create mode 100644 plugins/woocommerce-admin/packages/number/package.json create mode 100644 plugins/woocommerce-admin/packages/number/src/index.js create mode 100644 plugins/woocommerce-admin/packages/number/src/test/index.js diff --git a/plugins/woocommerce-admin/packages/currency/package.json b/plugins/woocommerce-admin/packages/currency/package.json index 694a729c34f..d6cf273ca4f 100644 --- a/plugins/woocommerce-admin/packages/currency/package.json +++ b/plugins/woocommerce-admin/packages/currency/package.json @@ -22,7 +22,8 @@ "react-native": "src/index", "dependencies": { "@babel/runtime": "^7.0.0", - "lodash": "^4.17.11" + "lodash": "^4.17.11", + "@woocommerce/number": "1.0.0" }, "publishConfig": { "access": "public" diff --git a/plugins/woocommerce-admin/packages/currency/src/index.js b/plugins/woocommerce-admin/packages/currency/src/index.js index 8cecc1b34fc..71bb512b38c 100644 --- a/plugins/woocommerce-admin/packages/currency/src/index.js +++ b/plugins/woocommerce-admin/packages/currency/src/index.js @@ -6,9 +6,9 @@ import { get, isNaN } from 'lodash'; import { sprintf } from '@wordpress/i18n'; /** - * Internal dependencies + * WooCommerce dependencies */ -import { numberFormat } from 'lib/number'; +import { numberFormat } from '@woocommerce/number'; /** * Formats money with a given currency code. Uses site's currency settings for formatting. diff --git a/plugins/woocommerce-admin/packages/number/.npmrc b/plugins/woocommerce-admin/packages/number/.npmrc new file mode 100644 index 00000000000..9cf9495031e --- /dev/null +++ b/plugins/woocommerce-admin/packages/number/.npmrc @@ -0,0 +1 @@ +package-lock=false \ No newline at end of file diff --git a/plugins/woocommerce-admin/packages/number/CHANGELOG.md b/plugins/woocommerce-admin/packages/number/CHANGELOG.md new file mode 100644 index 00000000000..3388a443ca8 --- /dev/null +++ b/plugins/woocommerce-admin/packages/number/CHANGELOG.md @@ -0,0 +1,3 @@ +# 1.0.0 + +- Initial release exports `numberFormat`, `formatValue`, and `calculateDelta` diff --git a/plugins/woocommerce-admin/packages/number/README.md b/plugins/woocommerce-admin/packages/number/README.md new file mode 100644 index 00000000000..19a4de6fd32 --- /dev/null +++ b/plugins/woocommerce-admin/packages/number/README.md @@ -0,0 +1,31 @@ +# Number + +A collection of utilities to propery localize numerical values in WooCommerce + +## Installation + +Install the module + +```bash +npm install @woocommerce/number --save +``` + +_This package assumes that your code will run in an **ES2015+** environment. If you're using an environment that has limited or no support for ES2015+ such as lower versions of IE then using [core-js](https://github.com/zloirock/core-js) or [@babel/polyfill](https://babeljs.io/docs/en/next/babel-polyfill) will add support for these methods. Learn more about it in [Babel docs](https://babeljs.io/docs/en/next/caveats)._ + +## Usage + +```JS +import { formatNumber, formatValue, calculateDelta } from '@woocommerce/number'; + +// Formats a number using site's current locale. +// Defaults to en-US localization +const localizedNumber = formatNumber( 1337 ); // '1,377' + +// formatValue's first argument is a type: average, or number +// The second argument is the number/value to format +const formattedAverage = formatValue( 'average', '10.5' ); // 11 just uses Math.round +const formattedNumber = formatValue( 'number', '1337' ); // 1,337 calls formatNumber ( see above ) + +// Get a rounded percent change/delta between two numbers +const delta = calculateDelta( 10, 8 ); // '25' +``` diff --git a/plugins/woocommerce-admin/packages/number/package.json b/plugins/woocommerce-admin/packages/number/package.json new file mode 100644 index 00000000000..c8a920cc12c --- /dev/null +++ b/plugins/woocommerce-admin/packages/number/package.json @@ -0,0 +1,30 @@ +{ + "name": "@woocommerce/number", + "version": "1.0.0", + "description": "Number formatting utilities for WooCommerce.", + "author": "Automattic", + "license": "GPL-2.0-or-later", + "keywords": [ + "wordpress", + "woocommerce" + ], + "homepage": "https://github.com/WooCommerce/wc-admin/tree/master/packages/number/README.md", + "repository": { + "type": "git", + "url": "https://github.com/WooCommerce/wc-admin.git" + }, + "bugs": { + "url": "https://github.com/WooCommerce/wc-admin/issues" + }, + "main": "build/index.js", + "module": "build-module/index.js", + "react-native": "src/index", + "dependencies": { + "@babel/runtime-corejs2": "7.1.5", + "locutus": "^2.0.10", + "lodash": "^4.17.11" + }, + "publishConfig": { + "access": "public" + } +} \ No newline at end of file diff --git a/plugins/woocommerce-admin/packages/number/src/index.js b/plugins/woocommerce-admin/packages/number/src/index.js new file mode 100644 index 00000000000..e376224a6f8 --- /dev/null +++ b/plugins/woocommerce-admin/packages/number/src/index.js @@ -0,0 +1,74 @@ +/** @format */ +/** + * External dependencies + */ +import { get, isFinite } from 'lodash'; +const number_format = require( 'locutus/php/strings/number_format' ); + +/** + * Formats a number using site's current locale + * + * @see http://locutus.io/php/strings/number_format/ + * @param {Number|String} number number to format + * @param {int|null} [precision=null] optional decimal precision + * @returns {?String} A formatted string. + */ +export function numberFormat( number, precision = null ) { + if ( 'number' !== typeof number ) { + number = parseFloat( number ); + } + + if ( isNaN( number ) ) { + return ''; + } + + const decimalSeparator = get( wcSettings, [ 'currency', 'decimal_separator' ], '.' ); + const thousandSeparator = get( wcSettings, [ 'currency', 'thousand_separator' ], ',' ); + precision = parseInt( precision ); + + if ( isNaN( precision ) ) { + const [ , decimals ] = number.toString().split( '.' ); + precision = decimals ? decimals.length : 0; + } + + return number_format( number, precision, decimalSeparator, thousandSeparator ); +} + +/** + * Formats a number string based on type of `average` or `number`. + * + * @param {String} type of number to format, average or number + * @param {int} value to format. + * @returns {?String} A formatted string. + */ +export function formatValue( type, value ) { + if ( ! isFinite( value ) ) { + return null; + } + + switch ( type ) { + case 'average': + return Math.round( value ); + case 'number': + return numberFormat( value ); + } +} + +/** + * Calculates the delta/percentage change between two numbers. + * + * @param {int} primaryValue the value to calculate change for. + * @param {int} secondaryValue the baseline which to calculdate the change against. + * @returns {?int} Percent change between the primaryValue from the secondaryValue. + */ +export function calculateDelta( primaryValue, secondaryValue ) { + if ( ! isFinite( primaryValue ) || ! isFinite( secondaryValue ) ) { + return null; + } + + if ( secondaryValue === 0 ) { + return 0; + } + + return Math.round( ( primaryValue - secondaryValue ) / secondaryValue * 100 ); +} diff --git a/plugins/woocommerce-admin/packages/number/src/test/index.js b/plugins/woocommerce-admin/packages/number/src/test/index.js new file mode 100644 index 00000000000..83df3f32f06 --- /dev/null +++ b/plugins/woocommerce-admin/packages/number/src/test/index.js @@ -0,0 +1,39 @@ +/** @format */ +/** + * Internal dependencies + */ +import { numberFormat } from '../index'; + +describe( 'numberFormat', () => { + it( 'should default to precision=null decimal=. thousands=,', () => { + expect( numberFormat( 1000 ) ).toBe( '1,000' ); + } ); + + it( 'should return an empty string if no argument is passed', () => { + expect( numberFormat() ).toBe( '' ); + } ); + + it( 'should accept a string', () => { + expect( numberFormat( '10000' ) ).toBe( '10,000' ); + } ); + + it( 'maintains all decimals if no precision specified', () => { + expect( numberFormat( '10000.123456' ) ).toBe( '10,000.123456' ); + } ); + + it( 'maintains all decimals if invalid precision specified', () => { + expect( numberFormat( '10000.123456', 'not a number' ) ).toBe( '10,000.123456' ); + } ); + + it( 'calculates the correct decimals based on precision passed in', () => { + expect( numberFormat( '1337.4498', 2 ) ).toBe( '1,337.45' ); + } ); + + it( 'uses store currency settings, not locale', () => { + global.wcSettings.siteLocale = 'en-US'; + global.wcSettings.currency.decimal_separator = ','; + global.wcSettings.currency.thousand_separator = '.'; + + expect( numberFormat( '12345.6789', 3 ) ).toBe( '12.345,679' ); + } ); +} ); From 3379491c91f99922b70075328745da0db68cc09f Mon Sep 17 00:00:00 2001 From: Paul Sealock Date: Tue, 29 Jan 2019 13:35:27 +1300 Subject: [PATCH 29/53] Customers Report: fix order count filter --- .../client/analytics/report/customers/config.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/plugins/woocommerce-admin/client/analytics/report/customers/config.js b/plugins/woocommerce-admin/client/analytics/report/customers/config.js index 7869a76fe89..18a38e323ad 100644 --- a/plugins/woocommerce-admin/client/analytics/report/customers/config.js +++ b/plugins/woocommerce-admin/client/analytics/report/customers/config.js @@ -163,7 +163,7 @@ export const advancedFilters = { } ) ), }, }, - order_count: { + orders_count: { labels: { add: __( 'No. of Orders', 'wc-admin' ), remove: __( 'Remove order filter', 'wc-admin' ), From 10c6016d4cc71afda58ffcaaa27fb7390b368017 Mon Sep 17 00:00:00 2001 From: Timmy Crawford Date: Tue, 29 Jan 2019 08:48:46 -0800 Subject: [PATCH 30/53] Update usage of lib/number to @woocommerce/number (https://github.com/woocommerce/woocommerce-admin/pull/1400) * Remove usage of lib/number * Remove formatNumber usage when currency is used. * Add wc-number as a dependency of wc-currency. * Add locutus as a dev dependency. * Add number to test helper. --- .../components/leaderboard/test/index.js | 2 +- .../components/report-summary/index.js | 12 +++- .../analytics/report/categories/table.js | 3 +- .../client/analytics/report/coupons/table.js | 2 +- .../analytics/report/customers/table.js | 4 +- .../analytics/report/downloads/table.js | 2 +- .../client/analytics/report/orders/table.js | 2 +- .../report/products/table-variations.js | 2 +- .../client/analytics/report/products/table.js | 2 +- .../client/analytics/report/revenue/table.js | 2 +- .../client/analytics/report/stock/table.js | 2 +- .../client/analytics/report/taxes/table.js | 2 +- .../dashboard/leaderboards/top-coupons.js | 2 +- .../leaderboards/top-selling-categories.js | 2 +- .../leaderboards/top-selling-products.js | 2 +- .../dashboard/store-performance/index.js | 13 +++- .../client/lib/number/index.js | 63 ------------------- .../client/lib/number/test/index.js | 35 ----------- .../woocommerce-admin/lib/client-assets.php | 11 +++- plugins/woocommerce-admin/package-lock.json | 3 +- plugins/woocommerce-admin/package.json | 2 +- .../tests/js/setup-globals.js | 1 + plugins/woocommerce-admin/webpack.config.js | 1 + 23 files changed, 49 insertions(+), 123 deletions(-) delete mode 100644 plugins/woocommerce-admin/client/lib/number/index.js delete mode 100644 plugins/woocommerce-admin/client/lib/number/test/index.js diff --git a/plugins/woocommerce-admin/client/analytics/components/leaderboard/test/index.js b/plugins/woocommerce-admin/client/analytics/components/leaderboard/test/index.js index 1bc05197c0c..368e8ff9d48 100644 --- a/plugins/woocommerce-admin/client/analytics/components/leaderboard/test/index.js +++ b/plugins/woocommerce-admin/client/analytics/components/leaderboard/test/index.js @@ -12,13 +12,13 @@ import { createRegistry, RegistryProvider } from '@wordpress/data'; * WooCommerce dependencies */ import { formatCurrency, getCurrencyFormatDecimal } from '@woocommerce/currency'; +import { numberFormat } from '@woocommerce/number'; /** * Internal dependencies */ import LeaderboardWithSelect, { Leaderboard } from '../'; import { NAMESPACE } from 'store/constants'; -import { numberFormat } from 'lib/number'; import mockData from '../__mocks__/top-selling-products-mock-data'; // Mock to avoid tests failing due to it using DOM properties that diff --git a/plugins/woocommerce-admin/client/analytics/components/report-summary/index.js b/plugins/woocommerce-admin/client/analytics/components/report-summary/index.js index 23933fe1290..89e2a2f309f 100644 --- a/plugins/woocommerce-admin/client/analytics/components/report-summary/index.js +++ b/plugins/woocommerce-admin/client/analytics/components/report-summary/index.js @@ -13,13 +13,14 @@ import PropTypes from 'prop-types'; import { getDateParamsFromQuery } from '@woocommerce/date'; import { getNewPath } from '@woocommerce/navigation'; import { SummaryList, SummaryListPlaceholder, SummaryNumber } from '@woocommerce/components'; +import { calculateDelta, formatValue } from '@woocommerce/number'; +import { formatCurrency } from '@woocommerce/currency'; /** * Internal dependencies */ import { getSummaryNumbers } from 'store/reports/utils'; import ReportError from 'analytics/components/report-error'; -import { calculateDelta, formatValue } from 'lib/number'; import withSelect from 'wc-api/with-select'; /** @@ -45,11 +46,16 @@ export class ReportSummary extends Component { const renderSummaryNumbers = ( { onToggle } ) => charts.map( chart => { const { key, label, type } = chart; + const isCurrency = 'currency' === type; const delta = calculateDelta( primaryTotals[ key ], secondaryTotals[ key ] ); const href = getNewPath( { chart: key } ); - const prevValue = formatValue( type, secondaryTotals[ key ] ); + const prevValue = isCurrency + ? formatCurrency( secondaryTotals[ key ] ) + : formatValue( type, secondaryTotals[ key ] ); const isSelected = selectedChart.key === key; - const value = formatValue( type, primaryTotals[ key ] ); + const value = isCurrency + ? formatCurrency( primaryTotals[ key ] ) + : formatValue( type, primaryTotals[ key ] ); return ( { const { category_id, items_sold, net_revenue, products_count, orders_count } = categoryStat; const { categories, query } = this.props; diff --git a/plugins/woocommerce-admin/client/analytics/report/coupons/table.js b/plugins/woocommerce-admin/client/analytics/report/coupons/table.js index 50fba9e655c..7953c218dec 100644 --- a/plugins/woocommerce-admin/client/analytics/report/coupons/table.js +++ b/plugins/woocommerce-admin/client/analytics/report/coupons/table.js @@ -13,12 +13,12 @@ import { Date, Link } from '@woocommerce/components'; import { defaultTableDateFormat } from '@woocommerce/date'; import { formatCurrency, getCurrencyFormatDecimal } from '@woocommerce/currency'; import { getNewPath, getPersistedQuery } from '@woocommerce/navigation'; +import { numberFormat } from '@woocommerce/number'; /** * Internal dependencies */ import ReportTable from 'analytics/components/report-table'; -import { numberFormat } from 'lib/number'; export default class CouponsReportTable extends Component { constructor() { diff --git a/plugins/woocommerce-admin/client/analytics/report/customers/table.js b/plugins/woocommerce-admin/client/analytics/report/customers/table.js index 465964afbaf..3fead05afb6 100644 --- a/plugins/woocommerce-admin/client/analytics/report/customers/table.js +++ b/plugins/woocommerce-admin/client/analytics/report/customers/table.js @@ -12,12 +12,12 @@ import { Tooltip } from '@wordpress/components'; import { defaultTableDateFormat } from '@woocommerce/date'; import { formatCurrency, getCurrencyFormatDecimal } from '@woocommerce/currency'; import { Date, Link } from '@woocommerce/components'; +import { numberFormat } from '@woocommerce/number'; /** * Internal dependencies */ import ReportTable from 'analytics/components/report-table'; -import { numberFormat } from 'lib/number'; export default class CustomersReportTable extends Component { constructor() { @@ -233,4 +233,4 @@ export default class CustomersReportTable extends Component { /> ); } -} \ No newline at end of file +} diff --git a/plugins/woocommerce-admin/client/analytics/report/downloads/table.js b/plugins/woocommerce-admin/client/analytics/report/downloads/table.js index 690e1bed014..9d2f403602d 100644 --- a/plugins/woocommerce-admin/client/analytics/report/downloads/table.js +++ b/plugins/woocommerce-admin/client/analytics/report/downloads/table.js @@ -13,12 +13,12 @@ import moment from 'moment'; import { defaultTableDateFormat, getCurrentDates } from '@woocommerce/date'; import { Date, Link } from '@woocommerce/components'; import { getNewPath, getPersistedQuery } from '@woocommerce/navigation'; +import { numberFormat } from '@woocommerce/number'; /** * Internal dependencies */ import ReportTable from 'analytics/components/report-table'; -import { numberFormat } from 'lib/number'; export default class CouponsReportTable extends Component { constructor() { diff --git a/plugins/woocommerce-admin/client/analytics/report/orders/table.js b/plugins/woocommerce-admin/client/analytics/report/orders/table.js index 25bc7d9b33c..cdd9db732ba 100644 --- a/plugins/woocommerce-admin/client/analytics/report/orders/table.js +++ b/plugins/woocommerce-admin/client/analytics/report/orders/table.js @@ -12,11 +12,11 @@ import { map } from 'lodash'; import { Date, Link, OrderStatus, ViewMoreList } from '@woocommerce/components'; import { defaultTableDateFormat } from '@woocommerce/date'; import { formatCurrency } from '@woocommerce/currency'; +import { numberFormat } from '@woocommerce/number'; /** * Internal dependencies */ -import { numberFormat } from 'lib/number'; import ReportTable from 'analytics/components/report-table'; import { getNewPath, getPersistedQuery } from '@woocommerce/navigation'; import './style.scss'; diff --git a/plugins/woocommerce-admin/client/analytics/report/products/table-variations.js b/plugins/woocommerce-admin/client/analytics/report/products/table-variations.js index 2d3841c5700..5bfda17057b 100644 --- a/plugins/woocommerce-admin/client/analytics/report/products/table-variations.js +++ b/plugins/woocommerce-admin/client/analytics/report/products/table-variations.js @@ -12,12 +12,12 @@ import { map, get } from 'lodash'; import { Link } from '@woocommerce/components'; import { formatCurrency, getCurrencyFormatDecimal } from '@woocommerce/currency'; import { getNewPath, getPersistedQuery } from '@woocommerce/navigation'; +import { numberFormat } from '@woocommerce/number'; /** * Internal dependencies */ import ReportTable from 'analytics/components/report-table'; -import { numberFormat } from 'lib/number'; import { isLowStock } from './utils'; export default class VariationsReportTable extends Component { diff --git a/plugins/woocommerce-admin/client/analytics/report/products/table.js b/plugins/woocommerce-admin/client/analytics/report/products/table.js index 05cec8fa7ea..49847567184 100644 --- a/plugins/woocommerce-admin/client/analytics/report/products/table.js +++ b/plugins/woocommerce-admin/client/analytics/report/products/table.js @@ -13,13 +13,13 @@ import { map } from 'lodash'; import { formatCurrency, getCurrencyFormatDecimal } from '@woocommerce/currency'; import { getNewPath, getPersistedQuery } from '@woocommerce/navigation'; import { Link, Tag } from '@woocommerce/components'; +import { numberFormat } from '@woocommerce/number'; /** * Internal dependencies */ import CategoryBreacrumbs from '../categories/breadcrumbs'; import { isLowStock } from './utils'; -import { numberFormat } from 'lib/number'; import ReportTable from 'analytics/components/report-table'; import withSelect from 'wc-api/with-select'; import './style.scss'; diff --git a/plugins/woocommerce-admin/client/analytics/report/revenue/table.js b/plugins/woocommerce-admin/client/analytics/report/revenue/table.js index ef8aca4c0c3..aa0e7c23f14 100644 --- a/plugins/woocommerce-admin/client/analytics/report/revenue/table.js +++ b/plugins/woocommerce-admin/client/analytics/report/revenue/table.js @@ -14,12 +14,12 @@ import { get } from 'lodash'; import { appendTimestamp, defaultTableDateFormat, getCurrentDates } from '@woocommerce/date'; import { Date, Link } from '@woocommerce/components'; import { formatCurrency, getCurrencyFormatDecimal } from '@woocommerce/currency'; +import { numberFormat } from '@woocommerce/number'; /** * Internal dependencies */ import { QUERY_DEFAULTS } from 'store/constants'; -import { numberFormat } from 'lib/number'; import ReportTable from 'analytics/components/report-table'; import withSelect from 'wc-api/with-select'; diff --git a/plugins/woocommerce-admin/client/analytics/report/stock/table.js b/plugins/woocommerce-admin/client/analytics/report/stock/table.js index ffdf8e15fb6..ddabf01351c 100644 --- a/plugins/woocommerce-admin/client/analytics/report/stock/table.js +++ b/plugins/woocommerce-admin/client/analytics/report/stock/table.js @@ -10,12 +10,12 @@ import { Component } from '@wordpress/element'; */ import { Link } from '@woocommerce/components'; import { getNewPath, getPersistedQuery } from '@woocommerce/navigation'; +import { numberFormat } from '@woocommerce/number'; /** * Internal dependencies */ import ReportTable from 'analytics/components/report-table'; -import { numberFormat } from 'lib/number'; export default class StockReportTable extends Component { constructor() { diff --git a/plugins/woocommerce-admin/client/analytics/report/taxes/table.js b/plugins/woocommerce-admin/client/analytics/report/taxes/table.js index 84c30cb4809..d6e076677ae 100644 --- a/plugins/woocommerce-admin/client/analytics/report/taxes/table.js +++ b/plugins/woocommerce-admin/client/analytics/report/taxes/table.js @@ -12,12 +12,12 @@ import { map } from 'lodash'; import { Link } from '@woocommerce/components'; import { formatCurrency, getCurrencyFormatDecimal } from '@woocommerce/currency'; import { getTaxCode } from './utils'; +import { numberFormat } from '@woocommerce/number'; /** * Internal dependencies */ import ReportTable from 'analytics/components/report-table'; -import { numberFormat } from 'lib/number'; export default class TaxesReportTable extends Component { constructor() { diff --git a/plugins/woocommerce-admin/client/dashboard/leaderboards/top-coupons.js b/plugins/woocommerce-admin/client/dashboard/leaderboards/top-coupons.js index afc05275c19..bc39ba449cc 100644 --- a/plugins/woocommerce-admin/client/dashboard/leaderboards/top-coupons.js +++ b/plugins/woocommerce-admin/client/dashboard/leaderboards/top-coupons.js @@ -12,11 +12,11 @@ import { map } from 'lodash'; import { formatCurrency, getCurrencyFormatDecimal } from '@woocommerce/currency'; import { getNewPath, getPersistedQuery } from '@woocommerce/navigation'; import { Link } from '@woocommerce/components'; +import { numberFormat } from '@woocommerce/number'; /** * Internal dependencies */ -import { numberFormat } from 'lib/number'; import Leaderboard from 'analytics/components/leaderboard'; export class TopCoupons extends Component { diff --git a/plugins/woocommerce-admin/client/dashboard/leaderboards/top-selling-categories.js b/plugins/woocommerce-admin/client/dashboard/leaderboards/top-selling-categories.js index 272503fe8aa..338dfcc2552 100644 --- a/plugins/woocommerce-admin/client/dashboard/leaderboards/top-selling-categories.js +++ b/plugins/woocommerce-admin/client/dashboard/leaderboards/top-selling-categories.js @@ -12,11 +12,11 @@ import { get, map } from 'lodash'; import { formatCurrency, getCurrencyFormatDecimal } from '@woocommerce/currency'; import { getNewPath, getPersistedQuery } from '@woocommerce/navigation'; import { Link } from '@woocommerce/components'; +import { numberFormat } from '@woocommerce/number'; /** * Internal dependencies */ -import { numberFormat } from 'lib/number'; import Leaderboard from 'analytics/components/leaderboard'; export class TopSellingCategories extends Component { diff --git a/plugins/woocommerce-admin/client/dashboard/leaderboards/top-selling-products.js b/plugins/woocommerce-admin/client/dashboard/leaderboards/top-selling-products.js index 905344e48b0..deaa43bd790 100644 --- a/plugins/woocommerce-admin/client/dashboard/leaderboards/top-selling-products.js +++ b/plugins/woocommerce-admin/client/dashboard/leaderboards/top-selling-products.js @@ -12,11 +12,11 @@ import { get, map } from 'lodash'; import { formatCurrency, getCurrencyFormatDecimal } from '@woocommerce/currency'; import { getNewPath, getPersistedQuery } from '@woocommerce/navigation'; import { Link } from '@woocommerce/components'; +import { numberFormat } from '@woocommerce/number'; /** * Internal dependencies */ -import { numberFormat } from 'lib/number'; import Leaderboard from 'analytics/components/leaderboard'; export class TopSellingProducts extends Component { diff --git a/plugins/woocommerce-admin/client/dashboard/store-performance/index.js b/plugins/woocommerce-admin/client/dashboard/store-performance/index.js index 473414fdfb4..dbcacb002b8 100644 --- a/plugins/woocommerce-admin/client/dashboard/store-performance/index.js +++ b/plugins/woocommerce-admin/client/dashboard/store-performance/index.js @@ -15,6 +15,8 @@ import { find } from 'lodash'; */ import { getCurrentDates, appendTimestamp, getDateParamsFromQuery } from '@woocommerce/date'; import { getNewPath, getPersistedQuery } from '@woocommerce/navigation'; +import { calculateDelta, formatValue } from '@woocommerce/number'; +import { formatCurrency } from '@woocommerce/currency'; /** * Internal dependencies @@ -31,7 +33,6 @@ import { } from '@woocommerce/components'; import withSelect from 'wc-api/with-select'; import './style.scss'; -import { calculateDelta, formatValue } from 'lib/number'; class StorePerformance extends Component { constructor( props ) { @@ -128,9 +129,15 @@ class StorePerformance extends Component { ''; const reportUrl = ( href && getNewPath( persistedQuery, href, { chart: primaryItem.chart } ) ) || ''; + const isCurrency = 'currency' === primaryItem.format; + const delta = calculateDelta( primaryItem.value, secondaryItem.value ); - const primaryValue = formatValue( primaryItem.format, primaryItem.value ); - const secondaryValue = formatValue( secondaryItem.format, secondaryItem.value ); + const primaryValue = isCurrency + ? formatCurrency( primaryItem.value ) + : formatValue( primaryItem.format, primaryItem.value ); + const secondaryValue = isCurrency + ? formatCurrency( secondaryItem.value ) + : formatValue( secondaryItem.format, secondaryItem.value ); return ( { - it( 'should default to precision=null decimal=. thousands=,', () => { - expect( numberFormat( 1000 ) ).toBe( '1,000' ); - } ); - - it( 'should return an empty string if no argument is passed', () => { - expect( numberFormat() ).toBe( '' ); - } ); - - it( 'should accept a string', () => { - expect( numberFormat( '10000' ) ).toBe( '10,000' ); - } ); - - it( 'maintains all decimals if no precision specified', () => { - expect( numberFormat( '10000.123456' ) ).toBe( '10,000.123456' ); - } ); - - it( 'maintains all decimals if invalid precision specified', () => { - expect( numberFormat( '10000.123456', 'not a number' ) ).toBe( '10,000.123456' ); - } ); - - it( 'uses store currency settings, not locale', () => { - global.wcSettings.siteLocale = 'en-US'; - global.wcSettings.currency.decimal_separator = ','; - global.wcSettings.currency.thousand_separator = '.'; - - expect( numberFormat( '12345.6789', 3 ) ).toBe( '12.345,679' ); - } ); -} ); diff --git a/plugins/woocommerce-admin/lib/client-assets.php b/plugins/woocommerce-admin/lib/client-assets.php index ae44494948d..5725689e037 100644 --- a/plugins/woocommerce-admin/lib/client-assets.php +++ b/plugins/woocommerce-admin/lib/client-assets.php @@ -29,7 +29,7 @@ function wc_admin_register_script() { wp_register_script( 'wc-currency', wc_admin_url( 'dist/currency/index.js' ), - array(), + array( 'wc-number' ), filemtime( wc_admin_dir_path( 'dist/currency/index.js' ) ), true ); @@ -42,6 +42,14 @@ function wc_admin_register_script() { true ); + wp_register_script( + 'wc-number', + wc_admin_url( 'dist/number/index.js' ), + array(), + filemtime( wc_admin_dir_path( 'dist/number/index.js' ) ), + true + ); + wp_register_script( 'wc-date', wc_admin_url( 'dist/date/index.js' ), @@ -64,6 +72,7 @@ function wc_admin_register_script() { 'wc-currency', 'wc-date', 'wc-navigation', + 'wc-number', ), filemtime( wc_admin_dir_path( 'dist/components/index.js' ) ), true diff --git a/plugins/woocommerce-admin/package-lock.json b/plugins/woocommerce-admin/package-lock.json index 326cca17a77..d648bb3d958 100644 --- a/plugins/woocommerce-admin/package-lock.json +++ b/plugins/woocommerce-admin/package-lock.json @@ -12944,7 +12944,8 @@ "locutus": { "version": "2.0.10", "resolved": "https://registry.npmjs.org/locutus/-/locutus-2.0.10.tgz", - "integrity": "sha512-AZg2kCqrquMJ5FehDsBidV0qHl98NrsYtseUClzjAQ3HFnsDBJTCwGVplSQ82t9/QfgahqvTjaKcZqZkHmS0wQ==" + "integrity": "sha512-AZg2kCqrquMJ5FehDsBidV0qHl98NrsYtseUClzjAQ3HFnsDBJTCwGVplSQ82t9/QfgahqvTjaKcZqZkHmS0wQ==", + "dev": true }, "lodash": { "version": "4.17.11", diff --git a/plugins/woocommerce-admin/package.json b/plugins/woocommerce-admin/package.json index d7011710654..b969ea7aa6a 100644 --- a/plugins/woocommerce-admin/package.json +++ b/plugins/woocommerce-admin/package.json @@ -85,6 +85,7 @@ "grunt-wp-i18n": "1.0.3", "husky": "1.3.1", "lerna": "3.10.5", + "locutus": "^2.0.10", "mini-css-extract-plugin": "0.5.0", "node-sass": "4.11.0", "node-watch": "0.6.0", @@ -137,7 +138,6 @@ "history": "4.7.2", "html-to-react": "1.3.4", "interpolate-components": "1.1.1", - "locutus": "^2.0.10", "lodash": "^4.17.11", "marked": "0.6.0", "prismjs": "^1.15.0", diff --git a/plugins/woocommerce-admin/tests/js/setup-globals.js b/plugins/woocommerce-admin/tests/js/setup-globals.js index e07b32c27ab..d3ed144ed8c 100644 --- a/plugins/woocommerce-admin/tests/js/setup-globals.js +++ b/plugins/woocommerce-admin/tests/js/setup-globals.js @@ -27,6 +27,7 @@ const wooCommercePackages = [ 'currency', 'date', 'navigation', + 'number', ]; wordPressPackages.forEach( lib => { diff --git a/plugins/woocommerce-admin/webpack.config.js b/plugins/woocommerce-admin/webpack.config.js index 63320a0c03c..328947b73d2 100644 --- a/plugins/woocommerce-admin/webpack.config.js +++ b/plugins/woocommerce-admin/webpack.config.js @@ -38,6 +38,7 @@ const wcAdminPackages = [ 'currency', 'date', 'navigation', + 'number', ]; const entryPoints = {}; From dfd15f959a184b733fd7dbf99f890a3dc3b875f3 Mon Sep 17 00:00:00 2001 From: Kelly Dwan Date: Tue, 29 Jan 2019 16:19:00 -0500 Subject: [PATCH 31/53] Components package: Add emoji-flags dependency (https://github.com/woocommerce/woocommerce-admin/pull/1411) * Add emoji-flags to the components package.json * Update the changelog --- plugins/woocommerce-admin/packages/components/CHANGELOG.md | 5 ++++- plugins/woocommerce-admin/packages/components/package.json | 4 ++-- 2 files changed, 6 insertions(+), 3 deletions(-) diff --git a/plugins/woocommerce-admin/packages/components/CHANGELOG.md b/plugins/woocommerce-admin/packages/components/CHANGELOG.md index 7234f23da80..6f38b0cf78b 100644 --- a/plugins/woocommerce-admin/packages/components/CHANGELOG.md +++ b/plugins/woocommerce-admin/packages/components/CHANGELOG.md @@ -1,4 +1,7 @@ -# 1.4.1 (unreleased) +# 1.4.2 (unreleased) +- Add emoji-flags dependency + +# 1.4.1 - Chart component: format numbers and prices using store currency settings. - Make `href`/linking optional in SummaryNumber. - Fix SummaryNumber example code. diff --git a/plugins/woocommerce-admin/packages/components/package.json b/plugins/woocommerce-admin/packages/components/package.json index c03ece5c319..3738ab1855e 100644 --- a/plugins/woocommerce-admin/packages/components/package.json +++ b/plugins/woocommerce-admin/packages/components/package.json @@ -44,6 +44,7 @@ "d3-selection": "^1.3.2", "d3-shape": "^1.2.2", "d3-time-format": "^2.1.3", + "emoji-flags": "^1.2.0", "gridicons": "3.1.1", "interpolate-components": "1.1.1", "lodash": "^4.17.11", @@ -52,8 +53,7 @@ "qs": "^6.5.2", "react-dates": "^18.0.4", "react-router-dom": "4.3.1", - "react-transition-group": "^2.4.0", - "react-world-flags": "1.2.4" + "react-transition-group": "^2.4.0" }, "publishConfig": { "access": "public" From 88ea6136274124475117db8e272c099e0f471d9f Mon Sep 17 00:00:00 2001 From: Timmy Crawford Date: Tue, 29 Jan 2019 15:37:25 -0800 Subject: [PATCH 32/53] Build: Updates from latest npm publish (https://github.com/woocommerce/woocommerce-admin/pull/1409) * remove unreleased tags from changelogs * chore(release): publish - @woocommerce/components@1.4.1 - @woocommerce/csv-export@1.0.3 - @woocommerce/currency@1.1.0 - @woocommerce/date@1.0.6 - @woocommerce/navigation@1.1.1 - @woocommerce/number@1.0.1 --- .../woocommerce-admin/packages/components/package.json | 10 +++++----- .../woocommerce-admin/packages/csv-export/package.json | 2 +- .../woocommerce-admin/packages/currency/CHANGELOG.md | 2 +- .../woocommerce-admin/packages/currency/package.json | 6 +++--- plugins/woocommerce-admin/packages/date/package.json | 2 +- .../woocommerce-admin/packages/navigation/package.json | 2 +- plugins/woocommerce-admin/packages/number/package.json | 10 +++++----- 7 files changed, 17 insertions(+), 17 deletions(-) diff --git a/plugins/woocommerce-admin/packages/components/package.json b/plugins/woocommerce-admin/packages/components/package.json index 3738ab1855e..46070b6560d 100644 --- a/plugins/woocommerce-admin/packages/components/package.json +++ b/plugins/woocommerce-admin/packages/components/package.json @@ -1,6 +1,6 @@ { "name": "@woocommerce/components", - "version": "1.4.0", + "version": "1.4.1", "description": "UI components for WooCommerce.", "author": "Automattic", "license": "GPL-2.0-or-later", @@ -22,10 +22,10 @@ "react-native": "src/index", "dependencies": { "@babel/runtime-corejs2": "7.2.0", - "@woocommerce/csv-export": "^1.0.2", - "@woocommerce/currency": "^1.0.0", - "@woocommerce/date": "^1.0.5", - "@woocommerce/navigation": "^1.1.0", + "@woocommerce/csv-export": "^1.0.3", + "@woocommerce/currency": "^1.1.0", + "@woocommerce/date": "^1.0.6", + "@woocommerce/navigation": "^1.1.1", "@wordpress/components": "7.0.5", "@wordpress/compose": "3.0.0", "@wordpress/date": "3.0.1", diff --git a/plugins/woocommerce-admin/packages/csv-export/package.json b/plugins/woocommerce-admin/packages/csv-export/package.json index 7d84f4a5a89..c917f8e0c28 100644 --- a/plugins/woocommerce-admin/packages/csv-export/package.json +++ b/plugins/woocommerce-admin/packages/csv-export/package.json @@ -1,6 +1,6 @@ { "name": "@woocommerce/csv-export", - "version": "1.0.2", + "version": "1.0.3", "description": "WooCommerce utility library to convert data to CSV files.", "author": "Automattic", "license": "GPL-2.0-or-later", diff --git a/plugins/woocommerce-admin/packages/currency/CHANGELOG.md b/plugins/woocommerce-admin/packages/currency/CHANGELOG.md index 7963769c489..95373e4bebd 100644 --- a/plugins/woocommerce-admin/packages/currency/CHANGELOG.md +++ b/plugins/woocommerce-admin/packages/currency/CHANGELOG.md @@ -1,4 +1,4 @@ -# 1.1.0 (unreleased) +# 1.1.0 - Format using store currency settings (instead of locale) - Add optional currency symbol parameter diff --git a/plugins/woocommerce-admin/packages/currency/package.json b/plugins/woocommerce-admin/packages/currency/package.json index d6cf273ca4f..ee203bada18 100644 --- a/plugins/woocommerce-admin/packages/currency/package.json +++ b/plugins/woocommerce-admin/packages/currency/package.json @@ -1,6 +1,6 @@ { "name": "@woocommerce/currency", - "version": "1.0.0", + "version": "1.1.0", "description": "WooCommerce currency utilities.", "author": "Automattic", "license": "GPL-2.0-or-later", @@ -22,8 +22,8 @@ "react-native": "src/index", "dependencies": { "@babel/runtime": "^7.0.0", - "lodash": "^4.17.11", - "@woocommerce/number": "1.0.0" + "@woocommerce/number": "^1.0.1", + "lodash": "^4.17.11" }, "publishConfig": { "access": "public" diff --git a/plugins/woocommerce-admin/packages/date/package.json b/plugins/woocommerce-admin/packages/date/package.json index 4b4c8a7f90e..1c8f3637964 100644 --- a/plugins/woocommerce-admin/packages/date/package.json +++ b/plugins/woocommerce-admin/packages/date/package.json @@ -1,6 +1,6 @@ { "name": "@woocommerce/date", - "version": "1.0.5", + "version": "1.0.6", "description": "WooCommerce date utilities.", "author": "Automattic", "license": "GPL-2.0-or-later", diff --git a/plugins/woocommerce-admin/packages/navigation/package.json b/plugins/woocommerce-admin/packages/navigation/package.json index c641c72cd42..74b17e1b7f9 100644 --- a/plugins/woocommerce-admin/packages/navigation/package.json +++ b/plugins/woocommerce-admin/packages/navigation/package.json @@ -1,6 +1,6 @@ { "name": "@woocommerce/navigation", - "version": "1.1.0", + "version": "1.1.1", "description": "WooCommerce navigation utilities.", "author": "Automattic", "license": "GPL-2.0-or-later", diff --git a/plugins/woocommerce-admin/packages/number/package.json b/plugins/woocommerce-admin/packages/number/package.json index c8a920cc12c..e9bb5388c32 100644 --- a/plugins/woocommerce-admin/packages/number/package.json +++ b/plugins/woocommerce-admin/packages/number/package.json @@ -1,6 +1,6 @@ { "name": "@woocommerce/number", - "version": "1.0.0", + "version": "1.0.1", "description": "Number formatting utilities for WooCommerce.", "author": "Automattic", "license": "GPL-2.0-or-later", @@ -20,11 +20,11 @@ "module": "build-module/index.js", "react-native": "src/index", "dependencies": { - "@babel/runtime-corejs2": "7.1.5", - "locutus": "^2.0.10", - "lodash": "^4.17.11" + "@babel/runtime-corejs2": "7.1.5", + "locutus": "^2.0.10", + "lodash": "^4.17.11" }, "publishConfig": { "access": "public" } -} \ No newline at end of file +} From 53a6e498740a8807efc77ad33520bf865633599f Mon Sep 17 00:00:00 2001 From: Justin Shreve Date: Wed, 30 Jan 2019 02:22:10 -0500 Subject: [PATCH 33/53] Finish cleaning up client/store. (https://github.com/woocommerce/woocommerce-admin/pull/1403) --- .../analytics/components/leaderboard/index.js | 2 +- .../components/leaderboard/test/index.js | 2 +- .../analytics/components/report-chart/index.js | 2 +- .../analytics/components/report-summary/index.js | 2 +- .../analytics/components/report-table/index.js | 2 +- .../client/analytics/report/customers/config.js | 2 +- .../client/analytics/report/revenue/table.js | 2 +- .../client/analytics/report/taxes/config.js | 2 +- .../client/header/activity-panel/panels/inbox.js | 2 +- .../header/activity-panel/panels/orders.js | 2 +- .../header/activity-panel/panels/reviews.js | 2 +- .../client/lib/async-requests/index.js | 2 +- .../woocommerce-admin/client/store/constants.js | 16 ---------------- plugins/woocommerce-admin/client/store/utils.js | 11 ----------- .../woocommerce-admin/client/wc-api/constants.js | 3 +++ .../client/wc-api/reports/stats/operations.js | 5 ++--- .../client/{store => wc-api}/reports/utils.js | 2 +- 17 files changed, 18 insertions(+), 43 deletions(-) delete mode 100644 plugins/woocommerce-admin/client/store/constants.js delete mode 100644 plugins/woocommerce-admin/client/store/utils.js rename plugins/woocommerce-admin/client/{store => wc-api}/reports/utils.js (99%) diff --git a/plugins/woocommerce-admin/client/analytics/components/leaderboard/index.js b/plugins/woocommerce-admin/client/analytics/components/leaderboard/index.js index 25989a874fa..41723e20f23 100644 --- a/plugins/woocommerce-admin/client/analytics/components/leaderboard/index.js +++ b/plugins/woocommerce-admin/client/analytics/components/leaderboard/index.js @@ -17,7 +17,7 @@ import { Card, EmptyTable, TableCard } from '@woocommerce/components'; * Internal dependencies */ import ReportError from 'analytics/components/report-error'; -import { getReportTableData } from 'store/reports/utils'; +import { getReportTableData } from 'wc-api/reports/utils'; import withSelect from 'wc-api/with-select'; import './style.scss'; diff --git a/plugins/woocommerce-admin/client/analytics/components/leaderboard/test/index.js b/plugins/woocommerce-admin/client/analytics/components/leaderboard/test/index.js index 368e8ff9d48..1cfc9e5c699 100644 --- a/plugins/woocommerce-admin/client/analytics/components/leaderboard/test/index.js +++ b/plugins/woocommerce-admin/client/analytics/components/leaderboard/test/index.js @@ -18,7 +18,7 @@ import { numberFormat } from '@woocommerce/number'; * Internal dependencies */ import LeaderboardWithSelect, { Leaderboard } from '../'; -import { NAMESPACE } from 'store/constants'; +import { NAMESPACE } from 'wc-api/constants'; import mockData from '../__mocks__/top-selling-products-mock-data'; // Mock
to avoid tests failing due to it using DOM properties that diff --git a/plugins/woocommerce-admin/client/analytics/components/report-chart/index.js b/plugins/woocommerce-admin/client/analytics/components/report-chart/index.js index 283beabbb40..58917aed6a2 100644 --- a/plugins/woocommerce-admin/client/analytics/components/report-chart/index.js +++ b/plugins/woocommerce-admin/client/analytics/components/report-chart/index.js @@ -25,7 +25,7 @@ import { Chart } from '@woocommerce/components'; /** * Internal dependencies */ -import { getReportChartData, getTooltipValueFormat } from 'store/reports/utils'; +import { getReportChartData, getTooltipValueFormat } from 'wc-api/reports/utils'; import ReportError from 'analytics/components/report-error'; import withSelect from 'wc-api/with-select'; diff --git a/plugins/woocommerce-admin/client/analytics/components/report-summary/index.js b/plugins/woocommerce-admin/client/analytics/components/report-summary/index.js index 89e2a2f309f..51a6ea4f1e2 100644 --- a/plugins/woocommerce-admin/client/analytics/components/report-summary/index.js +++ b/plugins/woocommerce-admin/client/analytics/components/report-summary/index.js @@ -19,7 +19,7 @@ import { formatCurrency } from '@woocommerce/currency'; /** * Internal dependencies */ -import { getSummaryNumbers } from 'store/reports/utils'; +import { getSummaryNumbers } from 'wc-api/reports/utils'; import ReportError from 'analytics/components/report-error'; import withSelect from 'wc-api/with-select'; diff --git a/plugins/woocommerce-admin/client/analytics/components/report-table/index.js b/plugins/woocommerce-admin/client/analytics/components/report-table/index.js index 4e922dde521..55b664bebf7 100644 --- a/plugins/woocommerce-admin/client/analytics/components/report-table/index.js +++ b/plugins/woocommerce-admin/client/analytics/components/report-table/index.js @@ -19,7 +19,7 @@ import { onQueryChange } from '@woocommerce/navigation'; * Internal dependencies */ import ReportError from 'analytics/components/report-error'; -import { getReportChartData, getReportTableData } from 'store/reports/utils'; +import { getReportChartData, getReportTableData } from 'wc-api/reports/utils'; import withSelect from 'wc-api/with-select'; import { extendTableData } from './utils'; diff --git a/plugins/woocommerce-admin/client/analytics/report/customers/config.js b/plugins/woocommerce-admin/client/analytics/report/customers/config.js index 18a38e323ad..bdcd9827930 100644 --- a/plugins/woocommerce-admin/client/analytics/report/customers/config.js +++ b/plugins/woocommerce-admin/client/analytics/report/customers/config.js @@ -9,7 +9,7 @@ import { decodeEntities } from '@wordpress/html-entities'; * Internal dependencies */ import { getCustomerLabels, getRequestByIdString } from 'lib/async-requests'; -import { NAMESPACE } from 'store/constants'; +import { NAMESPACE } from 'wc-api/constants'; export const filters = [ { diff --git a/plugins/woocommerce-admin/client/analytics/report/revenue/table.js b/plugins/woocommerce-admin/client/analytics/report/revenue/table.js index aa0e7c23f14..7a2230fb4e4 100644 --- a/plugins/woocommerce-admin/client/analytics/report/revenue/table.js +++ b/plugins/woocommerce-admin/client/analytics/report/revenue/table.js @@ -19,7 +19,7 @@ import { numberFormat } from '@woocommerce/number'; /** * Internal dependencies */ -import { QUERY_DEFAULTS } from 'store/constants'; +import { QUERY_DEFAULTS } from 'wc-api/constants'; import ReportTable from 'analytics/components/report-table'; import withSelect from 'wc-api/with-select'; diff --git a/plugins/woocommerce-admin/client/analytics/report/taxes/config.js b/plugins/woocommerce-admin/client/analytics/report/taxes/config.js index 39b236447b9..4eaf222afae 100644 --- a/plugins/woocommerce-admin/client/analytics/report/taxes/config.js +++ b/plugins/woocommerce-admin/client/analytics/report/taxes/config.js @@ -9,7 +9,7 @@ import { __ } from '@wordpress/i18n'; */ import { getRequestByIdString } from 'lib/async-requests'; import { getTaxCode } from './utils'; -import { NAMESPACE } from 'store/constants'; +import { NAMESPACE } from 'wc-api/constants'; export const charts = [ { diff --git a/plugins/woocommerce-admin/client/header/activity-panel/panels/inbox.js b/plugins/woocommerce-admin/client/header/activity-panel/panels/inbox.js index 31ba3e18a80..287b8df3f00 100644 --- a/plugins/woocommerce-admin/client/header/activity-panel/panels/inbox.js +++ b/plugins/woocommerce-admin/client/header/activity-panel/panels/inbox.js @@ -16,7 +16,7 @@ import { ActivityCard, ActivityCardPlaceholder } from '../activity-card'; import ActivityHeader from '../activity-header'; import { EmptyContent, Section } from '@woocommerce/components'; import sanitizeHTML from 'lib/sanitize-html'; -import { QUERY_DEFAULTS } from 'store/constants'; +import { QUERY_DEFAULTS } from 'wc-api/constants'; class InboxPanel extends Component { render() { diff --git a/plugins/woocommerce-admin/client/header/activity-panel/panels/orders.js b/plugins/woocommerce-admin/client/header/activity-panel/panels/orders.js index c1c4b2b4b62..8c0412a70ff 100644 --- a/plugins/woocommerce-admin/client/header/activity-panel/panels/orders.js +++ b/plugins/woocommerce-admin/client/header/activity-panel/panels/orders.js @@ -33,7 +33,7 @@ import { ActivityCard, ActivityCardPlaceholder } from '../activity-card'; import ActivityHeader from '../activity-header'; import ActivityOutboundLink from '../activity-outbound-link'; import { getOrderRefundTotal } from 'lib/order-values'; -import { QUERY_DEFAULTS } from 'store/constants'; +import { QUERY_DEFAULTS } from 'wc-api/constants'; import withSelect from 'wc-api/with-select'; function OrdersPanel( { orders, isRequesting, isError } ) { diff --git a/plugins/woocommerce-admin/client/header/activity-panel/panels/reviews.js b/plugins/woocommerce-admin/client/header/activity-panel/panels/reviews.js index 7389e33e29f..0db42c951e5 100644 --- a/plugins/woocommerce-admin/client/header/activity-panel/panels/reviews.js +++ b/plugins/woocommerce-admin/client/header/activity-panel/panels/reviews.js @@ -28,7 +28,7 @@ import { */ import { ActivityCard, ActivityCardPlaceholder } from '../activity-card'; import ActivityHeader from '../activity-header'; -import { QUERY_DEFAULTS } from 'store/constants'; +import { QUERY_DEFAULTS } from 'wc-api/constants'; import sanitizeHTML from 'lib/sanitize-html'; import withSelect from 'wc-api/with-select'; diff --git a/plugins/woocommerce-admin/client/lib/async-requests/index.js b/plugins/woocommerce-admin/client/lib/async-requests/index.js index 43d42b7aaab..1e4597ad8e4 100644 --- a/plugins/woocommerce-admin/client/lib/async-requests/index.js +++ b/plugins/woocommerce-admin/client/lib/async-requests/index.js @@ -13,7 +13,7 @@ import { getIdsFromQuery, stringifyQuery } from '@woocommerce/navigation'; /** * Internal dependencies */ -import { NAMESPACE } from 'store/constants'; +import { NAMESPACE } from 'wc-api/constants'; /** * Get a function that accepts ids as they are found in url parameter and diff --git a/plugins/woocommerce-admin/client/store/constants.js b/plugins/woocommerce-admin/client/store/constants.js deleted file mode 100644 index 6e801e08857..00000000000 --- a/plugins/woocommerce-admin/client/store/constants.js +++ /dev/null @@ -1,16 +0,0 @@ -/** - * @format - */ - -export const NAMESPACE = '/wc/v4/'; -export const SWAGGERNAMESPACE = 'https://virtserver.swaggerhub.com/peterfabian/wc-v3-api/1.0.0/'; -export const ERROR = 'ERROR'; - -// WordPress & WooCommerce both set a hard limit of 100 for the per_page parameter -export const MAX_PER_PAGE = 100; - -export const QUERY_DEFAULTS = { - pageSize: 25, - period: 'month', - compare: 'previous_year', -}; diff --git a/plugins/woocommerce-admin/client/store/utils.js b/plugins/woocommerce-admin/client/store/utils.js deleted file mode 100644 index b2830ab87a9..00000000000 --- a/plugins/woocommerce-admin/client/store/utils.js +++ /dev/null @@ -1,11 +0,0 @@ -/** @format */ - -/** - * Returns a string representation of a sorted query object. - * - * @param {Object} query Current state - * @return {String} Query Key - */ -export function getJsonString( query = {} ) { - return JSON.stringify( query, Object.keys( query ).sort() ); -} diff --git a/plugins/woocommerce-admin/client/wc-api/constants.js b/plugins/woocommerce-admin/client/wc-api/constants.js index 94b585332fc..1cdeeadfd86 100644 --- a/plugins/woocommerce-admin/client/wc-api/constants.js +++ b/plugins/woocommerce-admin/client/wc-api/constants.js @@ -6,6 +6,9 @@ import { MINUTE } from '@fresh-data/framework'; export const NAMESPACE = '/wc/v4'; +// TODO: Remove once swagger endpoints are phased out. +export const SWAGGERNAMESPACE = 'https://virtserver.swaggerhub.com/peterfabian/wc-v3-api/1.0.0/'; + export const DEFAULT_REQUIREMENT = { timeout: 1 * MINUTE, freshness: 5 * MINUTE, diff --git a/plugins/woocommerce-admin/client/wc-api/reports/stats/operations.js b/plugins/woocommerce-admin/client/wc-api/reports/stats/operations.js index 97193986cd9..5321ea838df 100644 --- a/plugins/woocommerce-admin/client/wc-api/reports/stats/operations.js +++ b/plugins/woocommerce-admin/client/wc-api/reports/stats/operations.js @@ -12,9 +12,8 @@ import { stringifyQuery } from '@woocommerce/navigation'; /** * Internal dependencies */ -import { getResourceIdentifier, getResourcePrefix } from '../../utils'; -import { NAMESPACE } from '../../constants'; -import { SWAGGERNAMESPACE } from 'store/constants'; +import { getResourceIdentifier, getResourcePrefix } from 'wc-api/utils'; +import { NAMESPACE, SWAGGERNAMESPACE } from 'wc-api/constants'; const statEndpoints = [ 'coupons', diff --git a/plugins/woocommerce-admin/client/store/reports/utils.js b/plugins/woocommerce-admin/client/wc-api/reports/utils.js similarity index 99% rename from plugins/woocommerce-admin/client/store/reports/utils.js rename to plugins/woocommerce-admin/client/wc-api/reports/utils.js index 1ab57f1845d..f008a24dd95 100644 --- a/plugins/woocommerce-admin/client/store/reports/utils.js +++ b/plugins/woocommerce-admin/client/wc-api/reports/utils.js @@ -16,7 +16,7 @@ import { formatCurrency } from '@woocommerce/currency'; /** * Internal dependencies */ -import { MAX_PER_PAGE, QUERY_DEFAULTS } from 'store/constants'; +import { MAX_PER_PAGE, QUERY_DEFAULTS } from 'wc-api/constants'; import * as categoriesConfig from 'analytics/report/categories/config'; import * as couponsConfig from 'analytics/report/coupons/config'; import * as customersConfig from 'analytics/report/customers/config'; From 08dfea7cff849f283018af07a1c20b31d11a8d07 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Albert=20Juh=C3=A9=20Lluveras?= Date: Wed, 30 Jan 2019 10:43:30 +0100 Subject: [PATCH 34/53] Add Taxes REST controller override (https://github.com/woocommerce/woocommerce-admin/pull/1407) --- .../class-wc-admin-rest-taxes-controller.php | 27 +++++++++++++++++++ .../includes/class-wc-admin-api-init.php | 13 +++++++++ 2 files changed, 40 insertions(+) create mode 100644 plugins/woocommerce-admin/includes/api/class-wc-admin-rest-taxes-controller.php diff --git a/plugins/woocommerce-admin/includes/api/class-wc-admin-rest-taxes-controller.php b/plugins/woocommerce-admin/includes/api/class-wc-admin-rest-taxes-controller.php new file mode 100644 index 00000000000..d30b678b7d3 --- /dev/null +++ b/plugins/woocommerce-admin/includes/api/class-wc-admin-rest-taxes-controller.php @@ -0,0 +1,27 @@ + Date: Wed, 30 Jan 2019 13:10:27 -0500 Subject: [PATCH 35/53] Update dependency eslint-plugin-jest to v22.2.1 (https://github.com/woocommerce/woocommerce-admin/pull/1415) --- plugins/woocommerce-admin/package-lock.json | 47 +++++++++++++++------ plugins/woocommerce-admin/package.json | 2 +- 2 files changed, 34 insertions(+), 15 deletions(-) diff --git a/plugins/woocommerce-admin/package-lock.json b/plugins/woocommerce-admin/package-lock.json index d648bb3d958..070bc26ae1f 100644 --- a/plugins/woocommerce-admin/package-lock.json +++ b/plugins/woocommerce-admin/package-lock.json @@ -7842,9 +7842,9 @@ } }, "eslint-plugin-jest": { - "version": "22.1.3", - "resolved": "https://registry.npmjs.org/eslint-plugin-jest/-/eslint-plugin-jest-22.1.3.tgz", - "integrity": "sha512-JTZTI6WQoNruAugNyCO8fXfTONVcDd5i6dMRFA5g3rUFn1UDDLILY1bTL6alvNXbW2U7Sc2OSpi8m08pInnq0A==", + "version": "22.2.1", + "resolved": "https://registry.npmjs.org/eslint-plugin-jest/-/eslint-plugin-jest-22.2.1.tgz", + "integrity": "sha512-cpxjB7xvPAEZYed5atKGD94TOYgV73qaX4XQ+E6DH0Y/xADcgqAYZKyZsFZ+qs/ll9wnNVZJdxZxav2vWYXOqw==", "dev": true }, "eslint-plugin-jsx-a11y": { @@ -8978,7 +8978,8 @@ }, "ansi-regex": { "version": "2.1.1", - "bundled": true + "bundled": true, + "optional": true }, "aproba": { "version": "1.2.0", @@ -8996,11 +8997,13 @@ }, "balanced-match": { "version": "1.0.0", - "bundled": true + "bundled": true, + "optional": true }, "brace-expansion": { "version": "1.1.11", "bundled": true, + "optional": true, "requires": { "balanced-match": "^1.0.0", "concat-map": "0.0.1" @@ -9013,15 +9016,18 @@ }, "code-point-at": { "version": "1.1.0", - "bundled": true + "bundled": true, + "optional": true }, "concat-map": { "version": "0.0.1", - "bundled": true + "bundled": true, + "optional": true }, "console-control-strings": { "version": "1.1.0", - "bundled": true + "bundled": true, + "optional": true }, "core-util-is": { "version": "1.0.2", @@ -9124,7 +9130,8 @@ }, "inherits": { "version": "2.0.3", - "bundled": true + "bundled": true, + "optional": true }, "ini": { "version": "1.3.5", @@ -9134,6 +9141,7 @@ "is-fullwidth-code-point": { "version": "1.0.0", "bundled": true, + "optional": true, "requires": { "number-is-nan": "^1.0.0" } @@ -9146,17 +9154,20 @@ "minimatch": { "version": "3.0.4", "bundled": true, + "optional": true, "requires": { "brace-expansion": "^1.1.7" } }, "minimist": { "version": "0.0.8", - "bundled": true + "bundled": true, + "optional": true }, "minipass": { "version": "2.2.4", "bundled": true, + "optional": true, "requires": { "safe-buffer": "^5.1.1", "yallist": "^3.0.0" @@ -9173,6 +9184,7 @@ "mkdirp": { "version": "0.5.1", "bundled": true, + "optional": true, "requires": { "minimist": "0.0.8" } @@ -9245,7 +9257,8 @@ }, "number-is-nan": { "version": "1.0.1", - "bundled": true + "bundled": true, + "optional": true }, "object-assign": { "version": "4.1.1", @@ -9255,6 +9268,7 @@ "once": { "version": "1.4.0", "bundled": true, + "optional": true, "requires": { "wrappy": "1" } @@ -9330,7 +9344,8 @@ }, "safe-buffer": { "version": "5.1.1", - "bundled": true + "bundled": true, + "optional": true }, "safer-buffer": { "version": "2.1.2", @@ -9360,6 +9375,7 @@ "string-width": { "version": "1.0.2", "bundled": true, + "optional": true, "requires": { "code-point-at": "^1.0.0", "is-fullwidth-code-point": "^1.0.0", @@ -9377,6 +9393,7 @@ "strip-ansi": { "version": "3.0.1", "bundled": true, + "optional": true, "requires": { "ansi-regex": "^2.0.0" } @@ -9415,11 +9432,13 @@ }, "wrappy": { "version": "1.0.2", - "bundled": true + "bundled": true, + "optional": true }, "yallist": { "version": "3.0.2", - "bundled": true + "bundled": true, + "optional": true } } }, diff --git a/plugins/woocommerce-admin/package.json b/plugins/woocommerce-admin/package.json index b969ea7aa6a..cb3feee6c3f 100644 --- a/plugins/woocommerce-admin/package.json +++ b/plugins/woocommerce-admin/package.json @@ -76,7 +76,7 @@ "eslint": "5.12.0", "eslint-config-wpcalypso": "4.0.1", "eslint-loader": "2.1.1", - "eslint-plugin-jest": "22.1.3", + "eslint-plugin-jest": "22.2.1", "eslint-plugin-jsx-a11y": "6.1.2", "eslint-plugin-react": "7.12.3", "eslint-plugin-wpcalypso": "4.0.2", From e2da828d1f741830df106c7901457c1b15300d25 Mon Sep 17 00:00:00 2001 From: "renovate[bot]" Date: Wed, 30 Jan 2019 13:14:58 -0500 Subject: [PATCH 36/53] Update dependency lerna to v3.10.7 (https://github.com/woocommerce/woocommerce-admin/pull/1419) --- plugins/woocommerce-admin/package-lock.json | 274 ++++++++++---------- plugins/woocommerce-admin/package.json | 2 +- 2 files changed, 138 insertions(+), 138 deletions(-) diff --git a/plugins/woocommerce-admin/package-lock.json b/plugins/woocommerce-admin/package-lock.json index 070bc26ae1f..d89aa78bcdf 100644 --- a/plugins/woocommerce-admin/package-lock.json +++ b/plugins/woocommerce-admin/package-lock.json @@ -738,14 +738,14 @@ } }, "@lerna/add": { - "version": "3.10.5", - "resolved": "https://registry.npmjs.org/@lerna/add/-/add-3.10.5.tgz", - "integrity": "sha512-T3d9FnSyBOYnM/a1j5Sa65SGOTgnv04HG7Y2lRWJcF6PvOoTsozYW0izi/vLAnAt/DvGhYf2morXkWS8AbIeDg==", + "version": "3.10.6", + "resolved": "https://registry.npmjs.org/@lerna/add/-/add-3.10.6.tgz", + "integrity": "sha512-FxQ5Bmyb5fF+3BQiNffM6cTeGCrl4uaAuGvxFIWF6Pgz6U14tUc1e16xgKDvVb1CurzJgIV5sLOT5xmCOqv1kA==", "dev": true, "requires": { - "@lerna/bootstrap": "3.10.5", - "@lerna/command": "3.10.0", - "@lerna/filter-options": "3.10.1", + "@lerna/bootstrap": "3.10.6", + "@lerna/command": "3.10.6", + "@lerna/filter-options": "3.10.6", "@lerna/npm-conf": "3.7.0", "@lerna/validation-error": "3.6.0", "dedent": "^0.7.0", @@ -755,28 +755,28 @@ } }, "@lerna/batch-packages": { - "version": "3.10.0", - "resolved": "https://registry.npmjs.org/@lerna/batch-packages/-/batch-packages-3.10.0.tgz", - "integrity": "sha512-ERvnpmmfV8H+3B+9FmHqmzfgz0xVe3ktW/e4WZZXYMGpqSGToILZlai4PsBrW5gUtnXA77LSskME+aRdkZaKsQ==", + "version": "3.10.6", + "resolved": "https://registry.npmjs.org/@lerna/batch-packages/-/batch-packages-3.10.6.tgz", + "integrity": "sha512-sInr3ZQJFMh9Zq+ZUoVjX8R67j9ViRkVy0uEMsOfG+jZlXj1lRPRMPRiRgU0jXSYEwCdwuAB5pTd9tTx0VCJUw==", "dev": true, "requires": { - "@lerna/package-graph": "3.10.0", + "@lerna/package-graph": "3.10.6", "@lerna/validation-error": "3.6.0", "libnpm": "^2.0.1" } }, "@lerna/bootstrap": { - "version": "3.10.5", - "resolved": "https://registry.npmjs.org/@lerna/bootstrap/-/bootstrap-3.10.5.tgz", - "integrity": "sha512-WMUfysmX2WFkOzWcpv0mW6Kw91Zsuq9Ecz/TIT4q3FywvABD0mrWbcDXSyrxMspxDEOtPqM/Lk9nm6F9M98kbg==", + "version": "3.10.6", + "resolved": "https://registry.npmjs.org/@lerna/bootstrap/-/bootstrap-3.10.6.tgz", + "integrity": "sha512-qbGjAxRpV/eiI9CboUIpsPPGpSogs8mN2/iDaAUBTaWVFVz/YyU64nui84Gll0kbdaHOyPput+kk2S8NCSCCdg==", "dev": true, "requires": { - "@lerna/batch-packages": "3.10.0", - "@lerna/command": "3.10.0", - "@lerna/filter-options": "3.10.1", + "@lerna/batch-packages": "3.10.6", + "@lerna/command": "3.10.6", + "@lerna/filter-options": "3.10.6", "@lerna/has-npm-version": "3.10.0", "@lerna/npm-install": "3.10.0", - "@lerna/package-graph": "3.10.0", + "@lerna/package-graph": "3.10.6", "@lerna/pulse-till-done": "3.7.1", "@lerna/rimraf-dir": "3.10.0", "@lerna/run-lifecycle": "3.10.5", @@ -797,16 +797,16 @@ } }, "@lerna/changed": { - "version": "3.10.5", - "resolved": "https://registry.npmjs.org/@lerna/changed/-/changed-3.10.5.tgz", - "integrity": "sha512-Uy3VWzjmGg2CjKRTW9os+R6Itg3LVJ6CjczeOsOFwSN4JMdNoObUnCTSdCCTUF/+hQNAoSnkw3+C8dC5FPL1Zw==", + "version": "3.10.6", + "resolved": "https://registry.npmjs.org/@lerna/changed/-/changed-3.10.6.tgz", + "integrity": "sha512-nZDVq/sKdhgoAg1BVnpqjqUUz5+zedG+AnU+6mjEN2f23YVtRCsW55N4I9eEdW2pxXUaCY85Hj/HPSA74BYaFg==", "dev": true, "requires": { "@lerna/collect-updates": "3.10.1", - "@lerna/command": "3.10.0", - "@lerna/listable": "3.10.0", + "@lerna/command": "3.10.6", + "@lerna/listable": "3.10.6", "@lerna/output": "3.6.0", - "@lerna/version": "3.10.5" + "@lerna/version": "3.10.6" } }, "@lerna/check-working-tree": { @@ -870,13 +870,13 @@ } }, "@lerna/clean": { - "version": "3.10.1", - "resolved": "https://registry.npmjs.org/@lerna/clean/-/clean-3.10.1.tgz", - "integrity": "sha512-eYSNSD4xD//OIDe0r4r/HhEMEXriIuKqp4BMDhrO7pJmYhk7FvznJUSc4jc85wdA4Y0ooqSs9gF/w2lgLGgUxw==", + "version": "3.10.6", + "resolved": "https://registry.npmjs.org/@lerna/clean/-/clean-3.10.6.tgz", + "integrity": "sha512-MuL8HOwnyvVtr6GOiAN/Ofjbx+BJdCrtjrM1Uuh8FFnbnZTPVf+0MPxL2jVzPMo0PmoIrX3fvlwvzKNk/lH0Ug==", "dev": true, "requires": { - "@lerna/command": "3.10.0", - "@lerna/filter-options": "3.10.1", + "@lerna/command": "3.10.6", + "@lerna/filter-options": "3.10.6", "@lerna/prompt": "3.6.0", "@lerna/pulse-till-done": "3.7.1", "@lerna/rimraf-dir": "3.10.0", @@ -886,12 +886,12 @@ } }, "@lerna/cli": { - "version": "3.10.0", - "resolved": "https://registry.npmjs.org/@lerna/cli/-/cli-3.10.0.tgz", - "integrity": "sha512-OTO8GlD6Rf298hxml3/Y3OE8yMDuW3NNqumbroiUb/KdkrnyjZl5F6aSMXJEySq+OSoBboZJMwj2IWglc/7fuw==", + "version": "3.10.7", + "resolved": "https://registry.npmjs.org/@lerna/cli/-/cli-3.10.7.tgz", + "integrity": "sha512-yuoz/24mIfYit3neKqoE5NVs42Rj9A6A6SlkNPDfsy3v/Vh7SgYkU3cwiGyvwBGzIdhqL4/SWYo8H7YJLs0C+g==", "dev": true, "requires": { - "@lerna/global-options": "3.1.3", + "@lerna/global-options": "3.10.6", "dedent": "^0.7.0", "libnpm": "^2.0.1", "yargs": "^12.0.1" @@ -1066,13 +1066,13 @@ } }, "@lerna/command": { - "version": "3.10.0", - "resolved": "https://registry.npmjs.org/@lerna/command/-/command-3.10.0.tgz", - "integrity": "sha512-TTtCDQ5+bDdA/RnBuDtkfqzUV8Mr61KBHxEZL8YLAmHZtY/HsnNpZzbAZ0STPxcFB96dhxVWbRDGP+yBgRfemQ==", + "version": "3.10.6", + "resolved": "https://registry.npmjs.org/@lerna/command/-/command-3.10.6.tgz", + "integrity": "sha512-jPZswMZXOpAaIuSF5hrz+eaWQzbDrvwbrkCoRJKfiAHx7URAkE6MQe9DeAnqrTKMqwfg0RciSrZLc8kWYfrzCQ==", "dev": true, "requires": { "@lerna/child-process": "3.3.0", - "@lerna/package-graph": "3.10.0", + "@lerna/package-graph": "3.10.6", "@lerna/project": "3.10.0", "@lerna/validation-error": "3.6.0", "@lerna/write-log-file": "3.6.0", @@ -1170,13 +1170,13 @@ } }, "@lerna/create": { - "version": "3.10.0", - "resolved": "https://registry.npmjs.org/@lerna/create/-/create-3.10.0.tgz", - "integrity": "sha512-1EQbhyGx/J+gwlxFPecpmrztyEfBRm/sNei95UJlJWLuturSv2Ax2nCa49tcerbPlYhhlJ6lyintukL5STOzdg==", + "version": "3.10.6", + "resolved": "https://registry.npmjs.org/@lerna/create/-/create-3.10.6.tgz", + "integrity": "sha512-OddQtGBHM2/eJONggLWoTE6275XGbnJ6dIVF+fLsKS93o4GC6g+qcc6Y7lUWHm5bfpeOwNOVKwj0tvqBZ6MgoA==", "dev": true, "requires": { "@lerna/child-process": "3.3.0", - "@lerna/command": "3.10.0", + "@lerna/command": "3.10.6", "@lerna/npm-conf": "3.7.0", "@lerna/validation-error": "3.6.0", "camelcase": "^4.1.0", @@ -1311,35 +1311,35 @@ } }, "@lerna/diff": { - "version": "3.10.0", - "resolved": "https://registry.npmjs.org/@lerna/diff/-/diff-3.10.0.tgz", - "integrity": "sha512-MU6P9uAND+dZ15Cm4onJakEYMC6xXZApLuPpWJf0kZtVoF2Feoo3mvQASdb17fe0jvvmWDS0RLCzq9Zhzrgm0A==", + "version": "3.10.6", + "resolved": "https://registry.npmjs.org/@lerna/diff/-/diff-3.10.6.tgz", + "integrity": "sha512-0MqFhosjrqsIdXiKIu7t3CiJELqiU9mkjFBhYPB7JruAzpPwjMXJnC6/Ur5/7LXJYYVpqGQwZI9ZaZlOYJhhrw==", "dev": true, "requires": { "@lerna/child-process": "3.3.0", - "@lerna/command": "3.10.0", + "@lerna/command": "3.10.6", "@lerna/validation-error": "3.6.0", "libnpm": "^2.0.1" } }, "@lerna/exec": { - "version": "3.10.1", - "resolved": "https://registry.npmjs.org/@lerna/exec/-/exec-3.10.1.tgz", - "integrity": "sha512-MM5/OMP4FrVH4PIlG+3xk3jpKq+trgu/eAPttaYZBHAumCOjrDVYdyk5O68+YLz+uLkM31ixTmsiAP9f77HTsg==", + "version": "3.10.6", + "resolved": "https://registry.npmjs.org/@lerna/exec/-/exec-3.10.6.tgz", + "integrity": "sha512-cdHqaRBMYceJu8rZLO8b4ZeR27O+xKPHgzi13OOOfBJQjrTuacjMWyHgmpy8jWc/0f7QnTl4VsHks7VJ3UK+vw==", "dev": true, "requires": { - "@lerna/batch-packages": "3.10.0", + "@lerna/batch-packages": "3.10.6", "@lerna/child-process": "3.3.0", - "@lerna/command": "3.10.0", - "@lerna/filter-options": "3.10.1", + "@lerna/command": "3.10.6", + "@lerna/filter-options": "3.10.6", "@lerna/run-parallel-batches": "3.0.0", "@lerna/validation-error": "3.6.0" } }, "@lerna/filter-options": { - "version": "3.10.1", - "resolved": "https://registry.npmjs.org/@lerna/filter-options/-/filter-options-3.10.1.tgz", - "integrity": "sha512-34q7P0/AA+omVk9uwv99i+4qmj5uGuj383RzqIcK8JDYL0JSzlmW0+c4IkxunCfRrWft8OFhSwZdOOmXtDSDYg==", + "version": "3.10.6", + "resolved": "https://registry.npmjs.org/@lerna/filter-options/-/filter-options-3.10.6.tgz", + "integrity": "sha512-r/dQbqN+RGFKZNn+DyWehswFmAkny/fkdMB2sRM2YVe7zRTtSl95YxD9DtdYnpJTG/jbOVICS/L5QJakrI6SSw==", "dev": true, "requires": { "@lerna/collect-updates": "3.10.1", @@ -1431,9 +1431,9 @@ } }, "@lerna/global-options": { - "version": "3.1.3", - "resolved": "https://registry.npmjs.org/@lerna/global-options/-/global-options-3.1.3.tgz", - "integrity": "sha512-LVeZU/Zgc0XkHdGMRYn+EmHfDmmYNwYRv3ta59iCVFXLVp7FRFWF7oB1ss/WRa9x/pYU0o6L8as/5DomLUGASA==", + "version": "3.10.6", + "resolved": "https://registry.npmjs.org/@lerna/global-options/-/global-options-3.10.6.tgz", + "integrity": "sha512-k5Xkq1M/uREFC2R9uwN5gcvIgjj4iOXo0YyeEXCMWBiW3j2GL9xN4d1MmAIcrYlAzVYh6kLlWaFWl/rNIneHIw==", "dev": true }, "@lerna/has-npm-version": { @@ -1447,13 +1447,13 @@ } }, "@lerna/import": { - "version": "3.10.0", - "resolved": "https://registry.npmjs.org/@lerna/import/-/import-3.10.0.tgz", - "integrity": "sha512-c8/s/ldaNVGuKnu600B3nbkwJTNElp1duJiZQ7EBChF+szbQBAiQUGNLvBbwClLBzVJhKTw6E4ku17HafQ4vqg==", + "version": "3.10.6", + "resolved": "https://registry.npmjs.org/@lerna/import/-/import-3.10.6.tgz", + "integrity": "sha512-LlGxhfDhovoNoBJLF3PYd3j/G2GFTnfLh0V38+hBQ6lomMNJbjkACfiLVomQxPWWpYLk0GTlpWYR8YGv6L7Ifw==", "dev": true, "requires": { "@lerna/child-process": "3.3.0", - "@lerna/command": "3.10.0", + "@lerna/command": "3.10.6", "@lerna/prompt": "3.6.0", "@lerna/pulse-till-done": "3.7.1", "@lerna/validation-error": "3.6.0", @@ -1485,13 +1485,13 @@ } }, "@lerna/init": { - "version": "3.10.0", - "resolved": "https://registry.npmjs.org/@lerna/init/-/init-3.10.0.tgz", - "integrity": "sha512-+zU1A870OOOqy3MPLcEoicN6dnIGZv/q0aqCVRRfCHAICciaswuIvdX0uDJx0NrUe0sW40dzIllxuUA39nPqcw==", + "version": "3.10.6", + "resolved": "https://registry.npmjs.org/@lerna/init/-/init-3.10.6.tgz", + "integrity": "sha512-RIlEx+ofWLYRNjxCkkV3G0XQPM+/KA5RXRDb5wKQLYO1f+tZAaHoUh8fHDIvxGf/ohY/OIjYYGSsU+ysimfwiQ==", "dev": true, "requires": { "@lerna/child-process": "3.3.0", - "@lerna/command": "3.10.0", + "@lerna/command": "3.10.6", "fs-extra": "^7.0.0", "p-map": "^1.2.0", "write-json-file": "^2.3.0" @@ -1520,37 +1520,37 @@ } }, "@lerna/link": { - "version": "3.10.0", - "resolved": "https://registry.npmjs.org/@lerna/link/-/link-3.10.0.tgz", - "integrity": "sha512-uZvLxTSekqV8Kx0zMPgcxpTWyRkjnqnUzRiff9HQtOq+gBBifX079jGT7X73CO5eXFzp2TkOJtI1KNL0BNoNtA==", + "version": "3.10.6", + "resolved": "https://registry.npmjs.org/@lerna/link/-/link-3.10.6.tgz", + "integrity": "sha512-dwD6qftRWitgLDYbqtDrgO7c8uF5C0fHVew5M6gU5m9tBJidqd7cDwHv/bXboLEI63U7tt5y6LY+wEpYUFsBRw==", "dev": true, "requires": { - "@lerna/command": "3.10.0", - "@lerna/package-graph": "3.10.0", + "@lerna/command": "3.10.6", + "@lerna/package-graph": "3.10.6", "@lerna/symlink-dependencies": "3.10.0", "p-map": "^1.2.0", "slash": "^1.0.0" } }, "@lerna/list": { - "version": "3.10.1", - "resolved": "https://registry.npmjs.org/@lerna/list/-/list-3.10.1.tgz", - "integrity": "sha512-y2VwTeJ8tcQ0dmJJNhloGfhmCBUG3RXafqNkUVUG/ItoJlfzVniQOMdIDlkre86ZtnQv9yrB2vFaC2Vg++PklQ==", + "version": "3.10.6", + "resolved": "https://registry.npmjs.org/@lerna/list/-/list-3.10.6.tgz", + "integrity": "sha512-3ElQBj2dOB4uUkpsjC1bxdeZwEzRBuV1pBBs5E1LncwsZf7D9D99Z32fuZsDaCHpEMgHAD4/j8juI3/7m5dkaQ==", "dev": true, "requires": { - "@lerna/command": "3.10.0", - "@lerna/filter-options": "3.10.1", - "@lerna/listable": "3.10.0", + "@lerna/command": "3.10.6", + "@lerna/filter-options": "3.10.6", + "@lerna/listable": "3.10.6", "@lerna/output": "3.6.0" } }, "@lerna/listable": { - "version": "3.10.0", - "resolved": "https://registry.npmjs.org/@lerna/listable/-/listable-3.10.0.tgz", - "integrity": "sha512-95EwogHBqJxrXOCkf3DAZQAzJes+I668Lg5BJDotfp9eZeJAbgGl6GPz5U+szPq0PrYfK+2kJv9xNXVnbfCZAw==", + "version": "3.10.6", + "resolved": "https://registry.npmjs.org/@lerna/listable/-/listable-3.10.6.tgz", + "integrity": "sha512-F7ZuvesSgeuMiJf99eOum5p1MQGQStykcmHH1ek+LQRMiGGF1o3PkBxPvHTZBADGOFarek8bFA5TVmRAMX7NIw==", "dev": true, "requires": { - "@lerna/batch-packages": "3.10.0", + "@lerna/batch-packages": "3.10.6", "chalk": "^2.3.1", "columnify": "^1.5.4" } @@ -1632,9 +1632,9 @@ } }, "@lerna/npm-publish": { - "version": "3.10.5", - "resolved": "https://registry.npmjs.org/@lerna/npm-publish/-/npm-publish-3.10.5.tgz", - "integrity": "sha512-6wpgTfu5A5jJeB8RnH2n01HzfaB4Y9aKC0Tq0AAkw37PZ12LTgEL9I+ZZPqhUVFIFLB8/Ekpnj3AcKznJLG5xQ==", + "version": "3.10.7", + "resolved": "https://registry.npmjs.org/@lerna/npm-publish/-/npm-publish-3.10.7.tgz", + "integrity": "sha512-oU3/Q+eHC1fRjh7bk6Nn4tRD1OLR6XZVs3v+UWMWMrF4hVSV61pxcP5tpeI1n4gDQjSgh7seI4EzKVJe/WfraA==", "dev": true, "requires": { "@lerna/run-lifecycle": "3.10.5", @@ -1772,9 +1772,9 @@ } }, "@lerna/package-graph": { - "version": "3.10.0", - "resolved": "https://registry.npmjs.org/@lerna/package-graph/-/package-graph-3.10.0.tgz", - "integrity": "sha512-9LX8I8KxzCMjfNPWvN/CxHW51s89S3Mnx2EYsbo8c8Gh8I6InA6e+Xur6uuCyZ6/0LKqQ/cXwrP3J81A4nIDSQ==", + "version": "3.10.6", + "resolved": "https://registry.npmjs.org/@lerna/package-graph/-/package-graph-3.10.6.tgz", + "integrity": "sha512-mpIOJbhi+xLqT9BcUrLVD4We8WUdousQf/QndbEWl8DWAW1ethtRHVsCm9ufdBB3F9nj4PH/hqnDWWwqE+rS4w==", "dev": true, "requires": { "@lerna/validation-error": "3.6.0", @@ -1969,21 +1969,21 @@ } }, "@lerna/publish": { - "version": "3.10.5", - "resolved": "https://registry.npmjs.org/@lerna/publish/-/publish-3.10.5.tgz", - "integrity": "sha512-26wjTtRbcUXlG8Na7goI0X1trMYivbuLT1bAXHNvuDaHYs7iE6LRjU4NCTNAmrdVnqagHkTxMuGRFn3r1NgcKg==", + "version": "3.10.7", + "resolved": "https://registry.npmjs.org/@lerna/publish/-/publish-3.10.7.tgz", + "integrity": "sha512-Qd8pml2l9s6GIvNX1pTnia+Ddjsm9LF3pRRoOQeugAdv2IJNf45c/83AAEyE9M2ShG5VjgxEITNW4Lg49zipjQ==", "dev": true, "requires": { - "@lerna/batch-packages": "3.10.0", + "@lerna/batch-packages": "3.10.6", "@lerna/check-working-tree": "3.10.0", "@lerna/child-process": "3.3.0", "@lerna/collect-updates": "3.10.1", - "@lerna/command": "3.10.0", + "@lerna/command": "3.10.6", "@lerna/describe-ref": "3.10.0", "@lerna/log-packed": "3.6.0", "@lerna/npm-conf": "3.7.0", "@lerna/npm-dist-tag": "3.8.5", - "@lerna/npm-publish": "3.10.5", + "@lerna/npm-publish": "3.10.7", "@lerna/output": "3.6.0", "@lerna/pack-directory": "3.10.5", "@lerna/prompt": "3.6.0", @@ -1991,7 +1991,7 @@ "@lerna/run-lifecycle": "3.10.5", "@lerna/run-parallel-batches": "3.0.0", "@lerna/validation-error": "3.6.0", - "@lerna/version": "3.10.5", + "@lerna/version": "3.10.6", "figgy-pudding": "^3.5.1", "fs-extra": "^7.0.0", "libnpm": "^2.0.1", @@ -2079,14 +2079,14 @@ } }, "@lerna/run": { - "version": "3.10.1", - "resolved": "https://registry.npmjs.org/@lerna/run/-/run-3.10.1.tgz", - "integrity": "sha512-g9YIcpk87Gok+zjicru/KsuZ1lcyuG5oERyAii3RSmpLaiwTh/SOSnxilrvDOYWwxYU5rPzvaCalkQI/i31Itw==", + "version": "3.10.6", + "resolved": "https://registry.npmjs.org/@lerna/run/-/run-3.10.6.tgz", + "integrity": "sha512-KS2lWbu/8WUUscQPi9U8sPO6yYpzf/0GmODjpruR1nRi1u/tuncdjTiG+hjGAeFC1BD7YktT9Za6imIpE8RXmA==", "dev": true, "requires": { - "@lerna/batch-packages": "3.10.0", - "@lerna/command": "3.10.0", - "@lerna/filter-options": "3.10.1", + "@lerna/batch-packages": "3.10.6", + "@lerna/command": "3.10.6", + "@lerna/filter-options": "3.10.6", "@lerna/npm-run-script": "3.10.0", "@lerna/output": "3.6.0", "@lerna/run-parallel-batches": "3.0.0", @@ -2203,16 +2203,16 @@ } }, "@lerna/version": { - "version": "3.10.5", - "resolved": "https://registry.npmjs.org/@lerna/version/-/version-3.10.5.tgz", - "integrity": "sha512-I6KynsrWvtusylggw+XmlfUud26ncfUctbn8hUQsofkxiouuElx1fUU4rEsOaonxvNk09bwlsGmfbIFsPeN6Hg==", + "version": "3.10.6", + "resolved": "https://registry.npmjs.org/@lerna/version/-/version-3.10.6.tgz", + "integrity": "sha512-77peW2ROlHHl1e/tHBUmhpb8tsO6CIdlx34XapZhUuIVykrkOuqVFFxqMecrGG8SJe0e3l1G+Fah7bJTQcG0kw==", "dev": true, "requires": { - "@lerna/batch-packages": "3.10.0", + "@lerna/batch-packages": "3.10.6", "@lerna/check-working-tree": "3.10.0", "@lerna/child-process": "3.3.0", "@lerna/collect-updates": "3.10.1", - "@lerna/command": "3.10.0", + "@lerna/command": "3.10.6", "@lerna/conventional-commits": "3.10.0", "@lerna/output": "3.6.0", "@lerna/prompt": "3.6.0", @@ -12497,26 +12497,26 @@ "integrity": "sha512-XI5MPzVNApjAyhQzphX8BkmKsKUxD4LdyK24iZeQGinBN9yTQT3bFlCBy/aVx2HrNcqQGsdot8ghrjyrvMCoEA==" }, "lerna": { - "version": "3.10.5", - "resolved": "https://registry.npmjs.org/lerna/-/lerna-3.10.5.tgz", - "integrity": "sha512-rJ67oqEiF8AVw+9phKbGkC0k0oqu1rdnmzrIfVS40EQCwEtzBC1ABX1886PBV0N40Pt9wCy6a0Jhrd+PV4IiIQ==", + "version": "3.10.7", + "resolved": "https://registry.npmjs.org/lerna/-/lerna-3.10.7.tgz", + "integrity": "sha512-ha/dehl/L3Nw0pbdir5z6Hrv2oYBg5ym2fTcuk8HCLe7Zdb/ylIHdrgW8CU9eTVZkwr4et8RdVtxFA/+xa65/Q==", "dev": true, "requires": { - "@lerna/add": "3.10.5", - "@lerna/bootstrap": "3.10.5", - "@lerna/changed": "3.10.5", - "@lerna/clean": "3.10.1", - "@lerna/cli": "3.10.0", - "@lerna/create": "3.10.0", - "@lerna/diff": "3.10.0", - "@lerna/exec": "3.10.1", - "@lerna/import": "3.10.0", - "@lerna/init": "3.10.0", - "@lerna/link": "3.10.0", - "@lerna/list": "3.10.1", - "@lerna/publish": "3.10.5", - "@lerna/run": "3.10.1", - "@lerna/version": "3.10.5", + "@lerna/add": "3.10.6", + "@lerna/bootstrap": "3.10.6", + "@lerna/changed": "3.10.6", + "@lerna/clean": "3.10.6", + "@lerna/cli": "3.10.7", + "@lerna/create": "3.10.6", + "@lerna/diff": "3.10.6", + "@lerna/exec": "3.10.6", + "@lerna/import": "3.10.6", + "@lerna/init": "3.10.6", + "@lerna/link": "3.10.6", + "@lerna/list": "3.10.6", + "@lerna/publish": "3.10.7", + "@lerna/run": "3.10.6", + "@lerna/version": "3.10.6", "import-local": "^1.0.0", "libnpm": "^2.0.1" } @@ -12707,9 +12707,9 @@ } }, "libnpmpublish": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/libnpmpublish/-/libnpmpublish-1.1.0.tgz", - "integrity": "sha512-mQ3LT2EWlpJ6Q8mgHTNqarQVCgcY32l6xadPVPMcjWLtVLz7II4WlWkzlbYg1nHGAf+xyABDwS+3aNUiRLkyaA==", + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/libnpmpublish/-/libnpmpublish-1.1.1.tgz", + "integrity": "sha512-nefbvJd/wY38zdt+b9SHL6171vqBrMtZ56Gsgfd0duEKb/pB8rDT4/ObUQLrHz1tOfht1flt2zM+UGaemzAG5g==", "dev": true, "requires": { "aproba": "^2.0.0", @@ -14392,9 +14392,9 @@ } }, "npm-registry-fetch": { - "version": "3.8.0", - "resolved": "https://registry.npmjs.org/npm-registry-fetch/-/npm-registry-fetch-3.8.0.tgz", - "integrity": "sha512-hrw8UMD+Nob3Kl3h8Z/YjmKamb1gf7D1ZZch2otrIXM3uFLB5vjEY6DhMlq80z/zZet6eETLbOXcuQudCB3Zpw==", + "version": "3.9.0", + "resolved": "https://registry.npmjs.org/npm-registry-fetch/-/npm-registry-fetch-3.9.0.tgz", + "integrity": "sha512-srwmt8YhNajAoSAaDWndmZgx89lJwIZ1GWxOuckH4Coek4uHv5S+o/l9FLQe/awA+JwTnj4FJHldxhlXdZEBmw==", "dev": true, "requires": { "JSONStream": "^1.3.4", @@ -14895,9 +14895,9 @@ } }, "pacote": { - "version": "9.3.0", - "resolved": "https://registry.npmjs.org/pacote/-/pacote-9.3.0.tgz", - "integrity": "sha512-uy5xghB5wUtmFS+uNhQGhlsIF9rfsfxw6Zsu2VpmSz4/f+8D2+5V1HwjHdSn7W6aQTrxNNmmoUF5qNE10/EVdA==", + "version": "9.4.1", + "resolved": "https://registry.npmjs.org/pacote/-/pacote-9.4.1.tgz", + "integrity": "sha512-YKSRsQqmeHxgra0KCdWA2FtVxDPUlBiCdmew+mSe44pzlx5t1ViRMWiQg18T+DREA+vSqYfKzynaToFR4hcKHw==", "dev": true, "requires": { "bluebird": "^3.5.3", @@ -18519,9 +18519,9 @@ "dev": true }, "smart-buffer": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/smart-buffer/-/smart-buffer-4.0.1.tgz", - "integrity": "sha512-RFqinRVJVcCAL9Uh1oVqE6FZkqsyLiVOYEZ20TqIOjuX7iFVJ+zsbs4RIghnw/pTs7mZvt8ZHhvm1ZUrR4fykg==", + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/smart-buffer/-/smart-buffer-4.0.2.tgz", + "integrity": "sha512-JDhEpTKzXusOqXZ0BUIdH+CjFdO/CR3tLlf5CN34IypI+xMmXW1uB16OOY8z3cICbJlDAVJzNbwBhNO0wt9OAw==", "dev": true }, "snapdragon": { @@ -18635,13 +18635,13 @@ } }, "socks": { - "version": "2.2.2", - "resolved": "https://registry.npmjs.org/socks/-/socks-2.2.2.tgz", - "integrity": "sha512-g6wjBnnMOZpE0ym6e0uHSddz9p3a+WsBaaYQaBaSCJYvrC4IXykQR9MNGjLQf38e9iIIhp3b1/Zk8YZI3KGJ0Q==", + "version": "2.2.3", + "resolved": "https://registry.npmjs.org/socks/-/socks-2.2.3.tgz", + "integrity": "sha512-+2r83WaRT3PXYoO/1z+RDEBE7Z2f9YcdQnJ0K/ncXXbV5gJ6wYfNAebYFYiiUjM6E4JyXnPY8cimwyvFYHVUUA==", "dev": true, "requires": { "ip": "^1.1.5", - "smart-buffer": "^4.0.1" + "smart-buffer": "4.0.2" } }, "socks-proxy-agent": { diff --git a/plugins/woocommerce-admin/package.json b/plugins/woocommerce-admin/package.json index cb3feee6c3f..3754a89f520 100644 --- a/plugins/woocommerce-admin/package.json +++ b/plugins/woocommerce-admin/package.json @@ -84,7 +84,7 @@ "grunt-checktextdomain": "1.0.1", "grunt-wp-i18n": "1.0.3", "husky": "1.3.1", - "lerna": "3.10.5", + "lerna": "3.10.7", "locutus": "^2.0.10", "mini-css-extract-plugin": "0.5.0", "node-sass": "4.11.0", From 974d263f69d58f5c8517e361477b2eb8a7509d78 Mon Sep 17 00:00:00 2001 From: Timmy Crawford Date: Wed, 30 Jan 2019 10:51:03 -0800 Subject: [PATCH 37/53] Release/v0.6.0 (https://github.com/woocommerce/woocommerce-admin/pull/1417) * Bump versions to 0.6.0 * Update docs * Updates after running build. --- .../docs/components/packages/flag.md | 32 ++++++------------- .../docs/components/packages/summary.md | 17 +++++++--- plugins/woocommerce-admin/package-lock.json | 2 +- plugins/woocommerce-admin/package.json | 2 +- plugins/woocommerce-admin/wc-admin.php | 2 +- 5 files changed, 24 insertions(+), 31 deletions(-) diff --git a/plugins/woocommerce-admin/docs/components/packages/flag.md b/plugins/woocommerce-admin/docs/components/packages/flag.md index 2c5c62dba88..a3c64007c30 100644 --- a/plugins/woocommerce-admin/docs/components/packages/flag.md +++ b/plugins/woocommerce-admin/docs/components/packages/flag.md @@ -1,9 +1,9 @@ `Flag` (component) ================== -Use the `Flag` component to display a country's flag. - +Use the `Flag` component to display a country's flag using the operating system's emojis. + React component. Props ----- @@ -22,27 +22,6 @@ Two letter, three letter or three digit country code. An order can be passed instead of `code` and the code will automatically be pulled from the billing or shipping data. -### `round` - -- Type: Boolean -- Default: `true` - -True to display a rounded flag. - -### `height` - -- Type: Number -- Default: `24` - -Flag image height. - -### `width` - -- Type: Number -- Default: `24` - -Flag image width. - ### `className` - Type: String @@ -50,3 +29,10 @@ Flag image width. Additional CSS classes. +### `size` + +- Type: Number +- Default: null + +Supply a font size to be applied to the emoji flag. + diff --git a/plugins/woocommerce-admin/docs/components/packages/summary.md b/plugins/woocommerce-admin/docs/components/packages/summary.md index f8e217e4020..804c7d4eeea 100644 --- a/plugins/woocommerce-admin/docs/components/packages/summary.md +++ b/plugins/woocommerce-admin/docs/components/packages/summary.md @@ -12,17 +12,17 @@ Props ### `children` - **Required** -- Type: ReactNode +- Type: Function - Default: null -A list of ``s +A function returning a list of ``s ### `label` - Type: String -- Default: null +- Default: `__( 'Performance Indicators', 'wc-admin' )` -An optional label of this group, read to screen reader users. Defaults to "Performance Indicators". +An optional label of this group, read to screen reader users. `SummaryNumber` (component) =========================== @@ -46,7 +46,7 @@ If omitted, no change value will display. ### `href` - Type: String -- Default: `'/analytics'` +- Default: `''` An internal link to the report focused on this number. @@ -109,6 +109,13 @@ A boolean used to show a highlight style on this number. A string or number value to display - a string is allowed so we can accept currency formatting. +### `onLinkClickCallback` + +- Type: Function +- Default: `noop` + +A function to be called after a SummaryNumber, rendered as a link, is clicked. + `SummaryListPlaceholder` (component) ==================================== diff --git a/plugins/woocommerce-admin/package-lock.json b/plugins/woocommerce-admin/package-lock.json index d89aa78bcdf..fe3cea0b11d 100644 --- a/plugins/woocommerce-admin/package-lock.json +++ b/plugins/woocommerce-admin/package-lock.json @@ -1,6 +1,6 @@ { "name": "wc-admin", - "version": "0.5.0", + "version": "0.6.0", "lockfileVersion": 1, "requires": true, "dependencies": { diff --git a/plugins/woocommerce-admin/package.json b/plugins/woocommerce-admin/package.json index 3754a89f520..04a2e9be1a7 100644 --- a/plugins/woocommerce-admin/package.json +++ b/plugins/woocommerce-admin/package.json @@ -1,6 +1,6 @@ { "name": "wc-admin", - "version": "0.5.0", + "version": "0.6.0", "main": "js/index.js", "author": "Automattic", "license": "GPL-2.0-or-later", diff --git a/plugins/woocommerce-admin/wc-admin.php b/plugins/woocommerce-admin/wc-admin.php index b324db51027..b933745e927 100755 --- a/plugins/woocommerce-admin/wc-admin.php +++ b/plugins/woocommerce-admin/wc-admin.php @@ -7,7 +7,7 @@ * Author URI: https://woocommerce.com/ * Text Domain: wc-admin * Domain Path: /languages - * Version: 0.5.0 + * Version: 0.6.0 * * @package WC_Admin */ From 43c753011a147ad4bfc154ab7081363a9a686dcb Mon Sep 17 00:00:00 2001 From: "renovate[bot]" Date: Wed, 30 Jan 2019 13:53:25 -0500 Subject: [PATCH 38/53] Update dependency eslint to v5.12.1 (https://github.com/woocommerce/woocommerce-admin/pull/1376) --- plugins/woocommerce-admin/package-lock.json | 26 ++++++++++----------- plugins/woocommerce-admin/package.json | 2 +- 2 files changed, 14 insertions(+), 14 deletions(-) diff --git a/plugins/woocommerce-admin/package-lock.json b/plugins/woocommerce-admin/package-lock.json index fe3cea0b11d..714fcead56e 100644 --- a/plugins/woocommerce-admin/package-lock.json +++ b/plugins/woocommerce-admin/package-lock.json @@ -7623,9 +7623,9 @@ } }, "eslint": { - "version": "5.12.0", - "resolved": "https://registry.npmjs.org/eslint/-/eslint-5.12.0.tgz", - "integrity": "sha512-LntwyPxtOHrsJdcSwyQKVtHofPHdv+4+mFwEe91r2V13vqpM8yLr7b1sW+Oo/yheOPkWYsYlYJCkzlFAt8KV7g==", + "version": "5.12.1", + "resolved": "https://registry.npmjs.org/eslint/-/eslint-5.12.1.tgz", + "integrity": "sha512-54NV+JkTpTu0d8+UYSA8mMKAG4XAsaOrozA9rCW7tgneg1mevcL7wIotPC+fZ0SkWwdhNqoXoxnQCTBp7UvTsg==", "dev": true, "requires": { "@babel/code-frame": "^7.0.0", @@ -7668,9 +7668,9 @@ }, "dependencies": { "acorn": { - "version": "6.0.5", - "resolved": "https://registry.npmjs.org/acorn/-/acorn-6.0.5.tgz", - "integrity": "sha512-i33Zgp3XWtmZBMNvCr4azvOFeWVw1Rk6p3hfi3LUDvIFraOMywb1kAtrbi+med14m4Xfpqm3zRZMT+c0FNE7kg==", + "version": "6.0.6", + "resolved": "https://registry.npmjs.org/acorn/-/acorn-6.0.6.tgz", + "integrity": "sha512-5M3G/A4uBSMIlfJ+h9W125vJvPFH/zirISsW5qfxF5YzEvXJCtolLoQvM5yZft0DvMcUrPGKPOlgEu55I6iUtA==", "dev": true }, "acorn-jsx": { @@ -7781,9 +7781,9 @@ "dev": true }, "slice-ansi": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/slice-ansi/-/slice-ansi-2.0.0.tgz", - "integrity": "sha512-4j2WTWjp3GsZ+AOagyzVbzp4vWGtZ0hEZ/gDY/uTvm6MTxUfTUIsnMIFb1bn8o0RuXiqUw15H1bue8f22Vw2oQ==", + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/slice-ansi/-/slice-ansi-2.1.0.tgz", + "integrity": "sha512-Qu+VC3EwYLldKa1fCxuuvULvSJOKEgk9pi8dZeCVK7TqBfUNTH4sFkk4joj8afVSfAYgJoSOetjx9QWOJ5mYoQ==", "dev": true, "requires": { "ansi-styles": "^3.2.0", @@ -7809,14 +7809,14 @@ } }, "table": { - "version": "5.2.0", - "resolved": "https://registry.npmjs.org/table/-/table-5.2.0.tgz", - "integrity": "sha512-hAdBBAMCZl4/U3eQhsPN2Z8wRJC98lpRhDW2I86VQbPBqyj4E681VhvUkfb90qUJ4rnRfu8t4/8SGHPsAH1ygg==", + "version": "5.2.2", + "resolved": "https://registry.npmjs.org/table/-/table-5.2.2.tgz", + "integrity": "sha512-f8mJmuu9beQEDkKHLzOv4VxVYlU68NpdzjbGPl69i4Hx0sTopJuNxuzJd17iV2h24dAfa93u794OnDA5jqXvfQ==", "dev": true, "requires": { "ajv": "^6.6.1", "lodash": "^4.17.11", - "slice-ansi": "2.0.0", + "slice-ansi": "^2.0.0", "string-width": "^2.1.1" } } diff --git a/plugins/woocommerce-admin/package.json b/plugins/woocommerce-admin/package.json index 04a2e9be1a7..51c4fcd9b5d 100644 --- a/plugins/woocommerce-admin/package.json +++ b/plugins/woocommerce-admin/package.json @@ -73,7 +73,7 @@ "deasync": "0.1.14", "deep-freeze": "0.0.1", "docsify-cli": "4.3.0", - "eslint": "5.12.0", + "eslint": "5.12.1", "eslint-config-wpcalypso": "4.0.1", "eslint-loader": "2.1.1", "eslint-plugin-jest": "22.2.1", From 40cd3545fe6e37fc09bb78b89593f9c60209e715 Mon Sep 17 00:00:00 2001 From: "renovate[bot]" Date: Wed, 30 Jan 2019 13:59:32 -0500 Subject: [PATCH 39/53] Update dependency eslint-plugin-react to v7.12.4 (https://github.com/woocommerce/woocommerce-admin/pull/1418) --- plugins/woocommerce-admin/package-lock.json | 6 +++--- plugins/woocommerce-admin/package.json | 2 +- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/plugins/woocommerce-admin/package-lock.json b/plugins/woocommerce-admin/package-lock.json index 714fcead56e..ef4f8be84a5 100644 --- a/plugins/woocommerce-admin/package-lock.json +++ b/plugins/woocommerce-admin/package-lock.json @@ -7864,9 +7864,9 @@ } }, "eslint-plugin-react": { - "version": "7.12.3", - "resolved": "https://registry.npmjs.org/eslint-plugin-react/-/eslint-plugin-react-7.12.3.tgz", - "integrity": "sha512-WTIA3cS8OzkPeCi4KWuPmjR33lgG9r9Y/7RmnLTRw08MZKgAfnK/n3BO4X0S67MPkVLazdfCNT/XWqcDu4BLTA==", + "version": "7.12.4", + "resolved": "https://registry.npmjs.org/eslint-plugin-react/-/eslint-plugin-react-7.12.4.tgz", + "integrity": "sha512-1puHJkXJY+oS1t467MjbqjvX53uQ05HXwjqDgdbGBqf5j9eeydI54G3KwiJmWciQ0HTBacIKw2jgwSBSH3yfgQ==", "dev": true, "requires": { "array-includes": "^3.0.3", diff --git a/plugins/woocommerce-admin/package.json b/plugins/woocommerce-admin/package.json index 51c4fcd9b5d..2bee5507c35 100644 --- a/plugins/woocommerce-admin/package.json +++ b/plugins/woocommerce-admin/package.json @@ -78,7 +78,7 @@ "eslint-loader": "2.1.1", "eslint-plugin-jest": "22.2.1", "eslint-plugin-jsx-a11y": "6.1.2", - "eslint-plugin-react": "7.12.3", + "eslint-plugin-react": "7.12.4", "eslint-plugin-wpcalypso": "4.0.2", "grunt": "1.0.3", "grunt-checktextdomain": "1.0.1", From 099e8a60afa7f99950df7c17d42e7132d3862bc9 Mon Sep 17 00:00:00 2001 From: "renovate[bot]" Date: Wed, 30 Jan 2019 14:20:36 -0500 Subject: [PATCH 40/53] Update dependency eslint-plugin-jsx-a11y to v6.2.0 (https://github.com/woocommerce/woocommerce-admin/pull/1416) --- plugins/woocommerce-admin/package-lock.json | 18 +++++++++++++----- plugins/woocommerce-admin/package.json | 2 +- 2 files changed, 14 insertions(+), 6 deletions(-) diff --git a/plugins/woocommerce-admin/package-lock.json b/plugins/woocommerce-admin/package-lock.json index ef4f8be84a5..89f2ab6257d 100644 --- a/plugins/woocommerce-admin/package-lock.json +++ b/plugins/woocommerce-admin/package-lock.json @@ -7848,19 +7848,27 @@ "dev": true }, "eslint-plugin-jsx-a11y": { - "version": "6.1.2", - "resolved": "https://registry.npmjs.org/eslint-plugin-jsx-a11y/-/eslint-plugin-jsx-a11y-6.1.2.tgz", - "integrity": "sha512-7gSSmwb3A+fQwtw0arguwMdOdzmKUgnUcbSNlo+GjKLAQFuC2EZxWqG9XHRI8VscBJD5a8raz3RuxQNFW+XJbw==", + "version": "6.2.0", + "resolved": "https://registry.npmjs.org/eslint-plugin-jsx-a11y/-/eslint-plugin-jsx-a11y-6.2.0.tgz", + "integrity": "sha512-KpibpIdKT0nbDG7G/ILWoZoN5G9cj3h1IHARxzvHk5Nt2LQ7oPUutbO9QbT1FKNHLPZB6BaoA1ASSLOiJZVEUQ==", "dev": true, "requires": { "aria-query": "^3.0.0", "array-includes": "^3.0.3", "ast-types-flow": "^0.0.7", - "axobject-query": "^2.0.1", + "axobject-query": "^2.0.2", "damerau-levenshtein": "^1.0.4", - "emoji-regex": "^6.5.1", + "emoji-regex": "^7.0.2", "has": "^1.0.3", "jsx-ast-utils": "^2.0.1" + }, + "dependencies": { + "emoji-regex": { + "version": "7.0.3", + "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-7.0.3.tgz", + "integrity": "sha512-CwBLREIQ7LvYFB0WyRvwhq5N5qPhc6PMjD6bYggFlI5YyDgl+0vxq5VHbMOFqLg7hfWzmu8T5Z1QofhmTIhItA==", + "dev": true + } } }, "eslint-plugin-react": { diff --git a/plugins/woocommerce-admin/package.json b/plugins/woocommerce-admin/package.json index 2bee5507c35..a9508c3a34f 100644 --- a/plugins/woocommerce-admin/package.json +++ b/plugins/woocommerce-admin/package.json @@ -77,7 +77,7 @@ "eslint-config-wpcalypso": "4.0.1", "eslint-loader": "2.1.1", "eslint-plugin-jest": "22.2.1", - "eslint-plugin-jsx-a11y": "6.1.2", + "eslint-plugin-jsx-a11y": "6.2.0", "eslint-plugin-react": "7.12.4", "eslint-plugin-wpcalypso": "4.0.2", "grunt": "1.0.3", From ead7ca05236ed7fedee21e7116b9ff3b8b115d09 Mon Sep 17 00:00:00 2001 From: "renovate[bot]" Date: Wed, 30 Jan 2019 15:13:31 -0500 Subject: [PATCH 41/53] Pin dependency locutus to 2.0.10 (https://github.com/woocommerce/woocommerce-admin/pull/1408) --- plugins/woocommerce-admin/package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/plugins/woocommerce-admin/package.json b/plugins/woocommerce-admin/package.json index a9508c3a34f..412d0258cba 100644 --- a/plugins/woocommerce-admin/package.json +++ b/plugins/woocommerce-admin/package.json @@ -85,7 +85,7 @@ "grunt-wp-i18n": "1.0.3", "husky": "1.3.1", "lerna": "3.10.7", - "locutus": "^2.0.10", + "locutus": "2.0.10", "mini-css-extract-plugin": "0.5.0", "node-sass": "4.11.0", "node-watch": "0.6.0", From e18837e255f4384ad3b5e9f46321dc2d83fc1a82 Mon Sep 17 00:00:00 2001 From: "renovate[bot]" Date: Wed, 30 Jan 2019 15:25:19 -0500 Subject: [PATCH 42/53] Update dependency autoprefixer to v9.4.7 (https://github.com/woocommerce/woocommerce-admin/pull/1374) --- plugins/woocommerce-admin/package-lock.json | 41 ++++++++++++++++----- plugins/woocommerce-admin/package.json | 2 +- 2 files changed, 33 insertions(+), 10 deletions(-) diff --git a/plugins/woocommerce-admin/package-lock.json b/plugins/woocommerce-admin/package-lock.json index 89f2ab6257d..5a2064dc601 100644 --- a/plugins/woocommerce-admin/package-lock.json +++ b/plugins/woocommerce-admin/package-lock.json @@ -3848,23 +3848,46 @@ "integrity": "sha512-Wm6ukoaOGJi/73p/cl2GvLjTI5JM1k/O14isD73YML8StrH/7/lRFgmg8nICZgD3bZZvjwCGxtMOD3wWNAu8cg==" }, "autoprefixer": { - "version": "9.4.5", - "resolved": "https://registry.npmjs.org/autoprefixer/-/autoprefixer-9.4.5.tgz", - "integrity": "sha512-M602C0ZxzFpJKqD4V6eq2j+K5CkzlhekCrcQupJmAOrPEZjWJyj/wSeo6qRSNoN6M3/9mtLPQqTTrABfReytQg==", + "version": "9.4.7", + "resolved": "https://registry.npmjs.org/autoprefixer/-/autoprefixer-9.4.7.tgz", + "integrity": "sha512-qS5wW6aXHkm53Y4z73tFGsUhmZu4aMPV9iHXYlF0c/wxjknXNHuj/1cIQb+6YH692DbJGGWcckAXX+VxKvahMA==", "dev": true, "requires": { - "browserslist": "^4.4.0", - "caniuse-lite": "^1.0.30000928", + "browserslist": "^4.4.1", + "caniuse-lite": "^1.0.30000932", "normalize-range": "^0.1.2", "num2fraction": "^1.2.2", - "postcss": "^7.0.11", + "postcss": "^7.0.14", "postcss-value-parser": "^3.3.1" }, "dependencies": { + "browserslist": { + "version": "4.4.1", + "resolved": "https://registry.npmjs.org/browserslist/-/browserslist-4.4.1.tgz", + "integrity": "sha512-pEBxEXg7JwaakBXjATYw/D1YZh4QUSCX/Mnd/wnqSRPPSi1U39iDhDoKGoBUcraKdxDlrYqJxSI5nNvD+dWP2A==", + "dev": true, + "requires": { + "caniuse-lite": "^1.0.30000929", + "electron-to-chromium": "^1.3.103", + "node-releases": "^1.1.3" + } + }, + "caniuse-lite": { + "version": "1.0.30000932", + "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30000932.tgz", + "integrity": "sha512-4bghJFItvzz8m0T3lLZbacmEY9X1Z2AtIzTr7s7byqZIOumASfr4ynDx7rtm0J85nDmx8vsgR6vnaSoeU8Oh0A==", + "dev": true + }, + "electron-to-chromium": { + "version": "1.3.108", + "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.3.108.tgz", + "integrity": "sha512-/QI4hMpAh48a1Sea6PALGv+kuVne9A2EWGd8HrWHMdYhIzGtbhVVHh6heL5fAzGaDnZuPyrlWJRl8WPm4RyiQQ==", + "dev": true + }, "postcss": { - "version": "7.0.11", - "resolved": "https://registry.npmjs.org/postcss/-/postcss-7.0.11.tgz", - "integrity": "sha512-9AXb//5UcjeOEof9T+yPw3XTa5SL207ZOIC/lHYP4mbUTEh4M0rDAQekQpVANCZdwQwKhBtFZCk3i3h3h2hdWg==", + "version": "7.0.14", + "resolved": "https://registry.npmjs.org/postcss/-/postcss-7.0.14.tgz", + "integrity": "sha512-NsbD6XUUMZvBxtQAJuWDJeeC4QFsmWsfozWxCJPWf3M55K9iu2iMDaKqyoOdTJ1R4usBXuxlVFAIo8rZPQD4Bg==", "dev": true, "requires": { "chalk": "^2.4.2", diff --git a/plugins/woocommerce-admin/package.json b/plugins/woocommerce-admin/package.json index 412d0258cba..724a600d015 100644 --- a/plugins/woocommerce-admin/package.json +++ b/plugins/woocommerce-admin/package.json @@ -59,7 +59,7 @@ "@wordpress/jest-preset-default": "3.0.3", "@wordpress/postcss-themes": "1.0.4", "ast-types": "0.11.7", - "autoprefixer": "9.4.5", + "autoprefixer": "9.4.7", "babel-core": "7.0.0-bridge.0", "babel-eslint": "10.0.1", "babel-loader": "8.0.5", From f128716d28e7e19a3b3cbfbe75fa29ac362a4769 Mon Sep 17 00:00:00 2001 From: "renovate[bot]" Date: Wed, 30 Jan 2019 15:46:29 -0500 Subject: [PATCH 43/53] Update babel monorepo (https://github.com/woocommerce/woocommerce-admin/pull/1373) --- plugins/woocommerce-admin/package-lock.json | 34 +++++++++++++------ plugins/woocommerce-admin/package.json | 4 +-- .../packages/components/package.json | 2 +- .../packages/csv-export/package.json | 2 +- .../packages/number/package.json | 2 +- 5 files changed, 28 insertions(+), 16 deletions(-) diff --git a/plugins/woocommerce-admin/package-lock.json b/plugins/woocommerce-admin/package-lock.json index 5a2064dc601..c1d97802dc9 100644 --- a/plugins/woocommerce-admin/package-lock.json +++ b/plugins/woocommerce-admin/package-lock.json @@ -89,12 +89,24 @@ } }, "@babel/helper-builder-react-jsx": { - "version": "7.0.0", - "resolved": "https://registry.npmjs.org/@babel/helper-builder-react-jsx/-/helper-builder-react-jsx-7.0.0.tgz", - "integrity": "sha512-ebJ2JM6NAKW0fQEqN8hOLxK84RbRz9OkUhGS/Xd5u56ejMfVbayJ4+LykERZCOUM6faa6Fp3SZNX3fcT16MKHw==", + "version": "7.3.0", + "resolved": "https://registry.npmjs.org/@babel/helper-builder-react-jsx/-/helper-builder-react-jsx-7.3.0.tgz", + "integrity": "sha512-MjA9KgwCuPEkQd9ncSXvSyJ5y+j2sICHyrI0M3L+6fnS4wMSNDc1ARXsbTfbb2cXHn17VisSnU/sHFTCxVxSMw==", "requires": { - "@babel/types": "^7.0.0", + "@babel/types": "^7.3.0", "esutils": "^2.0.0" + }, + "dependencies": { + "@babel/types": { + "version": "7.3.0", + "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.3.0.tgz", + "integrity": "sha512-QkFPw68QqWU1/RVPyBe8SO7lXbPfjtqAxRYQKpFpaB8yMq7X2qAqfwK5LKoQufEkSmO5NQ70O6Kc3Afk03RwXw==", + "requires": { + "esutils": "^2.0.2", + "lodash": "^4.17.10", + "to-fast-properties": "^2.0.0" + } + } } }, "@babel/helper-call-delegate": { @@ -548,11 +560,11 @@ } }, "@babel/plugin-transform-react-jsx": { - "version": "7.2.0", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-react-jsx/-/plugin-transform-react-jsx-7.2.0.tgz", - "integrity": "sha512-h/fZRel5wAfCqcKgq3OhbmYaReo7KkoJBpt8XnvpS7wqaNMqtw5xhxutzcm35iMUWucfAdT/nvGTsWln0JTg2Q==", + "version": "7.3.0", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-react-jsx/-/plugin-transform-react-jsx-7.3.0.tgz", + "integrity": "sha512-a/+aRb7R06WcKvQLOu4/TpjKOdvVEKRLWFpKcNuHhiREPgGRB4TQJxq07+EZLS8LFVYpfq1a5lDUnuMdcCpBKg==", "requires": { - "@babel/helper-builder-react-jsx": "^7.0.0", + "@babel/helper-builder-react-jsx": "^7.3.0", "@babel/helper-plugin-utils": "^7.0.0", "@babel/plugin-syntax-jsx": "^7.2.0" } @@ -685,9 +697,9 @@ } }, "@babel/runtime-corejs2": { - "version": "7.2.0", - "resolved": "https://registry.npmjs.org/@babel/runtime-corejs2/-/runtime-corejs2-7.2.0.tgz", - "integrity": "sha512-kPfmKoRI8Hpo5ZJGACWyrc9Eq1j3ZIUpUAQT2yH045OuYpccFJ9kYA/eErwzOM2jeBG1sC8XX1nl1EArtuM8tg==", + "version": "7.3.1", + "resolved": "https://registry.npmjs.org/@babel/runtime-corejs2/-/runtime-corejs2-7.3.1.tgz", + "integrity": "sha512-YpO13776h3e6Wy8dl2J8T9Qwlvopr+b4trCEhHE+yek6yIqV8sx6g3KozdHMbXeBpjosbPi+Ii5Z7X9oXFHUKA==", "requires": { "core-js": "^2.5.7", "regenerator-runtime": "^0.12.0" diff --git a/plugins/woocommerce-admin/package.json b/plugins/woocommerce-admin/package.json index 724a600d015..3f61d5d082e 100644 --- a/plugins/woocommerce-admin/package.json +++ b/plugins/woocommerce-admin/package.json @@ -49,8 +49,8 @@ "@babel/cli": "7.2.3", "@babel/core": "7.2.2", "@babel/plugin-transform-async-to-generator": "7.2.0", - "@babel/plugin-transform-react-jsx": "7.2.0", - "@babel/runtime-corejs2": "7.2.0", + "@babel/plugin-transform-react-jsx": "7.3.0", + "@babel/runtime-corejs2": "7.3.1", "@wordpress/babel-plugin-import-jsx-pragma": "1.1.2", "@wordpress/babel-plugin-makepot": "2.1.2", "@wordpress/babel-preset-default": "3.0.1", diff --git a/plugins/woocommerce-admin/packages/components/package.json b/plugins/woocommerce-admin/packages/components/package.json index 46070b6560d..bbc06a370c9 100644 --- a/plugins/woocommerce-admin/packages/components/package.json +++ b/plugins/woocommerce-admin/packages/components/package.json @@ -21,7 +21,7 @@ "module": "build-module/index.js", "react-native": "src/index", "dependencies": { - "@babel/runtime-corejs2": "7.2.0", + "@babel/runtime-corejs2": "7.3.1", "@woocommerce/csv-export": "^1.0.3", "@woocommerce/currency": "^1.1.0", "@woocommerce/date": "^1.0.6", diff --git a/plugins/woocommerce-admin/packages/csv-export/package.json b/plugins/woocommerce-admin/packages/csv-export/package.json index c917f8e0c28..339462e4ffc 100644 --- a/plugins/woocommerce-admin/packages/csv-export/package.json +++ b/plugins/woocommerce-admin/packages/csv-export/package.json @@ -21,7 +21,7 @@ "module": "build-module/index.js", "react-native": "src/index", "dependencies": { - "@babel/runtime-corejs2": "7.2.0", + "@babel/runtime-corejs2": "7.3.1", "browser-filesaver": "^1.1.1", "moment": "^2.22.2" }, diff --git a/plugins/woocommerce-admin/packages/number/package.json b/plugins/woocommerce-admin/packages/number/package.json index e9bb5388c32..d379317a640 100644 --- a/plugins/woocommerce-admin/packages/number/package.json +++ b/plugins/woocommerce-admin/packages/number/package.json @@ -20,7 +20,7 @@ "module": "build-module/index.js", "react-native": "src/index", "dependencies": { - "@babel/runtime-corejs2": "7.1.5", + "@babel/runtime-corejs2": "7.3.1", "locutus": "^2.0.10", "lodash": "^4.17.11" }, From 85a46252df39b717978dceb42d6787a74b7b56e2 Mon Sep 17 00:00:00 2001 From: "renovate[bot]" Date: Wed, 30 Jan 2019 15:59:19 -0500 Subject: [PATCH 44/53] Update dependency core-js to v2.6.3 (https://github.com/woocommerce/woocommerce-admin/pull/1375) --- plugins/woocommerce-admin/package-lock.json | 6 +++--- plugins/woocommerce-admin/package.json | 2 +- plugins/woocommerce-admin/packages/components/package.json | 2 +- 3 files changed, 5 insertions(+), 5 deletions(-) diff --git a/plugins/woocommerce-admin/package-lock.json b/plugins/woocommerce-admin/package-lock.json index c1d97802dc9..c1858b443f6 100644 --- a/plugins/woocommerce-admin/package-lock.json +++ b/plugins/woocommerce-admin/package-lock.json @@ -6136,9 +6136,9 @@ } }, "core-js": { - "version": "2.6.2", - "resolved": "https://registry.npmjs.org/core-js/-/core-js-2.6.2.tgz", - "integrity": "sha512-NdBPF/RVwPW6jr0NCILuyN9RiqLo2b1mddWHkUL+VnvcB7dzlnBJ1bXYntjpTGOgkZiiLWj2JxmOr7eGE3qK6g==" + "version": "2.6.3", + "resolved": "https://registry.npmjs.org/core-js/-/core-js-2.6.3.tgz", + "integrity": "sha512-l00tmFFZOBHtYhN4Cz7k32VM7vTn3rE2ANjQDxdEN6zmXZ/xq1jQuutnmHvMG1ZJ7xd72+TA5YpUK8wz3rWsfQ==" }, "core-util-is": { "version": "1.0.2", diff --git a/plugins/woocommerce-admin/package.json b/plugins/woocommerce-admin/package.json index 3f61d5d082e..9f6a56eac79 100644 --- a/plugins/woocommerce-admin/package.json +++ b/plugins/woocommerce-admin/package.json @@ -122,7 +122,7 @@ "@wordpress/viewport": "^2.0.7", "browser-filesaver": "^1.1.1", "classnames": "^2.2.5", - "core-js": "2.6.2", + "core-js": "2.6.3", "d3-array": "^2.0.0", "d3-axis": "^1.0.12", "d3-format": "^1.3.2", diff --git a/plugins/woocommerce-admin/packages/components/package.json b/plugins/woocommerce-admin/packages/components/package.json index bbc06a370c9..893f5333579 100644 --- a/plugins/woocommerce-admin/packages/components/package.json +++ b/plugins/woocommerce-admin/packages/components/package.json @@ -35,7 +35,7 @@ "@wordpress/keycodes": "2.0.5", "@wordpress/viewport": "^2.0.7", "classnames": "^2.2.5", - "core-js": "2.6.2", + "core-js": "2.6.3", "d3-array": "^2.0.0", "d3-axis": "^1.0.12", "d3-format": "^1.3.2", From 713d64c97a860dc2e5a20858d88fba2fbf7bf97a Mon Sep 17 00:00:00 2001 From: "renovate[bot]" Date: Wed, 30 Jan 2019 16:15:54 -0500 Subject: [PATCH 45/53] Lock file maintenance (https://github.com/woocommerce/woocommerce-admin/pull/1362) --- plugins/woocommerce-admin/package-lock.json | 2768 +++++++++---------- 1 file changed, 1346 insertions(+), 1422 deletions(-) diff --git a/plugins/woocommerce-admin/package-lock.json b/plugins/woocommerce-admin/package-lock.json index c1858b443f6..eb6859c8e24 100644 --- a/plugins/woocommerce-admin/package-lock.json +++ b/plugins/woocommerce-admin/package-lock.json @@ -60,11 +60,11 @@ } }, "@babel/generator": { - "version": "7.2.2", - "resolved": "https://registry.npmjs.org/@babel/generator/-/generator-7.2.2.tgz", - "integrity": "sha512-I4o675J/iS8k+P38dvJ3IBGqObLXyQLTxtrR4u9cSUJOURvafeEWb/pFMOTwtNrmq73mJzyF6ueTbO1BtN0Zeg==", + "version": "7.3.0", + "resolved": "https://registry.npmjs.org/@babel/generator/-/generator-7.3.0.tgz", + "integrity": "sha512-dZTwMvTgWfhmibq4V9X+LMf6Bgl7zAodRn9PvcPdhlzFMbvUutx74dbEv7Atz3ToeEpevYEJtAwfxq/bDCzHWg==", "requires": { - "@babel/types": "^7.2.2", + "@babel/types": "^7.3.0", "jsesc": "^2.5.1", "lodash": "^4.17.10", "source-map": "^0.5.0", @@ -95,18 +95,6 @@ "requires": { "@babel/types": "^7.3.0", "esutils": "^2.0.0" - }, - "dependencies": { - "@babel/types": { - "version": "7.3.0", - "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.3.0.tgz", - "integrity": "sha512-QkFPw68QqWU1/RVPyBe8SO7lXbPfjtqAxRYQKpFpaB8yMq7X2qAqfwK5LKoQufEkSmO5NQ70O6Kc3Afk03RwXw==", - "requires": { - "esutils": "^2.0.2", - "lodash": "^4.17.10", - "to-fast-properties": "^2.0.0" - } - } } }, "@babel/helper-call-delegate": { @@ -266,13 +254,13 @@ } }, "@babel/helpers": { - "version": "7.2.0", - "resolved": "https://registry.npmjs.org/@babel/helpers/-/helpers-7.2.0.tgz", - "integrity": "sha512-Fr07N+ea0dMcMN8nFpuK6dUIT7/ivt9yKQdEEnjVS83tG2pHwPi03gYmk/tyuwONnZ+sY+GFFPlWGgCtW1hF9A==", + "version": "7.3.1", + "resolved": "https://registry.npmjs.org/@babel/helpers/-/helpers-7.3.1.tgz", + "integrity": "sha512-Q82R3jKsVpUV99mgX50gOPCWwco9Ec5Iln/8Vyu4osNIOQgSrd9RFrQeUvmvddFNoLwMyOUWU+5ckioEKpDoGA==", "requires": { "@babel/template": "^7.1.2", "@babel/traverse": "^7.1.5", - "@babel/types": "^7.2.0" + "@babel/types": "^7.3.0" } }, "@babel/highlight": { @@ -286,9 +274,9 @@ } }, "@babel/parser": { - "version": "7.2.3", - "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.2.3.tgz", - "integrity": "sha512-0LyEcVlfCoFmci8mXx8A5oIkpkOgyo8dRHtxBnK9RRBwxO2+JZPNsqtVEZQ7mJFPxnXF9lfmU24mHOPI0qnlkA==" + "version": "7.3.1", + "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.3.1.tgz", + "integrity": "sha512-ATz6yX/L8LEnC3dtLQnIx4ydcPxhLcoy9Vl6re00zb2w5lG6itY6Vhnr1KFRPq/FHNsgl/gh2mjNN20f9iJTTA==" }, "@babel/plugin-proposal-async-generator-functions": { "version": "7.2.0", @@ -310,9 +298,9 @@ } }, "@babel/plugin-proposal-object-rest-spread": { - "version": "7.2.0", - "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-object-rest-spread/-/plugin-proposal-object-rest-spread-7.2.0.tgz", - "integrity": "sha512-1L5mWLSvR76XYUQJXkd/EEQgjq8HHRP6lQuZTTg0VA4tTGPpGemmCdAfQIz1rzEuWAm+ecP8PyyEm30jC1eQCg==", + "version": "7.3.1", + "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-object-rest-spread/-/plugin-proposal-object-rest-spread-7.3.1.tgz", + "integrity": "sha512-Nmmv1+3LqxJu/V5jU9vJmxR/KIRWFk2qLHmbB56yRRRFhlaSuOVXscX3gUmhaKgUhzA3otOHVubbIEVYsZ0eZg==", "requires": { "@babel/helper-plugin-utils": "^7.0.0", "@babel/plugin-syntax-object-rest-spread": "^7.2.0" @@ -532,6 +520,14 @@ "@babel/helper-plugin-utils": "^7.0.0" } }, + "@babel/plugin-transform-named-capturing-groups-regex": { + "version": "7.3.0", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-named-capturing-groups-regex/-/plugin-transform-named-capturing-groups-regex-7.3.0.tgz", + "integrity": "sha512-NxIoNVhk9ZxS+9lSoAQ/LM0V2UEvARLttEHUrRDGKFaAxOYQcrkN/nLRE+BbbicCAvZPl7wMP0X60HsHE5DtQw==", + "requires": { + "regexp-tree": "^0.1.0" + } + }, "@babel/plugin-transform-new-target": { "version": "7.0.0", "resolved": "https://registry.npmjs.org/@babel/plugin-transform-new-target/-/plugin-transform-new-target-7.0.0.tgz", @@ -641,18 +637,19 @@ } }, "@babel/preset-env": { - "version": "7.2.3", - "resolved": "https://registry.npmjs.org/@babel/preset-env/-/preset-env-7.2.3.tgz", - "integrity": "sha512-AuHzW7a9rbv5WXmvGaPX7wADxFkZIqKlbBh1dmZUQp4iwiPpkE/Qnrji6SC4UQCQzvWY/cpHET29eUhXS9cLPw==", + "version": "7.3.1", + "resolved": "https://registry.npmjs.org/@babel/preset-env/-/preset-env-7.3.1.tgz", + "integrity": "sha512-FHKrD6Dxf30e8xgHQO0zJZpUPfVZg+Xwgz5/RdSWCbza9QLNk4Qbp40ctRoqDxml3O8RMzB1DU55SXeDG6PqHQ==", "requires": { "@babel/helper-module-imports": "^7.0.0", "@babel/helper-plugin-utils": "^7.0.0", "@babel/plugin-proposal-async-generator-functions": "^7.2.0", "@babel/plugin-proposal-json-strings": "^7.2.0", - "@babel/plugin-proposal-object-rest-spread": "^7.2.0", + "@babel/plugin-proposal-object-rest-spread": "^7.3.1", "@babel/plugin-proposal-optional-catch-binding": "^7.2.0", "@babel/plugin-proposal-unicode-property-regex": "^7.2.0", "@babel/plugin-syntax-async-generators": "^7.2.0", + "@babel/plugin-syntax-json-strings": "^7.2.0", "@babel/plugin-syntax-object-rest-spread": "^7.2.0", "@babel/plugin-syntax-optional-catch-binding": "^7.2.0", "@babel/plugin-transform-arrow-functions": "^7.2.0", @@ -672,6 +669,7 @@ "@babel/plugin-transform-modules-commonjs": "^7.2.0", "@babel/plugin-transform-modules-systemjs": "^7.2.0", "@babel/plugin-transform-modules-umd": "^7.2.0", + "@babel/plugin-transform-named-capturing-groups-regex": "^7.3.0", "@babel/plugin-transform-new-target": "^7.0.0", "@babel/plugin-transform-object-super": "^7.2.0", "@babel/plugin-transform-parameters": "^7.2.0", @@ -689,9 +687,9 @@ } }, "@babel/runtime": { - "version": "7.2.0", - "resolved": "https://registry.npmjs.org/@babel/runtime/-/runtime-7.2.0.tgz", - "integrity": "sha512-oouEibCbHMVdZSDlJBO6bZmID/zA/G/Qx3H1d3rSNPTD+L8UNKvCat7aKWSJ74zYbm5zWGh0GQN0hKj8zYFTCg==", + "version": "7.3.1", + "resolved": "https://registry.npmjs.org/@babel/runtime/-/runtime-7.3.1.tgz", + "integrity": "sha512-7jGW8ppV0ant637pIqAcFfQDDH1orEPGJb8aXfUozuCU3QqX7rX4DA8iwrbPrR1hcH0FTTHz47yQnk+bl5xHQA==", "requires": { "regenerator-runtime": "^0.12.0" } @@ -732,9 +730,9 @@ } }, "@babel/types": { - "version": "7.2.2", - "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.2.2.tgz", - "integrity": "sha512-fKCuD6UFUMkR541eDWL+2ih/xFZBXPOg/7EQFeTluMDebfqR4jrpaCjLhkWlQS4hT6nRa2PMEgXKbRB5/H2fpg==", + "version": "7.3.0", + "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.3.0.tgz", + "integrity": "sha512-QkFPw68QqWU1/RVPyBe8SO7lXbPfjtqAxRYQKpFpaB8yMq7X2qAqfwK5LKoQufEkSmO5NQ70O6Kc3Afk03RwXw==", "requires": { "esutils": "^2.0.2", "lodash": "^4.17.10", @@ -840,45 +838,6 @@ "chalk": "^2.3.1", "execa": "^1.0.0", "strong-log-transformer": "^2.0.0" - }, - "dependencies": { - "cross-spawn": { - "version": "6.0.5", - "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-6.0.5.tgz", - "integrity": "sha512-eTVLrBSt7fjbDygz805pMnstIs2VTBNkRm0qxZd+M7A5XDdxVRWO5MxGBXZhjY4cqLYLdtrGqRf8mBPmzwSpWQ==", - "dev": true, - "requires": { - "nice-try": "^1.0.4", - "path-key": "^2.0.1", - "semver": "^5.5.0", - "shebang-command": "^1.2.0", - "which": "^1.2.9" - } - }, - "execa": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/execa/-/execa-1.0.0.tgz", - "integrity": "sha512-adbxcyWV46qiHyvSp50TKt05tB4tK3HcmF7/nxfAdhnox83seTDbwnaqKO4sXRy7roHAIFqJP/Rw/AuEbX61LA==", - "dev": true, - "requires": { - "cross-spawn": "^6.0.0", - "get-stream": "^4.0.0", - "is-stream": "^1.1.0", - "npm-run-path": "^2.0.0", - "p-finally": "^1.0.0", - "signal-exit": "^3.0.0", - "strip-eof": "^1.0.0" - } - }, - "get-stream": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/get-stream/-/get-stream-4.1.0.tgz", - "integrity": "sha512-GMat4EJ5161kIy2HevLlr4luNjBgvmj413KaQA7jt4V8B4RDsfpHk7WQ9GVqfYyyx8OS/L66Kox+rJRNklLK7w==", - "dev": true, - "requires": { - "pump": "^3.0.0" - } - } } }, "@lerna/clean": { @@ -907,161 +866,6 @@ "dedent": "^0.7.0", "libnpm": "^2.0.1", "yargs": "^12.0.1" - }, - "dependencies": { - "camelcase": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-5.0.0.tgz", - "integrity": "sha512-faqwZqnWxbxn+F1d399ygeamQNy3lPp/H9H6rNrqYh4FSVCtcY+3cub1MxA8o9mDd55mM8Aghuu/kuyYA6VTsA==", - "dev": true - }, - "cross-spawn": { - "version": "6.0.5", - "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-6.0.5.tgz", - "integrity": "sha512-eTVLrBSt7fjbDygz805pMnstIs2VTBNkRm0qxZd+M7A5XDdxVRWO5MxGBXZhjY4cqLYLdtrGqRf8mBPmzwSpWQ==", - "dev": true, - "requires": { - "nice-try": "^1.0.4", - "path-key": "^2.0.1", - "semver": "^5.5.0", - "shebang-command": "^1.2.0", - "which": "^1.2.9" - } - }, - "execa": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/execa/-/execa-1.0.0.tgz", - "integrity": "sha512-adbxcyWV46qiHyvSp50TKt05tB4tK3HcmF7/nxfAdhnox83seTDbwnaqKO4sXRy7roHAIFqJP/Rw/AuEbX61LA==", - "dev": true, - "requires": { - "cross-spawn": "^6.0.0", - "get-stream": "^4.0.0", - "is-stream": "^1.1.0", - "npm-run-path": "^2.0.0", - "p-finally": "^1.0.0", - "signal-exit": "^3.0.0", - "strip-eof": "^1.0.0" - } - }, - "find-up": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/find-up/-/find-up-3.0.0.tgz", - "integrity": "sha512-1yD6RmLI1XBfxugvORwlck6f75tYL+iR0jqwsOrOxMZyGYqUuDhJ0l4AXdO1iX/FTs9cBAMEk1gWSEx1kSbylg==", - "dev": true, - "requires": { - "locate-path": "^3.0.0" - } - }, - "get-stream": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/get-stream/-/get-stream-4.1.0.tgz", - "integrity": "sha512-GMat4EJ5161kIy2HevLlr4luNjBgvmj413KaQA7jt4V8B4RDsfpHk7WQ9GVqfYyyx8OS/L66Kox+rJRNklLK7w==", - "dev": true, - "requires": { - "pump": "^3.0.0" - } - }, - "invert-kv": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/invert-kv/-/invert-kv-2.0.0.tgz", - "integrity": "sha512-wPVv/y/QQ/Uiirj/vh3oP+1Ww+AWehmi1g5fFWGPF6IpCBCDVrhgHRMvrLfdYcwDh3QJbGXDW4JAuzxElLSqKA==", - "dev": true - }, - "lcid": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/lcid/-/lcid-2.0.0.tgz", - "integrity": "sha512-avPEb8P8EGnwXKClwsNUgryVjllcRqtMYa49NTsbQagYuT1DcXnl1915oxWjoyGrXR6zH/Y0Zc96xWsPcoDKeA==", - "dev": true, - "requires": { - "invert-kv": "^2.0.0" - } - }, - "locate-path": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-3.0.0.tgz", - "integrity": "sha512-7AO748wWnIhNqAuaty2ZWHkQHRSNfPVIsPIfwEOWO22AmaoVrWavlOcMR5nzTLNYvp36X220/maaRsrec1G65A==", - "dev": true, - "requires": { - "p-locate": "^3.0.0", - "path-exists": "^3.0.0" - } - }, - "mem": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/mem/-/mem-4.0.0.tgz", - "integrity": "sha512-WQxG/5xYc3tMbYLXoXPm81ET2WDULiU5FxbuIoNbJqLOOI8zehXFdZuiUEgfdrU2mVB1pxBZUGlYORSrpuJreA==", - "dev": true, - "requires": { - "map-age-cleaner": "^0.1.1", - "mimic-fn": "^1.0.0", - "p-is-promise": "^1.1.0" - } - }, - "os-locale": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/os-locale/-/os-locale-3.1.0.tgz", - "integrity": "sha512-Z8l3R4wYWM40/52Z+S265okfFj8Kt2cC2MKY+xNi3kFs+XGI7WXu/I309QQQYbRW4ijiZ+yxs9pqEhJh0DqW3Q==", - "dev": true, - "requires": { - "execa": "^1.0.0", - "lcid": "^2.0.0", - "mem": "^4.0.0" - } - }, - "p-limit": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-2.1.0.tgz", - "integrity": "sha512-NhURkNcrVB+8hNfLuysU8enY5xn2KXphsHBaC2YmRNTZRc7RWusw6apSpdEj3jo4CMb6W9nrF6tTnsJsJeyu6g==", - "dev": true, - "requires": { - "p-try": "^2.0.0" - } - }, - "p-locate": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-3.0.0.tgz", - "integrity": "sha512-x+12w/To+4GFfgJhBEpiDcLozRJGegY+Ei7/z0tSLkMmxGZNybVMSfWj9aJn8Z5Fc7dBUNJOOVgPv2H7IwulSQ==", - "dev": true, - "requires": { - "p-limit": "^2.0.0" - } - }, - "p-try": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/p-try/-/p-try-2.0.0.tgz", - "integrity": "sha512-hMp0onDKIajHfIkdRk3P4CdCmErkYAxxDtP3Wx/4nZ3aGlau2VKh3mZpcuFkH27WQkL/3WBCPOktzA9ZOAnMQQ==", - "dev": true - }, - "yargs": { - "version": "12.0.5", - "resolved": "https://registry.npmjs.org/yargs/-/yargs-12.0.5.tgz", - "integrity": "sha512-Lhz8TLaYnxq/2ObqHDql8dX8CJi97oHxrjUcYtzKbbykPtVW9WB+poxI+NM2UIzsMgNCZTIf0AQwsjK5yMAqZw==", - "dev": true, - "requires": { - "cliui": "^4.0.0", - "decamelize": "^1.2.0", - "find-up": "^3.0.0", - "get-caller-file": "^1.0.1", - "os-locale": "^3.0.0", - "require-directory": "^2.1.1", - "require-main-filename": "^1.0.1", - "set-blocking": "^2.0.0", - "string-width": "^2.0.0", - "which-module": "^2.0.0", - "y18n": "^3.2.1 || ^4.0.0", - "yargs-parser": "^11.1.1" - } - }, - "yargs-parser": { - "version": "11.1.1", - "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-11.1.1.tgz", - "integrity": "sha512-C6kB/WJDiaxONLJQnF8ccx9SEeoTTLek8RVbaOIsrAUS8VrBEXfmeSnCZxygc+XC2sNMBIwOOnfcxiynjHsVSQ==", - "dev": true, - "requires": { - "camelcase": "^5.0.0", - "decamelize": "^1.2.0" - } - } } }, "@lerna/collect-updates": { @@ -1093,45 +897,6 @@ "is-ci": "^1.0.10", "libnpm": "^2.0.1", "lodash": "^4.17.5" - }, - "dependencies": { - "cross-spawn": { - "version": "6.0.5", - "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-6.0.5.tgz", - "integrity": "sha512-eTVLrBSt7fjbDygz805pMnstIs2VTBNkRm0qxZd+M7A5XDdxVRWO5MxGBXZhjY4cqLYLdtrGqRf8mBPmzwSpWQ==", - "dev": true, - "requires": { - "nice-try": "^1.0.4", - "path-key": "^2.0.1", - "semver": "^5.5.0", - "shebang-command": "^1.2.0", - "which": "^1.2.9" - } - }, - "execa": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/execa/-/execa-1.0.0.tgz", - "integrity": "sha512-adbxcyWV46qiHyvSp50TKt05tB4tK3HcmF7/nxfAdhnox83seTDbwnaqKO4sXRy7roHAIFqJP/Rw/AuEbX61LA==", - "dev": true, - "requires": { - "cross-spawn": "^6.0.0", - "get-stream": "^4.0.0", - "is-stream": "^1.1.0", - "npm-run-path": "^2.0.0", - "p-finally": "^1.0.0", - "signal-exit": "^3.0.0", - "strip-eof": "^1.0.0" - } - }, - "get-stream": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/get-stream/-/get-stream-4.1.0.tgz", - "integrity": "sha512-GMat4EJ5161kIy2HevLlr4luNjBgvmj413KaQA7jt4V8B4RDsfpHk7WQ9GVqfYyyx8OS/L66Kox+rJRNklLK7w==", - "dev": true, - "requires": { - "pump": "^3.0.0" - } - } } }, "@lerna/conventional-commits": { @@ -1161,15 +926,6 @@ "universalify": "^0.1.0" } }, - "get-stream": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/get-stream/-/get-stream-4.1.0.tgz", - "integrity": "sha512-GMat4EJ5161kIy2HevLlr4luNjBgvmj413KaQA7jt4V8B4RDsfpHk7WQ9GVqfYyyx8OS/L66Kox+rJRNklLK7w==", - "dev": true, - "requires": { - "pump": "^3.0.0" - } - }, "jsonfile": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/jsonfile/-/jsonfile-4.0.0.tgz", @@ -1206,6 +962,12 @@ "whatwg-url": "^7.0.0" }, "dependencies": { + "camelcase": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-4.1.0.tgz", + "integrity": "sha1-1UVjW+HjPFQmScaRc+Xeas+uNN0=", + "dev": true + }, "dir-glob": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/dir-glob/-/dir-glob-2.0.0.tgz", @@ -1565,6 +1327,33 @@ "@lerna/batch-packages": "3.10.6", "chalk": "^2.3.1", "columnify": "^1.5.4" + }, + "dependencies": { + "ansi-regex": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-2.1.1.tgz", + "integrity": "sha1-w7M6te42DYbg5ijwRorn7yfWVN8=", + "dev": true + }, + "columnify": { + "version": "1.5.4", + "resolved": "https://registry.npmjs.org/columnify/-/columnify-1.5.4.tgz", + "integrity": "sha1-Rzfd8ce2mop8NAVweC6UfuyOeLs=", + "dev": true, + "requires": { + "strip-ansi": "^3.0.0", + "wcwidth": "^1.0.0" + } + }, + "strip-ansi": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-3.0.1.tgz", + "integrity": "sha1-ajhfuIU9lS1f8F0Oiq+UJ43GPc8=", + "dev": true, + "requires": { + "ansi-regex": "^2.0.0" + } + } } }, "@lerna/log-packed": { @@ -1577,6 +1366,33 @@ "columnify": "^1.5.4", "has-unicode": "^2.0.1", "libnpm": "^2.0.1" + }, + "dependencies": { + "ansi-regex": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-2.1.1.tgz", + "integrity": "sha1-w7M6te42DYbg5ijwRorn7yfWVN8=", + "dev": true + }, + "columnify": { + "version": "1.5.4", + "resolved": "https://registry.npmjs.org/columnify/-/columnify-1.5.4.tgz", + "integrity": "sha1-Rzfd8ce2mop8NAVweC6UfuyOeLs=", + "dev": true, + "requires": { + "strip-ansi": "^3.0.0", + "wcwidth": "^1.0.0" + } + }, + "strip-ansi": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-3.0.1.tgz", + "integrity": "sha1-ajhfuIU9lS1f8F0Oiq+UJ43GPc8=", + "dev": true, + "requires": { + "ansi-regex": "^2.0.0" + } + } } }, "@lerna/npm-conf": { @@ -2270,36 +2086,36 @@ "dev": true }, "@tannin/compile": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/@tannin/compile/-/compile-1.0.1.tgz", - "integrity": "sha512-ymd9icvnkQin8UG4eRU3+xBc7gqTn/Kv5+EMY3ALWVwIl6j/7McWbCkxB8MgU40UaHJk8kLCk06wiKszXLdXWQ==", + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/@tannin/compile/-/compile-1.0.2.tgz", + "integrity": "sha512-Zv4CtKcI5tmo5epgRwFR3uPrNuCzCuFJOFhONmEanNFSVt/Ck/rV4fdkOJ0bJPxV/AwR5fcmxDx4Xxd/GDvi6g==", "requires": { - "@tannin/evaluate": "^1.0.0", - "@tannin/postfix": "^1.0.0" + "@tannin/evaluate": "^1.1.0", + "@tannin/postfix": "^1.0.1" } }, "@tannin/evaluate": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/@tannin/evaluate/-/evaluate-1.0.0.tgz", - "integrity": "sha512-gO7YbJsD8sj5/nqUbFZv71Meu2++D9n4DZov/cWwp3YJbBwKShPlWwwlXr/0vz4vuxm/gys+3NiGbZkmhlXf0Q==" + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/@tannin/evaluate/-/evaluate-1.1.0.tgz", + "integrity": "sha512-plrVqbuiqh6tWpAKznsXkCT5t4cmTLinfrB3AmX6zDduJkFmKb55n2JBdSB6D6SFvtJHtiFCmp4CUrn9dCNlqA==" }, "@tannin/plural-forms": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/@tannin/plural-forms/-/plural-forms-1.0.1.tgz", - "integrity": "sha512-SXutT+XLbMOECvmWDBSqIOHhS5hzWG9875HCFGKYgp8ghGPrJ4HZ325Xc0hsRThdjgrWMEQixlbpWl4SXOQTig==", + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/@tannin/plural-forms/-/plural-forms-1.0.2.tgz", + "integrity": "sha512-LNO8NwyVRSDOL3yDWo7Oao1Guceqr6KD0nOqR1t2mEPw21u4Tscvb0UqnAZ+IiXRzZsymPgeECss5JaEXoq30w==", "requires": { - "@tannin/compile": "^1.0.0" + "@tannin/compile": "^1.0.2" } }, "@tannin/postfix": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/@tannin/postfix/-/postfix-1.0.0.tgz", - "integrity": "sha512-59/mWwU7sXHfoU2kI3RcWRki2Jjbz5nEVJNBN4MUyIhPjXTebAcZqgsQACvlk+sjKVOTMEMHcrFrKQbaxz/1Dw==" + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/@tannin/postfix/-/postfix-1.0.1.tgz", + "integrity": "sha512-y+h7tNlxDPDrH/TrSw1wCSm6FoEAY8FrbUxYng3BMSYBTUsX1utLooizk9v8J1yy6F9AioXNnPZ1qiu2vsa08Q==" }, "@types/node": { - "version": "10.12.18", - "resolved": "https://registry.npmjs.org/@types/node/-/node-10.12.18.tgz", - "integrity": "sha512-fh+pAqt4xRzPfqA6eh3Z2y6fyZavRIumvjhaCL753+TVkGKGhpPeyrJG2JftD0T9q4GF00KjefsQ+PQNDdWQaQ==" + "version": "10.12.19", + "resolved": "https://registry.npmjs.org/@types/node/-/node-10.12.19.tgz", + "integrity": "sha512-2NVovndCjJQj6fUUn9jCgpP4WSqr+u1SoUZMZyJkhGeBFsm6dE46l31S7lPUYt9uQ28XI+ibrJA1f5XyH5HNtA==" }, "@webassemblyjs/ast": { "version": "1.7.11", @@ -2818,9 +2634,9 @@ } }, "@wordpress/rich-text": { - "version": "3.0.5", - "resolved": "https://registry.npmjs.org/@wordpress/rich-text/-/rich-text-3.0.5.tgz", - "integrity": "sha512-QgufyH481QN7cJCnUJ5qlIC22tLedmFe5D+QoIICmCvWHjxBBfDSe9IFvEz2RW5t0i8hrGAmIl962gLb1OY0KQ==", + "version": "3.0.7", + "resolved": "https://registry.npmjs.org/@wordpress/rich-text/-/rich-text-3.0.7.tgz", + "integrity": "sha512-3zRyfVksOqt5BgrYRbcyVoXc4MXejBv9PjaXzcd5ZbzKm1dYt9J6mAPCiuErDCuNN2XF0LfSb5sXuVSdklHAqg==", "requires": { "@babel/runtime": "^7.0.0", "@wordpress/compose": "^3.0.1", @@ -3071,14 +2887,6 @@ "version": "0.3.1", "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-0.3.1.tgz", "integrity": "sha1-NJptRMU6Ud6JtAgFxdXlm0F9M0A=" - }, - "strip-ansi": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-4.0.0.tgz", - "integrity": "sha1-qEeQIusaw2iocTibY1JixQXuNo8=", - "requires": { - "ansi-regex": "^3.0.0" - } } } }, @@ -3191,9 +2999,9 @@ }, "dependencies": { "acorn": { - "version": "6.0.5", - "resolved": "https://registry.npmjs.org/acorn/-/acorn-6.0.5.tgz", - "integrity": "sha512-i33Zgp3XWtmZBMNvCr4azvOFeWVw1Rk6p3hfi3LUDvIFraOMywb1kAtrbi+med14m4Xfpqm3zRZMT+c0FNE7kg==" + "version": "6.0.6", + "resolved": "https://registry.npmjs.org/acorn/-/acorn-6.0.6.tgz", + "integrity": "sha512-5M3G/A4uBSMIlfJ+h9W125vJvPFH/zirISsW5qfxF5YzEvXJCtolLoQvM5yZft0DvMcUrPGKPOlgEu55I6iUtA==" } } }, @@ -3289,9 +3097,9 @@ } }, "ansi-escapes": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/ansi-escapes/-/ansi-escapes-3.1.0.tgz", - "integrity": "sha512-UgAb8H9D41AQnu/PbWlCofQVcnV4Gs2bBJi9eZPxfU/hgglFh3SMDMENRIqdr7H6XFnXdoknctFByVsCOotTVw==" + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/ansi-escapes/-/ansi-escapes-3.2.0.tgz", + "integrity": "sha512-cBhpre4ma+U0T1oM5fXg7Dy1Jw7zzwv7lt/GoCpr+hDQJoYnKVPLL4dCvSEFMmQurOQvSrwT7SL/DAlhBI97RQ==" }, "ansi-regex": { "version": "3.0.0", @@ -3873,29 +3681,6 @@ "postcss-value-parser": "^3.3.1" }, "dependencies": { - "browserslist": { - "version": "4.4.1", - "resolved": "https://registry.npmjs.org/browserslist/-/browserslist-4.4.1.tgz", - "integrity": "sha512-pEBxEXg7JwaakBXjATYw/D1YZh4QUSCX/Mnd/wnqSRPPSi1U39iDhDoKGoBUcraKdxDlrYqJxSI5nNvD+dWP2A==", - "dev": true, - "requires": { - "caniuse-lite": "^1.0.30000929", - "electron-to-chromium": "^1.3.103", - "node-releases": "^1.1.3" - } - }, - "caniuse-lite": { - "version": "1.0.30000932", - "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30000932.tgz", - "integrity": "sha512-4bghJFItvzz8m0T3lLZbacmEY9X1Z2AtIzTr7s7byqZIOumASfr4ynDx7rtm0J85nDmx8vsgR6vnaSoeU8Oh0A==", - "dev": true - }, - "electron-to-chromium": { - "version": "1.3.108", - "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.3.108.tgz", - "integrity": "sha512-/QI4hMpAh48a1Sea6PALGv+kuVne9A2EWGd8HrWHMdYhIzGtbhVVHh6heL5fAzGaDnZuPyrlWJRl8WPm4RyiQQ==", - "dev": true - }, "postcss": { "version": "7.0.14", "resolved": "https://registry.npmjs.org/postcss/-/postcss-7.0.14.tgz", @@ -3953,6 +3738,11 @@ "js-tokens": "^3.0.2" }, "dependencies": { + "ansi-regex": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-2.1.1.tgz", + "integrity": "sha1-w7M6te42DYbg5ijwRorn7yfWVN8=" + }, "ansi-styles": { "version": "2.2.1", "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-2.2.1.tgz", @@ -3975,6 +3765,14 @@ "resolved": "https://registry.npmjs.org/js-tokens/-/js-tokens-3.0.2.tgz", "integrity": "sha1-mGbfOVECEw449/mWvOtlRDIJwls=" }, + "strip-ansi": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-3.0.1.tgz", + "integrity": "sha1-ajhfuIU9lS1f8F0Oiq+UJ43GPc8=", + "requires": { + "ansi-regex": "^2.0.0" + } + }, "supports-color": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-2.0.0.tgz", @@ -4105,6 +3903,46 @@ "find-up": "^2.1.0", "istanbul-lib-instrument": "^1.10.1", "test-exclude": "^4.2.1" + }, + "dependencies": { + "find-up": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/find-up/-/find-up-2.1.0.tgz", + "integrity": "sha1-RdG35QbHF93UgndaK3eSCjwMV6c=", + "requires": { + "locate-path": "^2.0.0" + } + }, + "locate-path": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-2.0.0.tgz", + "integrity": "sha1-K1aLJl7slExtnA3pw9u7ygNUzY4=", + "requires": { + "p-locate": "^2.0.0", + "path-exists": "^3.0.0" + } + }, + "p-limit": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-1.3.0.tgz", + "integrity": "sha512-vvcXsLAJ9Dr5rQOPk7toZQZJApBl2K4J6dANSsEuh6QI41JYcsS/qhTGa9ErIUUgK3WNQoJYvylxvjqmiqEA9Q==", + "requires": { + "p-try": "^1.0.0" + } + }, + "p-locate": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-2.0.0.tgz", + "integrity": "sha1-IKAQOyIqcMj9OcwuWAaA893l7EM=", + "requires": { + "p-limit": "^1.1.0" + } + }, + "p-try": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/p-try/-/p-try-1.0.0.tgz", + "integrity": "sha1-y8ec26+P1CKOE/Yh8rGiN8GyB7M=" + } } }, "babel-plugin-jest-hoist": { @@ -4474,6 +4312,14 @@ "string-width": "^2.0.0", "term-size": "^1.2.0", "widest-line": "^2.0.0" + }, + "dependencies": { + "camelcase": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-4.1.0.tgz", + "integrity": "sha1-1UVjW+HjPFQmScaRc+Xeas+uNN0=", + "dev": true + } } }, "brace-expansion": { @@ -4603,12 +4449,12 @@ } }, "browserslist": { - "version": "4.4.0", - "resolved": "https://registry.npmjs.org/browserslist/-/browserslist-4.4.0.tgz", - "integrity": "sha512-tQkHS8VVxWbrjnNDXgt7/+SuPJ7qDvD0Y2e6bLtoQluR2SPvlmPUcfcU75L1KAalhqULlIFJlJ6BDfnYyJxJsw==", + "version": "4.4.1", + "resolved": "https://registry.npmjs.org/browserslist/-/browserslist-4.4.1.tgz", + "integrity": "sha512-pEBxEXg7JwaakBXjATYw/D1YZh4QUSCX/Mnd/wnqSRPPSi1U39iDhDoKGoBUcraKdxDlrYqJxSI5nNvD+dWP2A==", "requires": { - "caniuse-lite": "^1.0.30000928", - "electron-to-chromium": "^1.3.100", + "caniuse-lite": "^1.0.30000929", + "electron-to-chromium": "^1.3.103", "node-releases": "^1.1.3" } }, @@ -4703,14 +4549,6 @@ "ssri": "^5.2.4", "unique-filename": "^1.1.0", "y18n": "^4.0.0" - }, - "dependencies": { - "y18n": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/y18n/-/y18n-4.0.0.tgz", - "integrity": "sha512-r9S/ZyXu/Xu9q1tYlpsLIsa3EeLXXk0VwlxqTcFRfg9EhMW+17kbt9G0NrgCmhGb5vT2hyhJZLfDGx+7+5Uj/w==", - "dev": true - } } }, "cache-base": { @@ -4772,9 +4610,9 @@ "integrity": "sha1-BuuE8A7qQT2oav/vrL/7Ngk7PFA=" }, "camelcase": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-4.1.0.tgz", - "integrity": "sha1-1UVjW+HjPFQmScaRc+Xeas+uNN0=" + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-5.0.0.tgz", + "integrity": "sha512-faqwZqnWxbxn+F1d399ygeamQNy3lPp/H9H6rNrqYh4FSVCtcY+3cub1MxA8o9mDd55mM8Aghuu/kuyYA6VTsA==" }, "camelcase-keys": { "version": "4.2.0", @@ -4784,12 +4622,19 @@ "camelcase": "^4.1.0", "map-obj": "^2.0.0", "quick-lru": "^1.0.0" + }, + "dependencies": { + "camelcase": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-4.1.0.tgz", + "integrity": "sha1-1UVjW+HjPFQmScaRc+Xeas+uNN0=" + } } }, "caniuse-lite": { - "version": "1.0.30000928", - "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30000928.tgz", - "integrity": "sha512-aSpMWRXL6ZXNnzm8hgE4QDLibG5pVJ2Ujzsuj3icazlIkxXkPXtL+BWnMx6FBkWmkZgBHGUxPZQvrbRw2ZTxhg==" + "version": "1.0.30000932", + "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30000932.tgz", + "integrity": "sha512-4bghJFItvzz8m0T3lLZbacmEY9X1Z2AtIzTr7s7byqZIOumASfr4ynDx7rtm0J85nDmx8vsgR6vnaSoeU8Oh0A==" }, "capture-exit": { "version": "1.2.0", @@ -5078,6 +4923,16 @@ "restore-cursor": "^2.0.0" } }, + "cli-table3": { + "version": "0.5.1", + "resolved": "https://registry.npmjs.org/cli-table3/-/cli-table3-0.5.1.tgz", + "integrity": "sha512-7Qg2Jrep1S/+Q3EceiZtQcDPWxhAvBw+ERf1162v4sikJrvojMHFqXt8QIVha8UlH9rgU0BeWPytZ9/TzYqlUw==", + "requires": { + "colors": "^1.1.2", + "object-assign": "^4.1.0", + "string-width": "^2.1.1" + } + }, "cli-width": { "version": "2.2.0", "resolved": "https://registry.npmjs.org/cli-width/-/cli-width-2.2.0.tgz", @@ -5101,16 +4956,6 @@ "string-width": "^2.1.1", "strip-ansi": "^4.0.0", "wrap-ansi": "^2.0.0" - }, - "dependencies": { - "strip-ansi": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-4.0.0.tgz", - "integrity": "sha1-qEeQIusaw2iocTibY1JixQXuNo8=", - "requires": { - "ansi-regex": "^3.0.0" - } - } } }, "clone": { @@ -5232,19 +5077,32 @@ } }, "colors": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/colors/-/colors-1.1.2.tgz", - "integrity": "sha1-FopHAXVran9RoSzgyXv6KMCE7WM=", - "dev": true + "version": "1.3.3", + "resolved": "https://registry.npmjs.org/colors/-/colors-1.3.3.tgz", + "integrity": "sha512-mmGt/1pZqYRjMxB1axhTo16/snVZ5krrKkcmMeVKxzECMMXoCgnvTPp10QgHfcbQZw8Dq2jMNG6je4JlWU0gWg==" }, "columnify": { - "version": "1.5.4", - "resolved": "https://registry.npmjs.org/columnify/-/columnify-1.5.4.tgz", - "integrity": "sha1-Rzfd8ce2mop8NAVweC6UfuyOeLs=", - "dev": true, + "version": "1.5.1", + "resolved": "https://registry.npmjs.org/columnify/-/columnify-1.5.1.tgz", + "integrity": "sha1-Ff3agDo4dfh/nTArO8goky1mQAM=", "requires": { - "strip-ansi": "^3.0.0", + "strip-ansi": "^2.0.1", "wcwidth": "^1.0.0" + }, + "dependencies": { + "ansi-regex": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-1.1.1.tgz", + "integrity": "sha1-QchHGUZGN15qGl0Qw8oFTvn8mA0=" + }, + "strip-ansi": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-2.0.1.tgz", + "integrity": "sha1-32LBqpTtLxFOHQ8h/R1QSCt5pg4=", + "requires": { + "ansi-regex": "^1.0.0" + } + } } }, "combined-stream": { @@ -5359,135 +5217,12 @@ "yargs": "^12.0.1" }, "dependencies": { - "camelcase": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-5.0.0.tgz", - "integrity": "sha512-faqwZqnWxbxn+F1d399ygeamQNy3lPp/H9H6rNrqYh4FSVCtcY+3cub1MxA8o9mDd55mM8Aghuu/kuyYA6VTsA==", - "dev": true - }, - "cross-spawn": { - "version": "6.0.5", - "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-6.0.5.tgz", - "integrity": "sha512-eTVLrBSt7fjbDygz805pMnstIs2VTBNkRm0qxZd+M7A5XDdxVRWO5MxGBXZhjY4cqLYLdtrGqRf8mBPmzwSpWQ==", - "dev": true, - "requires": { - "nice-try": "^1.0.4", - "path-key": "^2.0.1", - "semver": "^5.5.0", - "shebang-command": "^1.2.0", - "which": "^1.2.9" - } - }, - "execa": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/execa/-/execa-1.0.0.tgz", - "integrity": "sha512-adbxcyWV46qiHyvSp50TKt05tB4tK3HcmF7/nxfAdhnox83seTDbwnaqKO4sXRy7roHAIFqJP/Rw/AuEbX61LA==", - "dev": true, - "requires": { - "cross-spawn": "^6.0.0", - "get-stream": "^4.0.0", - "is-stream": "^1.1.0", - "npm-run-path": "^2.0.0", - "p-finally": "^1.0.0", - "signal-exit": "^3.0.0", - "strip-eof": "^1.0.0" - } - }, - "find-up": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/find-up/-/find-up-3.0.0.tgz", - "integrity": "sha512-1yD6RmLI1XBfxugvORwlck6f75tYL+iR0jqwsOrOxMZyGYqUuDhJ0l4AXdO1iX/FTs9cBAMEk1gWSEx1kSbylg==", - "dev": true, - "requires": { - "locate-path": "^3.0.0" - } - }, - "get-stream": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/get-stream/-/get-stream-4.1.0.tgz", - "integrity": "sha512-GMat4EJ5161kIy2HevLlr4luNjBgvmj413KaQA7jt4V8B4RDsfpHk7WQ9GVqfYyyx8OS/L66Kox+rJRNklLK7w==", - "dev": true, - "requires": { - "pump": "^3.0.0" - } - }, "has-flag": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-2.0.0.tgz", "integrity": "sha1-6CB68cx7MNRGzHC3NLXovhj4jVE=", "dev": true }, - "invert-kv": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/invert-kv/-/invert-kv-2.0.0.tgz", - "integrity": "sha512-wPVv/y/QQ/Uiirj/vh3oP+1Ww+AWehmi1g5fFWGPF6IpCBCDVrhgHRMvrLfdYcwDh3QJbGXDW4JAuzxElLSqKA==", - "dev": true - }, - "lcid": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/lcid/-/lcid-2.0.0.tgz", - "integrity": "sha512-avPEb8P8EGnwXKClwsNUgryVjllcRqtMYa49NTsbQagYuT1DcXnl1915oxWjoyGrXR6zH/Y0Zc96xWsPcoDKeA==", - "dev": true, - "requires": { - "invert-kv": "^2.0.0" - } - }, - "locate-path": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-3.0.0.tgz", - "integrity": "sha512-7AO748wWnIhNqAuaty2ZWHkQHRSNfPVIsPIfwEOWO22AmaoVrWavlOcMR5nzTLNYvp36X220/maaRsrec1G65A==", - "dev": true, - "requires": { - "p-locate": "^3.0.0", - "path-exists": "^3.0.0" - } - }, - "mem": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/mem/-/mem-4.0.0.tgz", - "integrity": "sha512-WQxG/5xYc3tMbYLXoXPm81ET2WDULiU5FxbuIoNbJqLOOI8zehXFdZuiUEgfdrU2mVB1pxBZUGlYORSrpuJreA==", - "dev": true, - "requires": { - "map-age-cleaner": "^0.1.1", - "mimic-fn": "^1.0.0", - "p-is-promise": "^1.1.0" - } - }, - "os-locale": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/os-locale/-/os-locale-3.1.0.tgz", - "integrity": "sha512-Z8l3R4wYWM40/52Z+S265okfFj8Kt2cC2MKY+xNi3kFs+XGI7WXu/I309QQQYbRW4ijiZ+yxs9pqEhJh0DqW3Q==", - "dev": true, - "requires": { - "execa": "^1.0.0", - "lcid": "^2.0.0", - "mem": "^4.0.0" - } - }, - "p-limit": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-2.1.0.tgz", - "integrity": "sha512-NhURkNcrVB+8hNfLuysU8enY5xn2KXphsHBaC2YmRNTZRc7RWusw6apSpdEj3jo4CMb6W9nrF6tTnsJsJeyu6g==", - "dev": true, - "requires": { - "p-try": "^2.0.0" - } - }, - "p-locate": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-3.0.0.tgz", - "integrity": "sha512-x+12w/To+4GFfgJhBEpiDcLozRJGegY+Ei7/z0tSLkMmxGZNybVMSfWj9aJn8Z5Fc7dBUNJOOVgPv2H7IwulSQ==", - "dev": true, - "requires": { - "p-limit": "^2.0.0" - } - }, - "p-try": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/p-try/-/p-try-2.0.0.tgz", - "integrity": "sha512-hMp0onDKIajHfIkdRk3P4CdCmErkYAxxDtP3Wx/4nZ3aGlau2VKh3mZpcuFkH27WQkL/3WBCPOktzA9ZOAnMQQ==", - "dev": true - }, "parse-json": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/parse-json/-/parse-json-4.0.0.tgz", @@ -5523,36 +5258,6 @@ "requires": { "has-flag": "^2.0.0" } - }, - "yargs": { - "version": "12.0.5", - "resolved": "https://registry.npmjs.org/yargs/-/yargs-12.0.5.tgz", - "integrity": "sha512-Lhz8TLaYnxq/2ObqHDql8dX8CJi97oHxrjUcYtzKbbykPtVW9WB+poxI+NM2UIzsMgNCZTIf0AQwsjK5yMAqZw==", - "dev": true, - "requires": { - "cliui": "^4.0.0", - "decamelize": "^1.2.0", - "find-up": "^3.0.0", - "get-caller-file": "^1.0.1", - "os-locale": "^3.0.0", - "require-directory": "^2.1.1", - "require-main-filename": "^1.0.1", - "set-blocking": "^2.0.0", - "string-width": "^2.0.0", - "which-module": "^2.0.0", - "y18n": "^3.2.1 || ^4.0.0", - "yargs-parser": "^11.1.1" - } - }, - "yargs-parser": { - "version": "11.1.1", - "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-11.1.1.tgz", - "integrity": "sha512-C6kB/WJDiaxONLJQnF8ccx9SEeoTTLek8RVbaOIsrAUS8VrBEXfmeSnCZxygc+XC2sNMBIwOOnfcxiynjHsVSQ==", - "dev": true, - "requires": { - "camelcase": "^5.0.0", - "decamelize": "^1.2.0" - } } } }, @@ -5678,6 +5383,15 @@ "integrity": "sha512-jyCETtSl3VMZMWeRo7iY1FL19ges1t55hMo5yaam4Jrsm5EPL89UQkoQRyiI+Yf4k8r2ZpdngkV8hr1lIdjb3Q==", "dev": true }, + "find-up": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/find-up/-/find-up-2.1.0.tgz", + "integrity": "sha1-RdG35QbHF93UgndaK3eSCjwMV6c=", + "dev": true, + "requires": { + "locate-path": "^2.0.0" + } + }, "load-json-file": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/load-json-file/-/load-json-file-4.0.0.tgz", @@ -5690,6 +5404,40 @@ "strip-bom": "^3.0.0" } }, + "locate-path": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-2.0.0.tgz", + "integrity": "sha1-K1aLJl7slExtnA3pw9u7ygNUzY4=", + "dev": true, + "requires": { + "p-locate": "^2.0.0", + "path-exists": "^3.0.0" + } + }, + "p-limit": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-1.3.0.tgz", + "integrity": "sha512-vvcXsLAJ9Dr5rQOPk7toZQZJApBl2K4J6dANSsEuh6QI41JYcsS/qhTGa9ErIUUgK3WNQoJYvylxvjqmiqEA9Q==", + "dev": true, + "requires": { + "p-try": "^1.0.0" + } + }, + "p-locate": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-2.0.0.tgz", + "integrity": "sha1-IKAQOyIqcMj9OcwuWAaA893l7EM=", + "dev": true, + "requires": { + "p-limit": "^1.1.0" + } + }, + "p-try": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/p-try/-/p-try-1.0.0.tgz", + "integrity": "sha1-y8ec26+P1CKOE/Yh8rGiN8GyB7M=", + "dev": true + }, "parse-json": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/parse-json/-/parse-json-4.0.0.tgz", @@ -5774,6 +5522,15 @@ "integrity": "sha512-jyCETtSl3VMZMWeRo7iY1FL19ges1t55hMo5yaam4Jrsm5EPL89UQkoQRyiI+Yf4k8r2ZpdngkV8hr1lIdjb3Q==", "dev": true }, + "find-up": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/find-up/-/find-up-2.1.0.tgz", + "integrity": "sha1-RdG35QbHF93UgndaK3eSCjwMV6c=", + "dev": true, + "requires": { + "locate-path": "^2.0.0" + } + }, "load-json-file": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/load-json-file/-/load-json-file-4.0.0.tgz", @@ -5786,6 +5543,16 @@ "strip-bom": "^3.0.0" } }, + "locate-path": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-2.0.0.tgz", + "integrity": "sha1-K1aLJl7slExtnA3pw9u7ygNUzY4=", + "dev": true, + "requires": { + "p-locate": "^2.0.0", + "path-exists": "^3.0.0" + } + }, "meow": { "version": "4.0.1", "resolved": "https://registry.npmjs.org/meow/-/meow-4.0.1.tgz", @@ -5803,6 +5570,30 @@ "trim-newlines": "^2.0.0" } }, + "p-limit": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-1.3.0.tgz", + "integrity": "sha512-vvcXsLAJ9Dr5rQOPk7toZQZJApBl2K4J6dANSsEuh6QI41JYcsS/qhTGa9ErIUUgK3WNQoJYvylxvjqmiqEA9Q==", + "dev": true, + "requires": { + "p-try": "^1.0.0" + } + }, + "p-locate": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-2.0.0.tgz", + "integrity": "sha1-IKAQOyIqcMj9OcwuWAaA893l7EM=", + "dev": true, + "requires": { + "p-limit": "^1.1.0" + } + }, + "p-try": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/p-try/-/p-try-1.0.0.tgz", + "integrity": "sha1-y8ec26+P1CKOE/Yh8rGiN8GyB7M=", + "dev": true + }, "parse-json": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/parse-json/-/parse-json-4.0.0.tgz", @@ -5882,6 +5673,15 @@ "trim-off-newlines": "^1.0.0" }, "dependencies": { + "find-up": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/find-up/-/find-up-2.1.0.tgz", + "integrity": "sha1-RdG35QbHF93UgndaK3eSCjwMV6c=", + "dev": true, + "requires": { + "locate-path": "^2.0.0" + } + }, "load-json-file": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/load-json-file/-/load-json-file-4.0.0.tgz", @@ -5894,6 +5694,16 @@ "strip-bom": "^3.0.0" } }, + "locate-path": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-2.0.0.tgz", + "integrity": "sha1-K1aLJl7slExtnA3pw9u7ygNUzY4=", + "dev": true, + "requires": { + "p-locate": "^2.0.0", + "path-exists": "^3.0.0" + } + }, "meow": { "version": "4.0.1", "resolved": "https://registry.npmjs.org/meow/-/meow-4.0.1.tgz", @@ -5911,6 +5721,30 @@ "trim-newlines": "^2.0.0" } }, + "p-limit": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-1.3.0.tgz", + "integrity": "sha512-vvcXsLAJ9Dr5rQOPk7toZQZJApBl2K4J6dANSsEuh6QI41JYcsS/qhTGa9ErIUUgK3WNQoJYvylxvjqmiqEA9Q==", + "dev": true, + "requires": { + "p-try": "^1.0.0" + } + }, + "p-locate": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-2.0.0.tgz", + "integrity": "sha1-IKAQOyIqcMj9OcwuWAaA893l7EM=", + "dev": true, + "requires": { + "p-limit": "^1.1.0" + } + }, + "p-try": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/p-try/-/p-try-1.0.0.tgz", + "integrity": "sha1-y8ec26+P1CKOE/Yh8rGiN8GyB7M=", + "dev": true + }, "parse-json": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/parse-json/-/parse-json-4.0.0.tgz", @@ -5981,6 +5815,15 @@ "q": "^1.5.1" }, "dependencies": { + "find-up": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/find-up/-/find-up-2.1.0.tgz", + "integrity": "sha1-RdG35QbHF93UgndaK3eSCjwMV6c=", + "dev": true, + "requires": { + "locate-path": "^2.0.0" + } + }, "load-json-file": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/load-json-file/-/load-json-file-4.0.0.tgz", @@ -5993,6 +5836,16 @@ "strip-bom": "^3.0.0" } }, + "locate-path": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-2.0.0.tgz", + "integrity": "sha1-K1aLJl7slExtnA3pw9u7ygNUzY4=", + "dev": true, + "requires": { + "p-locate": "^2.0.0", + "path-exists": "^3.0.0" + } + }, "meow": { "version": "4.0.1", "resolved": "https://registry.npmjs.org/meow/-/meow-4.0.1.tgz", @@ -6010,6 +5863,30 @@ "trim-newlines": "^2.0.0" } }, + "p-limit": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-1.3.0.tgz", + "integrity": "sha512-vvcXsLAJ9Dr5rQOPk7toZQZJApBl2K4J6dANSsEuh6QI41JYcsS/qhTGa9ErIUUgK3WNQoJYvylxvjqmiqEA9Q==", + "dev": true, + "requires": { + "p-try": "^1.0.0" + } + }, + "p-locate": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-2.0.0.tgz", + "integrity": "sha1-IKAQOyIqcMj9OcwuWAaA893l7EM=", + "dev": true, + "requires": { + "p-limit": "^1.1.0" + } + }, + "p-try": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/p-try/-/p-try-1.0.0.tgz", + "integrity": "sha1-y8ec26+P1CKOE/Yh8rGiN8GyB7M=", + "dev": true + }, "parse-json": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/parse-json/-/parse-json-4.0.0.tgz", @@ -6132,6 +6009,21 @@ "requires": { "is-extglob": "^2.1.1" } + }, + "p-limit": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-1.3.0.tgz", + "integrity": "sha512-vvcXsLAJ9Dr5rQOPk7toZQZJApBl2K4J6dANSsEuh6QI41JYcsS/qhTGa9ErIUUgK3WNQoJYvylxvjqmiqEA9Q==", + "dev": true, + "requires": { + "p-try": "^1.0.0" + } + }, + "p-try": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/p-try/-/p-try-1.0.0.tgz", + "integrity": "sha1-y8ec26+P1CKOE/Yh8rGiN8GyB7M=", + "dev": true } } }, @@ -6370,9 +6262,9 @@ }, "dependencies": { "postcss": { - "version": "7.0.11", - "resolved": "https://registry.npmjs.org/postcss/-/postcss-7.0.11.tgz", - "integrity": "sha512-9AXb//5UcjeOEof9T+yPw3XTa5SL207ZOIC/lHYP4mbUTEh4M0rDAQekQpVANCZdwQwKhBtFZCk3i3h3h2hdWg==", + "version": "7.0.14", + "resolved": "https://registry.npmjs.org/postcss/-/postcss-7.0.14.tgz", + "integrity": "sha512-NsbD6XUUMZvBxtQAJuWDJeeC4QFsmWsfozWxCJPWf3M55K9iu2iMDaKqyoOdTJ1R4usBXuxlVFAIo8rZPQD4Bg==", "dev": true, "requires": { "chalk": "^2.4.2", @@ -6530,9 +6422,9 @@ "integrity": "sha512-q0cW1RpvA5c5ma2rch62mX8AYaiLX0+bdaSM2wxSU9tXjU4DNvkx9qiUvjkuWCj3p22UO/hlPivujqMiR9PDzA==" }, "d3-scale": { - "version": "2.1.2", - "resolved": "https://registry.npmjs.org/d3-scale/-/d3-scale-2.1.2.tgz", - "integrity": "sha512-bESpd64ylaKzCDzvULcmHKZTlzA/6DGSVwx7QSDj/EnX9cpSevsdiwdHFYI9ouo9tNBbV3v5xztHS2uFeOzh8Q==", + "version": "2.2.2", + "resolved": "https://registry.npmjs.org/d3-scale/-/d3-scale-2.2.2.tgz", + "integrity": "sha512-LbeEvGgIb8UMcAa0EATLNX0lelKWGYDQiPdHj+gLblGVhGLyNbaCn3EvrJf0A3Y/uOOU5aD6MTh5ZFCdEwGiCw==", "requires": { "d3-array": "^1.2.0", "d3-collection": "1", @@ -6559,14 +6451,14 @@ } }, "d3-selection": { - "version": "1.3.2", - "resolved": "https://registry.npmjs.org/d3-selection/-/d3-selection-1.3.2.tgz", - "integrity": "sha512-OoXdv1nZ7h2aKMVg3kaUFbLLK5jXUFAMLD/Tu5JA96mjf8f2a9ZUESGY+C36t8R1WFeWk/e55hy54Ml2I62CRQ==" + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/d3-selection/-/d3-selection-1.4.0.tgz", + "integrity": "sha512-EYVwBxQGEjLCKF2pJ4+yrErskDnz5v403qvAid96cNdCMr8rmCYfY5RGzWz24mdIbxmDf6/4EAH+K9xperD5jg==" }, "d3-shape": { - "version": "1.2.2", - "resolved": "https://registry.npmjs.org/d3-shape/-/d3-shape-1.2.2.tgz", - "integrity": "sha512-hUGEozlKecFZ2bOSNt7ENex+4Tk9uc/m0TtTEHBvitCBxUNjhzm5hS2GrrVRD/ae4IylSmxGeqX5tWC2rASMlQ==", + "version": "1.3.3", + "resolved": "https://registry.npmjs.org/d3-shape/-/d3-shape-1.3.3.tgz", + "integrity": "sha512-f7V9wHQCmv4s4N7EmD5i0mwJ5y09L8r1rWVrzH1Av0YfgBKJCnTJGho76rS4HNUIw6tTBbWfFcs4ntP/MKWF4A==", "requires": { "d3-path": "1" } @@ -6979,9 +6871,9 @@ } }, "dir-glob": { - "version": "2.2.1", - "resolved": "https://registry.npmjs.org/dir-glob/-/dir-glob-2.2.1.tgz", - "integrity": "sha512-UN6X6XwRjllabfRhBdkVSo63uurJ8nSvMGrwl94EYVz6g+exhTV+yVSYk5VC/xl3MBFBTtC0J20uFKce4Brrng==", + "version": "2.2.2", + "resolved": "https://registry.npmjs.org/dir-glob/-/dir-glob-2.2.2.tgz", + "integrity": "sha512-f9LBi5QWzIW3I6e//uxZoLBlUt9kcp66qo0sSCxL6YZKc75R1c4MFCoe/LaZiBGmgujvQdxc5Bn3QhfyvK5Hsw==", "dev": true, "requires": { "path-type": "^3.0.0" @@ -7059,6 +6951,12 @@ "yargs": "^7.0.2" }, "dependencies": { + "ansi-regex": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-2.1.1.tgz", + "integrity": "sha1-w7M6te42DYbg5ijwRorn7yfWVN8=", + "dev": true + }, "ansi-styles": { "version": "2.2.1", "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-2.2.1.tgz", @@ -7095,6 +6993,12 @@ "wrap-ansi": "^2.0.0" } }, + "invert-kv": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/invert-kv/-/invert-kv-1.0.0.tgz", + "integrity": "sha1-EEqOSqym09jNFXqO+L+rLXo//bY=", + "dev": true + }, "is-fullwidth-code-point": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-1.0.0.tgz", @@ -7104,6 +7008,15 @@ "number-is-nan": "^1.0.0" } }, + "lcid": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/lcid/-/lcid-1.0.0.tgz", + "integrity": "sha1-MIrMr6C8SDo4Z7S28rlQYlHRuDU=", + "dev": true, + "requires": { + "invert-kv": "^1.0.0" + } + }, "os-locale": { "version": "1.4.0", "resolved": "https://registry.npmjs.org/os-locale/-/os-locale-1.4.0.tgz", @@ -7124,6 +7037,15 @@ "strip-ansi": "^3.0.0" } }, + "strip-ansi": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-3.0.1.tgz", + "integrity": "sha1-ajhfuIU9lS1f8F0Oiq+UJ43GPc8=", + "dev": true, + "requires": { + "ansi-regex": "^2.0.0" + } + }, "supports-color": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-2.0.0.tgz", @@ -7136,6 +7058,12 @@ "integrity": "sha1-u6Y8qGGUiZT/MHc2CJ47lgJsKk8=", "dev": true }, + "y18n": { + "version": "3.2.1", + "resolved": "https://registry.npmjs.org/y18n/-/y18n-3.2.1.tgz", + "integrity": "sha1-bRX7qITAhnnA136I53WegR4H+kE=", + "dev": true + }, "yargs": { "version": "7.1.0", "resolved": "https://registry.npmjs.org/yargs/-/yargs-7.1.0.tgz", @@ -7389,9 +7317,9 @@ "dev": true }, "electron-to-chromium": { - "version": "1.3.102", - "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.3.102.tgz", - "integrity": "sha512-2nzZuXw/KBPnI3QX3UOCSRvJiVy7o9+VHRDQ3D/EHCvVc89X6aj/GlNmEgiR2GBIhmSWXIi4W1M5okA5ScSlNg==" + "version": "1.3.109", + "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.3.109.tgz", + "integrity": "sha512-1qhgVZD9KIULMyeBkbjU/dWmm30zpPUfdWZfVO3nPhbtqMHJqHr4Ua5wBcWtAymVFrUCuAJxjMF1OhG+bR21Ow==" }, "elliptic": { "version": "6.4.1", @@ -7415,36 +7343,12 @@ "requires": { "columnify": "1.5.1", "lodash.find": "3.2.1" - }, - "dependencies": { - "ansi-regex": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-1.1.1.tgz", - "integrity": "sha1-QchHGUZGN15qGl0Qw8oFTvn8mA0=" - }, - "columnify": { - "version": "1.5.1", - "resolved": "https://registry.npmjs.org/columnify/-/columnify-1.5.1.tgz", - "integrity": "sha1-Ff3agDo4dfh/nTArO8goky1mQAM=", - "requires": { - "strip-ansi": "^2.0.1", - "wcwidth": "^1.0.0" - } - }, - "strip-ansi": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-2.0.1.tgz", - "integrity": "sha1-32LBqpTtLxFOHQ8h/R1QSCt5pg4=", - "requires": { - "ansi-regex": "^1.0.0" - } - } } }, "emoji-regex": { - "version": "6.5.1", - "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-6.5.1.tgz", - "integrity": "sha512-PAHp6TxrCy7MGMFidro8uikr+zlJJKJ/Q6mm2ExZ7HwkyR9lSVFfE3kt36qcwa24BQL7y0G9axycGjK1A/0uNQ==", + "version": "7.0.3", + "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-7.0.3.tgz", + "integrity": "sha512-CwBLREIQ7LvYFB0WyRvwhq5N5qPhc6PMjD6bYggFlI5YyDgl+0vxq5VHbMOFqLg7hfWzmu8T5Z1QofhmTIhItA==", "dev": true }, "emojis-list": { @@ -7471,7 +7375,6 @@ "version": "1.4.1", "resolved": "https://registry.npmjs.org/end-of-stream/-/end-of-stream-1.4.1.tgz", "integrity": "sha512-1MkrZNvWTKCaigbn+W15elq2BB/L22nqrSY5DKlo3X6+vclJm8Bb5djXJBmEX6fS3+zCh/F4VBK5Z2KxJt4s2Q==", - "dev": true, "requires": { "once": "^1.4.0" } @@ -7519,26 +7422,27 @@ } }, "enzyme-adapter-react-16": { - "version": "1.7.1", - "resolved": "https://registry.npmjs.org/enzyme-adapter-react-16/-/enzyme-adapter-react-16-1.7.1.tgz", - "integrity": "sha512-OQXKgfHWyHN3sFu2nKj3mhgRcqIPIJX6aOzq5AHVFES4R9Dw/vCBZFMPyaG81g2AZ5DogVh39P3MMNUbqNLTcw==", + "version": "1.8.0", + "resolved": "https://registry.npmjs.org/enzyme-adapter-react-16/-/enzyme-adapter-react-16-1.8.0.tgz", + "integrity": "sha512-7cVHIKutqnesGeM3CjNFHSvktpypSWBokrBO8wIW+BVx+HGxWCF87W9TpkIIYJqgCtdw9FQGFrAbLg8kSwPRuQ==", "requires": { - "enzyme-adapter-utils": "^1.9.0", + "enzyme-adapter-utils": "^1.10.0", "function.prototype.name": "^1.1.0", "object.assign": "^4.1.0", - "object.values": "^1.0.4", + "object.values": "^1.1.0", "prop-types": "^15.6.2", - "react-is": "^16.6.1", + "react-is": "^16.7.0", "react-test-renderer": "^16.0.0-0" } }, "enzyme-adapter-utils": { - "version": "1.9.1", - "resolved": "https://registry.npmjs.org/enzyme-adapter-utils/-/enzyme-adapter-utils-1.9.1.tgz", - "integrity": "sha512-LWc88BbKztLXlpRf5Ba/pSMJRaNezAwZBvis3N/IuB65ltZEh2E2obWU9B36pAbw7rORYeBUuqc79OL17ZzN1A==", + "version": "1.10.0", + "resolved": "https://registry.npmjs.org/enzyme-adapter-utils/-/enzyme-adapter-utils-1.10.0.tgz", + "integrity": "sha512-VnIXJDYVTzKGbdW+lgK8MQmYHJquTQZiGzu/AseCZ7eHtOMAj4Rtvk8ZRopodkfPves0EXaHkXBDkVhPa3t0jA==", "requires": { "function.prototype.name": "^1.1.0", "object.assign": "^4.1.0", + "object.fromentries": "^2.0.0", "prop-types": "^15.6.2", "semver": "^5.6.0" } @@ -7826,23 +7730,6 @@ "is-fullwidth-code-point": "^2.0.0" } }, - "strip-ansi": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-4.0.0.tgz", - "integrity": "sha1-qEeQIusaw2iocTibY1JixQXuNo8=", - "dev": true, - "requires": { - "ansi-regex": "^3.0.0" - }, - "dependencies": { - "ansi-regex": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-3.0.0.tgz", - "integrity": "sha1-7QMXwyIGT3lGbAKWa922Bas32Zg=", - "dev": true - } - } - }, "table": { "version": "5.2.2", "resolved": "https://registry.npmjs.org/table/-/table-5.2.2.tgz", @@ -7896,14 +7783,6 @@ "emoji-regex": "^7.0.2", "has": "^1.0.3", "jsx-ast-utils": "^2.0.1" - }, - "dependencies": { - "emoji-regex": { - "version": "7.0.3", - "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-7.0.3.tgz", - "integrity": "sha512-CwBLREIQ7LvYFB0WyRvwhq5N5qPhc6PMjD6bYggFlI5YyDgl+0vxq5VHbMOFqLg7hfWzmu8T5Z1QofhmTIhItA==", - "dev": true - } } }, "eslint-plugin-react": { @@ -8003,9 +7882,9 @@ "dev": true }, "events": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/events/-/events-1.1.1.tgz", - "integrity": "sha1-nr23Y1rQmccNzEwqH1AEKI6L2SQ=", + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/events/-/events-3.0.0.tgz", + "integrity": "sha512-Dc381HFWJzEOhQ+d8pkNon++bk9h6cdAoAj4iE6Q4y6xgTzySWXlKn05/TVNpjnfRqi/X0EpJEJohPjNI3zpVA==", "dev": true }, "evp_bytestokey": { @@ -8027,17 +7906,31 @@ } }, "execa": { - "version": "0.7.0", - "resolved": "https://registry.npmjs.org/execa/-/execa-0.7.0.tgz", - "integrity": "sha1-lEvs00zEHuMqY6n68nrVpl/Fl3c=", + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/execa/-/execa-1.0.0.tgz", + "integrity": "sha512-adbxcyWV46qiHyvSp50TKt05tB4tK3HcmF7/nxfAdhnox83seTDbwnaqKO4sXRy7roHAIFqJP/Rw/AuEbX61LA==", "requires": { - "cross-spawn": "^5.0.1", - "get-stream": "^3.0.0", + "cross-spawn": "^6.0.0", + "get-stream": "^4.0.0", "is-stream": "^1.1.0", "npm-run-path": "^2.0.0", "p-finally": "^1.0.0", "signal-exit": "^3.0.0", "strip-eof": "^1.0.0" + }, + "dependencies": { + "cross-spawn": { + "version": "6.0.5", + "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-6.0.5.tgz", + "integrity": "sha512-eTVLrBSt7fjbDygz805pMnstIs2VTBNkRm0qxZd+M7A5XDdxVRWO5MxGBXZhjY4cqLYLdtrGqRf8mBPmzwSpWQ==", + "requires": { + "nice-try": "^1.0.4", + "path-key": "^2.0.1", + "semver": "^5.5.0", + "shebang-command": "^1.2.0", + "which": "^1.2.9" + } + } } }, "execall": { @@ -8651,49 +8544,6 @@ "pkg-dir": "^3.0.0" }, "dependencies": { - "find-up": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/find-up/-/find-up-3.0.0.tgz", - "integrity": "sha512-1yD6RmLI1XBfxugvORwlck6f75tYL+iR0jqwsOrOxMZyGYqUuDhJ0l4AXdO1iX/FTs9cBAMEk1gWSEx1kSbylg==", - "dev": true, - "requires": { - "locate-path": "^3.0.0" - } - }, - "locate-path": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-3.0.0.tgz", - "integrity": "sha512-7AO748wWnIhNqAuaty2ZWHkQHRSNfPVIsPIfwEOWO22AmaoVrWavlOcMR5nzTLNYvp36X220/maaRsrec1G65A==", - "dev": true, - "requires": { - "p-locate": "^3.0.0", - "path-exists": "^3.0.0" - } - }, - "p-limit": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-2.1.0.tgz", - "integrity": "sha512-NhURkNcrVB+8hNfLuysU8enY5xn2KXphsHBaC2YmRNTZRc7RWusw6apSpdEj3jo4CMb6W9nrF6tTnsJsJeyu6g==", - "dev": true, - "requires": { - "p-try": "^2.0.0" - } - }, - "p-locate": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-3.0.0.tgz", - "integrity": "sha512-x+12w/To+4GFfgJhBEpiDcLozRJGegY+Ei7/z0tSLkMmxGZNybVMSfWj9aJn8Z5Fc7dBUNJOOVgPv2H7IwulSQ==", - "dev": true, - "requires": { - "p-limit": "^2.0.0" - } - }, - "p-try": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/p-try/-/p-try-2.0.0.tgz", - "integrity": "sha512-hMp0onDKIajHfIkdRk3P4CdCmErkYAxxDtP3Wx/4nZ3aGlau2VKh3mZpcuFkH27WQkL/3WBCPOktzA9ZOAnMQQ==", - "dev": true - }, "pkg-dir": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/pkg-dir/-/pkg-dir-3.0.0.tgz", @@ -8717,11 +8567,11 @@ "integrity": "sha1-M8RLQpqysvBkYpnF+fcY83b/jVQ=" }, "find-up": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/find-up/-/find-up-2.1.0.tgz", - "integrity": "sha1-RdG35QbHF93UgndaK3eSCjwMV6c=", + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/find-up/-/find-up-3.0.0.tgz", + "integrity": "sha512-1yD6RmLI1XBfxugvORwlck6f75tYL+iR0jqwsOrOxMZyGYqUuDhJ0l4AXdO1iX/FTs9cBAMEk1gWSEx1kSbylg==", "requires": { - "locate-path": "^2.0.0" + "locate-path": "^3.0.0" } }, "findup": { @@ -9005,9 +8855,9 @@ "integrity": "sha1-FQStJSMVjKpA20onh8sBQRmU6k8=" }, "fsevents": { - "version": "1.2.4", - "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-1.2.4.tgz", - "integrity": "sha512-z8H8/diyk76B7q5wg+Ud0+CqzcAF3mBBI/bA5ne5zrRUUIvNkJY//D3BqyH571KuAC4Nr7Rw7CjWX4r0y9DvNg==", + "version": "1.2.7", + "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-1.2.7.tgz", + "integrity": "sha512-Pxm6sI2MeBD7RdD12RYsqaP0nMiwx8eZBXCa6z2L+mRHm2DYrOYwihmhjpkdjUHwQhslWQjRpEgNq4XvBmaAuw==", "optional": true, "requires": { "nan": "^2.9.2", @@ -9030,7 +8880,7 @@ "optional": true }, "are-we-there-yet": { - "version": "1.1.4", + "version": "1.1.5", "bundled": true, "optional": true, "requires": { @@ -9053,7 +8903,7 @@ } }, "chownr": { - "version": "1.0.1", + "version": "1.1.1", "bundled": true, "optional": true }, @@ -9086,7 +8936,7 @@ } }, "deep-extend": { - "version": "0.5.1", + "version": "0.6.0", "bundled": true, "optional": true }, @@ -9129,7 +8979,7 @@ } }, "glob": { - "version": "7.1.2", + "version": "7.1.3", "bundled": true, "optional": true, "requires": { @@ -9147,11 +8997,11 @@ "optional": true }, "iconv-lite": { - "version": "0.4.21", + "version": "0.4.24", "bundled": true, "optional": true, "requires": { - "safer-buffer": "^2.1.0" + "safer-buffer": ">= 2.1.2 < 3" } }, "ignore-walk": { @@ -9208,16 +9058,16 @@ "optional": true }, "minipass": { - "version": "2.2.4", + "version": "2.3.5", "bundled": true, "optional": true, "requires": { - "safe-buffer": "^5.1.1", + "safe-buffer": "^5.1.2", "yallist": "^3.0.0" } }, "minizlib": { - "version": "1.1.0", + "version": "1.2.1", "bundled": true, "optional": true, "requires": { @@ -9238,7 +9088,7 @@ "optional": true }, "needle": { - "version": "2.2.0", + "version": "2.2.4", "bundled": true, "optional": true, "requires": { @@ -9248,17 +9098,17 @@ } }, "node-pre-gyp": { - "version": "0.10.0", + "version": "0.10.3", "bundled": true, "optional": true, "requires": { "detect-libc": "^1.0.2", "mkdirp": "^0.5.1", - "needle": "^2.2.0", + "needle": "^2.2.1", "nopt": "^4.0.1", "npm-packlist": "^1.1.6", "npmlog": "^4.0.2", - "rc": "^1.1.7", + "rc": "^1.2.7", "rimraf": "^2.6.1", "semver": "^5.3.0", "tar": "^4" @@ -9274,12 +9124,12 @@ } }, "npm-bundled": { - "version": "1.0.3", + "version": "1.0.5", "bundled": true, "optional": true }, "npm-packlist": { - "version": "1.1.10", + "version": "1.2.0", "bundled": true, "optional": true, "requires": { @@ -9346,11 +9196,11 @@ "optional": true }, "rc": { - "version": "1.2.7", + "version": "1.2.8", "bundled": true, "optional": true, "requires": { - "deep-extend": "^0.5.1", + "deep-extend": "^0.6.0", "ini": "~1.3.0", "minimist": "^1.2.0", "strip-json-comments": "~2.0.1" @@ -9378,15 +9228,15 @@ } }, "rimraf": { - "version": "2.6.2", + "version": "2.6.3", "bundled": true, "optional": true, "requires": { - "glob": "^7.0.5" + "glob": "^7.1.3" } }, "safe-buffer": { - "version": "5.1.1", + "version": "5.1.2", "bundled": true, "optional": true }, @@ -9401,7 +9251,7 @@ "optional": true }, "semver": { - "version": "5.5.0", + "version": "5.6.0", "bundled": true, "optional": true }, @@ -9447,16 +9297,16 @@ "optional": true }, "tar": { - "version": "4.4.1", + "version": "4.4.8", "bundled": true, "optional": true, "requires": { - "chownr": "^1.0.1", + "chownr": "^1.1.1", "fs-minipass": "^1.2.5", - "minipass": "^2.2.4", - "minizlib": "^1.1.0", + "minipass": "^2.3.4", + "minizlib": "^1.1.1", "mkdirp": "^0.5.0", - "safe-buffer": "^5.1.1", + "safe-buffer": "^5.1.2", "yallist": "^3.0.2" } }, @@ -9466,11 +9316,11 @@ "optional": true }, "wide-align": { - "version": "1.1.2", + "version": "1.1.3", "bundled": true, "optional": true, "requires": { - "string-width": "^1.0.2" + "string-width": "^1.0.2 || 2" } }, "wrappy": { @@ -9479,7 +9329,7 @@ "optional": true }, "yallist": { - "version": "3.0.2", + "version": "3.0.3", "bundled": true, "optional": true } @@ -9533,6 +9383,12 @@ "wide-align": "^1.1.0" }, "dependencies": { + "ansi-regex": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-2.1.1.tgz", + "integrity": "sha1-w7M6te42DYbg5ijwRorn7yfWVN8=", + "dev": true + }, "is-fullwidth-code-point": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-1.0.0.tgz", @@ -9552,6 +9408,15 @@ "is-fullwidth-code-point": "^1.0.0", "strip-ansi": "^3.0.0" } + }, + "strip-ansi": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-3.0.1.tgz", + "integrity": "sha1-ajhfuIU9lS1f8F0Oiq+UJ43GPc8=", + "dev": true, + "requires": { + "ansi-regex": "^2.0.0" + } } } }, @@ -9693,9 +9558,12 @@ "dev": true }, "get-stream": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/get-stream/-/get-stream-3.0.0.tgz", - "integrity": "sha1-jpQ9E1jcN1VQVOy+LtsFqhdO3hQ=" + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/get-stream/-/get-stream-4.1.0.tgz", + "integrity": "sha512-GMat4EJ5161kIy2HevLlr4luNjBgvmj413KaQA7jt4V8B4RDsfpHk7WQ9GVqfYyyx8OS/L66Kox+rJRNklLK7w==", + "requires": { + "pump": "^3.0.0" + } }, "get-value": { "version": "2.0.6", @@ -9751,6 +9619,15 @@ "through2": "^2.0.0" }, "dependencies": { + "find-up": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/find-up/-/find-up-2.1.0.tgz", + "integrity": "sha1-RdG35QbHF93UgndaK3eSCjwMV6c=", + "dev": true, + "requires": { + "locate-path": "^2.0.0" + } + }, "load-json-file": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/load-json-file/-/load-json-file-4.0.0.tgz", @@ -9763,6 +9640,16 @@ "strip-bom": "^3.0.0" } }, + "locate-path": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-2.0.0.tgz", + "integrity": "sha1-K1aLJl7slExtnA3pw9u7ygNUzY4=", + "dev": true, + "requires": { + "p-locate": "^2.0.0", + "path-exists": "^3.0.0" + } + }, "meow": { "version": "4.0.1", "resolved": "https://registry.npmjs.org/meow/-/meow-4.0.1.tgz", @@ -9780,6 +9667,30 @@ "trim-newlines": "^2.0.0" } }, + "p-limit": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-1.3.0.tgz", + "integrity": "sha512-vvcXsLAJ9Dr5rQOPk7toZQZJApBl2K4J6dANSsEuh6QI41JYcsS/qhTGa9ErIUUgK3WNQoJYvylxvjqmiqEA9Q==", + "dev": true, + "requires": { + "p-try": "^1.0.0" + } + }, + "p-locate": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-2.0.0.tgz", + "integrity": "sha1-IKAQOyIqcMj9OcwuWAaA893l7EM=", + "dev": true, + "requires": { + "p-limit": "^1.1.0" + } + }, + "p-try": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/p-try/-/p-try-1.0.0.tgz", + "integrity": "sha1-y8ec26+P1CKOE/Yh8rGiN8GyB7M=", + "dev": true + }, "parse-json": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/parse-json/-/parse-json-4.0.0.tgz", @@ -9854,6 +9765,15 @@ "semver": "^5.5.0" }, "dependencies": { + "find-up": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/find-up/-/find-up-2.1.0.tgz", + "integrity": "sha1-RdG35QbHF93UgndaK3eSCjwMV6c=", + "dev": true, + "requires": { + "locate-path": "^2.0.0" + } + }, "load-json-file": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/load-json-file/-/load-json-file-4.0.0.tgz", @@ -9866,6 +9786,16 @@ "strip-bom": "^3.0.0" } }, + "locate-path": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-2.0.0.tgz", + "integrity": "sha1-K1aLJl7slExtnA3pw9u7ygNUzY4=", + "dev": true, + "requires": { + "p-locate": "^2.0.0", + "path-exists": "^3.0.0" + } + }, "meow": { "version": "4.0.1", "resolved": "https://registry.npmjs.org/meow/-/meow-4.0.1.tgz", @@ -9883,6 +9813,30 @@ "trim-newlines": "^2.0.0" } }, + "p-limit": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-1.3.0.tgz", + "integrity": "sha512-vvcXsLAJ9Dr5rQOPk7toZQZJApBl2K4J6dANSsEuh6QI41JYcsS/qhTGa9ErIUUgK3WNQoJYvylxvjqmiqEA9Q==", + "dev": true, + "requires": { + "p-try": "^1.0.0" + } + }, + "p-locate": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-2.0.0.tgz", + "integrity": "sha1-IKAQOyIqcMj9OcwuWAaA893l7EM=", + "dev": true, + "requires": { + "p-limit": "^1.1.0" + } + }, + "p-try": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/p-try/-/p-try-1.0.0.tgz", + "integrity": "sha1-y8ec26+P1CKOE/Yh8rGiN8GyB7M=", + "dev": true + }, "parse-json": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/parse-json/-/parse-json-4.0.0.tgz", @@ -10116,6 +10070,14 @@ "timed-out": "^4.0.0", "unzip-response": "^2.0.1", "url-parse-lax": "^1.0.0" + }, + "dependencies": { + "get-stream": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/get-stream/-/get-stream-3.0.0.tgz", + "integrity": "sha1-jpQ9E1jcN1VQVOy+LtsFqhdO3hQ=", + "dev": true + } } }, "graceful-fs": { @@ -10264,6 +10226,14 @@ "grunt-legacy-log-utils": "~2.0.0", "hooker": "~0.2.3", "lodash": "~4.17.5" + }, + "dependencies": { + "colors": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/colors/-/colors-1.1.2.tgz", + "integrity": "sha1-FopHAXVran9RoSzgyXv6KMCE7WM=", + "dev": true + } } }, "grunt-legacy-log-utils": { @@ -10684,58 +10654,12 @@ "integrity": "sha512-5tK7EtrZ0N+OLFMthtqOj4fI2Jeb88C4CAZPu25LDVUgXJ0A3Js4PMGqrn0JU1W0Mh1/Z8wZzYPxqUrXeBboCQ==", "dev": true }, - "cross-spawn": { - "version": "6.0.5", - "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-6.0.5.tgz", - "integrity": "sha512-eTVLrBSt7fjbDygz805pMnstIs2VTBNkRm0qxZd+M7A5XDdxVRWO5MxGBXZhjY4cqLYLdtrGqRf8mBPmzwSpWQ==", - "dev": true, - "requires": { - "nice-try": "^1.0.4", - "path-key": "^2.0.1", - "semver": "^5.5.0", - "shebang-command": "^1.2.0", - "which": "^1.2.9" - } - }, - "execa": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/execa/-/execa-1.0.0.tgz", - "integrity": "sha512-adbxcyWV46qiHyvSp50TKt05tB4tK3HcmF7/nxfAdhnox83seTDbwnaqKO4sXRy7roHAIFqJP/Rw/AuEbX61LA==", - "dev": true, - "requires": { - "cross-spawn": "^6.0.0", - "get-stream": "^4.0.0", - "is-stream": "^1.1.0", - "npm-run-path": "^2.0.0", - "p-finally": "^1.0.0", - "signal-exit": "^3.0.0", - "strip-eof": "^1.0.0" - } - }, - "find-up": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/find-up/-/find-up-3.0.0.tgz", - "integrity": "sha512-1yD6RmLI1XBfxugvORwlck6f75tYL+iR0jqwsOrOxMZyGYqUuDhJ0l4AXdO1iX/FTs9cBAMEk1gWSEx1kSbylg==", - "dev": true, - "requires": { - "locate-path": "^3.0.0" - } - }, "get-stdin": { "version": "6.0.0", "resolved": "https://registry.npmjs.org/get-stdin/-/get-stdin-6.0.0.tgz", "integrity": "sha512-jp4tHawyV7+fkkSKyvjuLZswblUtz+SQKzSWnBbii16BuZksJlU1wuBYXY75r+duh/llF1ur6oNwi+2ZzjKZ7g==", "dev": true }, - "get-stream": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/get-stream/-/get-stream-4.1.0.tgz", - "integrity": "sha512-GMat4EJ5161kIy2HevLlr4luNjBgvmj413KaQA7jt4V8B4RDsfpHk7WQ9GVqfYyyx8OS/L66Kox+rJRNklLK7w==", - "dev": true, - "requires": { - "pump": "^3.0.0" - } - }, "is-ci": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/is-ci/-/is-ci-2.0.0.tgz", @@ -10745,40 +10669,6 @@ "ci-info": "^2.0.0" } }, - "locate-path": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-3.0.0.tgz", - "integrity": "sha512-7AO748wWnIhNqAuaty2ZWHkQHRSNfPVIsPIfwEOWO22AmaoVrWavlOcMR5nzTLNYvp36X220/maaRsrec1G65A==", - "dev": true, - "requires": { - "p-locate": "^3.0.0", - "path-exists": "^3.0.0" - } - }, - "p-limit": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-2.1.0.tgz", - "integrity": "sha512-NhURkNcrVB+8hNfLuysU8enY5xn2KXphsHBaC2YmRNTZRc7RWusw6apSpdEj3jo4CMb6W9nrF6tTnsJsJeyu6g==", - "dev": true, - "requires": { - "p-try": "^2.0.0" - } - }, - "p-locate": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-3.0.0.tgz", - "integrity": "sha512-x+12w/To+4GFfgJhBEpiDcLozRJGegY+Ei7/z0tSLkMmxGZNybVMSfWj9aJn8Z5Fc7dBUNJOOVgPv2H7IwulSQ==", - "dev": true, - "requires": { - "p-limit": "^2.0.0" - } - }, - "p-try": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/p-try/-/p-try-2.0.0.tgz", - "integrity": "sha512-hMp0onDKIajHfIkdRk3P4CdCmErkYAxxDtP3Wx/4nZ3aGlau2VKh3mZpcuFkH27WQkL/3WBCPOktzA9ZOAnMQQ==", - "dev": true - }, "parse-json": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/parse-json/-/parse-json-4.0.0.tgz", @@ -10847,9 +10737,9 @@ }, "dependencies": { "postcss": { - "version": "7.0.11", - "resolved": "https://registry.npmjs.org/postcss/-/postcss-7.0.11.tgz", - "integrity": "sha512-9AXb//5UcjeOEof9T+yPw3XTa5SL207ZOIC/lHYP4mbUTEh4M0rDAQekQpVANCZdwQwKhBtFZCk3i3h3h2hdWg==", + "version": "7.0.14", + "resolved": "https://registry.npmjs.org/postcss/-/postcss-7.0.14.tgz", + "integrity": "sha512-NsbD6XUUMZvBxtQAJuWDJeeC4QFsmWsfozWxCJPWf3M55K9iu2iMDaKqyoOdTJ1R4usBXuxlVFAIo8rZPQD4Bg==", "dev": true, "requires": { "chalk": "^2.4.2", @@ -11042,16 +10932,6 @@ "string-width": "^2.1.0", "strip-ansi": "^4.0.0", "through": "^2.3.6" - }, - "dependencies": { - "strip-ansi": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-4.0.0.tgz", - "integrity": "sha1-qEeQIusaw2iocTibY1JixQXuNo8=", - "requires": { - "ansi-regex": "^3.0.0" - } - } } }, "interpolate-components": { @@ -11079,9 +10959,9 @@ } }, "invert-kv": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/invert-kv/-/invert-kv-1.0.0.tgz", - "integrity": "sha1-EEqOSqym09jNFXqO+L+rLXo//bY=" + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/invert-kv/-/invert-kv-2.0.0.tgz", + "integrity": "sha512-wPVv/y/QQ/Uiirj/vh3oP+1Ww+AWehmi1g5fFWGPF6IpCBCDVrhgHRMvrLfdYcwDh3QJbGXDW4JAuzxElLSqKA==" }, "ip": { "version": "1.1.5", @@ -11618,6 +11498,43 @@ "jest-cli": "^23.6.0" }, "dependencies": { + "camelcase": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-4.1.0.tgz", + "integrity": "sha1-1UVjW+HjPFQmScaRc+Xeas+uNN0=" + }, + "execa": { + "version": "0.7.0", + "resolved": "https://registry.npmjs.org/execa/-/execa-0.7.0.tgz", + "integrity": "sha1-lEvs00zEHuMqY6n68nrVpl/Fl3c=", + "requires": { + "cross-spawn": "^5.0.1", + "get-stream": "^3.0.0", + "is-stream": "^1.1.0", + "npm-run-path": "^2.0.0", + "p-finally": "^1.0.0", + "signal-exit": "^3.0.0", + "strip-eof": "^1.0.0" + } + }, + "find-up": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/find-up/-/find-up-2.1.0.tgz", + "integrity": "sha1-RdG35QbHF93UgndaK3eSCjwMV6c=", + "requires": { + "locate-path": "^2.0.0" + } + }, + "get-stream": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/get-stream/-/get-stream-3.0.0.tgz", + "integrity": "sha1-jpQ9E1jcN1VQVOy+LtsFqhdO3hQ=" + }, + "invert-kv": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/invert-kv/-/invert-kv-1.0.0.tgz", + "integrity": "sha1-EEqOSqym09jNFXqO+L+rLXo//bY=" + }, "jest-cli": { "version": "23.6.0", "resolved": "https://registry.npmjs.org/jest-cli/-/jest-cli-23.6.0.tgz", @@ -11703,6 +11620,62 @@ "source-map": "^0.6.0" } }, + "lcid": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/lcid/-/lcid-1.0.0.tgz", + "integrity": "sha1-MIrMr6C8SDo4Z7S28rlQYlHRuDU=", + "requires": { + "invert-kv": "^1.0.0" + } + }, + "locate-path": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-2.0.0.tgz", + "integrity": "sha1-K1aLJl7slExtnA3pw9u7ygNUzY4=", + "requires": { + "p-locate": "^2.0.0", + "path-exists": "^3.0.0" + } + }, + "mem": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/mem/-/mem-1.1.0.tgz", + "integrity": "sha1-Xt1StIXKHZAP5kiVUFOZoN+kX3Y=", + "requires": { + "mimic-fn": "^1.0.0" + } + }, + "os-locale": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/os-locale/-/os-locale-2.1.0.tgz", + "integrity": "sha512-3sslG3zJbEYcaC4YVAvDorjGxc7tv6KVATnLPZONiljsUncvihe9BQoVCEs0RZ1kmf4Hk9OBqlZfJZWI4GanKA==", + "requires": { + "execa": "^0.7.0", + "lcid": "^1.0.0", + "mem": "^1.1.0" + } + }, + "p-limit": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-1.3.0.tgz", + "integrity": "sha512-vvcXsLAJ9Dr5rQOPk7toZQZJApBl2K4J6dANSsEuh6QI41JYcsS/qhTGa9ErIUUgK3WNQoJYvylxvjqmiqEA9Q==", + "requires": { + "p-try": "^1.0.0" + } + }, + "p-locate": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-2.0.0.tgz", + "integrity": "sha1-IKAQOyIqcMj9OcwuWAaA893l7EM=", + "requires": { + "p-limit": "^1.1.0" + } + }, + "p-try": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/p-try/-/p-try-1.0.0.tgz", + "integrity": "sha1-y8ec26+P1CKOE/Yh8rGiN8GyB7M=" + }, "rimraf": { "version": "2.6.3", "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-2.6.3.tgz", @@ -11716,12 +11689,36 @@ "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==" }, - "strip-ansi": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-4.0.0.tgz", - "integrity": "sha1-qEeQIusaw2iocTibY1JixQXuNo8=", + "y18n": { + "version": "3.2.1", + "resolved": "https://registry.npmjs.org/y18n/-/y18n-3.2.1.tgz", + "integrity": "sha1-bRX7qITAhnnA136I53WegR4H+kE=" + }, + "yargs": { + "version": "11.1.0", + "resolved": "https://registry.npmjs.org/yargs/-/yargs-11.1.0.tgz", + "integrity": "sha512-NwW69J42EsCSanF8kyn5upxvjp5ds+t3+udGBeTbFnERA+lF541DDpMawzo4z6W/QrzNM18D+BPMiOBibnFV5A==", "requires": { - "ansi-regex": "^3.0.0" + "cliui": "^4.0.0", + "decamelize": "^1.1.1", + "find-up": "^2.1.0", + "get-caller-file": "^1.0.1", + "os-locale": "^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": "^9.0.2" + } + }, + "yargs-parser": { + "version": "9.0.2", + "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-9.0.2.tgz", + "integrity": "sha1-nM9qQ0YP5O1Aqbto9I1DuKaMwHc=", + "requires": { + "camelcase": "^4.1.0" } } } @@ -12203,6 +12200,11 @@ "source-map": "^0.5.7" } }, + "camelcase": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-4.1.0.tgz", + "integrity": "sha1-1UVjW+HjPFQmScaRc+Xeas+uNN0=" + }, "debug": { "version": "2.6.9", "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", @@ -12211,6 +12213,38 @@ "ms": "2.0.0" } }, + "execa": { + "version": "0.7.0", + "resolved": "https://registry.npmjs.org/execa/-/execa-0.7.0.tgz", + "integrity": "sha1-lEvs00zEHuMqY6n68nrVpl/Fl3c=", + "requires": { + "cross-spawn": "^5.0.1", + "get-stream": "^3.0.0", + "is-stream": "^1.1.0", + "npm-run-path": "^2.0.0", + "p-finally": "^1.0.0", + "signal-exit": "^3.0.0", + "strip-eof": "^1.0.0" + } + }, + "find-up": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/find-up/-/find-up-2.1.0.tgz", + "integrity": "sha1-RdG35QbHF93UgndaK3eSCjwMV6c=", + "requires": { + "locate-path": "^2.0.0" + } + }, + "get-stream": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/get-stream/-/get-stream-3.0.0.tgz", + "integrity": "sha1-jpQ9E1jcN1VQVOy+LtsFqhdO3hQ=" + }, + "invert-kv": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/invert-kv/-/invert-kv-1.0.0.tgz", + "integrity": "sha1-EEqOSqym09jNFXqO+L+rLXo//bY=" + }, "jest-message-util": { "version": "23.4.0", "resolved": "https://registry.npmjs.org/jest-message-util/-/jest-message-util-23.4.0.tgz", @@ -12250,15 +12284,103 @@ "resolved": "https://registry.npmjs.org/json5/-/json5-0.5.1.tgz", "integrity": "sha1-Hq3nrMASA0rYTiOWdn6tn6VJWCE=" }, + "lcid": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/lcid/-/lcid-1.0.0.tgz", + "integrity": "sha1-MIrMr6C8SDo4Z7S28rlQYlHRuDU=", + "requires": { + "invert-kv": "^1.0.0" + } + }, + "locate-path": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-2.0.0.tgz", + "integrity": "sha1-K1aLJl7slExtnA3pw9u7ygNUzY4=", + "requires": { + "p-locate": "^2.0.0", + "path-exists": "^3.0.0" + } + }, + "mem": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/mem/-/mem-1.1.0.tgz", + "integrity": "sha1-Xt1StIXKHZAP5kiVUFOZoN+kX3Y=", + "requires": { + "mimic-fn": "^1.0.0" + } + }, "ms": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g=" }, + "os-locale": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/os-locale/-/os-locale-2.1.0.tgz", + "integrity": "sha512-3sslG3zJbEYcaC4YVAvDorjGxc7tv6KVATnLPZONiljsUncvihe9BQoVCEs0RZ1kmf4Hk9OBqlZfJZWI4GanKA==", + "requires": { + "execa": "^0.7.0", + "lcid": "^1.0.0", + "mem": "^1.1.0" + } + }, + "p-limit": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-1.3.0.tgz", + "integrity": "sha512-vvcXsLAJ9Dr5rQOPk7toZQZJApBl2K4J6dANSsEuh6QI41JYcsS/qhTGa9ErIUUgK3WNQoJYvylxvjqmiqEA9Q==", + "requires": { + "p-try": "^1.0.0" + } + }, + "p-locate": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-2.0.0.tgz", + "integrity": "sha1-IKAQOyIqcMj9OcwuWAaA893l7EM=", + "requires": { + "p-limit": "^1.1.0" + } + }, + "p-try": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/p-try/-/p-try-1.0.0.tgz", + "integrity": "sha1-y8ec26+P1CKOE/Yh8rGiN8GyB7M=" + }, "strip-bom": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/strip-bom/-/strip-bom-3.0.0.tgz", "integrity": "sha1-IzTBjpx1n3vdVv3vfprj1YjmjtM=" + }, + "y18n": { + "version": "3.2.1", + "resolved": "https://registry.npmjs.org/y18n/-/y18n-3.2.1.tgz", + "integrity": "sha1-bRX7qITAhnnA136I53WegR4H+kE=" + }, + "yargs": { + "version": "11.1.0", + "resolved": "https://registry.npmjs.org/yargs/-/yargs-11.1.0.tgz", + "integrity": "sha512-NwW69J42EsCSanF8kyn5upxvjp5ds+t3+udGBeTbFnERA+lF541DDpMawzo4z6W/QrzNM18D+BPMiOBibnFV5A==", + "requires": { + "cliui": "^4.0.0", + "decamelize": "^1.1.1", + "find-up": "^2.1.0", + "get-caller-file": "^1.0.1", + "os-locale": "^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": "^9.0.2" + } + }, + "yargs-parser": { + "version": "9.0.2", + "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-9.0.2.tgz", + "integrity": "sha1-nM9qQ0YP5O1Aqbto9I1DuKaMwHc=", + "requires": { + "camelcase": "^4.1.0" + } } } }, @@ -12349,9 +12471,9 @@ } }, "js-base64": { - "version": "2.5.0", - "resolved": "https://registry.npmjs.org/js-base64/-/js-base64-2.5.0.tgz", - "integrity": "sha512-wlEBIZ5LP8usDylWbDNhKPEFVFdI5hCHpnVoT/Ysvoi/PRhJENm/Rlh9TvjYB38HFfKZN7OzEbRjmjvLkFw11g==", + "version": "2.5.1", + "resolved": "https://registry.npmjs.org/js-base64/-/js-base64-2.5.1.tgz", + "integrity": "sha512-M7kLczedRMYX4L8Mdh4MzyAMM9O5osx+4FcOQuTvr3A9F2D9S5JXheN0ewNbrvK2UatkTRhL5ejGmGSjNMiZuw==", "dev": true }, "js-levenshtein": { @@ -12527,11 +12649,11 @@ } }, "lcid": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/lcid/-/lcid-1.0.0.tgz", - "integrity": "sha1-MIrMr6C8SDo4Z7S28rlQYlHRuDU=", + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/lcid/-/lcid-2.0.0.tgz", + "integrity": "sha512-avPEb8P8EGnwXKClwsNUgryVjllcRqtMYa49NTsbQagYuT1DcXnl1915oxWjoyGrXR6zH/Y0Zc96xWsPcoDKeA==", "requires": { - "invert-kv": "^1.0.0" + "invert-kv": "^2.0.0" } }, "left-pad": { @@ -12623,15 +12745,6 @@ "resolved": "https://registry.npmjs.org/aproba/-/aproba-2.0.0.tgz", "integrity": "sha512-lYe4Gx7QT+MKGbDsA+Z+he/Wtef0BiwDOlK/XkBrdfsh9J/jPPXbX0tE9x9cl27Tmu5gg3QUbUrQYa/y+KOHPQ==", "dev": true - }, - "get-stream": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/get-stream/-/get-stream-4.1.0.tgz", - "integrity": "sha512-GMat4EJ5161kIy2HevLlr4luNjBgvmj413KaQA7jt4V8B4RDsfpHk7WQ9GVqfYyyx8OS/L66Kox+rJRNklLK7w==", - "dev": true, - "requires": { - "pump": "^3.0.0" - } } } }, @@ -12644,51 +12757,6 @@ "figgy-pudding": "^3.5.1", "find-up": "^3.0.0", "ini": "^1.3.5" - }, - "dependencies": { - "find-up": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/find-up/-/find-up-3.0.0.tgz", - "integrity": "sha512-1yD6RmLI1XBfxugvORwlck6f75tYL+iR0jqwsOrOxMZyGYqUuDhJ0l4AXdO1iX/FTs9cBAMEk1gWSEx1kSbylg==", - "dev": true, - "requires": { - "locate-path": "^3.0.0" - } - }, - "locate-path": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-3.0.0.tgz", - "integrity": "sha512-7AO748wWnIhNqAuaty2ZWHkQHRSNfPVIsPIfwEOWO22AmaoVrWavlOcMR5nzTLNYvp36X220/maaRsrec1G65A==", - "dev": true, - "requires": { - "p-locate": "^3.0.0", - "path-exists": "^3.0.0" - } - }, - "p-limit": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-2.1.0.tgz", - "integrity": "sha512-NhURkNcrVB+8hNfLuysU8enY5xn2KXphsHBaC2YmRNTZRc7RWusw6apSpdEj3jo4CMb6W9nrF6tTnsJsJeyu6g==", - "dev": true, - "requires": { - "p-try": "^2.0.0" - } - }, - "p-locate": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-3.0.0.tgz", - "integrity": "sha512-x+12w/To+4GFfgJhBEpiDcLozRJGegY+Ei7/z0tSLkMmxGZNybVMSfWj9aJn8Z5Fc7dBUNJOOVgPv2H7IwulSQ==", - "dev": true, - "requires": { - "p-limit": "^2.0.0" - } - }, - "p-try": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/p-try/-/p-try-2.0.0.tgz", - "integrity": "sha512-hMp0onDKIajHfIkdRk3P4CdCmErkYAxxDtP3Wx/4nZ3aGlau2VKh3mZpcuFkH27WQkL/3WBCPOktzA9ZOAnMQQ==", - "dev": true - } } }, "libnpmhook": { @@ -12708,15 +12776,6 @@ "resolved": "https://registry.npmjs.org/aproba/-/aproba-2.0.0.tgz", "integrity": "sha512-lYe4Gx7QT+MKGbDsA+Z+he/Wtef0BiwDOlK/XkBrdfsh9J/jPPXbX0tE9x9cl27Tmu5gg3QUbUrQYa/y+KOHPQ==", "dev": true - }, - "get-stream": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/get-stream/-/get-stream-4.1.0.tgz", - "integrity": "sha512-GMat4EJ5161kIy2HevLlr4luNjBgvmj413KaQA7jt4V8B4RDsfpHk7WQ9GVqfYyyx8OS/L66Kox+rJRNklLK7w==", - "dev": true, - "requires": { - "pump": "^3.0.0" - } } } }, @@ -12737,15 +12796,6 @@ "resolved": "https://registry.npmjs.org/aproba/-/aproba-2.0.0.tgz", "integrity": "sha512-lYe4Gx7QT+MKGbDsA+Z+he/Wtef0BiwDOlK/XkBrdfsh9J/jPPXbX0tE9x9cl27Tmu5gg3QUbUrQYa/y+KOHPQ==", "dev": true - }, - "get-stream": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/get-stream/-/get-stream-4.1.0.tgz", - "integrity": "sha512-GMat4EJ5161kIy2HevLlr4luNjBgvmj413KaQA7jt4V8B4RDsfpHk7WQ9GVqfYyyx8OS/L66Kox+rJRNklLK7w==", - "dev": true, - "requires": { - "pump": "^3.0.0" - } } } }, @@ -12772,15 +12822,6 @@ "integrity": "sha512-lYe4Gx7QT+MKGbDsA+Z+he/Wtef0BiwDOlK/XkBrdfsh9J/jPPXbX0tE9x9cl27Tmu5gg3QUbUrQYa/y+KOHPQ==", "dev": true }, - "get-stream": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/get-stream/-/get-stream-4.1.0.tgz", - "integrity": "sha512-GMat4EJ5161kIy2HevLlr4luNjBgvmj413KaQA7jt4V8B4RDsfpHk7WQ9GVqfYyyx8OS/L66Kox+rJRNklLK7w==", - "dev": true, - "requires": { - "pump": "^3.0.0" - } - }, "ssri": { "version": "6.0.1", "resolved": "https://registry.npmjs.org/ssri/-/ssri-6.0.1.tgz", @@ -12801,17 +12842,6 @@ "figgy-pudding": "^3.5.1", "get-stream": "^4.0.0", "npm-registry-fetch": "^3.8.0" - }, - "dependencies": { - "get-stream": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/get-stream/-/get-stream-4.1.0.tgz", - "integrity": "sha512-GMat4EJ5161kIy2HevLlr4luNjBgvmj413KaQA7jt4V8B4RDsfpHk7WQ9GVqfYyyx8OS/L66Kox+rJRNklLK7w==", - "dev": true, - "requires": { - "pump": "^3.0.0" - } - } } }, "libnpmteam": { @@ -12831,15 +12861,6 @@ "resolved": "https://registry.npmjs.org/aproba/-/aproba-2.0.0.tgz", "integrity": "sha512-lYe4Gx7QT+MKGbDsA+Z+he/Wtef0BiwDOlK/XkBrdfsh9J/jPPXbX0tE9x9cl27Tmu5gg3QUbUrQYa/y+KOHPQ==", "dev": true - }, - "get-stream": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/get-stream/-/get-stream-4.1.0.tgz", - "integrity": "sha512-GMat4EJ5161kIy2HevLlr4luNjBgvmj413KaQA7jt4V8B4RDsfpHk7WQ9GVqfYyyx8OS/L66Kox+rJRNklLK7w==", - "dev": true, - "requires": { - "pump": "^3.0.0" - } } } }, @@ -12957,9 +12978,9 @@ } }, "loader-runner": { - "version": "2.3.1", - "resolved": "https://registry.npmjs.org/loader-runner/-/loader-runner-2.3.1.tgz", - "integrity": "sha512-By6ZFY7ETWOc9RFaAIb23IjJVcM4dvJC/N57nmdz9RSkMXvAXGI7SyVlAw3v8vjtDRlqThgVDVmTnr9fqMlxkw==", + "version": "2.4.0", + "resolved": "https://registry.npmjs.org/loader-runner/-/loader-runner-2.4.0.tgz", + "integrity": "sha512-Jsmr89RcXGIwivFY21FcRrisYZfvLMTWx5kOLc+JTxtpBOG6xML0vzbc6SEQG2FO9/4Fc3wW4LVcB5DmGflaRw==", "dev": true }, "loader-utils": { @@ -12985,11 +13006,11 @@ } }, "locate-path": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-2.0.0.tgz", - "integrity": "sha1-K1aLJl7slExtnA3pw9u7ygNUzY4=", + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-3.0.0.tgz", + "integrity": "sha512-7AO748wWnIhNqAuaty2ZWHkQHRSNfPVIsPIfwEOWO22AmaoVrWavlOcMR5nzTLNYvp36X220/maaRsrec1G65A==", "requires": { - "p-locate": "^2.0.0", + "p-locate": "^3.0.0", "path-exists": "^3.0.0" } }, @@ -13345,12 +13366,6 @@ "figgy-pudding": "^3.5.1" } }, - "y18n": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/y18n/-/y18n-4.0.0.tgz", - "integrity": "sha512-r9S/ZyXu/Xu9q1tYlpsLIsa3EeLXXk0VwlxqTcFRfg9EhMW+17kbt9G0NrgCmhGb5vT2hyhJZLfDGx+7+5Uj/w==", - "dev": true - }, "yallist": { "version": "3.0.3", "resolved": "https://registry.npmjs.org/yallist/-/yallist-3.0.3.tgz", @@ -13371,7 +13386,6 @@ "version": "0.1.3", "resolved": "https://registry.npmjs.org/map-age-cleaner/-/map-age-cleaner-0.1.3.tgz", "integrity": "sha512-bJzx6nMoP6PDLPBFmg7+xRKeFZvFboMrGlxmNj9ClvX53KrmvM5bXFXEWjbz4cz1AFn+jWJ9z/DJSz7hrs0w3w==", - "dev": true, "requires": { "p-defer": "^1.0.0" } @@ -13412,9 +13426,9 @@ "integrity": "sha512-HduzIW2xApSXKXJSpCipSxKyvMbwRRa/TwMbepmlZziKdH8548WSoDP4SxzulEKjlo8BE39l+2fwJZuRKOln6g==" }, "math-random": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/math-random/-/math-random-1.0.2.tgz", - "integrity": "sha512-Bp2Bx2wFaUymE7pWi0bbldiheIXMvyzC3hRkT5YAv2qiqqJO5VB8KafgYgZmGCxkTmloLuAx3Jv2OmJ66990mg==" + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/math-random/-/math-random-1.0.4.tgz", + "integrity": "sha512-rUxjysqif/BZQH2yhd5Aaq7vXMSx9NdEsQcyA07uEzIvxgI7zIr33gGsh+RU0/XjmQpCW7RsVof1vlkvQVCK5A==" }, "mathml-tag-names": { "version": "2.1.0", @@ -13449,11 +13463,13 @@ "dev": true }, "mem": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/mem/-/mem-1.1.0.tgz", - "integrity": "sha1-Xt1StIXKHZAP5kiVUFOZoN+kX3Y=", + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/mem/-/mem-4.1.0.tgz", + "integrity": "sha512-I5u6Q1x7wxO0kdOpYBB28xueHADYps5uty/zg936CiG8NTe5sJL8EjrCuLneuDW3PlMdZBGDIn8BirEVdovZvg==", "requires": { - "mimic-fn": "^1.0.0" + "map-age-cleaner": "^0.1.1", + "mimic-fn": "^1.0.0", + "p-is-promise": "^2.0.0" } }, "memize": { @@ -13513,6 +13529,19 @@ "yargs-parser": "^10.0.0" }, "dependencies": { + "camelcase": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-4.1.0.tgz", + "integrity": "sha1-1UVjW+HjPFQmScaRc+Xeas+uNN0=" + }, + "find-up": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/find-up/-/find-up-2.1.0.tgz", + "integrity": "sha1-RdG35QbHF93UgndaK3eSCjwMV6c=", + "requires": { + "locate-path": "^2.0.0" + } + }, "load-json-file": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/load-json-file/-/load-json-file-4.0.0.tgz", @@ -13524,6 +13553,36 @@ "strip-bom": "^3.0.0" } }, + "locate-path": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-2.0.0.tgz", + "integrity": "sha1-K1aLJl7slExtnA3pw9u7ygNUzY4=", + "requires": { + "p-locate": "^2.0.0", + "path-exists": "^3.0.0" + } + }, + "p-limit": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-1.3.0.tgz", + "integrity": "sha512-vvcXsLAJ9Dr5rQOPk7toZQZJApBl2K4J6dANSsEuh6QI41JYcsS/qhTGa9ErIUUgK3WNQoJYvylxvjqmiqEA9Q==", + "requires": { + "p-try": "^1.0.0" + } + }, + "p-locate": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-2.0.0.tgz", + "integrity": "sha1-IKAQOyIqcMj9OcwuWAaA893l7EM=", + "requires": { + "p-limit": "^1.1.0" + } + }, + "p-try": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/p-try/-/p-try-1.0.0.tgz", + "integrity": "sha1-y8ec26+P1CKOE/Yh8rGiN8GyB7M=" + }, "parse-json": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/parse-json/-/parse-json-4.0.0.tgz", @@ -13838,9 +13897,9 @@ "dev": true }, "moment": { - "version": "2.23.0", - "resolved": "https://registry.npmjs.org/moment/-/moment-2.23.0.tgz", - "integrity": "sha512-3IE39bHVqFbWWaPOMHZF98Q9c3LDKGTmypMiTM2QygGXXElkFWIH7GxfmlwmY2vwa+wmNsoYZmG2iusf1ZjJoA==" + "version": "2.24.0", + "resolved": "https://registry.npmjs.org/moment/-/moment-2.24.0.tgz", + "integrity": "sha512-bV7f+6l2QigeBBZSM/6yTNq4P2fNpSWj/0e7jQcy87A8e7o2nAfP/34/2ky5Vw4B9S446EtIhodAzkFCcR4dQg==" }, "moment-timezone": { "version": "0.5.23", @@ -13968,8 +14027,7 @@ "nice-try": { "version": "1.0.5", "resolved": "https://registry.npmjs.org/nice-try/-/nice-try-1.0.5.tgz", - "integrity": "sha512-1nh45deeb5olNY7eX82BkPO7SSxR5SSYJiPTrTdFUVYwAl8CKMA5N9PjTYkHiRjisVcxcQ1HXdLhx2qxxJzLNQ==", - "dev": true + "integrity": "sha512-1nh45deeb5olNY7eX82BkPO7SSxR5SSYJiPTrTdFUVYwAl8CKMA5N9PjTYkHiRjisVcxcQ1HXdLhx2qxxJzLNQ==" }, "node-addon-api": { "version": "1.6.2", @@ -14040,9 +14098,9 @@ "integrity": "sha1-h6kGXNs1XTGC2PlM4RGIuCXGijs=" }, "node-libs-browser": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/node-libs-browser/-/node-libs-browser-2.1.0.tgz", - "integrity": "sha512-5AzFzdoIMb89hBGMZglEegffzgRg+ZFoUmisQ8HI4j1KDdpx13J0taNp2y9xPbur6W61gepGDDotGBVQ7mfUCg==", + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/node-libs-browser/-/node-libs-browser-2.2.0.tgz", + "integrity": "sha512-5MQunG/oyOaBdttrL40dA7bUfPORLRWMUJLQtMg7nluxUvk5XwnLdL9twQHFAjRx/y7mIMkLKT9++qPbbk6BZA==", "dev": true, "requires": { "assert": "^1.1.1", @@ -14052,7 +14110,7 @@ "constants-browserify": "^1.0.0", "crypto-browserify": "^3.11.0", "domain-browser": "^1.1.1", - "events": "^1.0.0", + "events": "^3.0.0", "https-browserify": "^1.0.0", "os-browserify": "^0.3.0", "path-browserify": "0.0.0", @@ -14066,7 +14124,7 @@ "timers-browserify": "^2.0.4", "tty-browserify": "0.0.0", "url": "^0.11.0", - "util": "^0.10.3", + "util": "^0.11.0", "vm-browserify": "0.0.4" }, "dependencies": { @@ -14116,9 +14174,9 @@ } }, "node-releases": { - "version": "1.1.3", - "resolved": "https://registry.npmjs.org/node-releases/-/node-releases-1.1.3.tgz", - "integrity": "sha512-6VrvH7z6jqqNFY200kdB6HdzkgM96Oaj9v3dqGfgp6mF+cHmU4wyQKZ2/WPDRVoR0Jz9KqbamaBN0ZhdUaysUQ==", + "version": "1.1.6", + "resolved": "https://registry.npmjs.org/node-releases/-/node-releases-1.1.6.tgz", + "integrity": "sha512-lODUVHEIZutZx+TDdOk47qLik8FJMXzJ+WnyUGci1MTvTOyzZrz5eVPIIpc5Hb3NfHZGeGHeuwrRYVI1PEITWg==", "requires": { "semver": "^5.3.0" } @@ -14150,6 +14208,12 @@ "true-case-path": "^1.0.2" }, "dependencies": { + "ansi-regex": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-2.1.1.tgz", + "integrity": "sha1-w7M6te42DYbg5ijwRorn7yfWVN8=", + "dev": true + }, "ansi-styles": { "version": "2.2.1", "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-2.2.1.tgz", @@ -14238,6 +14302,15 @@ "strip-indent": "^1.0.1" } }, + "strip-ansi": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-3.0.1.tgz", + "integrity": "sha1-ajhfuIU9lS1f8F0Oiq+UJ43GPc8=", + "dev": true, + "requires": { + "ansi-regex": "^2.0.0" + } + }, "strip-indent": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/strip-indent/-/strip-indent-1.0.1.tgz", @@ -14305,9 +14378,9 @@ } }, "normalize-package-data": { - "version": "2.4.0", - "resolved": "https://registry.npmjs.org/normalize-package-data/-/normalize-package-data-2.4.0.tgz", - "integrity": "sha512-9jjUFbTPfEy3R/ad/2oNbKtW9Hgovl5O1FvFWKkKblNXoN/Oou6+9+KKohPK13Yc3/TyunyWhJp6gvRNR/PPAw==", + "version": "2.4.2", + "resolved": "https://registry.npmjs.org/normalize-package-data/-/normalize-package-data-2.4.2.tgz", + "integrity": "sha512-YcMnjqeoUckXTPKZSAsPjUPLxH85XotbpqK3w4RyCwdFQSU5FxxBys8buehkSfg0j9fKvV1hn7O0+8reEgkAiw==", "requires": { "hosted-git-info": "^2.1.4", "is-builtin-module": "^1.0.0", @@ -14584,7 +14657,6 @@ "version": "2.0.0", "resolved": "https://registry.npmjs.org/object.fromentries/-/object.fromentries-2.0.0.tgz", "integrity": "sha512-9iLiI6H083uiqUuvzyY6qrlmc/Gz8hLQFOcb/Ri/0xXFkSNS3ctV+CbE6yM2+AnkYfOB3dGjdzC0wrMLIhQICA==", - "dev": true, "requires": { "define-properties": "^1.1.2", "es-abstract": "^1.11.0", @@ -14681,6 +14753,12 @@ "integrity": "sha1-06ioOzGapneTZisT52HHkRQiMG4=", "dev": true }, + "ansi-regex": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-2.1.1.tgz", + "integrity": "sha1-w7M6te42DYbg5ijwRorn7yfWVN8=", + "dev": true + }, "ansi-styles": { "version": "2.2.1", "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-2.2.1.tgz", @@ -14741,6 +14819,15 @@ "pinkie-promise": "^2.0.0" } }, + "strip-ansi": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-3.0.1.tgz", + "integrity": "sha1-ajhfuIU9lS1f8F0Oiq+UJ43GPc8=", + "dev": true, + "requires": { + "ansi-regex": "^2.0.0" + } + }, "supports-color": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-2.0.0.tgz", @@ -14816,13 +14903,13 @@ "integrity": "sha1-/7xJiDNuDoM94MFox+8VISGqf7M=" }, "os-locale": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/os-locale/-/os-locale-2.1.0.tgz", - "integrity": "sha512-3sslG3zJbEYcaC4YVAvDorjGxc7tv6KVATnLPZONiljsUncvihe9BQoVCEs0RZ1kmf4Hk9OBqlZfJZWI4GanKA==", + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/os-locale/-/os-locale-3.1.0.tgz", + "integrity": "sha512-Z8l3R4wYWM40/52Z+S265okfFj8Kt2cC2MKY+xNi3kFs+XGI7WXu/I309QQQYbRW4ijiZ+yxs9pqEhJh0DqW3Q==", "requires": { - "execa": "^0.7.0", - "lcid": "^1.0.0", - "mem": "^1.1.0" + "execa": "^1.0.0", + "lcid": "^2.0.0", + "mem": "^4.0.0" } }, "os-tmpdir": { @@ -14854,8 +14941,7 @@ "p-defer": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/p-defer/-/p-defer-1.0.0.tgz", - "integrity": "sha1-n26xgvbJqozXQwBKfU+WsZaw+ww=", - "dev": true + "integrity": "sha1-n26xgvbJqozXQwBKfU+WsZaw+ww=" }, "p-finally": { "version": "1.0.0", @@ -14863,25 +14949,24 @@ "integrity": "sha1-P7z7FbiZpEEjs0ttzBi3JDNqLK4=" }, "p-is-promise": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/p-is-promise/-/p-is-promise-1.1.0.tgz", - "integrity": "sha1-nJRWmJ6fZYgBewQ01WCXZ1w9oF4=", - "dev": true + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/p-is-promise/-/p-is-promise-2.0.0.tgz", + "integrity": "sha512-pzQPhYMCAgLAKPWD2jC3Se9fEfrD9npNos0y150EeqZll7akhEgGhTW/slB6lHku8AvYGiJ+YJ5hfHKePPgFWg==" }, "p-limit": { - "version": "1.3.0", - "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-1.3.0.tgz", - "integrity": "sha512-vvcXsLAJ9Dr5rQOPk7toZQZJApBl2K4J6dANSsEuh6QI41JYcsS/qhTGa9ErIUUgK3WNQoJYvylxvjqmiqEA9Q==", + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-2.1.0.tgz", + "integrity": "sha512-NhURkNcrVB+8hNfLuysU8enY5xn2KXphsHBaC2YmRNTZRc7RWusw6apSpdEj3jo4CMb6W9nrF6tTnsJsJeyu6g==", "requires": { - "p-try": "^1.0.0" + "p-try": "^2.0.0" } }, "p-locate": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-2.0.0.tgz", - "integrity": "sha1-IKAQOyIqcMj9OcwuWAaA893l7EM=", + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-3.0.0.tgz", + "integrity": "sha512-x+12w/To+4GFfgJhBEpiDcLozRJGegY+Ei7/z0tSLkMmxGZNybVMSfWj9aJn8Z5Fc7dBUNJOOVgPv2H7IwulSQ==", "requires": { - "p-limit": "^1.1.0" + "p-limit": "^2.0.0" } }, "p-map": { @@ -14912,9 +14997,9 @@ "dev": true }, "p-try": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/p-try/-/p-try-1.0.0.tgz", - "integrity": "sha1-y8ec26+P1CKOE/Yh8rGiN8GyB7M=" + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/p-try/-/p-try-2.0.0.tgz", + "integrity": "sha512-hMp0onDKIajHfIkdRk3P4CdCmErkYAxxDtP3Wx/4nZ3aGlau2VKh3mZpcuFkH27WQkL/3WBCPOktzA9ZOAnMQQ==" }, "p-waterfall": { "version": "1.0.0", @@ -14994,15 +15079,6 @@ "y18n": "^4.0.0" } }, - "get-stream": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/get-stream/-/get-stream-4.1.0.tgz", - "integrity": "sha512-GMat4EJ5161kIy2HevLlr4luNjBgvmj413KaQA7jt4V8B4RDsfpHk7WQ9GVqfYyyx8OS/L66Kox+rJRNklLK7w==", - "dev": true, - "requires": { - "pump": "^3.0.0" - } - }, "lru-cache": { "version": "5.1.1", "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-5.1.1.tgz", @@ -15054,12 +15130,6 @@ "yallist": "^3.0.2" } }, - "y18n": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/y18n/-/y18n-4.0.0.tgz", - "integrity": "sha512-r9S/ZyXu/Xu9q1tYlpsLIsa3EeLXXk0VwlxqTcFRfg9EhMW+17kbt9G0NrgCmhGb5vT2hyhJZLfDGx+7+5Uj/w==", - "dev": true - }, "yallist": { "version": "3.0.3", "resolved": "https://registry.npmjs.org/yallist/-/yallist-3.0.3.tgz", @@ -15069,9 +15139,9 @@ } }, "pako": { - "version": "1.0.7", - "resolved": "https://registry.npmjs.org/pako/-/pako-1.0.7.tgz", - "integrity": "sha512-3HNK5tW4x8o5mO8RuHZp3Ydw9icZXx0RANAOMzlMzx7LVXhMJ4mo3MOBpzyd7r/+RUu8BmndP47LXT+vzjtWcQ==", + "version": "1.0.8", + "resolved": "https://registry.npmjs.org/pako/-/pako-1.0.8.tgz", + "integrity": "sha512-6i0HVbUfcKaTv+EG8ZTr75az7GFXcLYk9UyLEg7Notv/Ma+z/UG3TCoz6GiNeOrn1E/e63I0X/Hpw18jHOTUnA==", "dev": true }, "parallel-transform": { @@ -15135,16 +15205,17 @@ "dev": true }, "parse-asn1": { - "version": "5.1.1", - "resolved": "https://registry.npmjs.org/parse-asn1/-/parse-asn1-5.1.1.tgz", - "integrity": "sha512-KPx7flKXg775zZpnp9SxJlz00gTd4BmJ2yJufSc44gMCRrRQ7NSzAcSJQfifuOLgW6bEi+ftrALtsgALeB2Adw==", + "version": "5.1.3", + "resolved": "https://registry.npmjs.org/parse-asn1/-/parse-asn1-5.1.3.tgz", + "integrity": "sha512-VrPoetlz7B/FqjBLD2f5wBVZvsZVLnRUrxVLfRYhGXCODa/NWE4p3Wp+6+aV3ZPL3KM7/OZmxDIwwijD7yuucg==", "dev": true, "requires": { "asn1.js": "^4.0.0", "browserify-aes": "^1.0.0", "create-hash": "^1.1.0", "evp_bytestokey": "^1.0.0", - "pbkdf2": "^3.0.3" + "pbkdf2": "^3.0.3", + "safe-buffer": "^5.1.1" } }, "parse-entities": { @@ -15330,6 +15401,46 @@ "integrity": "sha1-9tXREJ4Z1j7fQo4L1X4Sd3YVM0s=", "requires": { "find-up": "^2.1.0" + }, + "dependencies": { + "find-up": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/find-up/-/find-up-2.1.0.tgz", + "integrity": "sha1-RdG35QbHF93UgndaK3eSCjwMV6c=", + "requires": { + "locate-path": "^2.0.0" + } + }, + "locate-path": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-2.0.0.tgz", + "integrity": "sha1-K1aLJl7slExtnA3pw9u7ygNUzY4=", + "requires": { + "p-locate": "^2.0.0", + "path-exists": "^3.0.0" + } + }, + "p-limit": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-1.3.0.tgz", + "integrity": "sha512-vvcXsLAJ9Dr5rQOPk7toZQZJApBl2K4J6dANSsEuh6QI41JYcsS/qhTGa9ErIUUgK3WNQoJYvylxvjqmiqEA9Q==", + "requires": { + "p-try": "^1.0.0" + } + }, + "p-locate": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-2.0.0.tgz", + "integrity": "sha1-IKAQOyIqcMj9OcwuWAaA893l7EM=", + "requires": { + "p-limit": "^1.1.0" + } + }, + "p-try": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/p-try/-/p-try-1.0.0.tgz", + "integrity": "sha1-y8ec26+P1CKOE/Yh8rGiN8GyB7M=" + } } }, "please-upgrade-node": { @@ -15423,6 +15534,12 @@ "postcss": "^5.2.16" }, "dependencies": { + "ansi-regex": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-2.1.1.tgz", + "integrity": "sha1-w7M6te42DYbg5ijwRorn7yfWVN8=", + "dev": true + }, "ansi-styles": { "version": "2.2.1", "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-2.2.1.tgz", @@ -15468,6 +15585,15 @@ "supports-color": "^3.2.3" } }, + "strip-ansi": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-3.0.1.tgz", + "integrity": "sha1-ajhfuIU9lS1f8F0Oiq+UJ43GPc8=", + "dev": true, + "requires": { + "ansi-regex": "^2.0.0" + } + }, "supports-color": { "version": "3.2.3", "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-3.2.3.tgz", @@ -15526,9 +15652,9 @@ }, "dependencies": { "postcss": { - "version": "7.0.11", - "resolved": "https://registry.npmjs.org/postcss/-/postcss-7.0.11.tgz", - "integrity": "sha512-9AXb//5UcjeOEof9T+yPw3XTa5SL207ZOIC/lHYP4mbUTEh4M0rDAQekQpVANCZdwQwKhBtFZCk3i3h3h2hdWg==", + "version": "7.0.14", + "resolved": "https://registry.npmjs.org/postcss/-/postcss-7.0.14.tgz", + "integrity": "sha512-NsbD6XUUMZvBxtQAJuWDJeeC4QFsmWsfozWxCJPWf3M55K9iu2iMDaKqyoOdTJ1R4usBXuxlVFAIo8rZPQD4Bg==", "dev": true, "requires": { "chalk": "^2.4.2", @@ -15585,9 +15711,9 @@ }, "dependencies": { "postcss": { - "version": "7.0.11", - "resolved": "https://registry.npmjs.org/postcss/-/postcss-7.0.11.tgz", - "integrity": "sha512-9AXb//5UcjeOEof9T+yPw3XTa5SL207ZOIC/lHYP4mbUTEh4M0rDAQekQpVANCZdwQwKhBtFZCk3i3h3h2hdWg==", + "version": "7.0.14", + "resolved": "https://registry.npmjs.org/postcss/-/postcss-7.0.14.tgz", + "integrity": "sha512-NsbD6XUUMZvBxtQAJuWDJeeC4QFsmWsfozWxCJPWf3M55K9iu2iMDaKqyoOdTJ1R4usBXuxlVFAIo8rZPQD4Bg==", "dev": true, "requires": { "chalk": "^2.4.2", @@ -15624,9 +15750,9 @@ }, "dependencies": { "postcss": { - "version": "7.0.11", - "resolved": "https://registry.npmjs.org/postcss/-/postcss-7.0.11.tgz", - "integrity": "sha512-9AXb//5UcjeOEof9T+yPw3XTa5SL207ZOIC/lHYP4mbUTEh4M0rDAQekQpVANCZdwQwKhBtFZCk3i3h3h2hdWg==", + "version": "7.0.14", + "resolved": "https://registry.npmjs.org/postcss/-/postcss-7.0.14.tgz", + "integrity": "sha512-NsbD6XUUMZvBxtQAJuWDJeeC4QFsmWsfozWxCJPWf3M55K9iu2iMDaKqyoOdTJ1R4usBXuxlVFAIo8rZPQD4Bg==", "dev": true, "requires": { "chalk": "^2.4.2", @@ -15662,9 +15788,9 @@ }, "dependencies": { "postcss": { - "version": "7.0.11", - "resolved": "https://registry.npmjs.org/postcss/-/postcss-7.0.11.tgz", - "integrity": "sha512-9AXb//5UcjeOEof9T+yPw3XTa5SL207ZOIC/lHYP4mbUTEh4M0rDAQekQpVANCZdwQwKhBtFZCk3i3h3h2hdWg==", + "version": "7.0.14", + "resolved": "https://registry.npmjs.org/postcss/-/postcss-7.0.14.tgz", + "integrity": "sha512-NsbD6XUUMZvBxtQAJuWDJeeC4QFsmWsfozWxCJPWf3M55K9iu2iMDaKqyoOdTJ1R4usBXuxlVFAIo8rZPQD4Bg==", "dev": true, "requires": { "chalk": "^2.4.2", @@ -15700,9 +15826,9 @@ }, "dependencies": { "postcss": { - "version": "7.0.11", - "resolved": "https://registry.npmjs.org/postcss/-/postcss-7.0.11.tgz", - "integrity": "sha512-9AXb//5UcjeOEof9T+yPw3XTa5SL207ZOIC/lHYP4mbUTEh4M0rDAQekQpVANCZdwQwKhBtFZCk3i3h3h2hdWg==", + "version": "7.0.14", + "resolved": "https://registry.npmjs.org/postcss/-/postcss-7.0.14.tgz", + "integrity": "sha512-NsbD6XUUMZvBxtQAJuWDJeeC4QFsmWsfozWxCJPWf3M55K9iu2iMDaKqyoOdTJ1R4usBXuxlVFAIo8rZPQD4Bg==", "dev": true, "requires": { "chalk": "^2.4.2", @@ -15740,9 +15866,9 @@ }, "dependencies": { "postcss": { - "version": "7.0.11", - "resolved": "https://registry.npmjs.org/postcss/-/postcss-7.0.11.tgz", - "integrity": "sha512-9AXb//5UcjeOEof9T+yPw3XTa5SL207ZOIC/lHYP4mbUTEh4M0rDAQekQpVANCZdwQwKhBtFZCk3i3h3h2hdWg==", + "version": "7.0.14", + "resolved": "https://registry.npmjs.org/postcss/-/postcss-7.0.14.tgz", + "integrity": "sha512-NsbD6XUUMZvBxtQAJuWDJeeC4QFsmWsfozWxCJPWf3M55K9iu2iMDaKqyoOdTJ1R4usBXuxlVFAIo8rZPQD4Bg==", "dev": true, "requires": { "chalk": "^2.4.2", @@ -15783,9 +15909,9 @@ }, "dependencies": { "postcss": { - "version": "7.0.11", - "resolved": "https://registry.npmjs.org/postcss/-/postcss-7.0.11.tgz", - "integrity": "sha512-9AXb//5UcjeOEof9T+yPw3XTa5SL207ZOIC/lHYP4mbUTEh4M0rDAQekQpVANCZdwQwKhBtFZCk3i3h3h2hdWg==", + "version": "7.0.14", + "resolved": "https://registry.npmjs.org/postcss/-/postcss-7.0.14.tgz", + "integrity": "sha512-NsbD6XUUMZvBxtQAJuWDJeeC4QFsmWsfozWxCJPWf3M55K9iu2iMDaKqyoOdTJ1R4usBXuxlVFAIo8rZPQD4Bg==", "dev": true, "requires": { "chalk": "^2.4.2", @@ -15821,9 +15947,9 @@ }, "dependencies": { "postcss": { - "version": "7.0.11", - "resolved": "https://registry.npmjs.org/postcss/-/postcss-7.0.11.tgz", - "integrity": "sha512-9AXb//5UcjeOEof9T+yPw3XTa5SL207ZOIC/lHYP4mbUTEh4M0rDAQekQpVANCZdwQwKhBtFZCk3i3h3h2hdWg==", + "version": "7.0.14", + "resolved": "https://registry.npmjs.org/postcss/-/postcss-7.0.14.tgz", + "integrity": "sha512-NsbD6XUUMZvBxtQAJuWDJeeC4QFsmWsfozWxCJPWf3M55K9iu2iMDaKqyoOdTJ1R4usBXuxlVFAIo8rZPQD4Bg==", "dev": true, "requires": { "chalk": "^2.4.2", @@ -15976,6 +16102,12 @@ "integrity": "sha512-ribEzWEhWKKjY+1FdKCryo+HiN/1idPjUB8vyR5Yf221MtGzCd5+7OwPvWvYHerHHC2eJLr6MhvumbTocXGY7Q==", "dev": true }, + "camelcase": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-4.1.0.tgz", + "integrity": "sha1-1UVjW+HjPFQmScaRc+Xeas+uNN0=", + "dev": true + }, "chalk": { "version": "2.1.0", "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.1.0.tgz", @@ -16005,6 +16137,18 @@ "integrity": "sha1-yc45Okt8vQsFinJck98pkCeGj/k=", "dev": true }, + "emoji-regex": { + "version": "6.5.1", + "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-6.5.1.tgz", + "integrity": "sha512-PAHp6TxrCy7MGMFidro8uikr+zlJJKJ/Q6mm2ExZ7HwkyR9lSVFfE3kt36qcwa24BQL7y0G9axycGjK1A/0uNQ==", + "dev": true + }, + "get-stream": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/get-stream/-/get-stream-3.0.0.tgz", + "integrity": "sha1-jpQ9E1jcN1VQVOy+LtsFqhdO3hQ=", + "dev": true + }, "globby": { "version": "6.1.0", "resolved": "https://registry.npmjs.org/globby/-/globby-6.1.0.tgz", @@ -16063,6 +16207,15 @@ "integrity": "sha1-mGbfOVECEw449/mWvOtlRDIJwls=", "dev": true }, + "mem": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/mem/-/mem-1.1.0.tgz", + "integrity": "sha1-Xt1StIXKHZAP5kiVUFOZoN+kX3Y=", + "dev": true, + "requires": { + "mimic-fn": "^1.0.0" + } + }, "parse-json": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/parse-json/-/parse-json-3.0.0.tgz", @@ -16247,7 +16400,6 @@ "version": "3.0.0", "resolved": "https://registry.npmjs.org/pump/-/pump-3.0.0.tgz", "integrity": "sha512-LwZy+p3SFs1Pytd/jYct4wpv49HiYCqd9Rlc5ZVdk0V+8Yzv6jR5Blk3TRmPL1ft69TxP0IMZGJ+WPFU2BFhww==", - "dev": true, "requires": { "end-of-stream": "^1.1.0", "once": "^1.3.1" @@ -16449,9 +16601,9 @@ } }, "react-dates": { - "version": "18.3.1", - "resolved": "https://registry.npmjs.org/react-dates/-/react-dates-18.3.1.tgz", - "integrity": "sha512-sJdEt1KCHgHED8vRqxkzggF9XyFv58A9+xA0oSATKemBXroe/KVN6svp3TcKZ2VWMbdPmeM5Bd3xRWTkrGk9Dg==", + "version": "18.4.1", + "resolved": "https://registry.npmjs.org/react-dates/-/react-dates-18.4.1.tgz", + "integrity": "sha512-ew6HiORfbJkEGlJ+5SMC5GtgI87zj2BqNv8tRsdnPtgLMt5fY2Z9dUFxc+XATeRHs+wOm4ku0dlKWpuqBzYapQ==", "requires": { "airbnb-prop-types": "^2.10.0", "consolidated-events": "^1.1.1 || ^2.0.0", @@ -16670,9 +16822,9 @@ } }, "react-transition-group": { - "version": "2.5.2", - "resolved": "https://registry.npmjs.org/react-transition-group/-/react-transition-group-2.5.2.tgz", - "integrity": "sha512-vwHP++S+f6KL7rg8V1mfs62+MBKtbMeZDR8KiNmD7v98Gs3UPGsDZDahPJH2PVprFW5YHJfh6cbNim3zPndaSQ==", + "version": "2.5.3", + "resolved": "https://registry.npmjs.org/react-transition-group/-/react-transition-group-2.5.3.tgz", + "integrity": "sha512-2DGFck6h99kLNr8pOFk+z4Soq3iISydwOFeeEVPjTN6+Y01CmvbWmnN02VuTWyFdnRtIDPe+wy2q6Ui8snBPZg==", "requires": { "dom-helpers": "^3.3.1", "loose-envify": "^1.4.0", @@ -17251,6 +17403,16 @@ "safe-regex": "^1.1.0" } }, + "regexp-tree": { + "version": "0.1.1", + "resolved": "https://registry.npmjs.org/regexp-tree/-/regexp-tree-0.1.1.tgz", + "integrity": "sha512-HwRjOquc9QOwKTgbxvZTcddS5mlNlwePMQ3NFL8broajMLD5CXDAqas8Y5yxJH5QtZp5iRor3YCILd5pz71Cgw==", + "requires": { + "cli-table3": "^0.5.0", + "colors": "^1.1.2", + "yargs": "^12.0.5" + } + }, "regexpp": { "version": "1.1.0", "resolved": "https://registry.npmjs.org/regexpp/-/regexpp-1.1.0.tgz", @@ -17438,164 +17600,11 @@ "yargs": "12.0.5" }, "dependencies": { - "camelcase": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-5.0.0.tgz", - "integrity": "sha512-faqwZqnWxbxn+F1d399ygeamQNy3lPp/H9H6rNrqYh4FSVCtcY+3cub1MxA8o9mDd55mM8Aghuu/kuyYA6VTsA==", - "dev": true - }, "colors": { "version": "1.2.4", "resolved": "https://registry.npmjs.org/colors/-/colors-1.2.4.tgz", "integrity": "sha512-6Y+iBnWmXL+AWtlOp2Vr6R2w5MUlNJRwR0ShVFaAb1CqWzhPOpQg4L0jxD+xpw/Nc8QJwaq3KM79QUCriY8CWQ==", "dev": true - }, - "cross-spawn": { - "version": "6.0.5", - "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-6.0.5.tgz", - "integrity": "sha512-eTVLrBSt7fjbDygz805pMnstIs2VTBNkRm0qxZd+M7A5XDdxVRWO5MxGBXZhjY4cqLYLdtrGqRf8mBPmzwSpWQ==", - "dev": true, - "requires": { - "nice-try": "^1.0.4", - "path-key": "^2.0.1", - "semver": "^5.5.0", - "shebang-command": "^1.2.0", - "which": "^1.2.9" - } - }, - "execa": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/execa/-/execa-1.0.0.tgz", - "integrity": "sha512-adbxcyWV46qiHyvSp50TKt05tB4tK3HcmF7/nxfAdhnox83seTDbwnaqKO4sXRy7roHAIFqJP/Rw/AuEbX61LA==", - "dev": true, - "requires": { - "cross-spawn": "^6.0.0", - "get-stream": "^4.0.0", - "is-stream": "^1.1.0", - "npm-run-path": "^2.0.0", - "p-finally": "^1.0.0", - "signal-exit": "^3.0.0", - "strip-eof": "^1.0.0" - } - }, - "find-up": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/find-up/-/find-up-3.0.0.tgz", - "integrity": "sha512-1yD6RmLI1XBfxugvORwlck6f75tYL+iR0jqwsOrOxMZyGYqUuDhJ0l4AXdO1iX/FTs9cBAMEk1gWSEx1kSbylg==", - "dev": true, - "requires": { - "locate-path": "^3.0.0" - } - }, - "get-stream": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/get-stream/-/get-stream-4.1.0.tgz", - "integrity": "sha512-GMat4EJ5161kIy2HevLlr4luNjBgvmj413KaQA7jt4V8B4RDsfpHk7WQ9GVqfYyyx8OS/L66Kox+rJRNklLK7w==", - "dev": true, - "requires": { - "pump": "^3.0.0" - } - }, - "invert-kv": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/invert-kv/-/invert-kv-2.0.0.tgz", - "integrity": "sha512-wPVv/y/QQ/Uiirj/vh3oP+1Ww+AWehmi1g5fFWGPF6IpCBCDVrhgHRMvrLfdYcwDh3QJbGXDW4JAuzxElLSqKA==", - "dev": true - }, - "lcid": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/lcid/-/lcid-2.0.0.tgz", - "integrity": "sha512-avPEb8P8EGnwXKClwsNUgryVjllcRqtMYa49NTsbQagYuT1DcXnl1915oxWjoyGrXR6zH/Y0Zc96xWsPcoDKeA==", - "dev": true, - "requires": { - "invert-kv": "^2.0.0" - } - }, - "locate-path": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-3.0.0.tgz", - "integrity": "sha512-7AO748wWnIhNqAuaty2ZWHkQHRSNfPVIsPIfwEOWO22AmaoVrWavlOcMR5nzTLNYvp36X220/maaRsrec1G65A==", - "dev": true, - "requires": { - "p-locate": "^3.0.0", - "path-exists": "^3.0.0" - } - }, - "mem": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/mem/-/mem-4.0.0.tgz", - "integrity": "sha512-WQxG/5xYc3tMbYLXoXPm81ET2WDULiU5FxbuIoNbJqLOOI8zehXFdZuiUEgfdrU2mVB1pxBZUGlYORSrpuJreA==", - "dev": true, - "requires": { - "map-age-cleaner": "^0.1.1", - "mimic-fn": "^1.0.0", - "p-is-promise": "^1.1.0" - } - }, - "os-locale": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/os-locale/-/os-locale-3.1.0.tgz", - "integrity": "sha512-Z8l3R4wYWM40/52Z+S265okfFj8Kt2cC2MKY+xNi3kFs+XGI7WXu/I309QQQYbRW4ijiZ+yxs9pqEhJh0DqW3Q==", - "dev": true, - "requires": { - "execa": "^1.0.0", - "lcid": "^2.0.0", - "mem": "^4.0.0" - } - }, - "p-limit": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-2.1.0.tgz", - "integrity": "sha512-NhURkNcrVB+8hNfLuysU8enY5xn2KXphsHBaC2YmRNTZRc7RWusw6apSpdEj3jo4CMb6W9nrF6tTnsJsJeyu6g==", - "dev": true, - "requires": { - "p-try": "^2.0.0" - } - }, - "p-locate": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-3.0.0.tgz", - "integrity": "sha512-x+12w/To+4GFfgJhBEpiDcLozRJGegY+Ei7/z0tSLkMmxGZNybVMSfWj9aJn8Z5Fc7dBUNJOOVgPv2H7IwulSQ==", - "dev": true, - "requires": { - "p-limit": "^2.0.0" - } - }, - "p-try": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/p-try/-/p-try-2.0.0.tgz", - "integrity": "sha512-hMp0onDKIajHfIkdRk3P4CdCmErkYAxxDtP3Wx/4nZ3aGlau2VKh3mZpcuFkH27WQkL/3WBCPOktzA9ZOAnMQQ==", - "dev": true - }, - "yargs": { - "version": "12.0.5", - "resolved": "https://registry.npmjs.org/yargs/-/yargs-12.0.5.tgz", - "integrity": "sha512-Lhz8TLaYnxq/2ObqHDql8dX8CJi97oHxrjUcYtzKbbykPtVW9WB+poxI+NM2UIzsMgNCZTIf0AQwsjK5yMAqZw==", - "dev": true, - "requires": { - "cliui": "^4.0.0", - "decamelize": "^1.2.0", - "find-up": "^3.0.0", - "get-caller-file": "^1.0.1", - "os-locale": "^3.0.0", - "require-directory": "^2.1.1", - "require-main-filename": "^1.0.1", - "set-blocking": "^2.0.0", - "string-width": "^2.0.0", - "which-module": "^2.0.0", - "y18n": "^3.2.1 || ^4.0.0", - "yargs-parser": "^11.1.1" - } - }, - "yargs-parser": { - "version": "11.1.1", - "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-11.1.1.tgz", - "integrity": "sha512-C6kB/WJDiaxONLJQnF8ccx9SEeoTTLek8RVbaOIsrAUS8VrBEXfmeSnCZxygc+XC2sNMBIwOOnfcxiynjHsVSQ==", - "dev": true, - "requires": { - "camelcase": "^5.0.0", - "decamelize": "^1.2.0" - } } } }, @@ -17703,9 +17712,9 @@ "dev": true }, "resolve": { - "version": "1.9.0", - "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.9.0.tgz", - "integrity": "sha512-TZNye00tI67lwYvzxCxHGjwTNlUV70io54/Ed4j6PscB8xVfuBJpRenI/o6dVk0cY0PYTY27AgCoGGxRnYuItQ==", + "version": "1.10.0", + "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.10.0.tgz", + "integrity": "sha512-3sUr9aq5OfSg2S9pNtPA9hL1FVEAjvfOC4leW0SNf/mpnaakz2a9femSd6LqAww2RaFctwyf1lCqnTHuF1rxDg==", "requires": { "path-parse": "^1.0.6" } @@ -17878,9 +17887,9 @@ } }, "rxjs": { - "version": "6.3.3", - "resolved": "https://registry.npmjs.org/rxjs/-/rxjs-6.3.3.tgz", - "integrity": "sha512-JTWmoY9tWCs7zvIk/CvRjhjGaOd+OVBM987mxFo+OW66cGpdKjZcpmc74ES1sB//7Kl/PAe8+wEakuhG4pcgOw==", + "version": "6.4.0", + "resolved": "https://registry.npmjs.org/rxjs/-/rxjs-6.4.0.tgz", + "integrity": "sha512-Z9Yfa11F6B9Sg/BK9MnqnQ+aQYicPLtilXBp2yUtDt2JRCE0h26d33EnfO3ZxoNxG0T92OUucP3Ct7cpfkdFfw==", "dev": true, "requires": { "tslib": "^1.9.0" @@ -18195,6 +18204,12 @@ "yargs": "^7.0.0" }, "dependencies": { + "ansi-regex": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-2.1.1.tgz", + "integrity": "sha1-w7M6te42DYbg5ijwRorn7yfWVN8=", + "dev": true + }, "camelcase": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-3.0.0.tgz", @@ -18212,6 +18227,12 @@ "wrap-ansi": "^2.0.0" } }, + "invert-kv": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/invert-kv/-/invert-kv-1.0.0.tgz", + "integrity": "sha1-EEqOSqym09jNFXqO+L+rLXo//bY=", + "dev": true + }, "is-fullwidth-code-point": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-1.0.0.tgz", @@ -18221,6 +18242,15 @@ "number-is-nan": "^1.0.0" } }, + "lcid": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/lcid/-/lcid-1.0.0.tgz", + "integrity": "sha1-MIrMr6C8SDo4Z7S28rlQYlHRuDU=", + "dev": true, + "requires": { + "invert-kv": "^1.0.0" + } + }, "os-locale": { "version": "1.4.0", "resolved": "https://registry.npmjs.org/os-locale/-/os-locale-1.4.0.tgz", @@ -18241,12 +18271,27 @@ "strip-ansi": "^3.0.0" } }, + "strip-ansi": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-3.0.1.tgz", + "integrity": "sha1-ajhfuIU9lS1f8F0Oiq+UJ43GPc8=", + "dev": true, + "requires": { + "ansi-regex": "^2.0.0" + } + }, "which-module": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/which-module/-/which-module-1.0.0.tgz", "integrity": "sha1-u6Y8qGGUiZT/MHc2CJ47lgJsKk8=", "dev": true }, + "y18n": { + "version": "3.2.1", + "resolved": "https://registry.npmjs.org/y18n/-/y18n-3.2.1.tgz", + "integrity": "sha1-bRX7qITAhnnA136I53WegR4H+kE=", + "dev": true + }, "yargs": { "version": "7.1.0", "resolved": "https://registry.npmjs.org/yargs/-/yargs-7.1.0.tgz", @@ -18327,9 +18372,9 @@ }, "dependencies": { "ajv-keywords": { - "version": "3.2.0", - "resolved": "https://registry.npmjs.org/ajv-keywords/-/ajv-keywords-3.2.0.tgz", - "integrity": "sha1-6GuBnGAs+IIa1jdBNpjx3sAhhHo=", + "version": "3.3.0", + "resolved": "https://registry.npmjs.org/ajv-keywords/-/ajv-keywords-3.3.0.tgz", + "integrity": "sha512-CMzN9S62ZOO4sA/mJZIO4S++ZM7KFWzH3PPWkveLhy4OZ9i1/VatgwWMD46w/XbGCBy7Ye0gCk+Za6mmyfKK7g==", "dev": true } } @@ -18819,9 +18864,9 @@ "integrity": "sha512-VE0SOVEHCk7Qc8ulkWw3ntAzXuqf7S2lvwQaDLRnUeIEaKNQJzV6BwmLKhOqT61aGhfUMrXeaBk+oDGCzvhcug==" }, "sshpk": { - "version": "1.16.0", - "resolved": "https://registry.npmjs.org/sshpk/-/sshpk-1.16.0.tgz", - "integrity": "sha512-Zhev35/y7hRMcID/upReIvRse+I9SVhyVre/KTJSJQWMz3C3+G+HpO7m1wK/yckEtujKZ7dS4hkVxAnmHaIGVQ==", + "version": "1.16.1", + "resolved": "https://registry.npmjs.org/sshpk/-/sshpk-1.16.1.tgz", + "integrity": "sha512-HXXqVUq7+pcKeLqqZj6mHFUMvXtOJt1uoUx09pFW6011inTMxqI8BA8PM95myrIyyKwdnzjdFjLiE6KBPVtJIg==", "requires": { "asn1": "~0.2.3", "assert-plus": "^1.0.0", @@ -18920,9 +18965,9 @@ "integrity": "sha1-NbCYdbT/SfJqd35QmzCQoyJr8ks=" }, "stream-browserify": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/stream-browserify/-/stream-browserify-2.0.1.tgz", - "integrity": "sha1-ZiZu5fm9uZQKTkUUyvtDu3Hlyds=", + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/stream-browserify/-/stream-browserify-2.0.2.tgz", + "integrity": "sha512-nX6hmklHs/gr2FuxYDltq8fJA1GDlxKQCz8O/IM4atRqBH8OORmBNgfvW5gG10GT/qQ9u0CzIvr2X5Pkt6ntqg==", "dev": true, "requires": { "inherits": "~2.0.1", @@ -19017,16 +19062,6 @@ "requires": { "astral-regex": "^1.0.0", "strip-ansi": "^4.0.0" - }, - "dependencies": { - "strip-ansi": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-4.0.0.tgz", - "integrity": "sha1-qEeQIusaw2iocTibY1JixQXuNo8=", - "requires": { - "ansi-regex": "^3.0.0" - } - } } }, "string-width": { @@ -19036,16 +19071,6 @@ "requires": { "is-fullwidth-code-point": "^2.0.0", "strip-ansi": "^4.0.0" - }, - "dependencies": { - "strip-ansi": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-4.0.0.tgz", - "integrity": "sha1-qEeQIusaw2iocTibY1JixQXuNo8=", - "requires": { - "ansi-regex": "^3.0.0" - } - } } }, "string.prototype.trim": { @@ -19085,18 +19110,11 @@ "dev": true }, "strip-ansi": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-3.0.1.tgz", - "integrity": "sha1-ajhfuIU9lS1f8F0Oiq+UJ43GPc8=", + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-4.0.0.tgz", + "integrity": "sha1-qEeQIusaw2iocTibY1JixQXuNo8=", "requires": { - "ansi-regex": "^2.0.0" - }, - "dependencies": { - "ansi-regex": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-2.1.1.tgz", - "integrity": "sha1-w7M6te42DYbg5ijwRorn7yfWVN8=" - } + "ansi-regex": "^3.0.0" } }, "strip-bom": { @@ -19458,9 +19476,9 @@ } }, "ignore": { - "version": "5.0.4", - "resolved": "https://registry.npmjs.org/ignore/-/ignore-5.0.4.tgz", - "integrity": "sha512-WLsTMEhsQuXpCiG173+f3aymI43SXa+fB1rSfbzyP4GkPP+ZFVuO0/3sFUGNBtifisPeDcl/uD/Y2NxZ7xFq4g==", + "version": "5.0.5", + "resolved": "https://registry.npmjs.org/ignore/-/ignore-5.0.5.tgz", + "integrity": "sha512-kOC8IUb8HSDMVcYrDVezCxpJkzSQWTAzf3olpKM6o9rM5zpojx23O0Fl8Wr4+qJ6ZbPEHqf1fdwev/DS7v7pmA==", "dev": true }, "import-lazy": { @@ -19581,9 +19599,9 @@ "dev": true }, "postcss": { - "version": "7.0.11", - "resolved": "https://registry.npmjs.org/postcss/-/postcss-7.0.11.tgz", - "integrity": "sha512-9AXb//5UcjeOEof9T+yPw3XTa5SL207ZOIC/lHYP4mbUTEh4M0rDAQekQpVANCZdwQwKhBtFZCk3i3h3h2hdWg==", + "version": "7.0.14", + "resolved": "https://registry.npmjs.org/postcss/-/postcss-7.0.14.tgz", + "integrity": "sha512-NsbD6XUUMZvBxtQAJuWDJeeC4QFsmWsfozWxCJPWf3M55K9iu2iMDaKqyoOdTJ1R4usBXuxlVFAIo8rZPQD4Bg==", "dev": true, "requires": { "chalk": "^2.4.2", @@ -19592,12 +19610,12 @@ } }, "postcss-less": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/postcss-less/-/postcss-less-3.1.0.tgz", - "integrity": "sha512-+fDH2A9zV8B4gFu3Idhq8ma09/mMBXXc03T2lL9CHjBQqKrfUit+TrQrnojc6Y4k7N4E+tyE1Uj5U1tcoKtXLQ==", + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/postcss-less/-/postcss-less-3.1.2.tgz", + "integrity": "sha512-66ZBVo1JGkQ7r13M97xcHcyarWpgg21RaqIZWZXHE3XOtb5+ywK1uZWeY1DYkYRkIX/l8Hvxnx9iSKB68nFr+w==", "dev": true, "requires": { - "postcss": "^7.0.3" + "postcss": "^7.0.14" } }, "postcss-scss": { @@ -19633,9 +19651,9 @@ "dev": true }, "slice-ansi": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/slice-ansi/-/slice-ansi-2.0.0.tgz", - "integrity": "sha512-4j2WTWjp3GsZ+AOagyzVbzp4vWGtZ0hEZ/gDY/uTvm6MTxUfTUIsnMIFb1bn8o0RuXiqUw15H1bue8f22Vw2oQ==", + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/slice-ansi/-/slice-ansi-2.1.0.tgz", + "integrity": "sha512-Qu+VC3EwYLldKa1fCxuuvULvSJOKEgk9pi8dZeCVK7TqBfUNTH4sFkk4joj8afVSfAYgJoSOetjx9QWOJ5mYoQ==", "dev": true, "requires": { "ansi-styles": "^3.2.0", @@ -19659,14 +19677,14 @@ } }, "table": { - "version": "5.2.0", - "resolved": "https://registry.npmjs.org/table/-/table-5.2.0.tgz", - "integrity": "sha512-hAdBBAMCZl4/U3eQhsPN2Z8wRJC98lpRhDW2I86VQbPBqyj4E681VhvUkfb90qUJ4rnRfu8t4/8SGHPsAH1ygg==", + "version": "5.2.2", + "resolved": "https://registry.npmjs.org/table/-/table-5.2.2.tgz", + "integrity": "sha512-f8mJmuu9beQEDkKHLzOv4VxVYlU68NpdzjbGPl69i4Hx0sTopJuNxuzJd17iV2h24dAfa93u794OnDA5jqXvfQ==", "dev": true, "requires": { "ajv": "^6.6.1", "lodash": "^4.17.11", - "slice-ansi": "2.0.0", + "slice-ansi": "^2.0.0", "string-width": "^2.1.1" } } @@ -19699,9 +19717,9 @@ } }, "stylelint-scss": { - "version": "3.5.0", - "resolved": "https://registry.npmjs.org/stylelint-scss/-/stylelint-scss-3.5.0.tgz", - "integrity": "sha512-i8YhQd7IWWEacjUGvZycQ16c9NBj+Dbir1UwfQMlK1+5hr7crtxoo4j8TS8RR5ILP6g3bHSn24a8AvKrtFDBlQ==", + "version": "3.5.1", + "resolved": "https://registry.npmjs.org/stylelint-scss/-/stylelint-scss-3.5.1.tgz", + "integrity": "sha512-XNWKTU1a2EUNWdauxHPTJlGNNQzIbg48OTTIdBs5xTXxpbYAGtX/J+jBqMPjxfdySXijc/mexubuZ+ZinUGGgw==", "dev": true, "requires": { "lodash": "^4.17.11", @@ -19740,9 +19758,9 @@ }, "dependencies": { "postcss": { - "version": "7.0.11", - "resolved": "https://registry.npmjs.org/postcss/-/postcss-7.0.11.tgz", - "integrity": "sha512-9AXb//5UcjeOEof9T+yPw3XTa5SL207ZOIC/lHYP4mbUTEh4M0rDAQekQpVANCZdwQwKhBtFZCk3i3h3h2hdWg==", + "version": "7.0.14", + "resolved": "https://registry.npmjs.org/postcss/-/postcss-7.0.14.tgz", + "integrity": "sha512-NsbD6XUUMZvBxtQAJuWDJeeC4QFsmWsfozWxCJPWf3M55K9iu2iMDaKqyoOdTJ1R4usBXuxlVFAIo8rZPQD4Bg==", "dev": true, "requires": { "chalk": "^2.4.2", @@ -19828,11 +19846,11 @@ } }, "tannin": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/tannin/-/tannin-1.0.1.tgz", - "integrity": "sha512-dDtnwHQ63bS/Gz0ZLY+E+JCdRoTZkmoKDoC64y3hzAD2X2qrp8jSuWNUjtiYHA48mtj4Ens9xl4knAOm1t+rfQ==", + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/tannin/-/tannin-1.0.2.tgz", + "integrity": "sha512-5pqwELzsIO+zO3V3/jjlMR/ykzK41YNFLvb4SwPeAgrTiCjXwL/P3Om5uOiJk/iKdq6lBIO94rYAfBsEHu2vlA==", "requires": { - "@tannin/plural-forms": "^1.0.0" + "@tannin/plural-forms": "^1.0.2" } }, "tapable": { @@ -19887,6 +19905,29 @@ "dev": true, "requires": { "execa": "^0.7.0" + }, + "dependencies": { + "execa": { + "version": "0.7.0", + "resolved": "https://registry.npmjs.org/execa/-/execa-0.7.0.tgz", + "integrity": "sha1-lEvs00zEHuMqY6n68nrVpl/Fl3c=", + "dev": true, + "requires": { + "cross-spawn": "^5.0.1", + "get-stream": "^3.0.0", + "is-stream": "^1.1.0", + "npm-run-path": "^2.0.0", + "p-finally": "^1.0.0", + "signal-exit": "^3.0.0", + "strip-eof": "^1.0.0" + } + }, + "get-stream": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/get-stream/-/get-stream-3.0.0.tgz", + "integrity": "sha1-jpQ9E1jcN1VQVOy+LtsFqhdO3hQ=", + "dev": true + } } }, "terser": { @@ -20004,12 +20045,6 @@ "figgy-pudding": "^3.5.1" } }, - "y18n": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/y18n/-/y18n-4.0.0.tgz", - "integrity": "sha512-r9S/ZyXu/Xu9q1tYlpsLIsa3EeLXXk0VwlxqTcFRfg9EhMW+17kbt9G0NrgCmhGb5vT2hyhJZLfDGx+7+5Uj/w==", - "dev": true - }, "yallist": { "version": "3.0.3", "resolved": "https://registry.npmjs.org/yallist/-/yallist-3.0.3.tgz", @@ -20113,9 +20148,9 @@ "integrity": "sha1-9PrTM0R7wLB9TcjpIJ2POaisd+g=" }, "tinydate": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/tinydate/-/tinydate-1.0.0.tgz", - "integrity": "sha1-IPMXVqE5We+MV+wTO6KbWt4ELKw=", + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/tinydate/-/tinydate-1.0.1.tgz", + "integrity": "sha512-Imqa6iv3Ig5FmC3ESwmqczusIn1h8D5RqNbpatGc1eLHeoytuhodbsAPpSJ8iKiLhxBtLuRsrywWHlJM1bA3Rg==", "dev": true }, "tmp": { @@ -20678,9 +20713,9 @@ "integrity": "sha512-cwESVXlO3url9YWlFW/TA9cshCEhtu7IKJ/p5soJ/gGpj7vbvFrAY/eIioQ6Dw23KjZhYgiIo8HOs1nQ2vr/oQ==" }, "util": { - "version": "0.10.4", - "resolved": "https://registry.npmjs.org/util/-/util-0.10.4.tgz", - "integrity": "sha512-0Pm9hTQ3se5ll1XihRic3FDIku70C+iHUdT/W926rSgHV5QgXsYbKZN8MSC3tJtSkhuROzvsQjAaFENRXr+19A==", + "version": "0.11.1", + "resolved": "https://registry.npmjs.org/util/-/util-0.11.1.tgz", + "integrity": "sha512-HShAsny+zS2TZfaXxD9tYj4HQGlBezXZMZuM/S5PKLLoZkShZiGk9o5CzukI1LVHZvjdvZ2Sj1aW/Ndn2NB/HQ==", "dev": true, "requires": { "inherits": "2.0.3" @@ -20736,9 +20771,9 @@ } }, "validator": { - "version": "10.10.0", - "resolved": "https://registry.npmjs.org/validator/-/validator-10.10.0.tgz", - "integrity": "sha512-DyZyLJlMXM3CGdVaVHE/EDzCagMRoPI3mmGdxxNQbqkGqh56+M3d1i0ZAWd69En8U21DHbPTn12aOdhO+hfm5w==" + "version": "10.11.0", + "resolved": "https://registry.npmjs.org/validator/-/validator-10.11.0.tgz", + "integrity": "sha512-X/p3UZerAIsbBfN/IwahhYaBbY68EN/UQBWHtsbXGT5bfrH/p4NQzUCG1kF/rtKaNpnJ7jAu6NGTdSNtyNIXMw==" }, "value-equal": { "version": "0.4.0", @@ -20886,9 +20921,9 @@ }, "dependencies": { "ajv-keywords": { - "version": "3.2.0", - "resolved": "https://registry.npmjs.org/ajv-keywords/-/ajv-keywords-3.2.0.tgz", - "integrity": "sha1-6GuBnGAs+IIa1jdBNpjx3sAhhHo=", + "version": "3.3.0", + "resolved": "https://registry.npmjs.org/ajv-keywords/-/ajv-keywords-3.3.0.tgz", + "integrity": "sha512-CMzN9S62ZOO4sA/mJZIO4S++ZM7KFWzH3PPWkveLhy4OZ9i1/VatgwWMD46w/XbGCBy7Ye0gCk+Za6mmyfKK7g==", "dev": true }, "arr-diff": { @@ -21220,12 +21255,6 @@ "yargs": "^12.0.2" }, "dependencies": { - "camelcase": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-5.0.0.tgz", - "integrity": "sha512-faqwZqnWxbxn+F1d399ygeamQNy3lPp/H9H6rNrqYh4FSVCtcY+3cub1MxA8o9mDd55mM8Aghuu/kuyYA6VTsA==", - "dev": true - }, "cross-spawn": { "version": "6.0.5", "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-6.0.5.tgz", @@ -21239,39 +21268,6 @@ "which": "^1.2.9" } }, - "execa": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/execa/-/execa-1.0.0.tgz", - "integrity": "sha512-adbxcyWV46qiHyvSp50TKt05tB4tK3HcmF7/nxfAdhnox83seTDbwnaqKO4sXRy7roHAIFqJP/Rw/AuEbX61LA==", - "dev": true, - "requires": { - "cross-spawn": "^6.0.0", - "get-stream": "^4.0.0", - "is-stream": "^1.1.0", - "npm-run-path": "^2.0.0", - "p-finally": "^1.0.0", - "signal-exit": "^3.0.0", - "strip-eof": "^1.0.0" - } - }, - "find-up": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/find-up/-/find-up-3.0.0.tgz", - "integrity": "sha512-1yD6RmLI1XBfxugvORwlck6f75tYL+iR0jqwsOrOxMZyGYqUuDhJ0l4AXdO1iX/FTs9cBAMEk1gWSEx1kSbylg==", - "dev": true, - "requires": { - "locate-path": "^3.0.0" - } - }, - "get-stream": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/get-stream/-/get-stream-4.1.0.tgz", - "integrity": "sha512-GMat4EJ5161kIy2HevLlr4luNjBgvmj413KaQA7jt4V8B4RDsfpHk7WQ9GVqfYyyx8OS/L66Kox+rJRNklLK7w==", - "dev": true, - "requires": { - "pump": "^3.0.0" - } - }, "import-local": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/import-local/-/import-local-2.0.0.tgz", @@ -21282,77 +21278,6 @@ "resolve-cwd": "^2.0.0" } }, - "invert-kv": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/invert-kv/-/invert-kv-2.0.0.tgz", - "integrity": "sha512-wPVv/y/QQ/Uiirj/vh3oP+1Ww+AWehmi1g5fFWGPF6IpCBCDVrhgHRMvrLfdYcwDh3QJbGXDW4JAuzxElLSqKA==", - "dev": true - }, - "lcid": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/lcid/-/lcid-2.0.0.tgz", - "integrity": "sha512-avPEb8P8EGnwXKClwsNUgryVjllcRqtMYa49NTsbQagYuT1DcXnl1915oxWjoyGrXR6zH/Y0Zc96xWsPcoDKeA==", - "dev": true, - "requires": { - "invert-kv": "^2.0.0" - } - }, - "locate-path": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-3.0.0.tgz", - "integrity": "sha512-7AO748wWnIhNqAuaty2ZWHkQHRSNfPVIsPIfwEOWO22AmaoVrWavlOcMR5nzTLNYvp36X220/maaRsrec1G65A==", - "dev": true, - "requires": { - "p-locate": "^3.0.0", - "path-exists": "^3.0.0" - } - }, - "mem": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/mem/-/mem-4.0.0.tgz", - "integrity": "sha512-WQxG/5xYc3tMbYLXoXPm81ET2WDULiU5FxbuIoNbJqLOOI8zehXFdZuiUEgfdrU2mVB1pxBZUGlYORSrpuJreA==", - "dev": true, - "requires": { - "map-age-cleaner": "^0.1.1", - "mimic-fn": "^1.0.0", - "p-is-promise": "^1.1.0" - } - }, - "os-locale": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/os-locale/-/os-locale-3.1.0.tgz", - "integrity": "sha512-Z8l3R4wYWM40/52Z+S265okfFj8Kt2cC2MKY+xNi3kFs+XGI7WXu/I309QQQYbRW4ijiZ+yxs9pqEhJh0DqW3Q==", - "dev": true, - "requires": { - "execa": "^1.0.0", - "lcid": "^2.0.0", - "mem": "^4.0.0" - } - }, - "p-limit": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-2.1.0.tgz", - "integrity": "sha512-NhURkNcrVB+8hNfLuysU8enY5xn2KXphsHBaC2YmRNTZRc7RWusw6apSpdEj3jo4CMb6W9nrF6tTnsJsJeyu6g==", - "dev": true, - "requires": { - "p-try": "^2.0.0" - } - }, - "p-locate": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-3.0.0.tgz", - "integrity": "sha512-x+12w/To+4GFfgJhBEpiDcLozRJGegY+Ei7/z0tSLkMmxGZNybVMSfWj9aJn8Z5Fc7dBUNJOOVgPv2H7IwulSQ==", - "dev": true, - "requires": { - "p-limit": "^2.0.0" - } - }, - "p-try": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/p-try/-/p-try-2.0.0.tgz", - "integrity": "sha512-hMp0onDKIajHfIkdRk3P4CdCmErkYAxxDtP3Wx/4nZ3aGlau2VKh3mZpcuFkH27WQkL/3WBCPOktzA9ZOAnMQQ==", - "dev": true - }, "pkg-dir": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/pkg-dir/-/pkg-dir-3.0.0.tgz", @@ -21361,36 +21286,6 @@ "requires": { "find-up": "^3.0.0" } - }, - "yargs": { - "version": "12.0.5", - "resolved": "https://registry.npmjs.org/yargs/-/yargs-12.0.5.tgz", - "integrity": "sha512-Lhz8TLaYnxq/2ObqHDql8dX8CJi97oHxrjUcYtzKbbykPtVW9WB+poxI+NM2UIzsMgNCZTIf0AQwsjK5yMAqZw==", - "dev": true, - "requires": { - "cliui": "^4.0.0", - "decamelize": "^1.2.0", - "find-up": "^3.0.0", - "get-caller-file": "^1.0.1", - "os-locale": "^3.0.0", - "require-directory": "^2.1.1", - "require-main-filename": "^1.0.1", - "set-blocking": "^2.0.0", - "string-width": "^2.0.0", - "which-module": "^2.0.0", - "y18n": "^3.2.1 || ^4.0.0", - "yargs-parser": "^11.1.1" - } - }, - "yargs-parser": { - "version": "11.1.1", - "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-11.1.1.tgz", - "integrity": "sha512-C6kB/WJDiaxONLJQnF8ccx9SEeoTTLek8RVbaOIsrAUS8VrBEXfmeSnCZxygc+XC2sNMBIwOOnfcxiynjHsVSQ==", - "dev": true, - "requires": { - "camelcase": "^5.0.0", - "decamelize": "^1.2.0" - } } } }, @@ -21494,6 +21389,11 @@ "strip-ansi": "^3.0.1" }, "dependencies": { + "ansi-regex": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-2.1.1.tgz", + "integrity": "sha1-w7M6te42DYbg5ijwRorn7yfWVN8=" + }, "is-fullwidth-code-point": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-1.0.0.tgz", @@ -21511,6 +21411,14 @@ "is-fullwidth-code-point": "^1.0.0", "strip-ansi": "^3.0.0" } + }, + "strip-ansi": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-3.0.1.tgz", + "integrity": "sha1-ajhfuIU9lS1f8F0Oiq+UJ43GPc8=", + "requires": { + "ansi-regex": "^2.0.0" + } } } }, @@ -21528,9 +21436,9 @@ } }, "write-file-atomic": { - "version": "2.3.0", - "resolved": "https://registry.npmjs.org/write-file-atomic/-/write-file-atomic-2.3.0.tgz", - "integrity": "sha512-xuPeK4OdjWqtfi59ylvVL0Yn35SF3zgcAcv7rBPFHVaEapaDr4GdGgm3j7ckTwH9wHL7fGmgfAnb0+THrHb8tA==", + "version": "2.4.2", + "resolved": "https://registry.npmjs.org/write-file-atomic/-/write-file-atomic-2.4.2.tgz", + "integrity": "sha512-s0b6vB3xIVRLWywa6X9TOMA7k9zio0TMOsl9ZnDkliA/cfJlpHXAscj0gbHVJiTdIuAYpIyqS5GW91fqm6gG5g==", "requires": { "graceful-fs": "^4.1.11", "imurmurhash": "^0.1.4", @@ -21613,9 +21521,9 @@ "dev": true }, "y18n": { - "version": "3.2.1", - "resolved": "https://registry.npmjs.org/y18n/-/y18n-3.2.1.tgz", - "integrity": "sha1-bRX7qITAhnnA136I53WegR4H+kE=" + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/y18n/-/y18n-4.0.0.tgz", + "integrity": "sha512-r9S/ZyXu/Xu9q1tYlpsLIsa3EeLXXk0VwlxqTcFRfg9EhMW+17kbt9G0NrgCmhGb5vT2hyhJZLfDGx+7+5Uj/w==" }, "yallist": { "version": "2.1.2", @@ -21633,6 +21541,12 @@ "parent-require": "^1.0.0" }, "dependencies": { + "ansi-regex": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-2.1.1.tgz", + "integrity": "sha1-w7M6te42DYbg5ijwRorn7yfWVN8=", + "dev": true + }, "ansi-styles": { "version": "2.2.1", "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-2.2.1.tgz", @@ -21652,6 +21566,15 @@ "supports-color": "^2.0.0" } }, + "strip-ansi": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-3.0.1.tgz", + "integrity": "sha1-ajhfuIU9lS1f8F0Oiq+UJ43GPc8=", + "dev": true, + "requires": { + "ansi-regex": "^2.0.0" + } + }, "supports-color": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-2.0.0.tgz", @@ -21661,30 +21584,31 @@ } }, "yargs": { - "version": "11.1.0", - "resolved": "https://registry.npmjs.org/yargs/-/yargs-11.1.0.tgz", - "integrity": "sha512-NwW69J42EsCSanF8kyn5upxvjp5ds+t3+udGBeTbFnERA+lF541DDpMawzo4z6W/QrzNM18D+BPMiOBibnFV5A==", + "version": "12.0.5", + "resolved": "https://registry.npmjs.org/yargs/-/yargs-12.0.5.tgz", + "integrity": "sha512-Lhz8TLaYnxq/2ObqHDql8dX8CJi97oHxrjUcYtzKbbykPtVW9WB+poxI+NM2UIzsMgNCZTIf0AQwsjK5yMAqZw==", "requires": { "cliui": "^4.0.0", - "decamelize": "^1.1.1", - "find-up": "^2.1.0", + "decamelize": "^1.2.0", + "find-up": "^3.0.0", "get-caller-file": "^1.0.1", - "os-locale": "^2.0.0", + "os-locale": "^3.0.0", "require-directory": "^2.1.1", "require-main-filename": "^1.0.1", "set-blocking": "^2.0.0", "string-width": "^2.0.0", "which-module": "^2.0.0", - "y18n": "^3.2.1", - "yargs-parser": "^9.0.2" + "y18n": "^3.2.1 || ^4.0.0", + "yargs-parser": "^11.1.1" } }, "yargs-parser": { - "version": "9.0.2", - "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-9.0.2.tgz", - "integrity": "sha1-nM9qQ0YP5O1Aqbto9I1DuKaMwHc=", + "version": "11.1.1", + "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-11.1.1.tgz", + "integrity": "sha512-C6kB/WJDiaxONLJQnF8ccx9SEeoTTLek8RVbaOIsrAUS8VrBEXfmeSnCZxygc+XC2sNMBIwOOnfcxiynjHsVSQ==", "requires": { - "camelcase": "^4.1.0" + "camelcase": "^5.0.0", + "decamelize": "^1.2.0" } } } From 49e78b90cf4391751949ce2abf3fbffd14c524b8 Mon Sep 17 00:00:00 2001 From: Joshua T Flowers Date: Thu, 31 Jan 2019 09:04:11 +0800 Subject: [PATCH 46/53] Add settings page with excluded order statuses (https://github.com/woocommerce/woocommerce-admin/pull/1364) * Add settings page routes * Add control options for excluded statuses * Add control options for excluded statuses * Add excluded order statuses to rest api * Add wc settings to wc-api * Add wc settings to wc-api * Split and validate multiselect values in settings controller * Add wcAdminSettings to wcSettings global * Set initial excluded statuses from serverside wcSettings data * Add extensible filter for wcSettings global * Split arrays into comma separated strings in wc-api * Extract setting as separate component * Extra settings to config file * Add checkboxGroup option as input type * Separate status types into default and custom groups * Add setting option styling * Add responsive styling for settings * Fix wpClosedMenu and wpOpenMenu for settings page * Add support for resetting to default values * Only show checkbox group if options are available * Add proptypes to Setting component * Add extensible filter to analytics settings * Add readme for settings config and extensibility * Hook up excluded status settings to reports * Pass object to settings API instead of comma delimited string * Fix inpuType -> inputType typo * Remove hasError from constructor * Bump settings API to v4 * Use interpolateComponents instead of dangerously setting html * Use empty array in initial excldued statuses setting value if none is retrieved * Remove double check for refunded status in default order statuses * Update settings wc-api to use namespace * Add aria=labelledby to checkbox group --- .../client/analytics/settings/README.md | 34 +++++ .../client/analytics/settings/config.js | 68 +++++++++ .../client/analytics/settings/index.js | 134 +++++++++++++++++ .../client/analytics/settings/index.scss | 17 +++ .../client/analytics/settings/setting.js | 141 ++++++++++++++++++ .../client/analytics/settings/setting.scss | 49 ++++++ .../client/layout/controller.js | 7 + .../client/wc-api/settings/index.js | 13 ++ .../client/wc-api/settings/mutations.js | 10 ++ .../client/wc-api/settings/operations.js | 71 +++++++++ .../client/wc-api/settings/selectors.js | 14 ++ .../client/wc-api/wc-api-spec.js | 9 +- ...-admin-rest-setting-options-controller.php | 27 ++++ .../includes/class-wc-admin-api-init.php | 16 ++ .../class-wc-admin-reports-data-store.php | 4 +- plugins/woocommerce-admin/lib/admin.php | 44 ++++++ .../woocommerce-admin/lib/client-assets.php | 20 +++ 17 files changed, 676 insertions(+), 2 deletions(-) create mode 100644 plugins/woocommerce-admin/client/analytics/settings/README.md create mode 100644 plugins/woocommerce-admin/client/analytics/settings/config.js create mode 100644 plugins/woocommerce-admin/client/analytics/settings/index.js create mode 100644 plugins/woocommerce-admin/client/analytics/settings/index.scss create mode 100644 plugins/woocommerce-admin/client/analytics/settings/setting.js create mode 100644 plugins/woocommerce-admin/client/analytics/settings/setting.scss create mode 100644 plugins/woocommerce-admin/client/wc-api/settings/index.js create mode 100644 plugins/woocommerce-admin/client/wc-api/settings/mutations.js create mode 100644 plugins/woocommerce-admin/client/wc-api/settings/operations.js create mode 100644 plugins/woocommerce-admin/client/wc-api/settings/selectors.js create mode 100644 plugins/woocommerce-admin/includes/api/class-wc-admin-rest-setting-options-controller.php diff --git a/plugins/woocommerce-admin/client/analytics/settings/README.md b/plugins/woocommerce-admin/client/analytics/settings/README.md new file mode 100644 index 00000000000..fa8f5ffaa0d --- /dev/null +++ b/plugins/woocommerce-admin/client/analytics/settings/README.md @@ -0,0 +1,34 @@ +Settings +======= + +The settings used to modify the way data is retreived or displayed in WooCommerce reports. + +## Extending Settings + +Settings can be added, removed, or modified outside oc `wc-admin` by hooking into `woocommerce_admin_analytics_settings`. For example: + +```js +addFilter( 'woocommerce_admin_analytics_settings', 'wc-example/my-setting', settings => { + return [ + ...settings, + { + name: 'custom_setting', + label: __( 'Custom setting:', 'wc-admin' ), + inputType: 'text', + helpText: __( 'Help text to describe what the setting does.' ), + initialValue: 'Initial value used', + defaultValue: 'Default value', + }, + ]; +} ); +``` + +Each settings has the following properties: + +- `name` (string): The slug of the setting to be updated. +- `label` (string): The label used to describe and displayed next to the setting. +- `inputType` (enum: text|checkbox|checkboxGroup): The type of input to use. +- `helpText` (string): Text displayed beneath the setting. +- `options` (array): Array of options used for inputs with selectable options. +- `initialValue` (string|array): Initial value used when rendering the setting. +- `defaultValue` (string|array): Value used when resetting to default settings. diff --git a/plugins/woocommerce-admin/client/analytics/settings/config.js b/plugins/woocommerce-admin/client/analytics/settings/config.js new file mode 100644 index 00000000000..282108f82f9 --- /dev/null +++ b/plugins/woocommerce-admin/client/analytics/settings/config.js @@ -0,0 +1,68 @@ +/** @format */ +/** + * External dependencies + */ +import { __, sprintf } from '@wordpress/i18n'; +import { applyFilters } from '@wordpress/hooks'; +import interpolateComponents from 'interpolate-components'; + +/** + * WooCommerce dependencies + */ +import { Link } from '@woocommerce/components'; + +const SETTINGS_FILTER = 'woocommerce_admin_analytics_settings'; + +const defaultOrderStatuses = [ + 'completed', + 'processing', + 'refunded', + 'cancelled', + 'failed', + 'pending', + 'on-hold', +]; +const orderStatuses = Object.keys( wcSettings.orderStatuses ) + .filter( status => status !== 'refunded' ) + .map( key => { + return { + value: key, + label: wcSettings.orderStatuses[ key ], + description: sprintf( + __( 'Exclude the %s status from reports', 'wc-admin' ), + wcSettings.orderStatuses[ key ] + ), + }; + } ); + +export const analyticsSettings = applyFilters( SETTINGS_FILTER, [ + { + name: 'woocommerce_excluded_report_order_statuses', + label: __( 'Excluded Statuses:', 'wc-admin' ), + inputType: 'checkboxGroup', + options: [ + { + key: 'defaultStatuses', + options: orderStatuses.filter( status => defaultOrderStatuses.includes( status.value ) ), + }, + { + key: 'customStatuses', + label: __( 'Custom Statuses', 'wc-admin' ), + options: orderStatuses.filter( status => ! defaultOrderStatuses.includes( status.value ) ), + }, + ], + helpText: interpolateComponents( { + mixedString: __( + 'Orders with these statuses are excluded from the totals in your reports. ' + + 'The {{strong}}Refunded{{/strong}} status can not be excluded. {{moreLink}}Learn more{{/moreLink}}', + 'wc-admin' + ), + components: { + strong: , + moreLink: , // @TODO: this needs to be replaced with a real link. + }, + } ), + initialValue: wcSettings.wcAdminSettings.woocommerce_excluded_report_order_statuses || [], + defaultValue: [ 'pending', 'cancelled', 'failed' ], + }, +] ); diff --git a/plugins/woocommerce-admin/client/analytics/settings/index.js b/plugins/woocommerce-admin/client/analytics/settings/index.js new file mode 100644 index 00000000000..2b0c1faac80 --- /dev/null +++ b/plugins/woocommerce-admin/client/analytics/settings/index.js @@ -0,0 +1,134 @@ +/** @format */ +/** + * External dependencies + */ +import { __ } from '@wordpress/i18n'; +import { Button } from '@wordpress/components'; +import { Component, Fragment } from '@wordpress/element'; +import { compose } from '@wordpress/compose'; +import { remove } from 'lodash'; +import { withDispatch } from '@wordpress/data'; + +/** + * WooCommerce dependencies + */ +import { SectionHeader, useFilters } from '@woocommerce/components'; + +/** + * Internal dependencies + */ +import './index.scss'; +import { analyticsSettings } from './config'; +import Header from 'header'; +import Setting from './setting'; + +const SETTINGS_FILTER = 'woocommerce_admin_analytics_settings'; + +class Settings extends Component { + constructor() { + super( ...arguments ); + + const settings = {}; + analyticsSettings.forEach( setting => ( settings[ setting.name ] = setting.initialValue ) ); + + this.state = { + settings: settings, + }; + + this.handleInputChange = this.handleInputChange.bind( this ); + } + + componentDidCatch( error ) { + this.setState( { + hasError: true, + } ); + /* eslint-disable no-console */ + console.warn( error ); + /* eslint-enable no-console */ + } + + resetDefaults = () => { + if ( + window.confirm( + __( 'Are you sure you want to reset all settings to default values?', 'wc-admin' ) + ) + ) { + const settings = {}; + analyticsSettings.forEach( setting => ( settings[ setting.name ] = setting.defaultValue ) ); + this.setState( { settings }, this.saveChanges ); + } + }; + + saveChanges = () => { + this.props.updateSettings( this.state.settings ); + // @TODO: Need a confirmation on successful update. + }; + + handleInputChange( e ) { + const { checked, name, type, value } = e.target; + const { settings } = this.state; + + if ( 'checkbox' === type ) { + if ( checked ) { + settings[ name ].push( value ); + } else { + remove( settings[ name ], v => v === value ); + } + } else { + settings[ name ] = value; + } + + this.setState( { settings } ); + } + + render() { + const { hasError } = this.state; + if ( hasError ) { + return null; + } + + return ( + +
+ +
+ { analyticsSettings.map( setting => ( + + ) ) } +
+ + +
+
+ + ); + } +} + +export default compose( + withDispatch( dispatch => { + const { updateSettings } = dispatch( 'wc-api' ); + + return { + updateSettings, + }; + } ) +)( useFilters( SETTINGS_FILTER )( Settings ) ); diff --git a/plugins/woocommerce-admin/client/analytics/settings/index.scss b/plugins/woocommerce-admin/client/analytics/settings/index.scss new file mode 100644 index 00000000000..773dbca9c27 --- /dev/null +++ b/plugins/woocommerce-admin/client/analytics/settings/index.scss @@ -0,0 +1,17 @@ +/** @format */ + +.woocommerce-settings__wrapper { + @include breakpoint( '>782px' ) { + padding: 0 ($gap - 3); + } +} + +.woocommerce-settings__actions { + @include breakpoint( '>1280px' ) { + margin-left: 15%; + } + + button { + margin-right: $gap; + } +} diff --git a/plugins/woocommerce-admin/client/analytics/settings/setting.js b/plugins/woocommerce-admin/client/analytics/settings/setting.js new file mode 100644 index 00000000000..ef7b96286ab --- /dev/null +++ b/plugins/woocommerce-admin/client/analytics/settings/setting.js @@ -0,0 +1,141 @@ +/** @format */ +/** + * External dependencies + */ +import { Component } from '@wordpress/element'; +import PropTypes from 'prop-types'; +import { uniqueId } from 'lodash'; + +/** + * Internal dependencies + */ +import './setting.scss'; + +class Setting extends Component { + renderInput = () => { + const { handleChange, name, inputType, options, value } = this.props; + const id = uniqueId( name ); + + switch ( inputType ) { + case 'checkboxGroup': + return options.map( + optionGroup => + optionGroup.options.length > 0 && ( +
+ { optionGroup.label && ( + + { optionGroup.label } + + ) } + { this.renderCheckboxOptions( optionGroup.options ) } +
+ ) + ); + case 'checkbox': + return this.renderCheckboxOptions( options ); + case 'text': + default: + return ( + + ); + } + }; + + renderCheckboxOptions( options ) { + const { handleChange, name, value } = this.props; + + return options.map( option => { + const id = uniqueId( name + '-' + option.value ); + return ( + + ); + } ); + } + + render() { + const { helpText, label, name } = this.props; + + return ( +
+
+ { label } +
+
+ { this.renderInput() } + { helpText && { helpText } } +
+
+ ); + } +} + +Setting.propTypes = { + /** + * Function assigned to the onChange of all inputs. + */ + handleChange: PropTypes.func.isRequired, + /** + * Optional help text displayed underneath the setting. + */ + helpText: PropTypes.oneOfType( [ PropTypes.string, PropTypes.array ] ), + /** + * Type of input to use; defaults to a text input. + */ + inputType: PropTypes.oneOf( [ 'checkbox', 'checkboxGroup', 'text' ] ), + /** + * Label used for describing the setting. + */ + label: PropTypes.string.isRequired, + /** + * Setting slug applied to input names. + */ + name: PropTypes.string.isRequired, + /** + * Array of options used for when the `inputType` allows multiple selections. + */ + options: PropTypes.arrayOf( + PropTypes.shape( { + /** + * Input value for this option. + */ + value: PropTypes.string, + /** + * Label for this option or above a group for a group `inputType`. + */ + label: PropTypes.string, + /** + * Description used for screen readers. + */ + description: PropTypes.string, + /** + * Key used for a group `inputType`. + */ + key: PropTypes.string, + /** + * Nested options for a group `inputType`. + */ + options: PropTypes.array, + } ) + ), + /** + * The string value used for the input or array of items if the input allows multiselection. + */ + value: PropTypes.oneOfType( [ PropTypes.string, PropTypes.array ] ), +}; + +export default Setting; diff --git a/plugins/woocommerce-admin/client/analytics/settings/setting.scss b/plugins/woocommerce-admin/client/analytics/settings/setting.scss new file mode 100644 index 00000000000..98440fdcbfb --- /dev/null +++ b/plugins/woocommerce-admin/client/analytics/settings/setting.scss @@ -0,0 +1,49 @@ +/** @format */ + +.woocommerce-setting { + display: flex; + margin-bottom: $gap-large; + @include breakpoint( '<1280px' ) { + flex-direction: column; + } +} + +.woocommerce-setting__label { + @include font-size(16); + margin-bottom: $gap; + padding-right: $gap; + font-weight: bold; + @include breakpoint( '>1280px' ) { + width: 15%; + } +} + +.woocommerce-setting__options { + display: flex; + flex-direction: column; + @include breakpoint( '>1280px' ) { + width: 35%; + } + + label { + width: 100%; + display: block; + margin-bottom: $gap-small; + color: $core-grey-dark-500; + } + + input[type='checkbox'] { + margin-right: $gap-small; + } +} + +.woocommerce-setting__options-group-label { + display: block; + font-weight: bold; + margin-bottom: $gap-small; +} + +.woocommerce-setting__help { + font-style: italic; + color: $core-grey-dark-300; +} diff --git a/plugins/woocommerce-admin/client/layout/controller.js b/plugins/woocommerce-admin/client/layout/controller.js index 7050d60ff78..d9960efd0a8 100644 --- a/plugins/woocommerce-admin/client/layout/controller.js +++ b/plugins/woocommerce-admin/client/layout/controller.js @@ -16,6 +16,7 @@ import { getPersistedQuery, stringifyQuery } from '@woocommerce/navigation'; */ import Analytics from 'analytics'; import AnalyticsReport from 'analytics/report'; +import AnalyticsSettings from 'analytics/settings'; import Dashboard from 'dashboard'; import DevDocs from 'devdocs'; @@ -33,6 +34,12 @@ const getPages = () => { wpOpenMenu: 'toplevel_page_wc-admin--analytics-revenue', wpClosedMenu: 'toplevel_page_woocommerce', }, + { + container: AnalyticsSettings, + path: '/analytics/settings', + wpOpenMenu: 'toplevel_page_wc-admin--analytics-revenue', + wpClosedMenu: 'toplevel_page_woocommerce', + }, { container: AnalyticsReport, path: '/analytics/:report', diff --git a/plugins/woocommerce-admin/client/wc-api/settings/index.js b/plugins/woocommerce-admin/client/wc-api/settings/index.js new file mode 100644 index 00000000000..094ff3a82fa --- /dev/null +++ b/plugins/woocommerce-admin/client/wc-api/settings/index.js @@ -0,0 +1,13 @@ +/** @format */ +/** + * Internal dependencies + */ +import operations from './operations'; +import selectors from './selectors'; +import mutations from './mutations'; + +export default { + operations, + selectors, + mutations, +}; diff --git a/plugins/woocommerce-admin/client/wc-api/settings/mutations.js b/plugins/woocommerce-admin/client/wc-api/settings/mutations.js new file mode 100644 index 00000000000..f7e2ff21b23 --- /dev/null +++ b/plugins/woocommerce-admin/client/wc-api/settings/mutations.js @@ -0,0 +1,10 @@ +/** @format */ + +const updateSettings = operations => settingFields => { + const resourceKey = 'settings'; + operations.update( [ resourceKey ], { [ resourceKey ]: settingFields } ); +}; + +export default { + updateSettings, +}; diff --git a/plugins/woocommerce-admin/client/wc-api/settings/operations.js b/plugins/woocommerce-admin/client/wc-api/settings/operations.js new file mode 100644 index 00000000000..ada55a54fb2 --- /dev/null +++ b/plugins/woocommerce-admin/client/wc-api/settings/operations.js @@ -0,0 +1,71 @@ +/** @format */ + +/** + * External dependencies + */ +import apiFetch from '@wordpress/api-fetch'; +import { pick } from 'lodash'; + +/** + * Internal dependencies + */ +import { NAMESPACE } from '../constants'; + +function read( resourceNames, fetch = apiFetch ) { + return [ ...readSettings( resourceNames, fetch ) ]; +} + +function update( resourceNames, data, fetch = apiFetch ) { + return [ ...updateSettings( resourceNames, data, fetch ) ]; +} + +function readSettings( resourceNames, fetch ) { + if ( resourceNames.includes( 'settings' ) ) { + const url = NAMESPACE + '/settings/wc_admin'; + + return [ + fetch( { path: url } ) + .then( settingsToSettingsResource ) + .catch( error => { + return { [ 'settings' ]: { error: String( error.message ) } }; + } ), + ]; + } + return []; +} + +function updateSettings( resourceNames, data, fetch ) { + const resourceName = 'settings'; + const settingsFields = [ 'woocommerce_excluded_report_order_statuses' ]; + + if ( resourceNames.includes( resourceName ) ) { + const url = NAMESPACE + '/settings/wc_admin/'; + const settingsData = pick( data[ resourceName ], settingsFields ); + + const promises = Object.keys( settingsData ).map( setting => { + return fetch( { + path: url + setting, + method: 'POST', + data: { value: settingsData[ setting ] }, + } ) + .then( settingsToSettingsResource ) + .catch( error => { + return { [ resourceName ]: { error } }; + } ); + } ); + + return [ promises ]; + } + return []; +} + +function settingsToSettingsResource( settings ) { + const settingsData = {}; + settings.forEach( setting => ( settingsData[ setting.id ] = setting.value ) ); + return { [ 'settings' ]: { data: settingsData } }; +} + +export default { + read, + update, +}; diff --git a/plugins/woocommerce-admin/client/wc-api/settings/selectors.js b/plugins/woocommerce-admin/client/wc-api/settings/selectors.js new file mode 100644 index 00000000000..d586d90958e --- /dev/null +++ b/plugins/woocommerce-admin/client/wc-api/settings/selectors.js @@ -0,0 +1,14 @@ +/** @format */ + +/** + * Internal dependencies + */ +import { DEFAULT_REQUIREMENT } from '../constants'; + +const getSettings = ( getResource, requireResource ) => ( requirement = DEFAULT_REQUIREMENT ) => { + return requireResource( requirement, 'settings' ).data; +}; + +export default { + getSettings, +}; diff --git a/plugins/woocommerce-admin/client/wc-api/wc-api-spec.js b/plugins/woocommerce-admin/client/wc-api/wc-api-spec.js index df38ee4a4ef..9c2df94cb55 100644 --- a/plugins/woocommerce-admin/client/wc-api/wc-api-spec.js +++ b/plugins/woocommerce-admin/client/wc-api/wc-api-spec.js @@ -9,11 +9,13 @@ import orders from './orders'; import reportItems from './reports/items'; import reportStats from './reports/stats'; import reviews from './reviews'; +import settings from './settings'; import user from './user'; function createWcApiSpec() { return { mutations: { + ...settings.mutations, ...user.mutations, }, selectors: { @@ -23,6 +25,7 @@ function createWcApiSpec() { ...reportItems.selectors, ...reportStats.selectors, ...reviews.selectors, + ...settings.selectors, ...user.selectors, }, operations: { @@ -34,11 +37,15 @@ function createWcApiSpec() { ...reportItems.operations.read( resourceNames ), ...reportStats.operations.read( resourceNames ), ...reviews.operations.read( resourceNames ), + ...settings.operations.read( resourceNames ), ...user.operations.read( resourceNames ), ]; }, update( resourceNames, data ) { - return [ ...user.operations.update( resourceNames, data ) ]; + return [ + ...settings.operations.update( resourceNames, data ), + ...user.operations.update( resourceNames, data ), + ]; }, }, }; diff --git a/plugins/woocommerce-admin/includes/api/class-wc-admin-rest-setting-options-controller.php b/plugins/woocommerce-admin/includes/api/class-wc-admin-rest-setting-options-controller.php new file mode 100644 index 00000000000..bfa1a2fe6ec --- /dev/null +++ b/plugins/woocommerce-admin/includes/api/class-wc-admin-rest-setting-options-controller.php @@ -0,0 +1,27 @@ +[\w-]+)'] ) + && isset( $endpoints['/wc/v4/settings/(?P[\w-]+)'][5] ) + && isset( $endpoints['/wc/v4/settings/(?P[\w-]+)'][4] ) + && isset( $endpoints['/wc/v4/settings/(?P[\w-]+)'][3] ) + && $endpoints['/wc/v4/settings/(?P[\w-]+)'][3]['callback'][0] instanceof WC_Admin_REST_Setting_Options_Controller + && $endpoints['/wc/v4/settings/(?P[\w-]+)'][4]['callback'][0] instanceof WC_Admin_REST_Setting_Options_Controller + && $endpoints['/wc/v4/settings/(?P[\w-]+)'][5]['callback'][0] instanceof WC_Admin_REST_Setting_Options_Controller + ) { + $endpoints['/wc/v4/settings/(?P[\w-]+)'][0] = $endpoints['/wc/v4/settings/(?P[\w-]+)'][3]; + $endpoints['/wc/v4/settings/(?P[\w-]+)'][1] = $endpoints['/wc/v4/settings/(?P[\w-]+)'][4]; + $endpoints['/wc/v4/settings/(?P[\w-]+)'][2] = $endpoints['/wc/v4/settings/(?P[\w-]+)'][5]; + } + return $endpoints; } diff --git a/plugins/woocommerce-admin/includes/data-stores/class-wc-admin-reports-data-store.php b/plugins/woocommerce-admin/includes/data-stores/class-wc-admin-reports-data-store.php index c884cae5826..a8b5a5d4b79 100644 --- a/plugins/woocommerce-admin/includes/data-stores/class-wc-admin-reports-data-store.php +++ b/plugins/woocommerce-admin/includes/data-stores/class-wc-admin-reports-data-store.php @@ -406,7 +406,9 @@ class WC_Admin_Reports_Data_Store { * @return array */ protected static function get_excluded_report_order_statuses() { - return apply_filters( 'woocommerce_reports_excluded_order_statuses', array( 'refunded', 'pending', 'failed', 'cancelled' ) ); + $excluded_statuses = WC_Admin_Settings::get_option( 'woocommerce_excluded_report_order_statuses', array( 'pending', 'failed', 'cancelled' ) ); + $excluded_statuses[] = 'refunded'; + return apply_filters( 'woocommerce_reports_excluded_order_statuses', $excluded_statuses ); } /** diff --git a/plugins/woocommerce-admin/lib/admin.php b/plugins/woocommerce-admin/lib/admin.php index bfc132c9295..6d5bd9f0483 100644 --- a/plugins/woocommerce-admin/lib/admin.php +++ b/plugins/woocommerce-admin/lib/admin.php @@ -157,6 +157,14 @@ function wc_admin_register_pages() { ) ); + wc_admin_register_page( + array( + 'title' => __( 'Settings', 'wc-admin' ), + 'parent' => '/analytics/revenue', + 'path' => '/analytics/settings', + ) + ); + if ( defined( 'WP_DEBUG' ) && WP_DEBUG && defined( 'SCRIPT_DEBUG' ) && SCRIPT_DEBUG ) { wc_admin_register_page( array( @@ -447,3 +455,39 @@ function wc_admin_update_user_data_values( $values, $user, $field_id ) { return $updates; } + +/** + * Register the admin settings for use in the WC REST API + * + * @param array $groups Array of setting groups. + * @return array + */ +function wc_admin_add_settings_group( $groups ) { + $groups[] = array( + 'id' => 'wc_admin', + 'label' => __( 'WooCommerce Admin', 'wc-admin' ), + 'description' => __( 'Settings for WooCommerce admin reporting.', 'wc-admin' ), + ); + return $groups; +} +add_filter( 'woocommerce_settings_groups', 'wc_admin_add_settings_group' ); + +/** + * Add WC Admin specific settings + * + * @param array $settings Array of settings in wc admin group. + * @return array + */ +function wc_admin_add_settings( $settings ) { + $settings[] = array( + 'id' => 'woocommerce_excluded_report_order_statuses', + 'option_key' => 'woocommerce_excluded_report_order_statuses', + 'label' => __( 'Excluded report order statuses', 'wc-admin' ), + 'description' => __( 'Statuses that should not be included when calculating report totals.', 'wc-admin' ), + 'default' => '', + 'type' => 'multiselect', + 'options' => format_order_statuses( wc_get_order_statuses() ), + ); + return $settings; +}; +add_filter( 'woocommerce_settings-wc_admin', 'wc_admin_add_settings' ); diff --git a/plugins/woocommerce-admin/lib/client-assets.php b/plugins/woocommerce-admin/lib/client-assets.php index 5725689e037..8de11211e06 100644 --- a/plugins/woocommerce-admin/lib/client-assets.php +++ b/plugins/woocommerce-admin/lib/client-assets.php @@ -206,10 +206,13 @@ function wc_admin_print_script_settings() { ), 'currentUserData' => $current_user_data, ); + $settings = wc_admin_add_custom_settings( $settings ); foreach ( $preload_data_endpoints as $key => $endpoint ) { $settings['dataEndpoints'][ $key ] = $preload_data[ $endpoint ]['body']; } + + $settings = apply_filters( 'wc_admin_wc_settings', $settings ); ?>