diff --git a/.npmrc b/.npmrc index b6f27f135..d5831dd51 100644 --- a/.npmrc +++ b/.npmrc @@ -1 +1,2 @@ engine-strict=true +legacy-peer-deps=true diff --git a/classes/Collector.php b/classes/Collector.php index 15809a7ce..689bb4f78 100644 --- a/classes/Collector.php +++ b/classes/Collector.php @@ -160,6 +160,7 @@ final public function set_id( $id ) { * @return void */ final public function process_concerns() { + /** @var array $wp_filter */ global $wp_filter; $tracked = array(); diff --git a/classes/Collector_Assets.php b/classes/Collector_Assets.php index abf0b03f0..7df2ed48d 100644 --- a/classes/Collector_Assets.php +++ b/classes/Collector_Assets.php @@ -238,7 +238,7 @@ public function process() { sort( $all_dependents ); $this->data->dependents = $all_dependents; - $this->data->missing_dependencies = array_unique( $missing_dependencies ); + $this->data->missing_dependencies = $missing_dependencies; } /** @@ -295,7 +295,7 @@ public function get_dependents( _WP_Dependency $dependency, WP_Dependencies $dep * } */ public function get_dependency_data( _WP_Dependency $dependency ) { - /** @var QM_Data_Assets */ + /** @var QM_Data_Assets $data */ $data = $this->get_data(); $loader = rtrim( $this->get_dependency_type(), 's' ); $src = $dependency->src; diff --git a/classes/Dispatcher.php b/classes/Dispatcher.php index b24ce39cf..1ccaf50a0 100644 --- a/classes/Dispatcher.php +++ b/classes/Dispatcher.php @@ -209,6 +209,7 @@ public static function verify_cookie( $value ) { * @return bool True on success, false on failure. */ public static function switch_to_locale( $locale ) { + /** @var ?WP_Locale_Switcher $wp_locale_switcher */ global $wp_locale_switcher; if ( function_exists( 'switch_to_locale' ) && ( $wp_locale_switcher instanceof WP_Locale_Switcher ) ) { @@ -227,6 +228,7 @@ public static function switch_to_locale( $locale ) { * @return string|false Locale on success, false on error. */ public static function restore_previous_locale() { + /** @var ?WP_Locale_Switcher $wp_locale_switcher */ global $wp_locale_switcher; if ( function_exists( 'restore_previous_locale' ) && ( $wp_locale_switcher instanceof WP_Locale_Switcher ) ) { diff --git a/classes/Hook.php b/classes/Hook.php index fe3156e85..17545257d 100644 --- a/classes/Hook.php +++ b/classes/Hook.php @@ -20,7 +20,14 @@ class QM_Hook { * type: 'action'|'filter', * actions: list, + * callback: array{ + * accepted_args: int, + * name?: string, + * file?: string|false, + * line?: int|false, + * error?: WP_Error, + * component?: QM_Component, + * }, * }>, * parts: list, * components: array, diff --git a/classes/QM.php b/classes/QM.php index 3d60c324b..34de17fb2 100644 --- a/classes/QM.php +++ b/classes/QM.php @@ -151,7 +151,7 @@ public static function debug( $message, array $context = array() ) { * @return void */ public static function log( $level, $message, array $context = array() ) { - /** @var QM_Collector_Logger */ + /** @var QM_Collector_Logger $logger */ $logger = QM_Collectors::get( 'logger' ); $logger->log( $level, $message, $context ); } diff --git a/classes/Timer.php b/classes/Timer.php index dd6b6aeca..13ba41f1e 100644 --- a/classes/Timer.php +++ b/classes/Timer.php @@ -102,7 +102,14 @@ public function lap( array $data = null, $name = null ) { } /** - * @return mixed[] + * @return array> + * @phpstan-return array */ public function get_laps() { diff --git a/classes/Util.php b/classes/Util.php index afd9a7cdf..d5b02a66a 100644 --- a/classes/Util.php +++ b/classes/Util.php @@ -323,9 +323,10 @@ public static function get_file_component( $file ) { * @param array $callback * @return array * @phpstan-return array{ + * accepted_args: int, * name?: string, * file?: string|false, - * line?: string|false, + * line?: int|false, * error?: WP_Error, * component?: QM_Component, * } @@ -396,7 +397,7 @@ public static function populate_callback( array $callback ) { if ( '__lambda_func' === $name || 0 === strpos( $name, 'lambda_' ) ) { if ( $callback['file'] && preg_match( '|(?P.*)\((?P[0-9]+)\)|', $callback['file'], $matches ) ) { $callback['file'] = $matches['file']; - $callback['line'] = $matches['line']; + $callback['line'] = (int) $matches['line']; $file = trim( self::standard_dir( $callback['file'], '' ), '/' ); /* translators: 1: Line number, 2: File name */ $callback['name'] = sprintf( __( 'Anonymous function on line %1$d of %2$s', 'query-monitor' ), $callback['line'], $file ); diff --git a/collectors/block_editor.php b/collectors/block_editor.php index 5813f1660..1ed07ad50 100644 --- a/collectors/block_editor.php +++ b/collectors/block_editor.php @@ -128,6 +128,7 @@ public function filter_render_block( $block_content, array $block ) { } public function process() { + /** @var ?string $_wp_current_template_content */ global $_wp_current_template_content; $this->data->block_editor_enabled = self::wp_block_editor_enabled(); @@ -228,7 +229,7 @@ protected static function wp_has_blocks( $content ) { /** * @param string $content - * @return array|null + * @return array */ protected static function wp_parse_blocks( $content ) { if ( function_exists( 'parse_blocks' ) ) { @@ -237,11 +238,11 @@ protected static function wp_parse_blocks( $content ) { return gutenberg_parse_blocks( $content ); } - return null; + return array(); } /** - * @return array|null + * @return array */ protected static function wp_get_dynamic_block_names() { if ( function_exists( 'get_dynamic_block_names' ) ) { diff --git a/collectors/cache.php b/collectors/cache.php index 2461bdfbe..9abc17a92 100644 --- a/collectors/cache.php +++ b/collectors/cache.php @@ -24,6 +24,7 @@ public function get_storage(): QM_Data { * @return void */ public function process() { + /** @var ?object $wp_object_cache */ global $wp_object_cache; $this->data->has_object_cache = (bool) wp_using_ext_object_cache(); diff --git a/collectors/db_dupes.php b/collectors/db_dupes.php index e6733b503..4efa5a329 100644 --- a/collectors/db_dupes.php +++ b/collectors/db_dupes.php @@ -56,7 +56,6 @@ public function process() { foreach ( $query_ids as $query_id ) { if ( isset( $dbq_data->rows[ $query_id ]['trace'] ) ) { - /** @var QM_Backtrace */ $trace = $dbq_data->rows[ $query_id ]['trace']; $stack = array_column( $trace->get_filtered_trace(), 'id' ); $component = $trace->get_component(); @@ -68,8 +67,7 @@ public function process() { $components[ $sql ][ $component->name ] = 1; } } else { - /** @var array */ - $stack = $dbq_data->rows[ $query_id ]['stack']; + $stack = $dbq_data->rows[ $query_id ]['stack'] ?? array(); } // Populate the caller counts for this query diff --git a/collectors/db_queries.php b/collectors/db_queries.php index aec3b7f90..1190b7d81 100644 --- a/collectors/db_queries.php +++ b/collectors/db_queries.php @@ -21,6 +21,19 @@ } /** + * @phpstan-type QueryStandard array{ + * 0: string, + * 1: float, + * 2: string, + * trace?: QM_Backtrace, + * result?: int|bool|WP_Error, + * } + * @phpstan-type QueryVIP array{ + * query: string, + * elapsed: float, + * debug: string, + * } + * * @extends QM_DataCollector */ class QM_Collector_DB_Queries extends QM_DataCollector { @@ -107,6 +120,10 @@ protected function log_caller( $caller, $ltime, $type ) { * @return void */ public function process_db_object() { + /** + * @var WP_Query $wp_the_query + * @var wpdb $wpdb + */ global $wp_the_query, $wpdb; $this->wpdb = $wpdb; @@ -129,17 +146,7 @@ public function process_db_object() { } /** - * @phpstan-var array{ - * 0: string, - * 1: float, - * 2: string, - * trace?: QM_Backtrace, - * result?: int|bool|WP_Error, - * }|array{ - * query: string, - * elapsed: float, - * debug: string, - * } $query + * @phpstan-var QueryStandard|QueryVIP $query */ foreach ( $wpdb->queries as $query ) { $callers = array(); @@ -179,7 +186,6 @@ public function process_db_object() { $caller = $query['trace']->get_caller(); $caller_name = $caller['display'] ?? 'Unknown'; $caller = $caller['display'] ?? 'Unknown'; - $filtered_trace = $query['trace']->get_filtered_trace(); } else { @@ -190,7 +196,6 @@ public function process_db_object() { $callers = QM_Backtrace::get_filtered_stack( $callers ); $caller = reset( $callers ); $caller_name = $caller; - $filtered_trace = null; } diff --git a/collectors/debug_bar.php b/collectors/debug_bar.php index ccd3abb4b..c30900dd7 100644 --- a/collectors/debug_bar.php +++ b/collectors/debug_bar.php @@ -63,7 +63,7 @@ public function render() { * @return void */ function register_qm_collectors_debug_bar() { - + /** @var ?Debug_Bar $debug_bar */ global $debug_bar; if ( class_exists( 'Debug_Bar', false ) || qm_debug_bar_being_activated() ) { diff --git a/collectors/environment.php b/collectors/environment.php index 0275d1283..6fa09f80f 100644 --- a/collectors/environment.php +++ b/collectors/environment.php @@ -75,7 +75,7 @@ protected static function get_error_levels( $error_reporting ) { * @return void */ public function process() { - + /** @var string $wp_version */ global $wp_version; $mysql_vars = array( @@ -88,7 +88,7 @@ public function process() { 'innodb_buffer_pool_size' => false, # The amount of memory allocated to the InnoDB buffer pool ); - /** @var QM_Collector_DB_Queries|null */ + /** @var QM_Collector_DB_Queries|null $dbq */ $dbq = QM_Collectors::get( 'db_queries' ); if ( $dbq ) { @@ -101,7 +101,7 @@ public function process() { } // phpcs:disable - /** @var array|null */ + /** @var array|null $variables */ $variables = $dbq->wpdb->get_results( " SHOW VARIABLES WHERE Variable_name IN ( '" . implode( "', '", array_keys( $mysql_vars ) ) . "' ) @@ -141,7 +141,6 @@ public function process() { $this->data->db = array( 'info' => $info, - 'vars' => $mysql_vars, 'variables' => $variables ?: array(), ); } diff --git a/collectors/http.php b/collectors/http.php index d8e82bc48..b0f9d9920 100644 --- a/collectors/http.php +++ b/collectors/http.php @@ -41,7 +41,7 @@ class QM_Collector_HTTP extends QM_DataCollector { * @phpstan-var array, - * response: mixed[]|WP_Error, + * response: array|WP_Error, * info: array|null, * }> */ @@ -283,7 +283,7 @@ public function action_fsockopen_after_request( $headers, array $info = null ) { * @return void */ public function log_http_response( $response, array $args, $url ) { - /** @var string */ + /** @var string $key */ $key = $args['_qm_key']; if ( is_array( $response ) && isset( $response['body'] ) ) { @@ -299,7 +299,7 @@ public function log_http_response( $response, array $args, $url ) { ); if ( isset( $args['_qm_original_key'] ) ) { - /** @var string */ + /** @var string $original_key */ $original_key = $args['_qm_original_key']; $this->http_responses[ $original_key ]['end'] = $this->http_requests[ $original_key ]['start']; $this->http_responses[ $original_key ]['response'] = new WP_Error( 'http_request_not_executed', sprintf( diff --git a/collectors/request.php b/collectors/request.php index 3aebf033b..ff420d3f2 100644 --- a/collectors/request.php +++ b/collectors/request.php @@ -43,6 +43,7 @@ public function get_concerned_actions() { * @return array */ public function get_concerned_filters() { + /** @var WP_Rewrite $wp_rewrite */ global $wp_rewrite; $filters = array( @@ -138,7 +139,13 @@ public function get_concerned_constants() { * @return void */ public function process() { - + /** + * @var \WP $wp + * @var \WP_Query $wp_query + * @var \WP_Site $current_blog + * @var \WP_Network $current_site + * @var \WP_Rewrite $wp_rewrite + */ global $wp, $wp_query, $current_blog, $current_site, $wp_rewrite; $qo = get_queried_object(); @@ -204,7 +211,7 @@ public function process() { /** This filter is documented in wp-includes/class-wp.php */ $plugin_qvars = array_flip( apply_filters( 'query_vars', array() ) ); - /** @var array */ + /** @var array $qvars */ $qvars = $wp_query->query_vars; $query_vars = array(); @@ -237,61 +244,57 @@ public function process() { } } - switch ( true ) { - - case ! is_object( $qo ): - // Nada - break; - - case is_a( $qo, 'WP_Post' ): - // Single post - $this->data->queried_object['title'] = sprintf( - /* translators: 1: Post type name, 2: Post ID */ - __( 'Single %1$s: #%2$d', 'query-monitor' ), - get_post_type_object( $qo->post_type )->labels->singular_name, - $qo->ID - ); - break; - - case is_a( $qo, 'WP_User' ): - // Author archive - $this->data->queried_object['title'] = sprintf( - /* translators: %s: Author name */ - __( 'Author archive: %s', 'query-monitor' ), - $qo->user_nicename - ); - break; - - case is_a( $qo, 'WP_Term' ): - case property_exists( $qo, 'slug' ): - // Term archive - $this->data->queried_object['title'] = sprintf( - /* translators: %s: Taxonomy term name */ - __( 'Term archive: %s', 'query-monitor' ), - $qo->slug - ); - break; - - case is_a( $qo, 'WP_Post_Type' ): - case property_exists( $qo, 'has_archive' ): - // Post type archive - $this->data->queried_object['title'] = sprintf( - /* translators: %s: Post type name */ - __( 'Post type archive: %s', 'query-monitor' ), - $qo->name - ); - break; - - default: - // Unknown, but we have a queried object - $this->data->queried_object['title'] = __( 'Unknown queried object', 'query-monitor' ); - break; + if ( is_object( $qo ) ) { + $queried_object = array(); + + switch ( $qo::class ) { + case WP_Post::class: + // Single post + $queried_object['title'] = sprintf( + /* translators: 1: Post type name, 2: Post ID */ + __( 'Single %1$s: #%2$d', 'query-monitor' ), + get_post_type_object( $qo->post_type )->labels->singular_name, + $qo->ID + ); + break; + + case WP_User::class: + // Author archive + $queried_object['title'] = sprintf( + /* translators: %s: Author name */ + __( 'Author archive: %s', 'query-monitor' ), + $qo->user_nicename + ); + break; + + case WP_Term::class: + // Term archive + $queried_object['title'] = sprintf( + /* translators: %s: Taxonomy term name */ + __( 'Term archive: %s', 'query-monitor' ), + $qo->slug + ); + break; + + case WP_Post_Type::class: + // Post type archive + $queried_object['title'] = sprintf( + /* translators: %s: Post type name */ + __( 'Post type archive: %s', 'query-monitor' ), + $qo->name + ); + break; + + default: + // Unknown, but we have a queried object + $queried_object['title'] = __( 'Unknown queried object', 'query-monitor' ); + break; + } - } + $queried_object['data'] = $qo; + $queried_object['type'] = get_class( $qo ); - if ( $qo ) { - $this->data->queried_object['data'] = $qo; - $this->data->queried_object['type'] = get_class( $qo ); + $this->data->queried_object = $queried_object; } if ( isset( $_SERVER['REQUEST_METHOD'] ) ) { diff --git a/collectors/transients.php b/collectors/transients.php index d3b970156..793f1bb5e 100644 --- a/collectors/transients.php +++ b/collectors/transients.php @@ -26,6 +26,8 @@ public function get_storage(): QM_Data { public function set_up() { parent::set_up(); + $this->data->trans = array(); + add_action( 'setted_site_transient', array( $this, 'action_setted_site_transient' ), 10, 3 ); add_action( 'setted_transient', array( $this, 'action_setted_blog_transient' ), 10, 3 ); } diff --git a/composer.json b/composer.json index 5483b72a4..123b08d50 100644 --- a/composer.json +++ b/composer.json @@ -35,7 +35,7 @@ "johnbillion/plugin-infrastructure": "dev-trunk", "lucatume/wp-browser": "^3.0.21", "phpcompatibility/phpcompatibility-wp": "2.1.4", - "phpstan/phpstan": "^1.0", + "phpstan/phpstan": "^1.10.12", "phpstan/phpstan-phpunit": "^1.0", "roots/wordpress-core-installer": "^1.0.0", "roots/wordpress-full": "*", @@ -77,6 +77,7 @@ "test": [ "@composer validate --strict --no-check-lock", "@composer normalize --dry-run", + "npm run build-schemas", "@test:phpstan", "@test:phpcs", "@test:integration", diff --git a/data/admin.php b/data/admin.php index f6a18af70..26825835b 100644 --- a/data/admin.php +++ b/data/admin.php @@ -1,4 +1,11 @@ * @phpstan-var ?array{ * columns_filter: string, * sortables_filter: string, diff --git a/data/assets.php b/data/assets.php index 656afb49c..780c34214 100644 --- a/data/assets.php +++ b/data/assets.php @@ -1,4 +1,11 @@ , - * dependencies: array, + * dependents: array, + * dependencies: array, * } * @phpstan-type AssetList array */ class QM_Data_Assets extends QM_Data { /** - * @var ?array>> * @phpstan-var ?array{ - * missing: AssetList, - * broken: AssetList, - * header: AssetList, - * footer: AssetList, + * missing?: AssetList, + * broken?: AssetList, + * header?: AssetList, + * footer?: AssetList, * } */ public $assets; /** - * @var array * @phpstan-var array{ * missing: int, * broken: int, @@ -84,7 +89,7 @@ class QM_Data_Assets extends QM_Data { public $is_ssl; /** - * @var array + * @var array */ public $missing_dependencies; diff --git a/data/block_editor.php b/data/block_editor.php index d3778061e..56a06ace1 100644 --- a/data/block_editor.php +++ b/data/block_editor.php @@ -1,4 +1,11 @@ |null + * @var array */ public $post_blocks; @@ -40,5 +47,4 @@ class QM_Data_Block_Editor extends QM_Data { * @var int */ public $total_blocks; - } diff --git a/data/cache.php b/data/cache.php index 9234830e5..50a09df2d 100644 --- a/data/cache.php +++ b/data/cache.php @@ -1,4 +1,11 @@ */ public $opcode_cache_extensions; - } diff --git a/data/caps.php b/data/caps.php index 5c0a58f4d..5e00315a8 100644 --- a/data/caps.php +++ b/data/caps.php @@ -1,19 +1,25 @@ > - * @phpstan-var list, - * filtered_trace: list>, + * @phpstan-var array, + * filtered_trace: array>, * component: QM_Component, * result: bool, - * parts: list, + * parts: array, * name: string, * user: string, * }> diff --git a/data/conditionals.php b/data/conditionals.php index 193cf1142..c2d4e2cd3 100644 --- a/data/conditionals.php +++ b/data/conditionals.php @@ -1,4 +1,11 @@ > * @phpstan-var array{ - * true: list, - * false: list, - * na: list, + * true: array, + * false: array, + * na: array, * } */ public $conds; diff --git a/data/db_callers.php b/data/db_callers.php index 0e802f6b4..8109a3066 100644 --- a/data/db_callers.php +++ b/data/db_callers.php @@ -1,4 +1,11 @@ > * @phpstan-var array, * }> */ - public $times = array(); + public $times; } diff --git a/data/db_components.php b/data/db_components.php index 2f3a1fc52..fbfd1577c 100644 --- a/data/db_components.php +++ b/data/db_components.php @@ -1,4 +1,11 @@ > * @phpstan-var array, diff --git a/data/db_dupes.php b/data/db_dupes.php index 4f468910f..b36f956e9 100644 --- a/data/db_dupes.php +++ b/data/db_dupes.php @@ -1,4 +1,11 @@ , + * sql: string, + * ltime: float, + * result: int|bool|WP_Error, + * type: string, + * component: QM_Component|null, + * trace: ?QM_Backtrace, + * is_main_query: bool, + * filtered_trace?: array>, + * } + */ class QM_Data_DB_Queries extends QM_Data { /** * @var int @@ -27,7 +49,7 @@ class QM_Data_DB_Queries extends QM_Data { public $expensive; /** - * @var array> + * @phpstan-var array */ public $rows; @@ -47,14 +69,13 @@ class QM_Data_DB_Queries extends QM_Data { public $has_main_query; /** - * @var ?array> * @phpstan-var ?array, * }> */ - public $times = array(); + public $times; /** * @var ?array> diff --git a/data/doing_it_wrong.php b/data/doing_it_wrong.php index 6f2c694f5..ec5db9948 100644 --- a/data/doing_it_wrong.php +++ b/data/doing_it_wrong.php @@ -1,4 +1,11 @@ > * @phpstan-var array>, + * filtered_trace: array>, * message: string, * component: QM_Component, * }> diff --git a/data/environment.php b/data/environment.php index 874266003..1f015bda1 100644 --- a/data/environment.php +++ b/data/environment.php @@ -1,4 +1,11 @@ * @phpstan-var array{ * variables: array, * version: string|false, @@ -23,8 +28,6 @@ class QM_Data_Environment extends QM_Data { public $php; /** - * @TODO data class - * @var array * @phpstan-var array{ * info: array{ * server-version: string, @@ -34,27 +37,22 @@ class QM_Data_Environment extends QM_Data { * host: string, * database: string, * }, - * vars: array, - * variables: list, + * variables: array, * } */ public $db; /** - * @TODO data class - * @var array * @phpstan-var array{ * version: string, * environment_type?: string, * development_mode?: string, * constants: array, - * }> + * } */ public $wp; /** - * @TODO data class - * @var array * @phpstan-var array{ * name: string, * version: string|null, @@ -62,7 +60,7 @@ class QM_Data_Environment extends QM_Data { * host: string|null, * OS: string|null, * arch: string|null, - * }> + * } */ public $server; } diff --git a/data/hooks.php b/data/hooks.php index 85d4126d2..792cb43fe 100644 --- a/data/hooks.php +++ b/data/hooks.php @@ -1,4 +1,11 @@ > - * @phpstan-var list, + * callback: array{ + * accepted_args: int, + * name?: string, + * file?: string|false, + * line?: int|false, + * error?: WP_Error, + * component?: QM_Component, + * }, * }>, - * parts: list, + * parts: array, * components: array, * }> */ diff --git a/data/http.php b/data/http.php index 18028e9ef..dd4752586 100644 --- a/data/http.php +++ b/data/http.php @@ -1,4 +1,11 @@ > * @phpstan-var array, * component: QM_Component, - * filtered_trace: list>, + * filtered_trace: array>, * info: array|null, * host: string, * local: bool, * ltime: float, * redirected_to: string|null, - * response: mixed[]|WP_Error, + * response: array|WP_Error, * type: string, * url: string, * }> @@ -30,10 +36,9 @@ class QM_Data_HTTP extends QM_Data { public $ltime; /** - * @var array> * @phpstan-var array{ - * alert?: list, - * warning?: list, + * alert?: array, + * warning?: array, * } */ public $errors; diff --git a/data/languages.php b/data/languages.php index ea955c645..35885a991 100644 --- a/data/languages.php +++ b/data/languages.php @@ -1,4 +1,11 @@ >> * @phpstan-var array, * domain: string, * file: string|false, * found: int|false, @@ -40,15 +46,11 @@ class QM_Data_Languages extends QM_Data { public $language_attributes; /** - * MultilingualPress language. - * * @var string */ public $mlp_language; /** - * Polylang language. - * * @var string */ public $pll_language; diff --git a/data/logger.php b/data/logger.php index d7363ae5e..640330c11 100644 --- a/data/logger.php +++ b/data/logger.php @@ -1,4 +1,11 @@ * @phpstan-var array */ public $counts; /** - * @var array> - * @phpstan-var list>, * component: QM_Component, * level: QM_Collector_Logger::*, * }> diff --git a/data/multisite.php b/data/multisite.php index 9e4123914..ab53d6311 100644 --- a/data/multisite.php +++ b/data/multisite.php @@ -1,4 +1,11 @@ > - * @phpstan-var list>|null, + * filtered_trace: array>|null, * component: QM_Component, * calls: int, * } @@ -26,19 +33,16 @@ class QM_Data_PHP_Errors extends QM_Data { public $components; /** - * @var array>> * @phpstan-var errorObjects */ public $errors; /** - * @var array>> * @phpstan-var errorObjects */ public $suppressed; /** - * @var array>> * @phpstan-var errorObjects */ public $silenced; diff --git a/data/raw_request.php b/data/raw_request.php index 3665d6992..dc7f8fefd 100644 --- a/data/raw_request.php +++ b/data/raw_request.php @@ -1,4 +1,11 @@ * @phpstan-var array{ * title: string, * data: WP_User|false, @@ -16,12 +22,26 @@ class QM_Data_Request extends QM_Data { public $user; /** - * @var array> + * @phpstan-var array{ + * current_site?: array{ + * title: string, + * data: WP_Site, + * }, + * current_network?: array{ + * title: string, + * data: WP_Network, + * }, + * } */ public $multisite; /** - * @var array + * @phpstan-var array{ + * request: string, + * matched_rule?: string, + * matched_query?: string, + * query_string: string, + * } */ public $request; @@ -36,7 +56,11 @@ class QM_Data_Request extends QM_Data { public $plugin_qvars; /** - * @var array + * @phpstan-var ?array{ + * title: string, + * data?: WP_Term|WP_Post_Type|WP_Post|WP_User, + * type?: string, + * } */ public $queried_object; diff --git a/data/theme.php b/data/theme.php index b24418ebd..06554aa6f 100644 --- a/data/theme.php +++ b/data/theme.php @@ -1,4 +1,11 @@ > */ public $unsuccessful_template_parts; - } diff --git a/data/timing.php b/data/timing.php index ffe6efd70..36517f152 100644 --- a/data/timing.php +++ b/data/timing.php @@ -1,4 +1,11 @@ > + * @phpstan-var array>, + * component: QM_Component, + * }> */ public $warning; /** - * @var array> + * @phpstan-var array, + * filtered_trace: array>, + * component: QM_Component, + * start_time: float, + * end_time: float, + * }> */ public $timing; } diff --git a/data/transients.php b/data/transients.php index 80e678873..738fd90c2 100644 --- a/data/transients.php +++ b/data/transients.php @@ -1,4 +1,11 @@ >, * component: QM_Component, * type: string, * value: mixed, @@ -19,7 +26,7 @@ class QM_Data_Transients extends QM_Data { * size_formatted: string, * }> */ - public $trans = array(); + public $trans; /** * @var bool diff --git a/dispatchers/Html.php b/dispatchers/Html.php index cd972f1ed..c45b0f7f9 100644 --- a/dispatchers/Html.php +++ b/dispatchers/Html.php @@ -202,6 +202,7 @@ public function build_warning() { * @return void */ public function enqueue_assets() { + /** @var WP_Locale $wp_locale */ global $wp_locale; $deps = array( diff --git a/output/Html.php b/output/Html.php index 6f343dfb8..91d928320 100644 --- a/output/Html.php +++ b/output/Html.php @@ -525,7 +525,7 @@ public static function output_filename( $text, $file, $line = 0, $is_filename = } } - /** @var string */ + /** @var string $link_format */ $link_format = self::get_file_link_format(); $link = sprintf( $link_format, rawurlencode( $file ), intval( $link_line ) ); diff --git a/output/assets.tsx b/output/assets.tsx index f9747ac92..310031e7e 100644 --- a/output/assets.tsx +++ b/output/assets.tsx @@ -48,7 +48,9 @@ interface iAssetsProps { header: Array; host: string; is_ssl: boolean; - missing_dependencies: Array; + missing_dependencies: { + [k:string]: true; + } port: string; }; labels: { @@ -183,7 +185,7 @@ class Assets extends React.Component> { whiteSpace: 'nowrap', } } > - { data.missing_dependencies.includes( dep ) ? ( + { data.missing_dependencies[ dep ] ? ( <>   diff --git a/output/db.tsx b/output/db.tsx index 3135ba6ea..287993710 100644 --- a/output/db.tsx +++ b/output/db.tsx @@ -1,39 +1,24 @@ import { Warning } from 'qmi'; +import { + Environment as EnvironmentData, +} from 'qmi/data-types'; import * as React from 'react'; import { __, - sprintf, } from '@wordpress/i18n'; -interface dbItem { - 'server-version': string; // @TODO check - 'extension': string; // @TODO check - 'client-version': string; // @TODO check - 'user': string; - 'host': string; - 'database': string; -} - interface iDBProps { - name: string; - db: { - info: dbItem; - variables: { - Variable_name: string; - Value: string; - }[]; - } + db: EnvironmentData['db']; } class DB extends React.Component> { render() { const { - name, db, } = this.props; - const info: dbItem = { + const infoLabels = { 'server-version': __( 'Server Version', 'query-monitor' ), 'extension': __( 'Extension', 'query-monitor' ), 'client-version': __( 'Client Version', 'query-monitor' ), @@ -45,14 +30,14 @@ class DB extends React.Component> { return (

- { sprintf( __( 'Database: %s', 'query-monitor' ), name ) } + { __( 'Database', 'query-monitor' ) }

- { Object.keys( info ).map( ( key: keyof typeof info ) => ( + { Object.keys( infoLabels ).map( ( key: keyof typeof infoLabels ) => ( - { Object.keys( data.current_screen ).map( key => ( + { Object.keys( data.current_screen ).map( ( key: keyof typeof data.current_screen ) => ( ) ) } diff --git a/output/raw/db_queries.php b/output/raw/db_queries.php index 621bc7864..11b011cd5 100644 --- a/output/raw/db_queries.php +++ b/output/raw/db_queries.php @@ -5,6 +5,9 @@ * @package query-monitor */ +/** + * @phpstan-import-type QueryRow from QM_Data_DB_Queries + */ class QM_Output_Raw_DB_Queries extends QM_Output_Raw { /** @@ -82,8 +85,16 @@ public function get_output() { } /** - * @param array $row + * @param array $row + * @phpstan-param QueryRow $row * @return array + * @phpstan-return array{ + * i: int, + * sql: string, + * time: float, + * stack: string[], + * result: int|bool|WP_Error, + * } */ protected function output_query_row( array $row ) { $output = array(); @@ -100,7 +111,7 @@ protected function output_query_row( array $row ) { $stack[] = $item['display']; } } else { - $stack = $row['stack']; + $stack = $row['stack'] ?? array(); } $output['stack'] = $stack; diff --git a/output/server.tsx b/output/server.tsx index 24fb397a0..95771bd59 100644 --- a/output/server.tsx +++ b/output/server.tsx @@ -1,30 +1,27 @@ import { Warning } from 'qmi'; +import { + Environment as EnvironmentData, +} from 'qmi/data-types'; import * as React from 'react'; import { __ } from '@wordpress/i18n'; -interface ServerItem { - name: string; - version: string; - address: string; - host: string; - OS: string; -} - interface iServerProps { - server: ServerItem; + server: EnvironmentData['server']; } class WordPress extends React.Component> { render() { const { server } = this.props; - const info: ServerItem = { + const info = { name: __( 'Software', 'query-monitor' ), version: __( 'Version', 'query-monitor' ), address: __( 'Address', 'query-monitor' ), host: __( 'Host', 'query-monitor' ), + /* translators: OS stands for Operating System */ OS: __( 'OS', 'query-monitor' ), + arch: __( 'Architecture', 'query-monitor' ), }; return ( diff --git a/output/wordpress.tsx b/output/wordpress.tsx index 8a532585c..2eaf54ddc 100644 --- a/output/wordpress.tsx +++ b/output/wordpress.tsx @@ -1,9 +1,12 @@ +import { + Environment as EnvironmentData, +} from 'qmi/data-types'; import * as React from 'react'; import { __ } from '@wordpress/i18n'; interface iWordPressProps { - wordpress: any; + wordpress: EnvironmentData['wp']; } class WordPress extends React.Component> { diff --git a/package-lock.json b/package-lock.json index 45e080624..a8aa7e4c5 100644 --- a/package-lock.json +++ b/package-lock.json @@ -38,6 +38,7 @@ "eslint-plugin-react": "^7.21.5", "eslint-plugin-react-hooks": "^4.2.0", "eslint-plugin-sort-destructure-keys": "^1.3.5", + "json-schema-to-typescript": "^12", "plugin-infrastructure": "file:vendor/johnbillion/plugin-infrastructure", "sass": "^1", "source-map-loader": "^2", @@ -46,6 +47,7 @@ "version-bump-prompt": "^6.1.0", "webpack": "^5.47.1", "webpack-cli": "^4.9.1", + "wp-json-schemas": "^3", "wp-types": "^3" }, "engines": { @@ -2087,6 +2089,42 @@ "node": ">=6.9.0" } }, + "node_modules/@bcherny/json-schema-ref-parser": { + "version": "10.0.5-fork", + "resolved": "https://registry.npmjs.org/@bcherny/json-schema-ref-parser/-/json-schema-ref-parser-10.0.5-fork.tgz", + "integrity": "sha512-E/jKbPoca1tfUPj3iSbitDZTGnq6FUFjkH6L8U2oDwSuwK1WhnnVtCG7oFOTg/DDnyoXbQYUiUiGOibHqaGVnw==", + "dev": true, + "dependencies": { + "@jsdevtools/ono": "^7.1.3", + "@types/json-schema": "^7.0.6", + "call-me-maybe": "^1.0.1", + "js-yaml": "^4.1.0" + }, + "engines": { + "node": ">= 16" + }, + "funding": { + "url": "https://github.com/sponsors/philsturgeon" + } + }, + "node_modules/@bcherny/json-schema-ref-parser/node_modules/argparse": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/argparse/-/argparse-2.0.1.tgz", + "integrity": "sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q==", + "dev": true + }, + "node_modules/@bcherny/json-schema-ref-parser/node_modules/js-yaml": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-4.1.0.tgz", + "integrity": "sha512-wpxZs9NoxZaJESJGIZTyDEaYpl0FKSA+FB9aJiyemKhMwkxQg63h4T1KJgUGHpTqPDNRcmmYLugrRjJlBtWvRA==", + "dev": true, + "dependencies": { + "argparse": "^2.0.1" + }, + "bin": { + "js-yaml": "bin/js-yaml.js" + } + }, "node_modules/@bcoe/v8-coverage": { "version": "0.2.3", "resolved": "https://registry.npmjs.org/@bcoe/v8-coverage/-/v8-coverage-0.2.3.tgz", @@ -2625,6 +2663,12 @@ "node": ">=10" } }, + "node_modules/@jsdevtools/ono": { + "version": "7.1.3", + "resolved": "https://registry.npmjs.org/@jsdevtools/ono/-/ono-7.1.3.tgz", + "integrity": "sha512-4JQNk+3mVzK3xh2rqd6RB4J46qUR19azEHBneZyTZM+c456qOrbbM/5xcR8huNCCcbVt7+UmizG6GuUvPvKUYg==", + "dev": true + }, "node_modules/@jsdevtools/version-bump-prompt": { "version": "6.1.0", "resolved": "https://registry.npmjs.org/@jsdevtools/version-bump-prompt/-/version-bump-prompt-6.1.0.tgz", @@ -3352,6 +3396,12 @@ "integrity": "sha512-dRLjCWHYg4oaA77cxO64oO+7JwCwnIzkZPdrrC71jQmQtlhM556pwKo5bUzqvZndkVbeFLIIi+9TC40JNF5hNQ==", "dev": true }, + "node_modules/@types/lodash": { + "version": "4.14.192", + "resolved": "https://registry.npmjs.org/@types/lodash/-/lodash-4.14.192.tgz", + "integrity": "sha512-km+Vyn3BYm5ytMO13k9KTp27O75rbQ0NFw+U//g+PX7VZyjCioXaRFisqSIJRECljcTv73G3i6BpglNGHgUQ5A==", + "dev": true + }, "node_modules/@types/mdast": { "version": "3.0.11", "resolved": "https://registry.npmjs.org/@types/mdast/-/mdast-3.0.11.tgz", @@ -4913,6 +4963,12 @@ "url": "https://github.com/chalk/ansi-styles?sponsor=1" } }, + "node_modules/any-promise": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/any-promise/-/any-promise-1.3.0.tgz", + "integrity": "sha512-7UvmKalWRt1wgjL1RrGxoSJW/0QZFIegpeGvZG9kjp8vrRu55XTHbwnqq2GpXm9uLbcuhxm3IqX9OB4MZR1b2A==", + "dev": true + }, "node_modules/anymatch": { "version": "3.1.2", "resolved": "https://registry.npmjs.org/anymatch/-/anymatch-3.1.2.tgz", @@ -6183,6 +6239,22 @@ "webpack": "*" } }, + "node_modules/cli-color": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/cli-color/-/cli-color-2.0.3.tgz", + "integrity": "sha512-OkoZnxyC4ERN3zLzZaY9Emb7f/MhBOIpePv0Ycok0fJYT+Ouo00UBEIwsVsr0yoow++n5YWlSUgST9GKhNHiRQ==", + "dev": true, + "dependencies": { + "d": "^1.0.1", + "es5-ext": "^0.10.61", + "es6-iterator": "^2.0.3", + "memoizee": "^0.4.15", + "timers-ext": "^0.1.7" + }, + "engines": { + "node": ">=0.10" + } + }, "node_modules/cli-cursor": { "version": "3.1.0", "resolved": "https://registry.npmjs.org/cli-cursor/-/cli-cursor-3.1.0.tgz", @@ -6902,6 +6974,16 @@ "node": ">=0.8" } }, + "node_modules/d": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/d/-/d-1.0.1.tgz", + "integrity": "sha512-m62ShEObQ39CfralilEQRjH6oAMtNCV1xJyEx5LpRYUVN+EviphDgUc/F3hnYbADmkiNs67Y+3ylmlG7Lnu+FA==", + "dev": true, + "dependencies": { + "es5-ext": "^0.10.50", + "type": "^1.0.1" + } + }, "node_modules/damerau-levenshtein": { "version": "1.0.8", "resolved": "https://registry.npmjs.org/damerau-levenshtein/-/damerau-levenshtein-1.0.8.tgz", @@ -7665,6 +7747,54 @@ "url": "https://github.com/sponsors/ljharb" } }, + "node_modules/es5-ext": { + "version": "0.10.62", + "resolved": "https://registry.npmjs.org/es5-ext/-/es5-ext-0.10.62.tgz", + "integrity": "sha512-BHLqn0klhEpnOKSrzn/Xsz2UIW8j+cGmo9JLzr8BiUapV8hPL9+FliFqjwr9ngW7jWdnxv6eO+/LqyhJVqgrjA==", + "dev": true, + "hasInstallScript": true, + "dependencies": { + "es6-iterator": "^2.0.3", + "es6-symbol": "^3.1.3", + "next-tick": "^1.1.0" + }, + "engines": { + "node": ">=0.10" + } + }, + "node_modules/es6-iterator": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/es6-iterator/-/es6-iterator-2.0.3.tgz", + "integrity": "sha512-zw4SRzoUkd+cl+ZoE15A9o1oQd920Bb0iOJMQkQhl3jNc03YqVjAhG7scf9C5KWRU/R13Orf588uCC6525o02g==", + "dev": true, + "dependencies": { + "d": "1", + "es5-ext": "^0.10.35", + "es6-symbol": "^3.1.1" + } + }, + "node_modules/es6-symbol": { + "version": "3.1.3", + "resolved": "https://registry.npmjs.org/es6-symbol/-/es6-symbol-3.1.3.tgz", + "integrity": "sha512-NJ6Yn3FuDinBaBRWl/q5X/s4koRHBrgKAu+yGI6JCBeiu3qrcbJhwT2GeR/EXVfylRk8dpQVJoLEFhK+Mu31NA==", + "dev": true, + "dependencies": { + "d": "^1.0.1", + "ext": "^1.1.2" + } + }, + "node_modules/es6-weak-map": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/es6-weak-map/-/es6-weak-map-2.0.3.tgz", + "integrity": "sha512-p5um32HOTO1kP+w7PRnB+5lQ43Z6muuMuIMffvDN8ZB4GcnjLBV6zGStpbASIMk4DCAvEaamhe2zhyCb/QXXsA==", + "dev": true, + "dependencies": { + "d": "1", + "es5-ext": "^0.10.46", + "es6-iterator": "^2.0.3", + "es6-symbol": "^3.1.1" + } + }, "node_modules/escalade": { "version": "3.1.1", "resolved": "https://registry.npmjs.org/escalade/-/escalade-3.1.1.tgz", @@ -8352,6 +8482,16 @@ "node": ">=0.10.0" } }, + "node_modules/event-emitter": { + "version": "0.3.5", + "resolved": "https://registry.npmjs.org/event-emitter/-/event-emitter-0.3.5.tgz", + "integrity": "sha512-D9rRn9y7kLPnJ+hMq7S/nhvoKwwvVJahBi2BPmx3bvbsEdK3W9ii8cBSGjP+72/LnM4n6fo3+dkCX5FeTQruXA==", + "dev": true, + "dependencies": { + "d": "1", + "es5-ext": "~0.10.14" + } + }, "node_modules/events": { "version": "3.3.0", "resolved": "https://registry.npmjs.org/events/-/events-3.3.0.tgz", @@ -8642,6 +8782,21 @@ "integrity": "sha512-6Ey4Xy2xvmuQu7z7YQtMsaMV0EHJRpVxIDOd5GRrm04/I3nkTKIutELfECsLp6le+b3SSa3cXhPiw6PgqzxYWA==", "dev": true }, + "node_modules/ext": { + "version": "1.7.0", + "resolved": "https://registry.npmjs.org/ext/-/ext-1.7.0.tgz", + "integrity": "sha512-6hxeJYaL110a9b5TEJSj0gojyHQAmA2ch5Os+ySCiA1QGdS697XWY1pzsrSjqA9LDEEgdB/KypIlR59RcLuHYw==", + "dev": true, + "dependencies": { + "type": "^2.7.2" + } + }, + "node_modules/ext/node_modules/type": { + "version": "2.7.2", + "resolved": "https://registry.npmjs.org/type/-/type-2.7.2.tgz", + "integrity": "sha512-dzlvlNlt6AXU7EBSfpAscydQ7gXB+pPGsPnfJnZpiNJBDj7IaJzQlBZYGdEi4R9HmPdBv2XmWJ6YUtoTa7lmCw==", + "dev": true + }, "node_modules/extend": { "version": "3.0.2", "resolved": "https://registry.npmjs.org/extend/-/extend-3.0.2.tgz", @@ -9339,6 +9494,25 @@ "node": ">= 6" } }, + "node_modules/glob-promise": { + "version": "4.2.2", + "resolved": "https://registry.npmjs.org/glob-promise/-/glob-promise-4.2.2.tgz", + "integrity": "sha512-xcUzJ8NWN5bktoTIX7eOclO1Npxd/dyVqUJxlLIDasT4C7KZyqlPIwkdJ0Ypiy3p2ZKahTjK4M9uC3sNSfNMzw==", + "dev": true, + "dependencies": { + "@types/glob": "^7.1.3" + }, + "engines": { + "node": ">=12" + }, + "funding": { + "type": "individual", + "url": "https://github.com/sponsors/ahmadnassri" + }, + "peerDependencies": { + "glob": "^7.1.6" + } + }, "node_modules/glob-to-regexp": { "version": "0.4.1", "resolved": "https://registry.npmjs.org/glob-to-regexp/-/glob-to-regexp-0.4.1.tgz", @@ -10420,6 +10594,12 @@ "integrity": "sha512-bCYeRA2rVibKZd+s2625gGnGF/t7DSqDs4dP7CrLA1m7jKWz6pps0LpYLJN8Q64HtmPKJ1hrN3nzPNKFEKOUiQ==", "dev": true }, + "node_modules/is-promise": { + "version": "2.2.2", + "resolved": "https://registry.npmjs.org/is-promise/-/is-promise-2.2.2.tgz", + "integrity": "sha512-+lP4/6lKUBfQjZ2pdxThZvLUAafmZb8OAxFb8XXtiQmS35INgr85hdOGoEs124ez1FCnZJt6jau/T+alh58QFQ==", + "dev": true + }, "node_modules/is-regex": { "version": "1.1.4", "resolved": "https://registry.npmjs.org/is-regex/-/is-regex-1.1.4.tgz", @@ -11625,6 +11805,61 @@ "integrity": "sha512-xyFwyhro/JEof6Ghe2iz2NcXoj2sloNsWr/XsERDK/oiPCfaNhl5ONfp+jQdAZRQQ0IJWNzH9zIZF7li91kh2w==", "dev": true }, + "node_modules/json-schema-to-typescript": { + "version": "12.0.0", + "resolved": "https://registry.npmjs.org/json-schema-to-typescript/-/json-schema-to-typescript-12.0.0.tgz", + "integrity": "sha512-Uk/BDIAo8vqepPBhM86UhNMHgCv7JulicNj/BgnQPHE1fGCoej0UTtcEYzXU/uk6lSvbZCf7pccW+dnNMrr5rg==", + "dev": true, + "dependencies": { + "@bcherny/json-schema-ref-parser": "10.0.5-fork", + "@types/json-schema": "^7.0.11", + "@types/lodash": "^4.14.182", + "@types/prettier": "^2.6.1", + "cli-color": "^2.0.2", + "get-stdin": "^8.0.0", + "glob": "^7.1.6", + "glob-promise": "^4.2.2", + "is-glob": "^4.0.3", + "lodash": "^4.17.21", + "minimist": "^1.2.6", + "mkdirp": "^1.0.4", + "mz": "^2.7.0", + "prettier": "^2.6.2" + }, + "bin": { + "json2ts": "dist/src/cli.js" + }, + "engines": { + "node": ">=12.0.0" + } + }, + "node_modules/json-schema-to-typescript/node_modules/mkdirp": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-1.0.4.tgz", + "integrity": "sha512-vVqVZQyf3WLx2Shd0qJ9xuvqgAyKPLAiqITEtqW0oIUjzo3PePDd6fW9iFz30ef7Ysp/oiWqbhszeGWW2T6Gzw==", + "dev": true, + "bin": { + "mkdirp": "bin/cmd.js" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/json-schema-to-typescript/node_modules/prettier": { + "version": "2.8.7", + "resolved": "https://registry.npmjs.org/prettier/-/prettier-2.8.7.tgz", + "integrity": "sha512-yPngTo3aXUUmyuTjeTUT75txrf+aMh9FiD7q9ZE/i6r0bPb22g4FsE6Y338PQX1bmfy08i9QQCB7/rcUAVntfw==", + "dev": true, + "bin": { + "prettier": "bin-prettier.js" + }, + "engines": { + "node": ">=10.13.0" + }, + "funding": { + "url": "https://github.com/prettier/prettier?sponsor=1" + } + }, "node_modules/json-schema-traverse": { "version": "0.4.1", "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-0.4.1.tgz", @@ -12026,6 +12261,15 @@ "node": ">=10" } }, + "node_modules/lru-queue": { + "version": "0.1.0", + "resolved": "https://registry.npmjs.org/lru-queue/-/lru-queue-0.1.0.tgz", + "integrity": "sha512-BpdYkt9EvGl8OfWHDQPISVpcl5xZthb+XPsbELj5AQXxIC8IriDZIQYjBJPEm5rS420sjZ0TLEzRcq5KdBhYrQ==", + "dev": true, + "dependencies": { + "es5-ext": "~0.10.2" + } + }, "node_modules/macos-release": { "version": "2.5.0", "resolved": "https://registry.npmjs.org/macos-release/-/macos-release-2.5.0.tgz", @@ -12307,6 +12551,22 @@ "resolved": "https://registry.npmjs.org/memize/-/memize-1.1.0.tgz", "integrity": "sha512-K4FcPETOMTwe7KL2LK0orMhpOmWD2wRGwWWpbZy0fyArwsyIKR8YJVz8+efBAh3BO4zPqlSICu4vsLTRRqtFAg==" }, + "node_modules/memoizee": { + "version": "0.4.15", + "resolved": "https://registry.npmjs.org/memoizee/-/memoizee-0.4.15.tgz", + "integrity": "sha512-UBWmJpLZd5STPm7PMUlOw/TSy972M+z8gcyQ5veOnSDRREz/0bmpyTfKt3/51DhEBqCZQn1udM/5flcSPYhkdQ==", + "dev": true, + "dependencies": { + "d": "^1.0.1", + "es5-ext": "^0.10.53", + "es6-weak-map": "^2.0.3", + "event-emitter": "^0.3.5", + "is-promise": "^2.2.2", + "lru-queue": "^0.1.0", + "next-tick": "^1.1.0", + "timers-ext": "^0.1.7" + } + }, "node_modules/meow": { "version": "6.1.1", "resolved": "https://registry.npmjs.org/meow/-/meow-6.1.1.tgz", @@ -12791,6 +13051,17 @@ "integrity": "sha512-nnbWWOkoWyUsTjKrhgD0dcz22mdkSnpYqbEjIm2nhwhuxlSkpywJmBo8h0ZqJdkp73mb90SssHkN4rsRaBAfAA==", "dev": true }, + "node_modules/mz": { + "version": "2.7.0", + "resolved": "https://registry.npmjs.org/mz/-/mz-2.7.0.tgz", + "integrity": "sha512-z81GNO7nnYMEhrGh9LeymoE4+Yr0Wn5McHIZMK5cfQCl+NDX08sCZgUc9/6MHni9IWuFLm1Z3HTCXu2z9fN62Q==", + "dev": true, + "dependencies": { + "any-promise": "^1.0.0", + "object-assign": "^4.0.1", + "thenify-all": "^1.0.0" + } + }, "node_modules/nanoid": { "version": "3.3.6", "resolved": "https://registry.npmjs.org/nanoid/-/nanoid-3.3.6.tgz", @@ -12886,6 +13157,12 @@ "integrity": "sha512-Yd3UES5mWCSqR+qNT93S3UoYUkqAZ9lLg8a7g9rimsWmYGK8cVToA4/sF3RrshdyV3sAGMXVUmpMYOw+dLpOuw==", "dev": true }, + "node_modules/next-tick": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/next-tick/-/next-tick-1.1.0.tgz", + "integrity": "sha512-CXdUiJembsNjuToQvxayPZF9Vqht7hewsvy2sOWafLvi2awflj9mOC6bHIg50orX8IJvWKY9wYQ/zB2kogPslQ==", + "dev": true + }, "node_modules/nice-try": { "version": "1.0.5", "resolved": "https://registry.npmjs.org/nice-try/-/nice-try-1.0.5.tgz", @@ -17848,6 +18125,27 @@ "integrity": "sha512-N+8UisAXDGk8PFXP4HAzVR9nbfmVJ3zYLAWiTIoqC5v5isinhr+r5uaO8+7r3BMfuNIufIsA7RdpVgacC2cSpw==", "dev": true }, + "node_modules/thenify": { + "version": "3.3.1", + "resolved": "https://registry.npmjs.org/thenify/-/thenify-3.3.1.tgz", + "integrity": "sha512-RVZSIV5IG10Hk3enotrhvz0T9em6cyHBLkH/YAZuKqd8hRkKhSfCGIcP2KUY0EPxndzANBmNllzWPwak+bheSw==", + "dev": true, + "dependencies": { + "any-promise": "^1.0.0" + } + }, + "node_modules/thenify-all": { + "version": "1.6.0", + "resolved": "https://registry.npmjs.org/thenify-all/-/thenify-all-1.6.0.tgz", + "integrity": "sha512-RNxQH/qI8/t3thXJDwcstUO4zeqo64+Uy/+sNVRBx4Xn2OX+OZ9oP+iJnNFqplFra2ZUVeKCSa2oVWi3T4uVmA==", + "dev": true, + "dependencies": { + "thenify": ">= 3.1.0 < 4" + }, + "engines": { + "node": ">=0.8" + } + }, "node_modules/throat": { "version": "5.0.0", "resolved": "https://registry.npmjs.org/throat/-/throat-5.0.0.tgz", @@ -17860,6 +18158,16 @@ "integrity": "sha1-DdTJ/6q8NXlgsbckEV1+Doai4fU=", "dev": true }, + "node_modules/timers-ext": { + "version": "0.1.7", + "resolved": "https://registry.npmjs.org/timers-ext/-/timers-ext-0.1.7.tgz", + "integrity": "sha512-b85NUNzTSdodShTIbky6ZF02e8STtVVfD+fu4aXXShEELpozH+bCpJLYMPZbsABN2wDH7fJpqIoXxJpzbf0NqQ==", + "dev": true, + "dependencies": { + "es5-ext": "~0.10.46", + "next-tick": "1" + } + }, "node_modules/tiny-lr": { "version": "1.1.1", "resolved": "https://registry.npmjs.org/tiny-lr/-/tiny-lr-1.1.1.tgz", @@ -18098,6 +18406,12 @@ "node": ">=0.6.11 <=0.7.0 || >=0.7.3" } }, + "node_modules/type": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/type/-/type-1.2.0.tgz", + "integrity": "sha512-+5nt5AAniqsCnu2cEQQdpzCAh33kVx8n0VoFidKpB1dVVLAN/F+bgVOqOJqOnEnrhp222clB5p3vUlD+1QAnfg==", + "dev": true + }, "node_modules/type-check": { "version": "0.4.0", "resolved": "https://registry.npmjs.org/type-check/-/type-check-0.4.0.tgz", @@ -19065,11 +19379,19 @@ "node": ">=0.10.0" } }, - "node_modules/wp-types": { - "version": "3.62.2", - "resolved": "https://registry.npmjs.org/wp-types/-/wp-types-3.62.2.tgz", - "integrity": "sha512-jdDei/IJZO7VXsAQdDfI+thj0qEhP6XO0tzcL14mWAQ7EPDBJs3as4hjwwgQaoXGXwHLP2e7TS0zrhb9rAQMWg==", + "node_modules/wp-json-schemas": { + "version": "3.62.4", + "resolved": "https://registry.npmjs.org/wp-json-schemas/-/wp-json-schemas-3.62.4.tgz", + "integrity": "sha512-yH99aZNIGCzmdfe1T4C9bjC0znTUrgwrxZtrZ3IqMrrlSROk2FrRN3niksjk3Ic7BYjNaTlVjDL/xyYqM7812A==", "dev": true, + "funding": { + "url": "https://github.com/sponsors/johnbillion" + } + }, + "node_modules/wp-types": { + "version": "3.62.4", + "resolved": "https://registry.npmjs.org/wp-types/-/wp-types-3.62.4.tgz", + "integrity": "sha512-hZ5a1LqxwLovLMj8BL9Ly1F95jriScKPtebJBQy044KgTK+poXfiZsscIv2UGn9JTQfIZV4gH4XWyKwYcItwzg==", "dependencies": { "typescript": ">=3" }, @@ -19224,23 +19546,12 @@ "dependencies": { "@types/react": "^17", "@types/react-dom": "^17", - "wp-types": "^2" + "wp-types": "^3" }, "peerDependencies": { "react": "^17" } }, - "packages/qmi/node_modules/wp-types": { - "version": "2.12.0", - "resolved": "https://registry.npmjs.org/wp-types/-/wp-types-2.12.0.tgz", - "integrity": "sha512-PVRp/3NCSksOXEb4DGMVqgkAS+JhmjDro8CXdFVfP05+yCXlqaHDuvoOpCoEKmXEd0sYN9EEf8675+Fz8eL4zQ==", - "dependencies": { - "typescript": ">=3" - }, - "funding": { - "url": "https://github.com/sponsors/johnbillion" - } - }, "vendor/johnbillion/plugin-infrastructure": { "version": "1.0.0", "dev": true, @@ -20697,6 +21008,35 @@ "to-fast-properties": "^2.0.0" } }, + "@bcherny/json-schema-ref-parser": { + "version": "10.0.5-fork", + "resolved": "https://registry.npmjs.org/@bcherny/json-schema-ref-parser/-/json-schema-ref-parser-10.0.5-fork.tgz", + "integrity": "sha512-E/jKbPoca1tfUPj3iSbitDZTGnq6FUFjkH6L8U2oDwSuwK1WhnnVtCG7oFOTg/DDnyoXbQYUiUiGOibHqaGVnw==", + "dev": true, + "requires": { + "@jsdevtools/ono": "^7.1.3", + "@types/json-schema": "^7.0.6", + "call-me-maybe": "^1.0.1", + "js-yaml": "^4.1.0" + }, + "dependencies": { + "argparse": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/argparse/-/argparse-2.0.1.tgz", + "integrity": "sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q==", + "dev": true + }, + "js-yaml": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-4.1.0.tgz", + "integrity": "sha512-wpxZs9NoxZaJESJGIZTyDEaYpl0FKSA+FB9aJiyemKhMwkxQg63h4T1KJgUGHpTqPDNRcmmYLugrRjJlBtWvRA==", + "dev": true, + "requires": { + "argparse": "^2.0.1" + } + } + } + }, "@bcoe/v8-coverage": { "version": "0.2.3", "resolved": "https://registry.npmjs.org/@bcoe/v8-coverage/-/v8-coverage-0.2.3.tgz", @@ -21127,6 +21467,12 @@ "type-detect": "^4.0.8" } }, + "@jsdevtools/ono": { + "version": "7.1.3", + "resolved": "https://registry.npmjs.org/@jsdevtools/ono/-/ono-7.1.3.tgz", + "integrity": "sha512-4JQNk+3mVzK3xh2rqd6RB4J46qUR19azEHBneZyTZM+c456qOrbbM/5xcR8huNCCcbVt7+UmizG6GuUvPvKUYg==", + "dev": true + }, "@jsdevtools/version-bump-prompt": { "version": "6.1.0", "resolved": "https://registry.npmjs.org/@jsdevtools/version-bump-prompt/-/version-bump-prompt-6.1.0.tgz", @@ -21724,6 +22070,12 @@ "integrity": "sha512-dRLjCWHYg4oaA77cxO64oO+7JwCwnIzkZPdrrC71jQmQtlhM556pwKo5bUzqvZndkVbeFLIIi+9TC40JNF5hNQ==", "dev": true }, + "@types/lodash": { + "version": "4.14.192", + "resolved": "https://registry.npmjs.org/@types/lodash/-/lodash-4.14.192.tgz", + "integrity": "sha512-km+Vyn3BYm5ytMO13k9KTp27O75rbQ0NFw+U//g+PX7VZyjCioXaRFisqSIJRECljcTv73G3i6BpglNGHgUQ5A==", + "dev": true + }, "@types/mdast": { "version": "3.0.11", "resolved": "https://registry.npmjs.org/@types/mdast/-/mdast-3.0.11.tgz", @@ -22869,6 +23221,12 @@ "color-convert": "^2.0.1" } }, + "any-promise": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/any-promise/-/any-promise-1.3.0.tgz", + "integrity": "sha512-7UvmKalWRt1wgjL1RrGxoSJW/0QZFIegpeGvZG9kjp8vrRu55XTHbwnqq2GpXm9uLbcuhxm3IqX9OB4MZR1b2A==", + "dev": true + }, "anymatch": { "version": "3.1.2", "resolved": "https://registry.npmjs.org/anymatch/-/anymatch-3.1.2.tgz", @@ -23827,6 +24185,19 @@ "del": "^4.1.1" } }, + "cli-color": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/cli-color/-/cli-color-2.0.3.tgz", + "integrity": "sha512-OkoZnxyC4ERN3zLzZaY9Emb7f/MhBOIpePv0Ycok0fJYT+Ouo00UBEIwsVsr0yoow++n5YWlSUgST9GKhNHiRQ==", + "dev": true, + "requires": { + "d": "^1.0.1", + "es5-ext": "^0.10.61", + "es6-iterator": "^2.0.3", + "memoizee": "^0.4.15", + "timers-ext": "^0.1.7" + } + }, "cli-cursor": { "version": "3.1.0", "resolved": "https://registry.npmjs.org/cli-cursor/-/cli-cursor-3.1.0.tgz", @@ -24392,6 +24763,16 @@ "fs-exists-sync": "^0.1.0" } }, + "d": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/d/-/d-1.0.1.tgz", + "integrity": "sha512-m62ShEObQ39CfralilEQRjH6oAMtNCV1xJyEx5LpRYUVN+EviphDgUc/F3hnYbADmkiNs67Y+3ylmlG7Lnu+FA==", + "dev": true, + "requires": { + "es5-ext": "^0.10.50", + "type": "^1.0.1" + } + }, "damerau-levenshtein": { "version": "1.0.8", "resolved": "https://registry.npmjs.org/damerau-levenshtein/-/damerau-levenshtein-1.0.8.tgz", @@ -24995,6 +25376,50 @@ "is-symbol": "^1.0.2" } }, + "es5-ext": { + "version": "0.10.62", + "resolved": "https://registry.npmjs.org/es5-ext/-/es5-ext-0.10.62.tgz", + "integrity": "sha512-BHLqn0klhEpnOKSrzn/Xsz2UIW8j+cGmo9JLzr8BiUapV8hPL9+FliFqjwr9ngW7jWdnxv6eO+/LqyhJVqgrjA==", + "dev": true, + "requires": { + "es6-iterator": "^2.0.3", + "es6-symbol": "^3.1.3", + "next-tick": "^1.1.0" + } + }, + "es6-iterator": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/es6-iterator/-/es6-iterator-2.0.3.tgz", + "integrity": "sha512-zw4SRzoUkd+cl+ZoE15A9o1oQd920Bb0iOJMQkQhl3jNc03YqVjAhG7scf9C5KWRU/R13Orf588uCC6525o02g==", + "dev": true, + "requires": { + "d": "1", + "es5-ext": "^0.10.35", + "es6-symbol": "^3.1.1" + } + }, + "es6-symbol": { + "version": "3.1.3", + "resolved": "https://registry.npmjs.org/es6-symbol/-/es6-symbol-3.1.3.tgz", + "integrity": "sha512-NJ6Yn3FuDinBaBRWl/q5X/s4koRHBrgKAu+yGI6JCBeiu3qrcbJhwT2GeR/EXVfylRk8dpQVJoLEFhK+Mu31NA==", + "dev": true, + "requires": { + "d": "^1.0.1", + "ext": "^1.1.2" + } + }, + "es6-weak-map": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/es6-weak-map/-/es6-weak-map-2.0.3.tgz", + "integrity": "sha512-p5um32HOTO1kP+w7PRnB+5lQ43Z6muuMuIMffvDN8ZB4GcnjLBV6zGStpbASIMk4DCAvEaamhe2zhyCb/QXXsA==", + "dev": true, + "requires": { + "d": "1", + "es5-ext": "^0.10.46", + "es6-iterator": "^2.0.3", + "es6-symbol": "^3.1.1" + } + }, "escalade": { "version": "3.1.1", "resolved": "https://registry.npmjs.org/escalade/-/escalade-3.1.1.tgz", @@ -25483,6 +25908,16 @@ "integrity": "sha512-kVscqXk4OCp68SZ0dkgEKVi6/8ij300KBWTJq32P/dYeWTSwK41WyTxalN1eRmA5Z9UU/LX9D7FWSmV9SAYx6g==", "dev": true }, + "event-emitter": { + "version": "0.3.5", + "resolved": "https://registry.npmjs.org/event-emitter/-/event-emitter-0.3.5.tgz", + "integrity": "sha512-D9rRn9y7kLPnJ+hMq7S/nhvoKwwvVJahBi2BPmx3bvbsEdK3W9ii8cBSGjP+72/LnM4n6fo3+dkCX5FeTQruXA==", + "dev": true, + "requires": { + "d": "1", + "es5-ext": "~0.10.14" + } + }, "events": { "version": "3.3.0", "resolved": "https://registry.npmjs.org/events/-/events-3.3.0.tgz", @@ -25718,6 +26153,23 @@ "integrity": "sha512-6Ey4Xy2xvmuQu7z7YQtMsaMV0EHJRpVxIDOd5GRrm04/I3nkTKIutELfECsLp6le+b3SSa3cXhPiw6PgqzxYWA==", "dev": true }, + "ext": { + "version": "1.7.0", + "resolved": "https://registry.npmjs.org/ext/-/ext-1.7.0.tgz", + "integrity": "sha512-6hxeJYaL110a9b5TEJSj0gojyHQAmA2ch5Os+ySCiA1QGdS697XWY1pzsrSjqA9LDEEgdB/KypIlR59RcLuHYw==", + "dev": true, + "requires": { + "type": "^2.7.2" + }, + "dependencies": { + "type": { + "version": "2.7.2", + "resolved": "https://registry.npmjs.org/type/-/type-2.7.2.tgz", + "integrity": "sha512-dzlvlNlt6AXU7EBSfpAscydQ7gXB+pPGsPnfJnZpiNJBDj7IaJzQlBZYGdEi4R9HmPdBv2XmWJ6YUtoTa7lmCw==", + "dev": true + } + } + }, "extend": { "version": "3.0.2", "resolved": "https://registry.npmjs.org/extend/-/extend-3.0.2.tgz", @@ -26240,6 +26692,15 @@ "is-glob": "^4.0.1" } }, + "glob-promise": { + "version": "4.2.2", + "resolved": "https://registry.npmjs.org/glob-promise/-/glob-promise-4.2.2.tgz", + "integrity": "sha512-xcUzJ8NWN5bktoTIX7eOclO1Npxd/dyVqUJxlLIDasT4C7KZyqlPIwkdJ0Ypiy3p2ZKahTjK4M9uC3sNSfNMzw==", + "dev": true, + "requires": { + "@types/glob": "^7.1.3" + } + }, "glob-to-regexp": { "version": "0.4.1", "resolved": "https://registry.npmjs.org/glob-to-regexp/-/glob-to-regexp-0.4.1.tgz", @@ -27000,6 +27461,12 @@ "integrity": "sha512-bCYeRA2rVibKZd+s2625gGnGF/t7DSqDs4dP7CrLA1m7jKWz6pps0LpYLJN8Q64HtmPKJ1hrN3nzPNKFEKOUiQ==", "dev": true }, + "is-promise": { + "version": "2.2.2", + "resolved": "https://registry.npmjs.org/is-promise/-/is-promise-2.2.2.tgz", + "integrity": "sha512-+lP4/6lKUBfQjZ2pdxThZvLUAafmZb8OAxFb8XXtiQmS35INgr85hdOGoEs124ez1FCnZJt6jau/T+alh58QFQ==", + "dev": true + }, "is-regex": { "version": "1.1.4", "resolved": "https://registry.npmjs.org/is-regex/-/is-regex-1.1.4.tgz", @@ -27935,6 +28402,42 @@ "integrity": "sha512-xyFwyhro/JEof6Ghe2iz2NcXoj2sloNsWr/XsERDK/oiPCfaNhl5ONfp+jQdAZRQQ0IJWNzH9zIZF7li91kh2w==", "dev": true }, + "json-schema-to-typescript": { + "version": "12.0.0", + "resolved": "https://registry.npmjs.org/json-schema-to-typescript/-/json-schema-to-typescript-12.0.0.tgz", + "integrity": "sha512-Uk/BDIAo8vqepPBhM86UhNMHgCv7JulicNj/BgnQPHE1fGCoej0UTtcEYzXU/uk6lSvbZCf7pccW+dnNMrr5rg==", + "dev": true, + "requires": { + "@bcherny/json-schema-ref-parser": "10.0.5-fork", + "@types/json-schema": "^7.0.11", + "@types/lodash": "^4.14.182", + "@types/prettier": "^2.6.1", + "cli-color": "^2.0.2", + "get-stdin": "^8.0.0", + "glob": "^7.1.6", + "glob-promise": "^4.2.2", + "is-glob": "^4.0.3", + "lodash": "^4.17.21", + "minimist": "^1.2.6", + "mkdirp": "^1.0.4", + "mz": "^2.7.0", + "prettier": "^2.6.2" + }, + "dependencies": { + "mkdirp": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-1.0.4.tgz", + "integrity": "sha512-vVqVZQyf3WLx2Shd0qJ9xuvqgAyKPLAiqITEtqW0oIUjzo3PePDd6fW9iFz30ef7Ysp/oiWqbhszeGWW2T6Gzw==", + "dev": true + }, + "prettier": { + "version": "2.8.7", + "resolved": "https://registry.npmjs.org/prettier/-/prettier-2.8.7.tgz", + "integrity": "sha512-yPngTo3aXUUmyuTjeTUT75txrf+aMh9FiD7q9ZE/i6r0bPb22g4FsE6Y338PQX1bmfy08i9QQCB7/rcUAVntfw==", + "dev": true + } + } + }, "json-schema-traverse": { "version": "0.4.1", "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-0.4.1.tgz", @@ -28272,6 +28775,15 @@ "yallist": "^4.0.0" } }, + "lru-queue": { + "version": "0.1.0", + "resolved": "https://registry.npmjs.org/lru-queue/-/lru-queue-0.1.0.tgz", + "integrity": "sha512-BpdYkt9EvGl8OfWHDQPISVpcl5xZthb+XPsbELj5AQXxIC8IriDZIQYjBJPEm5rS420sjZ0TLEzRcq5KdBhYrQ==", + "dev": true, + "requires": { + "es5-ext": "~0.10.2" + } + }, "macos-release": { "version": "2.5.0", "resolved": "https://registry.npmjs.org/macos-release/-/macos-release-2.5.0.tgz", @@ -28489,6 +29001,22 @@ "resolved": "https://registry.npmjs.org/memize/-/memize-1.1.0.tgz", "integrity": "sha512-K4FcPETOMTwe7KL2LK0orMhpOmWD2wRGwWWpbZy0fyArwsyIKR8YJVz8+efBAh3BO4zPqlSICu4vsLTRRqtFAg==" }, + "memoizee": { + "version": "0.4.15", + "resolved": "https://registry.npmjs.org/memoizee/-/memoizee-0.4.15.tgz", + "integrity": "sha512-UBWmJpLZd5STPm7PMUlOw/TSy972M+z8gcyQ5veOnSDRREz/0bmpyTfKt3/51DhEBqCZQn1udM/5flcSPYhkdQ==", + "dev": true, + "requires": { + "d": "^1.0.1", + "es5-ext": "^0.10.53", + "es6-weak-map": "^2.0.3", + "event-emitter": "^0.3.5", + "is-promise": "^2.2.2", + "lru-queue": "^0.1.0", + "next-tick": "^1.1.0", + "timers-ext": "^0.1.7" + } + }, "meow": { "version": "6.1.1", "resolved": "https://registry.npmjs.org/meow/-/meow-6.1.1.tgz", @@ -28858,6 +29386,17 @@ "integrity": "sha512-nnbWWOkoWyUsTjKrhgD0dcz22mdkSnpYqbEjIm2nhwhuxlSkpywJmBo8h0ZqJdkp73mb90SssHkN4rsRaBAfAA==", "dev": true }, + "mz": { + "version": "2.7.0", + "resolved": "https://registry.npmjs.org/mz/-/mz-2.7.0.tgz", + "integrity": "sha512-z81GNO7nnYMEhrGh9LeymoE4+Yr0Wn5McHIZMK5cfQCl+NDX08sCZgUc9/6MHni9IWuFLm1Z3HTCXu2z9fN62Q==", + "dev": true, + "requires": { + "any-promise": "^1.0.0", + "object-assign": "^4.0.1", + "thenify-all": "^1.0.0" + } + }, "nanoid": { "version": "3.3.6", "resolved": "https://registry.npmjs.org/nanoid/-/nanoid-3.3.6.tgz", @@ -28929,6 +29468,12 @@ "integrity": "sha512-Yd3UES5mWCSqR+qNT93S3UoYUkqAZ9lLg8a7g9rimsWmYGK8cVToA4/sF3RrshdyV3sAGMXVUmpMYOw+dLpOuw==", "dev": true }, + "next-tick": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/next-tick/-/next-tick-1.1.0.tgz", + "integrity": "sha512-CXdUiJembsNjuToQvxayPZF9Vqht7hewsvy2sOWafLvi2awflj9mOC6bHIg50orX8IJvWKY9wYQ/zB2kogPslQ==", + "dev": true + }, "nice-try": { "version": "1.0.5", "resolved": "https://registry.npmjs.org/nice-try/-/nice-try-1.0.5.tgz", @@ -30442,17 +30987,7 @@ "requires": { "@types/react": "^17", "@types/react-dom": "^17", - "wp-types": "^2" - }, - "dependencies": { - "wp-types": { - "version": "2.12.0", - "resolved": "https://registry.npmjs.org/wp-types/-/wp-types-2.12.0.tgz", - "integrity": "sha512-PVRp/3NCSksOXEb4DGMVqgkAS+JhmjDro8CXdFVfP05+yCXlqaHDuvoOpCoEKmXEd0sYN9EEf8675+Fz8eL4zQ==", - "requires": { - "typescript": ">=3" - } - } + "wp-types": "^3" } }, "qs": { @@ -32726,6 +33261,24 @@ "integrity": "sha512-N+8UisAXDGk8PFXP4HAzVR9nbfmVJ3zYLAWiTIoqC5v5isinhr+r5uaO8+7r3BMfuNIufIsA7RdpVgacC2cSpw==", "dev": true }, + "thenify": { + "version": "3.3.1", + "resolved": "https://registry.npmjs.org/thenify/-/thenify-3.3.1.tgz", + "integrity": "sha512-RVZSIV5IG10Hk3enotrhvz0T9em6cyHBLkH/YAZuKqd8hRkKhSfCGIcP2KUY0EPxndzANBmNllzWPwak+bheSw==", + "dev": true, + "requires": { + "any-promise": "^1.0.0" + } + }, + "thenify-all": { + "version": "1.6.0", + "resolved": "https://registry.npmjs.org/thenify-all/-/thenify-all-1.6.0.tgz", + "integrity": "sha512-RNxQH/qI8/t3thXJDwcstUO4zeqo64+Uy/+sNVRBx4Xn2OX+OZ9oP+iJnNFqplFra2ZUVeKCSa2oVWi3T4uVmA==", + "dev": true, + "requires": { + "thenify": ">= 3.1.0 < 4" + } + }, "throat": { "version": "5.0.0", "resolved": "https://registry.npmjs.org/throat/-/throat-5.0.0.tgz", @@ -32738,6 +33291,16 @@ "integrity": "sha1-DdTJ/6q8NXlgsbckEV1+Doai4fU=", "dev": true }, + "timers-ext": { + "version": "0.1.7", + "resolved": "https://registry.npmjs.org/timers-ext/-/timers-ext-0.1.7.tgz", + "integrity": "sha512-b85NUNzTSdodShTIbky6ZF02e8STtVVfD+fu4aXXShEELpozH+bCpJLYMPZbsABN2wDH7fJpqIoXxJpzbf0NqQ==", + "dev": true, + "requires": { + "es5-ext": "~0.10.46", + "next-tick": "1" + } + }, "tiny-lr": { "version": "1.1.1", "resolved": "https://registry.npmjs.org/tiny-lr/-/tiny-lr-1.1.1.tgz", @@ -32927,6 +33490,12 @@ "integrity": "sha512-1h/Lnq9yajKY2PEbBadPXj3VxsDDu844OnaAo52UVmIzIvwwtBPIuNvkjuzBlTWpfJyUbG3ez0KSBibQkj4ojg==", "dev": true }, + "type": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/type/-/type-1.2.0.tgz", + "integrity": "sha512-+5nt5AAniqsCnu2cEQQdpzCAh33kVx8n0VoFidKpB1dVVLAN/F+bgVOqOJqOnEnrhp222clB5p3vUlD+1QAnfg==", + "dev": true + }, "type-check": { "version": "0.4.0", "resolved": "https://registry.npmjs.org/type-check/-/type-check-0.4.0.tgz", @@ -33646,11 +34215,16 @@ "integrity": "sha512-Hz/mrNwitNRh/HUAtM/VT/5VH+ygD6DV7mYKZAtHOrbs8U7lvPS6xf7EJKMF0uW1KJCl0H701g3ZGus+muE5vQ==", "dev": true }, + "wp-json-schemas": { + "version": "3.62.4", + "resolved": "https://registry.npmjs.org/wp-json-schemas/-/wp-json-schemas-3.62.4.tgz", + "integrity": "sha512-yH99aZNIGCzmdfe1T4C9bjC0znTUrgwrxZtrZ3IqMrrlSROk2FrRN3niksjk3Ic7BYjNaTlVjDL/xyYqM7812A==", + "dev": true + }, "wp-types": { - "version": "3.62.2", - "resolved": "https://registry.npmjs.org/wp-types/-/wp-types-3.62.2.tgz", - "integrity": "sha512-jdDei/IJZO7VXsAQdDfI+thj0qEhP6XO0tzcL14mWAQ7EPDBJs3as4hjwwgQaoXGXwHLP2e7TS0zrhb9rAQMWg==", - "dev": true, + "version": "3.62.4", + "resolved": "https://registry.npmjs.org/wp-types/-/wp-types-3.62.4.tgz", + "integrity": "sha512-hZ5a1LqxwLovLMj8BL9Ly1F95jriScKPtebJBQy044KgTK+poXfiZsscIv2UGn9JTQfIZV4gH4XWyKwYcItwzg==", "requires": { "typescript": ">=3" } diff --git a/package.json b/package.json index ca30adb4d..475cded88 100644 --- a/package.json +++ b/package.json @@ -40,6 +40,7 @@ "eslint-plugin-react": "^7.21.5", "eslint-plugin-react-hooks": "^4.2.0", "eslint-plugin-sort-destructure-keys": "^1.3.5", + "json-schema-to-typescript": "^12", "plugin-infrastructure": "file:vendor/johnbillion/plugin-infrastructure", "sass": "^1", "source-map-loader": "^2", @@ -48,14 +49,16 @@ "version-bump-prompt": "^6.1.0", "webpack": "^5.47.1", "webpack-cli": "^4.9.1", + "wp-json-schemas": "^3", "wp-types": "^3" }, "scripts": { + "build-schemas": "json2ts -i src/schema.json -o packages/qmi/data-types.ts --style.trailingComma=all --style.useTabs --bannerComment='' && echo '/* eslint-disable */\n\n/**\n * This file is generated by the build-schemas script.\n * Do not edit it manually.\n */\n' > packages/qmi/tmp.ts && cat src/bannerComment.ts packages/qmi/data-types.ts >> packages/qmi/tmp.ts && mv packages/qmi/tmp.ts packages/qmi/data-types.ts && node src/generate.mjs", "lint:js": "eslint --ext .js,.jsx,.ts,.tsx .", "bump:patch": "bump patch --commit 'Version %s.' query-monitor.php package.json package-lock.json readme.txt wp-content/db.php", "bump:minor": "bump minor --commit 'Version %s.' query-monitor.php package.json package-lock.json readme.txt wp-content/db.php", "bump:major": "bump major --commit 'Version %s.' query-monitor.php package.json package-lock.json readme.txt wp-content/db.php", - "build": "concurrently \"sass --no-source-map assets/query-monitor.scss assets/query-monitor.css\" \"wp-scripts build\"", - "watch": "concurrently \"sass --watch --poll assets/query-monitor.scss assets/query-monitor.css\" \"wp-scripts build\" \"wp-scripts start\"" + "build": "npm run build-schemas && concurrently \"sass --no-source-map assets/query-monitor.scss assets/query-monitor.css\" \"wp-scripts build\"", + "watch": "npm run build-schemas && concurrently \"sass --watch --poll assets/query-monitor.scss assets/query-monitor.css\" \"wp-scripts build\" \"wp-scripts start\"" } } diff --git a/packages/qmi/data-types.ts b/packages/qmi/data-types.ts new file mode 100644 index 000000000..1f04f5c9b --- /dev/null +++ b/packages/qmi/data-types.ts @@ -0,0 +1,660 @@ +/* eslint-disable */ + +/** + * This file is generated by the build-schemas script. + * Do not edit it manually. + */ + +import { + WP_Block_Template, + WP_Error, + WP_Network, + WP_Post_Type, + WP_Post, + WP_Screen, + WP_Site, + WP_Term, + WP_User, +} from 'wp-types'; + +export interface DataTypes { + Admin: AbstractData & Admin; + Assets: AbstractData & Assets; + Block_Editor: AbstractData & Block_Editor; + Cache: AbstractData & Cache; + Caps: AbstractData & Caps; + Conditionals: AbstractData & Conditionals; + DB_Callers: AbstractData & DB_Callers; + DB_Components: AbstractData & DB_Components; + DB_Dupes: AbstractData & DB_Dupes; + DB_Queries: AbstractData & DB_Queries; + Environment: AbstractData & Environment; + Hooks: AbstractData & Hooks; + HTTP: AbstractData & HTTP; + Languages: AbstractData & Languages; + Logger: AbstractData & Logger; + Multisite: AbstractData & Multisite; + Overview: AbstractData & Overview; + PHP_Errors: AbstractData & PHP_Errors; + Raw_Request: AbstractData & Raw_Request; + Redirect: AbstractData & Redirect; + Request: AbstractData & Request; + Theme: AbstractData & Theme; + Timing: AbstractData & Timing; + Transients: AbstractData & Transients; +} +export interface AbstractData { + types: { + [k: string]: unknown; + }; + component_times: { + [k: string]: { + component: string; + ltime: number; + types: { + [k: string]: number; + }; + }; + }; +} +/** + * Admin screen data transfer object. + */ +export interface Admin { + current_screen?: WP_Screen; + hook_suffix: string; + list_table?: { + columns_filter: string; + sortables_filter: string; + column_action: string; + class_name?: string; + }; + pagenow: string; + taxnow: string; + typenow: string; +} +/** + * Asset data transfer object. + */ +export interface Assets { + assets?: { + missing?: AssetList; + broken?: AssetList; + header?: AssetList; + footer?: AssetList; + }; + counts: { + missing: number; + broken: number; + header: number; + footer: number; + total: number; + }; + default_version: string; + dependencies: string[]; + dependents: string[]; + footer: string[]; + header: string[]; + full_host: string; + host: string; + is_ssl: boolean; + missing_dependencies: { + [k: string]: true; + }; + port: string; +} +export interface AssetList { + [k: string]: Asset; +} +export interface Asset { + host: string; + port: string; + source: string | WP_Error; + local: boolean; + ver: string; + warning: boolean; + display: string; + dependents: string[]; + dependencies: string[]; + [k: string]: unknown; +} +/** + * Block editor data transfer object. + */ +export interface Block_Editor { + all_dynamic_blocks: string[]; + block_editor_enabled: boolean; + has_block_context: boolean; + has_block_timing: boolean; + post_blocks: unknown[]; + post_has_blocks: boolean; + total_blocks: number; +} +/** + * Cache data transfer object. + */ +export interface Cache { + has_object_cache: boolean; + display_hit_rate_warning: boolean; + has_opcode_cache: boolean; + cache_hit_percentage: number; + stats: { + [k: string]: unknown; + }; + object_cache_extensions: { + [k: string]: boolean; + }; + opcode_cache_extensions: { + [k: string]: boolean; + }; +} +/** + * User capability checks data transfer object. + */ +export interface Caps { + caps: { + args: unknown[]; + filtered_trace: FrameItem[]; + component: Component; + result: boolean; + parts: string[]; + name: string; + user: string; + }[]; + parts: string[]; + users: number[]; + components: { + [k: string]: string; + }; +} +/** + * Stack trace frame. + */ +export interface FrameItem { + display: string; + args: string[]; + calling_file: string; + calling_line: number; + file: string; + function: string; + id: string; + line: number; +} +/** + * Class representing a component. + */ +export interface Component { + type: string; + name: string; + context: string; +} +/** + * Conditionals data transfer object. + */ +export interface Conditionals { + conds: { + true: string[]; + false: string[]; + na: string[]; + }; +} +/** + * Database query callers data transfer object. + */ +export interface DB_Callers { + times: { + [k: string]: { + caller: string; + ltime: number; + types: { + [k: string]: number; + }; + }; + }; +} +/** + * Database query components data transfer object. + */ +export interface DB_Components { + times: { + [k: string]: { + ltime: number; + types: { + [k: string]: number; + }; + component: string; + }; + }; +} +/** + * Duplicate database queries data transfer object. + */ +export interface DB_Dupes { + total_qs: number; + dupe_sources: { + [k: string]: { + [k: string]: number; + }; + }; + dupe_callers: { + [k: string]: { + [k: string]: number; + }; + }; + dupe_components: { + [k: string]: { + [k: string]: number; + }; + }; + dupes: { + [k: string]: number[]; + }; + dupe_times: { + [k: string]: number; + }; +} +/** + * Database queries data transfer object. + */ +export interface DB_Queries { + total_qs: number; + total_time: number; + errors: { + [k: string]: unknown; + }[]; + expensive?: { + [k: string]: unknown; + }[]; + rows: QueryRow[]; + has_result: boolean; + has_trace: boolean; + has_main_query: boolean; + times?: { + [k: string]: { + caller: string; + ltime: number; + types: { + [k: string]: number; + }; + }; + }; + dupes?: { + [k: string]: number[]; + }; +} +export interface QueryRow { + caller: string; + caller_name: string | null; + stack?: string[]; + sql: string; + ltime: number; + result: number | boolean | WP_Error; + type: string; + component: Component | null; + trace: { + [k: string]: unknown; + } | null; + is_main_query: boolean; + filtered_trace?: FrameItem[]; +} +/** + * Environment data transfer object. + */ +export interface Environment { + php: { + variables: { + [k: string]: string | null; + }; + version: string | false; + sapi: string | false; + user: string; + old: boolean; + extensions: { + [k: string]: string; + }; + error_reporting: number; + error_levels: { + [k: string]: boolean; + }; + }; + db: { + info: { + "server-version": string; + extension: string | null; + "client-version": string | null; + user: string; + host: string; + database: string; + }; + variables: { + Variable_name: string; + Value: string; + }[]; + }; + wp: { + version: string; + environment_type?: string; + development_mode?: string; + constants: { + [k: string]: string; + }; + }; + server: { + name: string; + version: string | null; + address: string | null; + host: string | null; + OS: string | null; + arch: string | null; + }; +} +/** + * Hooks data transfer object. + */ +export interface Hooks { + hooks: { + name: string; + actions: { + priority: number; + callback: { + accepted_args: number; + name?: string; + file?: string | false; + line?: number | false; + error?: WP_Error; + component?: Component; + }; + }[]; + parts: string[]; + components: { + [k: string]: string; + }; + }[]; + parts: string[]; + components: { + [k: string]: string; + }; + all_hooks: boolean; +} +/** + * HTTP data transfer object. + */ +export interface HTTP { + http: { + [k: string]: { + args: { + [k: string]: unknown; + }; + component: Component; + filtered_trace: FrameItem[]; + info: { + [k: string]: unknown; + } | null; + host: string; + local: boolean; + ltime: number; + redirected_to: string | null; + response: + | { + [k: string]: unknown; + } + | WP_Error; + type: string; + url: string; + }; + }; + ltime: number; + errors: { + alert?: string[]; + warning?: string[]; + }; +} +/** + * Languages data transfer object. + */ +export interface Languages { + languages: { + [k: string]: { + [k: string]: { + caller: FrameItem; + domain: string; + file: string | false; + found: number | false; + handle: string | null; + type: "gettext" | "jed"; + }; + }; + }; + locale: string; + user_locale: string; + determined_locale: string; + language_attributes: string; + mlp_language: string; + pll_language: string; + total_size: number; +} +/** + * Logger data transfer object. + */ +export interface Logger { + counts: { + [k: string]: { + [k: string]: number; + }; + }; + logs: { + message: string; + filtered_trace: FrameItem[]; + component: Component; + level: string; + [k: string]: unknown; + }[]; + components: { + [k: string]: string; + }; + levels: string[]; + warning_levels: string[]; +} +/** + * Multisite data transfer object. + */ +export interface Multisite { + switches: { + new: number; + prev: number; + to: boolean; + trace: { + [k: string]: unknown; + }; + }[]; +} +/** + * Overview data transfer object. + */ +export interface Overview { + time_taken?: number; + time_limit: number; + time_start: number; + time_usage: number; + memory: number; + memory_limit: number; + memory_usage: number; + current_user?: { + [k: string]: unknown; + }; + switched_user?: { + [k: string]: unknown; + }; + display_time_usage_warning: boolean; + display_memory_usage_warning: boolean; + is_admin: boolean; +} +/** + * PHP errors data transfer object. + */ +export interface PHP_Errors { + components: { + [k: string]: string; + }; + errors: ErrorObjects; + suppressed: ErrorObjects; + silenced: ErrorObjects; +} +export interface ErrorObjects { + [k: string]: { + [k: string]: ErrorObject; + }; +} +export interface ErrorObject { + errno: number; + type: string; + message: string; + file: string | null; + filename: string; + line: number | null; + filtered_trace: FrameItem[] | null; + component: Component; + calls: number; +} +/** + * Raw request data transfer object. + */ +export interface Raw_Request { + request: { + [k: string]: unknown; + }; + response: { + [k: string]: unknown; + }; +} +/** + * Redirect data transfer object. + */ +export interface Redirect { + trace?: { + [k: string]: unknown; + }; + location?: string; + status?: number; +} +/** + * Request data transfer object. + */ +export interface Request { + user: { + title: string; + data: WP_User | false; + }; + multisite: { + current_site?: { + title: string; + data: WP_Site; + }; + current_network?: { + title: string; + data: WP_Network; + }; + }; + request: { + request: string; + matched_rule?: string; + matched_query?: string; + query_string: string; + }; + qvars: { + [k: string]: unknown; + }; + plugin_qvars: { + [k: string]: unknown; + }; + queried_object?: { + title: string; + data?: WP_Term | WP_Post_Type | WP_Post | WP_User; + type?: "WP_Term" | "WP_Post_Type" | "WP_Post" | "WP_User"; + }; + request_method: string; + matching_rewrites: { + [k: string]: string; + }; +} +/** + * Theme data transfer object. + */ +export interface Theme { + is_child_theme: boolean; + stylesheet_theme_json: string; + template_theme_json: string; + block_template: WP_Block_Template | null; + theme_dirs: { + [k: string]: string; + }; + theme_folders: { + [k: string]: string; + }; + stylesheet: string; + template: string; + theme_template_file: string; + template_path: string; + template_file?: string; + template_hierarchy?: string[]; + timber_files?: string[]; + body_class?: string[]; + template_parts: { + [k: string]: string; + }; + theme_template_parts: { + [k: string]: string; + }; + count_template_parts: { + [k: string]: number; + }; + unsuccessful_template_parts: { + [k: string]: unknown; + }[]; +} +/** + * Timing data transfer object. + */ +export interface Timing { + warning: { + function: string; + message: string; + filtered_trace: FrameItem[]; + component: Component; + }[]; + timing: { + function: string; + function_time: number; + function_memory: number; + laps: { + [k: string]: { + time: number; + time_used: number; + memory: number; + memory_used: number; + data: unknown; + }; + }; + filtered_trace: FrameItem[]; + component: Component; + start_time: number; + end_time: number; + }[]; +} +/** + * Transients data transfer object. + */ +export interface Transients { + trans: { + name: string; + filtered_trace: FrameItem[]; + component: Component; + type: string; + value: unknown; + expiration: number; + exp_diff: string; + size: number; + size_formatted: string; + }[]; + has_type: boolean; +} diff --git a/packages/qmi/index.ts b/packages/qmi/index.ts index 8af59614a..c638fba4f 100644 --- a/packages/qmi/index.ts +++ b/packages/qmi/index.ts @@ -1,8 +1,5 @@ export { Caller } from './src/caller'; -export { - Frame, - FrameItem, -} from './src/frame'; +export { Frame } from './src/frame'; export { Icon } from './src/icon'; export { NonTabular } from './src/non-tabular'; export { NotEnabled } from './src/not-enabled'; @@ -15,6 +12,7 @@ export { TotalTime } from './src/totaltime'; export { Toggler } from './src/toggler'; export { Warning } from './src/warning'; export * as Utils from './src/utils'; +export * as Data from './data-types'; export interface iPanelProps { data: any; diff --git a/packages/qmi/package.json b/packages/qmi/package.json index 69eb07f4f..13bf8a384 100644 --- a/packages/qmi/package.json +++ b/packages/qmi/package.json @@ -28,6 +28,6 @@ "dependencies": { "@types/react": "^17", "@types/react-dom": "^17", - "wp-types": "^2" + "wp-types": "^3" } } diff --git a/packages/qmi/src/caller.tsx b/packages/qmi/src/caller.tsx index 9a3bcceda..228bcef3c 100644 --- a/packages/qmi/src/caller.tsx +++ b/packages/qmi/src/caller.tsx @@ -1,8 +1,9 @@ import { Frame } from 'qmi'; +import { + FrameItem, +} from 'qmi/data-types'; import * as React from 'react'; -import type { FrameItem } from './frame'; - export interface CallerProps { trace: FrameItem[]; toggleLabel: string; diff --git a/packages/qmi/src/component.tsx b/packages/qmi/src/component.tsx index d6f087c1c..b87cf7f58 100644 --- a/packages/qmi/src/component.tsx +++ b/packages/qmi/src/component.tsx @@ -1,11 +1,10 @@ +import { + Component, +} from 'qmi/data-types'; import * as React from 'react'; interface iComponentProps { - component: { - context: string; - name: string; - type: string; - }; + component: Component; } export class QMComponent extends React.Component> { diff --git a/packages/qmi/src/frame.tsx b/packages/qmi/src/frame.tsx index e7bfa009d..b0804c8f9 100644 --- a/packages/qmi/src/frame.tsx +++ b/packages/qmi/src/frame.tsx @@ -1,16 +1,8 @@ +import { + FrameItem, +} from 'qmi/data-types'; import * as React from 'react'; -export interface FrameItem { - display: string; - args: string[]; - calling_file: string; - calling_line: number; - file: string; - function: string; - id: string; - line: number; -} - export interface FrameProps { frame: FrameItem; } diff --git a/src/bannerComment.ts b/src/bannerComment.ts new file mode 100644 index 000000000..eec983367 --- /dev/null +++ b/src/bannerComment.ts @@ -0,0 +1,12 @@ +import { + WP_Block_Template, + WP_Error, + WP_Network, + WP_Post_Type, + WP_Post, + WP_Screen, + WP_Site, + WP_Term, + WP_User, +} from 'wp-types'; + diff --git a/src/generate.mjs b/src/generate.mjs new file mode 100644 index 000000000..36a2408e3 --- /dev/null +++ b/src/generate.mjs @@ -0,0 +1,218 @@ +import fs from 'fs'; + +const dir = './src/schemas/data'; +const files = fs.readdirSync( dir ); + +for ( const file of files ) { + const [ basename, ext ] = file.split( '.' ); + + if ( ext !== 'json' ) { + continue; + } + + const path = `${dir}/${file}`; + const schema = JSON.parse( fs.readFileSync( path, 'utf8' ) ); + const output = getOutput( schema ); + + fs.writeFileSync( `./data/${basename}.php`, output ); +} + +/** + * @param {object} schema + * @returns {string} + */ +function getOutput( schema ) { + let classComment = null; + + if ( schema.definitions ) { + const headers = []; + + // iterate all definitions and add to headers + for ( const key in schema.definitions ) { + const definition = schema.definitions[key]; + + headers.push( `@phpstan-type ${key} ${mapDefinition( definition, schema )}` ); + } + + classComment = `/** +${headers.map( ( line ) => ` * ${line}` ).join( '\n' )} + */`; + } + + let output = ` mapType( one, true, schema, level, prefix ) ).join( '|' ) }`; + } + + if ( prop.oneOf ) { + return `${requiredMarker}${ prop.oneOf.map( ( one ) => mapType( one, true, schema, level, prefix ) ).join( '|' ) }`; + } + + if ( typeof type === 'undefined' ) { + return `${requiredMarker}mixed`; + } + + if ( typeof type == 'object' ) { + return `${requiredMarker}${ type.map( getPHPType ).join( '|' ) }`; + } + + const indentation = ' '.repeat( level ); + let baseType = 'array'; + + switch ( type ) { + case 'array': + if ( prop.items ) { + returnType = `array`; + } else { + returnType = 'array'; + } + break; + case 'object': + if ( prop.phpStanType && prop.phpStanType === 'object' ) { + baseType = 'object'; + } + if ( prop.properties ) { + let type = `${baseType}{`; + for ( const subKey in prop.properties ) { + const subRequiredMarker = prop.required && prop.required.includes( subKey ) ? '' : '?'; + const sub = prop.properties[subKey]; + + type += ` +${prefix} *${indentation} ${subKey}${subRequiredMarker}: ${mapType( sub, true, schema, level + 1, prefix )},`; + } + type += ` +${prefix} *${indentation} }`; + returnType = type; + } else if ( prop.additionalProperties?.type ) { + returnType = `${baseType}`; + } else { + returnType = `${baseType}`; + } + break; + default: + returnType = getPHPType( type ); + break; + } + + return `${requiredMarker}${returnType}`; +} + +/** + * @param {object} prop + * @param {object} schema + * @returns {object} + */ +function resolveRef( prop, schema ) { + if ( ! prop.$ref ) { + return prop; + } + + if ( prop.$ref.startsWith( '#/definitions/' ) ) { + const definition = prop.$ref.replace( '#/definitions/', '' ); + const refProp = schema.definitions[definition] || prop; + refProp.phpStanType = refProp.phpStanType || definition; + return refProp; + } + + return prop; +} + +/** + * @param {string} type + * @returns {string} + */ +function getPHPType( type ) { + switch ( type ) { + case 'string': + return 'string'; + case 'null': + return 'null'; + case 'number': + return 'float'; + case 'integer': + return 'int'; + case 'boolean': + return 'bool'; + case 'array': + case 'object': + return 'array'; + default: + return `'${type}'`; + } +} diff --git a/src/schema.json b/src/schema.json new file mode 100644 index 000000000..b1e84eda6 --- /dev/null +++ b/src/schema.json @@ -0,0 +1,317 @@ +{ + "$schema": "http://json-schema.org/draft-07/schema#", + "$id": "https://schemas.querymonitor.com/src/schema.json", + "title": "DataTypes", + "type": "object", + "required": [ + "Admin", + "Assets", + "Block_Editor", + "Cache", + "Caps", + "Conditionals", + "DB_Callers", + "DB_Components", + "DB_Dupes", + "DB_Queries", + "Environment", + "Hooks", + "HTTP", + "Languages", + "Logger", + "Multisite", + "Overview", + "PHP_Errors", + "Raw_Request", + "Redirect", + "Request", + "Theme", + "Timing", + "Transients" + ], + "definitions": { + "data": { + "title": "AbstractData", + "type": "object", + "required": [ + "types", + "component_times" + ], + "properties": { + "types": { + "type": "object" + }, + "component_times": { + "type": "object", + "additionalProperties": { + "type": "object", + "required": [ + "component", + "ltime", + "types" + ], + "properties": { + "component": { + "type": "string" + }, + "ltime": { + "type": "number" + }, + "types": { + "type": "object", + "additionalProperties": { + "type": "integer" + } + } + }, + "additionalProperties": false + } + } + }, + "additionalProperties": false + } + }, + "properties": { + "Admin": { + "allOf": [ + { + "$ref": "#/definitions/data" + }, + { + "$ref": "src/schemas/data/admin.json" + } + ] + }, + "Assets": { + "allOf": [ + { + "$ref": "#/definitions/data" + }, + { + "$ref": "src/schemas/data/assets.json" + } + ] + }, + "Block_Editor": { + "allOf": [ + { + "$ref": "#/definitions/data" + }, + { + "$ref": "src/schemas/data/block_editor.json" + } + ] + }, + "Cache": { + "allOf": [ + { + "$ref": "#/definitions/data" + }, + { + "$ref": "src/schemas/data/cache.json" + } + ] + }, + "Caps": { + "allOf": [ + { + "$ref": "#/definitions/data" + }, + { + "$ref": "src/schemas/data/caps.json" + } + ] + }, + "Conditionals": { + "allOf": [ + { + "$ref": "#/definitions/data" + }, + { + "$ref": "src/schemas/data/conditionals.json" + } + ] + }, + "DB_Callers": { + "allOf": [ + { + "$ref": "#/definitions/data" + }, + { + "$ref": "src/schemas/data/db_callers.json" + } + ] + }, + "DB_Components": { + "allOf": [ + { + "$ref": "#/definitions/data" + }, + { + "$ref": "src/schemas/data/db_components.json" + } + ] + }, + "DB_Dupes": { + "allOf": [ + { + "$ref": "#/definitions/data" + }, + { + "$ref": "src/schemas/data/db_dupes.json" + } + ] + }, + "DB_Queries": { + "allOf": [ + { + "$ref": "#/definitions/data" + }, + { + "$ref": "src/schemas/data/db_queries.json" + } + ] + }, + "Environment": { + "allOf": [ + { + "$ref": "#/definitions/data" + }, + { + "$ref": "src/schemas/data/environment.json" + } + ] + }, + "Hooks": { + "allOf": [ + { + "$ref": "#/definitions/data" + }, + { + "$ref": "src/schemas/data/hooks.json" + } + ] + }, + "HTTP": { + "allOf": [ + { + "$ref": "#/definitions/data" + }, + { + "$ref": "src/schemas/data/http.json" + } + ] + }, + "Languages": { + "allOf": [ + { + "$ref": "#/definitions/data" + }, + { + "$ref": "src/schemas/data/languages.json" + } + ] + }, + "Logger": { + "allOf": [ + { + "$ref": "#/definitions/data" + }, + { + "$ref": "src/schemas/data/logger.json" + } + ] + }, + "Multisite": { + "allOf": [ + { + "$ref": "#/definitions/data" + }, + { + "$ref": "src/schemas/data/multisite.json" + } + ] + }, + "Overview": { + "allOf": [ + { + "$ref": "#/definitions/data" + }, + { + "$ref": "src/schemas/data/overview.json" + } + ] + }, + "PHP_Errors": { + "allOf": [ + { + "$ref": "#/definitions/data" + }, + { + "$ref": "src/schemas/data/php_errors.json" + } + ] + }, + "Raw_Request": { + "allOf": [ + { + "$ref": "#/definitions/data" + }, + { + "$ref": "src/schemas/data/raw_request.json" + } + ] + }, + "Redirect": { + "allOf": [ + { + "$ref": "#/definitions/data" + }, + { + "$ref": "src/schemas/data/redirect.json" + } + ] + }, + "Request": { + "allOf": [ + { + "$ref": "#/definitions/data" + }, + { + "$ref": "src/schemas/data/request.json" + } + ] + }, + "Theme": { + "allOf": [ + { + "$ref": "#/definitions/data" + }, + { + "$ref": "src/schemas/data/theme.json" + } + ] + }, + "Timing": { + "allOf": [ + { + "$ref": "#/definitions/data" + }, + { + "$ref": "src/schemas/data/timing.json" + } + ] + }, + "Transients": { + "allOf": [ + { + "$ref": "#/definitions/data" + }, + { + "$ref": "src/schemas/data/transients.json" + } + ] + } + }, + "additionalProperties": false +} diff --git a/src/schemas/component.json b/src/schemas/component.json new file mode 100644 index 000000000..11f32eaa2 --- /dev/null +++ b/src/schemas/component.json @@ -0,0 +1,24 @@ +{ + "$schema": "http://json-schema.org/draft-07/schema#", + "$id": "https://schemas.querymonitor.com/src/schemas/component.json", + "title": "Component", + "description": "Class representing a component.", + "type": "object", + "required": [ + "type", + "name", + "context" + ], + "properties": { + "type": { + "type": "string" + }, + "name": { + "type": "string" + }, + "context": { + "type": "string" + } + }, + "additionalProperties": false +} diff --git a/src/schemas/data/admin.json b/src/schemas/data/admin.json new file mode 100644 index 000000000..eacdbeb40 --- /dev/null +++ b/src/schemas/data/admin.json @@ -0,0 +1,61 @@ +{ + "$schema": "http://json-schema.org/draft-07/schema#", + "$id": "https://schemas.querymonitor.com/src/schemas/data/admin.json", + "title": "Admin", + "description": "Admin screen data transfer object.", + "type": "object", + "required": [ + "hook_suffix", + "pagenow", + "taxnow", + "typenow" + ], + "properties": { + "current_screen": { + "type": "object", + "tsType": "WP_Screen", + "phpType": "WP_Screen", + "allOf": [ + { + "$ref": "../../../node_modules/wp-json-schemas/schemas/screen.json" + } + ] + }, + "hook_suffix": { + "type": "string" + }, + "list_table": { + "type": "object", + "required": [ + "columns_filter", + "sortables_filter", + "column_action" + ], + "properties": { + "columns_filter": { + "type": "string" + }, + "sortables_filter": { + "type": "string" + }, + "column_action": { + "type": "string" + }, + "class_name": { + "type": "string" + } + }, + "additionalProperties": false + }, + "pagenow": { + "type": "string" + }, + "taxnow": { + "type": "string" + }, + "typenow": { + "type": "string" + } + }, + "additionalProperties": false +} diff --git a/src/schemas/data/assets.json b/src/schemas/data/assets.json new file mode 100644 index 000000000..8173fbb82 --- /dev/null +++ b/src/schemas/data/assets.json @@ -0,0 +1,188 @@ +{ + "$schema": "http://json-schema.org/draft-07/schema#", + "$id": "https://schemas.querymonitor.com/src/schemas/data/assets.json", + "title": "Assets", + "description": "Asset data transfer object.", + "type": "object", + "definitions": { + "Asset": { + "type": "object", + "properties": { + "host": { + "type": "string" + }, + "port": { + "type": "string" + }, + "source": { + "oneOf": [ + { + "type": "string" + }, + { + "type": "object", + "tsType": "WP_Error", + "phpType": "WP_Error", + "allOf": [ + { + "$ref": "../../../node_modules/wp-json-schemas/schemas/error.json" + } + ] + } + ] + }, + "local": { + "type": "boolean" + }, + "ver": { + "type": "string" + }, + "warning": { + "type": "boolean" + }, + "display": { + "type": "string" + }, + "dependents": { + "type": "array", + "items": { + "type": "string" + } + }, + "dependencies": { + "type": "array", + "items": { + "type": "string" + } + } + }, + "required": [ + "host", + "port", + "source", + "local", + "ver", + "warning", + "display", + "dependents", + "dependencies" + ] + }, + "AssetList": { + "type": "object", + "additionalProperties": { + "type": "object", + "$ref": "#/definitions/Asset" + } + } + }, + "required": [ + "counts", + "default_version", + "dependencies", + "dependents", + "footer", + "header", + "full_host", + "host", + "is_ssl", + "missing_dependencies", + "port" + ], + "properties": { + "assets": { + "type": "object", + "properties": { + "missing": { + "$ref": "#/definitions/AssetList" + }, + "broken": { + "$ref": "#/definitions/AssetList" + }, + "header": { + "$ref": "#/definitions/AssetList" + }, + "footer": { + "$ref": "#/definitions/AssetList" + } + }, + "additionalProperties": false + }, + "counts": { + "type": "object", + "properties": { + "missing": { + "type": "integer" + }, + "broken": { + "type": "integer" + }, + "header": { + "type": "integer" + }, + "footer": { + "type": "integer" + }, + "total": { + "type": "integer" + } + }, + "required": [ + "missing", + "broken", + "header", + "footer", + "total" + ], + "additionalProperties": false + }, + "default_version": { + "type": "string" + }, + "dependencies": { + "type": "array", + "items": { + "type": "string" + } + }, + "dependents": { + "type": "array", + "items": { + "type": "string" + } + }, + "footer": { + "type": "array", + "items": { + "type": "string" + } + }, + "header": { + "type": "array", + "items": { + "type": "string" + } + }, + "full_host": { + "type": "string" + }, + "host": { + "type": "string" + }, + "is_ssl": { + "type": "boolean" + }, + "missing_dependencies": { + "type": "object", + "additionalProperties": { + "type": "boolean", + "phpType": "true", + "tsType": "true" + } + }, + "port": { + "type": "string" + } + }, + "additionalProperties": false +} diff --git a/src/schemas/data/block_editor.json b/src/schemas/data/block_editor.json new file mode 100644 index 000000000..eebea8cf8 --- /dev/null +++ b/src/schemas/data/block_editor.json @@ -0,0 +1,43 @@ +{ + "$schema": "http://json-schema.org/draft-07/schema#", + "$id": "https://schemas.querymonitor.com/src/schemas/data/block_editor.json", + "title": "Block_Editor", + "description": "Block editor data transfer object.", + "type": "object", + "required": [ + "all_dynamic_blocks", + "block_editor_enabled", + "has_block_context", + "has_block_timing", + "post_blocks", + "post_has_blocks", + "total_blocks" + ], + "properties": { + "all_dynamic_blocks": { + "type": "array", + "items": { + "type": "string" + } + }, + "block_editor_enabled": { + "type": "boolean" + }, + "has_block_context": { + "type": "boolean" + }, + "has_block_timing": { + "type": "boolean" + }, + "post_blocks": { + "type": "array" + }, + "post_has_blocks": { + "type": "boolean" + }, + "total_blocks": { + "type": "integer" + } + }, + "additionalProperties": false +} diff --git a/src/schemas/data/cache.json b/src/schemas/data/cache.json new file mode 100644 index 000000000..d063cc08a --- /dev/null +++ b/src/schemas/data/cache.json @@ -0,0 +1,46 @@ +{ + "$schema": "http://json-schema.org/draft-07/schema#", + "$id": "https://schemas.querymonitor.com/src/schemas/data/cache.json", + "title": "Cache", + "description": "Cache data transfer object.", + "type": "object", + "required": [ + "has_object_cache", + "display_hit_rate_warning", + "has_opcode_cache", + "cache_hit_percentage", + "stats", + "object_cache_extensions", + "opcode_cache_extensions" + ], + "properties": { + "has_object_cache": { + "type": "boolean" + }, + "display_hit_rate_warning": { + "type": "boolean" + }, + "has_opcode_cache": { + "type": "boolean" + }, + "cache_hit_percentage": { + "type": "integer" + }, + "stats": { + "type": "object" + }, + "object_cache_extensions": { + "type": "object", + "additionalProperties": { + "type": "boolean" + } + }, + "opcode_cache_extensions": { + "type": "object", + "additionalProperties": { + "type": "boolean" + } + } + }, + "additionalProperties": false +} diff --git a/src/schemas/data/caps.json b/src/schemas/data/caps.json new file mode 100644 index 000000000..6f7a27e15 --- /dev/null +++ b/src/schemas/data/caps.json @@ -0,0 +1,90 @@ +{ + "$schema": "http://json-schema.org/draft-07/schema#", + "$id": "https://schemas.querymonitor.com/src/schemas/data/caps.json", + "title": "Caps", + "description": "User capability checks data transfer object.", + "type": "object", + "required": [ + "caps", + "parts", + "users", + "components" + ], + "properties": { + "caps": { + "type": "array", + "items": { + "type": "object", + "required": [ + "args", + "filtered_trace", + "component", + "result", + "parts", + "name", + "user" + ], + "properties": { + "args": { + "type": "array" + }, + "filtered_trace": { + "phpType": "array>", + "type": "array", + "items": { + "allOf": [ + { + "$ref": "../frameitem.json" + } + ] + } + }, + "component": { + "phpType": "QM_Component", + "type": "object", + "allOf": [ + { + "$ref": "../component.json" + } + ] + }, + "result": { + "type": "boolean" + }, + "parts": { + "type": "array", + "items": { + "type": "string" + } + }, + "name": { + "type": "string" + }, + "user": { + "type": "string" + } + }, + "additionalProperties": false + } + }, + "parts": { + "type": "array", + "items": { + "type": "string" + } + }, + "users": { + "type": "array", + "items": { + "type": "integer" + } + }, + "components": { + "type": "object", + "additionalProperties": { + "type": "string" + } + } + }, + "additionalProperties": false +} diff --git a/src/schemas/data/conditionals.json b/src/schemas/data/conditionals.json new file mode 100644 index 000000000..dc9f88c7b --- /dev/null +++ b/src/schemas/data/conditionals.json @@ -0,0 +1,42 @@ +{ + "$schema": "http://json-schema.org/draft-07/schema#", + "$id": "https://schemas.querymonitor.com/src/schemas/data/conditionals.json", + "title": "Conditionals", + "description": "Conditionals data transfer object.", + "type": "object", + "required": [ + "conds" + ], + "properties": { + "conds": { + "type": "object", + "properties": { + "true": { + "type": "array", + "items": { + "type": "string" + } + }, + "false": { + "type": "array", + "items": { + "type": "string" + } + }, + "na": { + "type": "array", + "items": { + "type": "string" + } + } + }, + "required": [ + "true", + "false", + "na" + ], + "additionalProperties": false + } + }, + "additionalProperties": false +} diff --git a/src/schemas/data/db_callers.json b/src/schemas/data/db_callers.json new file mode 100644 index 000000000..8f0341af5 --- /dev/null +++ b/src/schemas/data/db_callers.json @@ -0,0 +1,39 @@ +{ + "$schema": "http://json-schema.org/draft-07/schema#", + "$id": "https://schemas.querymonitor.com/src/schemas/data/db_callers.json", + "title": "DB_Callers", + "description": "Database query callers data transfer object.", + "type": "object", + "required": [ + "times" + ], + "properties": { + "times": { + "type": "object", + "additionalProperties": { + "type": "object", + "properties": { + "caller": { + "type": "string" + }, + "ltime": { + "type": "number" + }, + "types": { + "type": "object", + "additionalProperties": { + "type": "integer" + } + } + }, + "required": [ + "caller", + "ltime", + "types" + ], + "additionalProperties": false + } + } + }, + "additionalProperties": false +} diff --git a/src/schemas/data/db_components.json b/src/schemas/data/db_components.json new file mode 100644 index 000000000..1e3392869 --- /dev/null +++ b/src/schemas/data/db_components.json @@ -0,0 +1,39 @@ +{ + "$schema": "http://json-schema.org/draft-07/schema#", + "$id": "https://schemas.querymonitor.com/src/schemas/data/db_components.json", + "title": "DB_Components", + "description": "Database query components data transfer object.", + "type": "object", + "required": [ + "times" + ], + "properties": { + "times": { + "type": "object", + "additionalProperties": { + "type": "object", + "properties": { + "ltime": { + "type": "number" + }, + "types": { + "type": "object", + "additionalProperties": { + "type": "integer" + } + }, + "component": { + "type": "string" + } + }, + "required": [ + "ltime", + "types", + "component" + ], + "additionalProperties": false + } + } + }, + "additionalProperties": false +} diff --git a/src/schemas/data/db_dupes.json b/src/schemas/data/db_dupes.json new file mode 100644 index 000000000..74d25bef2 --- /dev/null +++ b/src/schemas/data/db_dupes.json @@ -0,0 +1,63 @@ +{ + "$schema": "http://json-schema.org/draft-07/schema#", + "$id": "https://schemas.querymonitor.com/src/schemas/data/db_dupes.json", + "title": "DB_Dupes", + "description": "Duplicate database queries data transfer object.", + "type": "object", + "required": [ + "total_qs", + "dupe_sources", + "dupe_callers", + "dupe_components", + "dupes", + "dupe_times" + ], + "properties": { + "total_qs": { + "type": "integer" + }, + "dupe_sources": { + "type": "object", + "additionalProperties": { + "type": "object", + "additionalProperties": { + "type": "integer" + } + } + }, + "dupe_callers": { + "type": "object", + "additionalProperties": { + "type": "object", + "additionalProperties": { + "type": "integer" + } + } + }, + "dupe_components": { + "type": "object", + "additionalProperties": { + "type": "object", + "additionalProperties": { + "type": "integer" + } + } + }, + "dupes": { + "type": "object", + "additionalProperties": { + "type": "array", + "items": { + "type": "integer" + } + } + }, + "dupe_times": { + "type": "object", + "additionalProperties": { + "type": "number" + } + } + }, + "additionalProperties": false +} diff --git a/src/schemas/data/db_queries.json b/src/schemas/data/db_queries.json new file mode 100644 index 000000000..fe35020f6 --- /dev/null +++ b/src/schemas/data/db_queries.json @@ -0,0 +1,192 @@ +{ + "$schema": "http://json-schema.org/draft-07/schema#", + "$id": "https://schemas.querymonitor.com/src/schemas/data/db_queries.json", + "title": "DB_Queries", + "description": "Database queries data transfer object.", + "type": "object", + "definitions": { + "QueryRow": { + "type": "object", + "required": [ + "caller", + "caller_name", + "sql", + "ltime", + "result", + "type", + "component", + "trace", + "is_main_query" + ], + "properties": { + "caller": { + "type": "string" + }, + "caller_name": { + "type": [ + "string", + "null" + ] + }, + "stack": { + "type": "array", + "items": { + "type": "string" + } + }, + "sql": { + "type": "string" + }, + "ltime": { + "type": "number" + }, + "result": { + "oneOf": [ + { + "type": "integer" + }, + { + "type": "boolean" + }, + { + "type": "object", + "tsType": "WP_Error", + "phpType": "WP_Error", + "allOf": [ + { + "$ref": "../../../node_modules/wp-json-schemas/schemas/error.json" + } + ] + } + ] + }, + "type": { + "type": "string" + }, + "component": { + "oneOf": [ + { + "phpType": "QM_Component", + "type": "object", + "allOf": [ + { + "$ref": "../component.json" + } + ] + }, + { + "type": "null" + } + ] + }, + "trace": { + "phpType": "?QM_Backtrace", + "type": [ + "object", + "null" + ] + }, + "is_main_query": { + "type": "boolean" + }, + "filtered_trace": { + "phpType": "array>", + "type": "array", + "items": { + "allOf": [ + { + "$ref": "../frameitem.json" + } + ] + } + } + }, + "additionalProperties": false + } + }, + "required": [ + "total_qs", + "total_time", + "has_result", + "has_trace", + "has_main_query", + "rows", + "errors" + ], + "properties": { + "total_qs": { + "type": "integer" + }, + "total_time": { + "type": "number" + }, + "errors": { + "type": "array", + "items": { + "type": "object" + } + }, + "expensive": { + "type": "array", + "items": { + "type": "object" + } + }, + "rows": { + "phpStanType": "array", + "type": "array", + "items": { + "allOf": [ + { + "$ref": "#/definitions/QueryRow" + } + ] + } + }, + "has_result": { + "type": "boolean" + }, + "has_trace": { + "type": "boolean" + }, + "has_main_query": { + "type": "boolean" + }, + "times": { + "type": "object", + "additionalProperties": { + "type": "object", + "properties": { + "caller": { + "type": "string" + }, + "ltime": { + "type": "number" + }, + "types": { + "type": "object", + "additionalProperties": { + "type": "integer" + } + } + }, + "required": [ + "caller", + "ltime", + "types" + ], + "additionalProperties": false + } + }, + "dupes": { + "type": "object", + "additionalProperties": { + "type": "array", + "items": { + "type": "integer" + } + } + } + }, + "additionalProperties": false +} diff --git a/src/schemas/data/doing_it_wrong.json b/src/schemas/data/doing_it_wrong.json new file mode 100644 index 000000000..c9c1b6180 --- /dev/null +++ b/src/schemas/data/doing_it_wrong.json @@ -0,0 +1,53 @@ +{ + "$schema": "http://json-schema.org/draft-07/schema#", + "$id": "https://schemas.querymonitor.com/src/schemas/data/doing_it_wrong.json", + "title": "Doing_It_Wrong", + "description": "Doing it Wrong data transfer object.", + "type": "object", + "required": [ + "actions" + ], + "properties": { + "actions": { + "type": "array", + "items": { + "type": "object", + "required": [ + "hook", + "filtered_trace", + "message", + "component" + ], + "properties": { + "hook": { + "type": "string" + }, + "filtered_trace": { + "phpType": "array>", + "type": "array", + "items": { + "allOf": [ + { + "$ref": "../frameitem.json" + } + ] + } + }, + "message": { + "type": "string" + }, + "component": { + "phpType": "QM_Component", + "type": "object", + "allOf": [ + { + "$ref": "../component.json" + } + ] + } + } + } + } + }, + "additionalProperties": false +} diff --git a/src/schemas/data/environment.json b/src/schemas/data/environment.json new file mode 100644 index 000000000..11174f5f6 --- /dev/null +++ b/src/schemas/data/environment.json @@ -0,0 +1,206 @@ +{ + "$schema": "http://json-schema.org/draft-07/schema#", + "$id": "https://schemas.querymonitor.com/src/schemas/data/environment.json", + "title": "Environment", + "description": "Environment data transfer object.", + "type": "object", + "required": [ + "php", + "db", + "wp", + "server" + ], + "properties": { + "php": { + "type": "object", + "properties": { + "variables": { + "type": "object", + "additionalProperties": { + "type": [ + "string", + "null" + ] + } + }, + "version": { + "type": [ + "string", + "boolean" + ], + "phpType": "string|false", + "tsType": "string|false" + }, + "sapi": { + "type": [ + "string", + "boolean" + ], + "phpType": "string|false", + "tsType": "string|false" + }, + "user": { + "type": "string" + }, + "old": { + "type": "boolean" + }, + "extensions": { + "type": "object", + "additionalProperties": { + "type": "string" + } + }, + "error_reporting": { + "type": "integer" + }, + "error_levels": { + "type": "object", + "additionalProperties": { + "type": "boolean" + } + } + }, + "required": [ + "variables", + "version", + "sapi", + "user", + "old", + "extensions", + "error_reporting", + "error_levels" + ], + "additionalProperties": false + }, + "db": { + "type": "object", + "properties": { + "info": { + "type": "object", + "properties": { + "server-version": { + "type": "string" + }, + "extension": { + "type": [ + "string", + "null" + ] + }, + "client-version": { + "type": [ + "string", + "null" + ] + }, + "user": { + "type": "string" + }, + "host": { + "type": "string" + }, + "database": { + "type": "string" + } + }, + "required": [ + "server-version", + "extension", + "client-version", + "user", + "host", + "database" + ], + "additionalProperties": false + }, + "variables": { + "type": "array", + "tsType": "{\nVariable_name: string;\nValue: string;\n}[]", + "items": { + "type": "object", + "phpType": "stdClass" + } + } + }, + "required": [ + "info", + "variables" + ], + "additionalProperties": false + }, + "wp": { + "type": "object", + "properties": { + "version": { + "type": "string" + }, + "environment_type": { + "type": "string" + }, + "development_mode": { + "type": "string" + }, + "constants": { + "type": "object", + "additionalProperties": { + "type": "string" + } + } + }, + "required": [ + "version", + "constants" + ], + "additionalProperties": false + }, + "server": { + "type": "object", + "properties": { + "name": { + "type": "string" + }, + "version": { + "type": [ + "string", + "null" + ] + }, + "address": { + "type": [ + "string", + "null" + ] + }, + "host": { + "type": [ + "string", + "null" + ] + }, + "OS": { + "type": [ + "string", + "null" + ] + }, + "arch": { + "type": [ + "string", + "null" + ] + } + }, + "required": [ + "name", + "version", + "address", + "host", + "OS", + "arch" + ], + "additionalProperties": false + } + }, + "additionalProperties": false +} diff --git a/src/schemas/data/hooks.json b/src/schemas/data/hooks.json new file mode 100644 index 000000000..f52d60438 --- /dev/null +++ b/src/schemas/data/hooks.json @@ -0,0 +1,127 @@ +{ + "$schema": "http://json-schema.org/draft-07/schema#", + "$id": "https://schemas.querymonitor.com/src/schemas/data/hooks.json", + "title": "Hooks", + "description": "Hooks data transfer object.", + "type": "object", + "required": [ + "hooks", + "parts", + "components", + "all_hooks" + ], + "properties": { + "hooks": { + "type": "array", + "items": { + "type": "object", + "properties": { + "name": { + "type": "string" + }, + "actions": { + "type": "array", + "items": { + "type": "object", + "properties": { + "priority": { + "type": "integer" + }, + "callback": { + "type": "object", + "properties": { + "accepted_args": { + "type": "integer" + }, + "name": { + "type": "string" + }, + "file": { + "phpType": "string|false", + "tsType": "string|false", + "type": [ + "string", + "boolean" + ] + }, + "line": { + "phpType": "int|false", + "tsType": "number|false", + "type": [ + "number", + "boolean" + ] + }, + "error": { + "type": "object", + "tsType": "WP_Error", + "phpType": "WP_Error", + "allOf": [ + { + "$ref": "../../../node_modules/wp-json-schemas/schemas/error.json" + } + ] + }, + "component": { + "phpType": "QM_Component", + "type": "object", + "allOf": [ + { + "$ref": "../component.json" + } + ] + } + }, + "required": [ + "accepted_args" + ], + "additionalProperties": false + } + }, + "required": [ + "priority", + "callback" + ], + "additionalProperties": false + } + }, + "parts": { + "type": "array", + "items": { + "type": "string" + } + }, + "components": { + "type": "object", + "additionalProperties": { + "type": "string" + } + } + }, + "required": [ + "name", + "actions", + "parts", + "components" + ], + "additionalProperties": false + } + }, + "parts": { + "type": "array", + "items": { + "type": "string" + } + }, + "components": { + "type": "object", + "additionalProperties": { + "type": "string" + } + }, + "all_hooks": { + "type": "boolean" + } + }, + "additionalProperties": false +} diff --git a/src/schemas/data/http.json b/src/schemas/data/http.json new file mode 100644 index 000000000..21e419b10 --- /dev/null +++ b/src/schemas/data/http.json @@ -0,0 +1,117 @@ +{ + "$schema": "http://json-schema.org/draft-07/schema#", + "$id": "https://schemas.querymonitor.com/src/schemas/data/http.json", + "title": "HTTP", + "description": "HTTP data transfer object.", + "type": "object", + "required": [ + "http", + "ltime", + "errors" + ], + "properties": { + "http": { + "type": "object", + "additionalProperties": { + "type": "object", + "properties": { + "args": { + "type": "object" + }, + "component": { + "phpType": "QM_Component", + "type": "object", + "allOf": [ + { + "$ref": "../component.json" + } + ] + }, + "filtered_trace": { + "phpType": "array>", + "type": "array", + "items": { + "allOf": [ + { + "$ref": "../frameitem.json" + } + ] + } + }, + "info": { + "type": [ + "object", + "null" + ], + "phpType": "array|null" + }, + "host": { + "type": "string" + }, + "local": { + "type": "boolean" + }, + "ltime": { + "type": "number" + }, + "redirected_to": { + "type": [ + "string", + "null" + ] + }, + "response": { + "type": [ + "array", + "object" + ], + "phpType": "array|WP_Error", + "tsType": "{\n[k: string]: unknown;\n}|WP_Error" + }, + "type": { + "type": "string" + }, + "url": { + "type": "string" + } + }, + "required": [ + "args", + "component", + "filtered_trace", + "host", + "info", + "local", + "ltime", + "redirected_to", + "response", + "type", + "url" + ], + "additionalProperties": false + } + }, + "ltime": { + "type": "number" + }, + "errors": { + "type": "object", + "properties": { + "alert": { + "type": "array", + "items": { + "type": "string" + } + }, + "warning": { + "type": "array", + "items": { + "type": "string" + } + } + }, + "additionalProperties": false + } + }, + "additionalProperties": false +} diff --git a/src/schemas/data/languages.json b/src/schemas/data/languages.json new file mode 100644 index 000000000..54413b49a --- /dev/null +++ b/src/schemas/data/languages.json @@ -0,0 +1,102 @@ +{ + "$schema": "http://json-schema.org/draft-07/schema#", + "$id": "https://schemas.querymonitor.com/src/schemas/data/languages.json", + "title": "Languages", + "description": "Languages data transfer object.", + "type": "object", + "required": [ + "languages", + "locale", + "user_locale", + "determined_locale", + "language_attributes", + "mlp_language", + "pll_language", + "total_size" + ], + "properties": { + "languages": { + "type": "object", + "additionalProperties": { + "type": "object", + "additionalProperties": { + "type": "object", + "properties": { + "caller": { + "phpType": "array", + "type": "object", + "allOf": [ + { + "$ref": "../frameitem.json" + } + ] + }, + "domain": { + "type": "string" + }, + "file": { + "type": [ + "string", + "boolean" + ], + "phpType": "string|false", + "tsType": "string|false" + }, + "found": { + "type": [ + "integer", + "boolean" + ], + "phpType": "int|false", + "tsType": "number|false" + }, + "handle": { + "type": [ + "string", + "null" + ] + }, + "type": { + "type": "string", + "enum": [ + "gettext", + "jed" + ] + } + }, + "required": [ + "caller", + "domain", + "file", + "found", + "handle", + "type" + ], + "additionalProperties": false + } + } + }, + "locale": { + "type": "string" + }, + "user_locale": { + "type": "string" + }, + "determined_locale": { + "type": "string" + }, + "language_attributes": { + "type": "string" + }, + "mlp_language": { + "type": "string" + }, + "pll_language": { + "type": "string" + }, + "total_size": { + "type": "integer" + } + }, + "additionalProperties": false +} diff --git a/src/schemas/data/logger.json b/src/schemas/data/logger.json new file mode 100644 index 000000000..c89e1d9e2 --- /dev/null +++ b/src/schemas/data/logger.json @@ -0,0 +1,87 @@ +{ + "$schema": "http://json-schema.org/draft-07/schema#", + "$id": "https://schemas.querymonitor.com/src/schemas/data/logger.json", + "title": "Logger", + "description": "Logger data transfer object.", + "type": "object", + "required": [ + "counts", + "logs", + "components", + "levels", + "warning_levels" + ], + "properties": { + "counts": { + "type": "object", + "phpStanType": "array", + "additionalProperties": { + "type": "object", + "additionalProperties": { + "type": "integer" + } + } + }, + "logs": { + "type": "array", + "items": { + "type": "object", + "properties": { + "message": { + "type": "string" + }, + "filtered_trace": { + "phpType": "array>", + "type": "array", + "items": { + "allOf": [ + { + "$ref": "../frameitem.json" + } + ] + } + }, + "component": { + "phpType": "QM_Component", + "type": "object", + "allOf": [ + { + "$ref": "../component.json" + } + ] + }, + "level": { + "type": "string", + "phpType": "QM_Collector_Logger::*" + } + }, + "required": [ + "message", + "filtered_trace", + "component", + "level" + ], + "additionalItems": false + } + }, + "components": { + "type": "object", + "additionalProperties": { + "type": "string" + } + }, + "levels": { + "type": "array", + "items": { + "type": "string" + } + }, + "warning_levels": { + "type": "array", + "items": { + "type": "string" + } + } + }, + "additionalProperties": false +} diff --git a/src/schemas/data/multisite.json b/src/schemas/data/multisite.json new file mode 100644 index 000000000..6e866e79a --- /dev/null +++ b/src/schemas/data/multisite.json @@ -0,0 +1,41 @@ +{ + "$schema": "http://json-schema.org/draft-07/schema#", + "$id": "https://schemas.querymonitor.com/src/schemas/data/multisite.json", + "title": "Multisite", + "description": "Multisite data transfer object.", + "type": "object", + "required": [ + "switches" + ], + "properties": { + "switches": { + "type": "array", + "items": { + "type": "object", + "properties": { + "new": { + "type": "integer" + }, + "prev": { + "type": "integer" + }, + "to": { + "type": "boolean" + }, + "trace": { + "type": "object", + "phpType": "QM_Backtrace" + } + }, + "required": [ + "new", + "prev", + "to", + "trace" + ], + "additionalProperties": false + } + } + }, + "additionalProperties": false +} diff --git a/src/schemas/data/overview.json b/src/schemas/data/overview.json new file mode 100644 index 000000000..ab0eb0df5 --- /dev/null +++ b/src/schemas/data/overview.json @@ -0,0 +1,63 @@ +{ + "$schema": "http://json-schema.org/draft-07/schema#", + "$id": "https://schemas.querymonitor.com/src/schemas/data/overview.json", + "title": "Overview", + "description": "Overview data transfer object.", + "type": "object", + "required": [ + "time_limit", + "time_start", + "time_usage", + "memory", + "memory_limit", + "memory_usage", + "display_time_usage_warning", + "display_memory_usage_warning", + "is_admin" + ], + "properties": { + "time_taken": { + "type": "number" + }, + "time_limit": { + "type": "integer" + }, + "time_start": { + "type": "number" + }, + "time_usage": { + "type": [ + "integer", + "number" + ] + }, + "memory": { + "type": "integer" + }, + "memory_limit": { + "type": "number" + }, + "memory_usage": { + "type": [ + "integer", + "number" + ] + }, + "current_user": { + "type": "object" + }, + "switched_user": { + "type": "object" + }, + "display_time_usage_warning": { + "type": "boolean" + }, + "display_memory_usage_warning": { + "type": "boolean" + }, + "is_admin": { + "type": "boolean" + } + }, + "additionalProperties": false +} diff --git a/src/schemas/data/php_errors.json b/src/schemas/data/php_errors.json new file mode 100644 index 000000000..3d6dc076b --- /dev/null +++ b/src/schemas/data/php_errors.json @@ -0,0 +1,114 @@ +{ + "$schema": "http://json-schema.org/draft-07/schema#", + "$id": "https://schemas.querymonitor.com/src/schemas/data/php_errors.json", + "title": "PHP_Errors", + "description": "PHP errors data transfer object.", + "type": "object", + "definitions": { + "errorObject": { + "type": "object", + "properties": { + "errno": { + "type": "integer" + }, + "type": { + "type": "string" + }, + "message": { + "type": "string" + }, + "file": { + "type": [ + "string", + "null" + ] + }, + "filename": { + "type": "string" + }, + "line": { + "type": [ + "integer", + "null" + ] + }, + "filtered_trace": { + "oneOf": [ + { + "phpType": "array>", + "type": "array", + "items": { + "allOf": [ + { + "$ref": "../frameitem.json" + } + ] + } + }, + { + "type": "null" + } + ] + }, + "component": { + "phpType": "QM_Component", + "type": "object", + "allOf": [ + { + "$ref": "../component.json" + } + ] + }, + "calls": { + "type": "integer" + } + }, + "required": [ + "errno", + "type", + "message", + "file", + "filename", + "line", + "filtered_trace", + "component", + "calls" + ], + "additionalProperties": false + }, + "errorObjects": { + "type": "object", + "additionalProperties": { + "type": "object", + "additionalProperties": { + "type": "object", + "$ref": "#/definitions/errorObject" + } + } + } + }, + "required": [ + "components", + "errors", + "suppressed", + "silenced" + ], + "properties": { + "components": { + "type": "object", + "additionalProperties": { + "type": "string" + } + }, + "errors": { + "$ref": "#/definitions/errorObjects" + }, + "suppressed": { + "$ref": "#/definitions/errorObjects" + }, + "silenced": { + "$ref": "#/definitions/errorObjects" + } + }, + "additionalProperties": false +} diff --git a/src/schemas/data/raw_request.json b/src/schemas/data/raw_request.json new file mode 100644 index 000000000..fc0f3c519 --- /dev/null +++ b/src/schemas/data/raw_request.json @@ -0,0 +1,20 @@ +{ + "$schema": "http://json-schema.org/draft-07/schema#", + "$id": "https://schemas.querymonitor.com/src/schemas/data/raw_request.json", + "title": "Raw_Request", + "description": "Raw request data transfer object.", + "type": "object", + "required": [ + "request", + "response" + ], + "properties": { + "request": { + "type": "object" + }, + "response": { + "type": "object" + } + }, + "additionalProperties": false +} diff --git a/src/schemas/data/redirect.json b/src/schemas/data/redirect.json new file mode 100644 index 000000000..63d8c802f --- /dev/null +++ b/src/schemas/data/redirect.json @@ -0,0 +1,20 @@ +{ + "$schema": "http://json-schema.org/draft-07/schema#", + "$id": "https://schemas.querymonitor.com/src/schemas/data/redirect.json", + "title": "Redirect", + "description": "Redirect data transfer object.", + "type": "object", + "properties": { + "trace": { + "type": "object", + "phpType": "QM_Backtrace" + }, + "location": { + "type": "string" + }, + "status": { + "type": "integer" + } + }, + "additionalProperties": false +} diff --git a/src/schemas/data/request.json b/src/schemas/data/request.json new file mode 100644 index 000000000..97bced0c1 --- /dev/null +++ b/src/schemas/data/request.json @@ -0,0 +1,189 @@ +{ + "$schema": "http://json-schema.org/draft-07/schema#", + "$id": "https://schemas.querymonitor.com/src/schemas/data/request.json", + "title": "Request", + "description": "Request data transfer object.", + "type": "object", + "required": [ + "user", + "multisite", + "request", + "qvars", + "plugin_qvars", + "request_method", + "matching_rewrites" + ], + "properties": { + "user": { + "type": "object", + "properties": { + "title": { + "type": "string" + }, + "data": { + "type": [ + "object", + "boolean" + ], + "tsType": "WP_User|false", + "phpType": "WP_User|false" + } + }, + "required": [ + "title", + "data" + ], + "additionalProperties": false + }, + "multisite": { + "type": "object", + "properties": { + "current_site": { + "type": "object", + "properties": { + "title": { + "type": "string" + }, + "data": { + "type": "object", + "tsType": "WP_Site", + "phpType": "WP_Site", + "allOf": [ + { + "$ref": "../../../node_modules/wp-json-schemas/schemas/site.json" + } + ] + } + }, + "required": [ + "title", + "data" + ], + "additionalProperties": false + }, + "current_network": { + "type": "object", + "properties": { + "title": { + "type": "string" + }, + "data": { + "type": "object", + "tsType": "WP_Network", + "phpType": "WP_Network", + "allOf": [ + { + "$ref": "../../../node_modules/wp-json-schemas/schemas/network.json" + } + ] + } + }, + "required": [ + "title", + "data" + ], + "additionalProperties": false + } + }, + "additionalProperties": false + }, + "request": { + "type": "object", + "properties": { + "request": { + "type": "string" + }, + "matched_rule": { + "type": "string" + }, + "matched_query": { + "type": "string" + }, + "query_string": { + "type": "string" + } + }, + "required": [ + "request", + "query_string" + ], + "additionalProperties": false + }, + "qvars": { + "type": "object" + }, + "plugin_qvars": { + "type": "object" + }, + "queried_object": { + "type": "object", + "properties": { + "title": { + "type": "string" + }, + "data": { + "oneOf": [ + { + "type": "object", + "phpType": "WP_Term", + "tsType": "WP_Term", + "allOf": [ + { + "$ref": "../../../node_modules/wp-json-schemas/schemas/term.json" + } + ] + }, + { + "type": "object", + "phpType": "WP_Post_Type", + "tsType": "WP_Post_Type", + "allOf": [ + { + "$ref": "../../../node_modules/wp-json-schemas/schemas/post-type.json" + } + ] + }, + { + "type": "object", + "phpType": "WP_Post", + "tsType": "WP_Post", + "allOf": [ + { + "$ref": "../../../node_modules/wp-json-schemas/schemas/post.json" + } + ] + }, + { + "type": "object", + "phpType": "WP_User", + "tsType": "WP_User", + "allOf": [ + { + "$ref": "../../../node_modules/wp-json-schemas/schemas/user.json" + } + ] + } + ] + }, + "type": { + "type": "string", + "tsType": "'WP_Term'|'WP_Post_Type'|'WP_Post'|'WP_User'" + } + }, + "required": [ + "title" + ], + "additionalProperties": false + }, + "request_method": { + "type": "string" + }, + "matching_rewrites": { + "type": "object", + "additionalProperties": { + "type": "string" + } + } + }, + "additionalProperties": false +} diff --git a/src/schemas/data/theme.json b/src/schemas/data/theme.json new file mode 100644 index 000000000..9eeb35611 --- /dev/null +++ b/src/schemas/data/theme.json @@ -0,0 +1,124 @@ +{ + "$schema": "http://json-schema.org/draft-07/schema#", + "$id": "https://schemas.querymonitor.com/src/schemas/data/theme.json", + "title": "Theme", + "description": "Theme data transfer object.", + "type": "object", + "required": [ + "is_child_theme", + "stylesheet_theme_json", + "template_theme_json", + "block_template", + "theme_dirs", + "theme_folders", + "stylesheet", + "template", + "theme_template_file", + "template_path", + "template_parts", + "theme_template_parts", + "count_template_parts", + "unsuccessful_template_parts" + ], + "properties": { + "is_child_theme": { + "type": "boolean" + }, + "stylesheet_theme_json": { + "type": "string" + }, + "template_theme_json": { + "type": "string" + }, + "block_template": { + "oneOf": [ + { + "type": "object", + "tsType": "WP_Block_Template", + "phpType": "WP_Block_Template", + "allOf": [ + { + "$ref": "../../../node_modules/wp-json-schemas/schemas/block-template.json" + } + ] + }, + { + "type": "null" + } + ] + }, + "theme_dirs": { + "type": "object", + "additionalProperties": { + "type": "string" + } + }, + "theme_folders": { + "type": "object", + "additionalProperties": { + "type": "string" + } + }, + "stylesheet": { + "type": "string" + }, + "template": { + "type": "string" + }, + "theme_template_file": { + "type": "string" + }, + "template_path": { + "type": "string" + }, + "template_file": { + "type": "string" + }, + "template_hierarchy": { + "type": "array", + "items": { + "type": "string" + } + }, + "timber_files": { + "type": "array", + "items": { + "type": "string" + } + }, + "body_class": { + "type": "array", + "items": { + "type": "string" + } + }, + "template_parts": { + "type": "object", + "phpType": "array", + "additionalProperties": { + "type": "string" + } + }, + "theme_template_parts": { + "type": "object", + "phpType": "array", + "additionalProperties": { + "type": "string" + } + }, + "count_template_parts": { + "type": "object", + "phpType": "array", + "additionalProperties": { + "type": "integer" + } + }, + "unsuccessful_template_parts": { + "type": "array", + "items": { + "type": "object" + } + } + }, + "additionalProperties": false +} diff --git a/src/schemas/data/timing.json b/src/schemas/data/timing.json new file mode 100644 index 000000000..d6a1df33d --- /dev/null +++ b/src/schemas/data/timing.json @@ -0,0 +1,138 @@ +{ + "$schema": "http://json-schema.org/draft-07/schema#", + "$id": "https://schemas.querymonitor.com/src/schemas/data/timing.json", + "title": "Timing", + "description": "Timing data transfer object.", + "type": "object", + "required": [ + "warning", + "timing" + ], + "properties": { + "warning": { + "type": "array", + "items": { + "type": "object", + "properties": { + "function": { + "type": "string" + }, + "message": { + "type": "string" + }, + "filtered_trace": { + "phpType": "array>", + "type": "array", + "items": { + "allOf": [ + { + "$ref": "../frameitem.json" + } + ] + } + }, + "component": { + "phpType": "QM_Component", + "type": "object", + "allOf": [ + { + "$ref": "../component.json" + } + ] + } + }, + "required": [ + "function", + "message", + "filtered_trace", + "component" + ], + "additionalProperties": false + } + }, + "timing": { + "type": "array", + "items": { + "type": "object", + "properties": { + "function": { + "type": "string" + }, + "function_time": { + "type": "number" + }, + "function_memory": { + "type": "integer" + }, + "laps": { + "type": "object", + "additionalProperties": { + "type": "object", + "properties": { + "time": { + "type": "number" + }, + "time_used": { + "type": "number" + }, + "memory": { + "type": "integer" + }, + "memory_used": { + "type": "integer" + }, + "data": {} + }, + "required": [ + "time", + "time_used", + "memory", + "memory_used", + "data" + ], + "additionalProperties": false + } + }, + "filtered_trace": { + "phpType": "array>", + "type": "array", + "items": { + "allOf": [ + { + "$ref": "../frameitem.json" + } + ] + } + }, + "component": { + "phpType": "QM_Component", + "type": "object", + "allOf": [ + { + "$ref": "../component.json" + } + ] + }, + "start_time": { + "type": "number" + }, + "end_time": { + "type": "number" + } + }, + "required": [ + "function", + "function_time", + "function_memory", + "laps", + "filtered_trace", + "component", + "start_time", + "end_time" + ], + "additionalProperties": false + } + } + }, + "additionalProperties": false +} diff --git a/src/schemas/data/transients.json b/src/schemas/data/transients.json new file mode 100644 index 000000000..2d3d710ac --- /dev/null +++ b/src/schemas/data/transients.json @@ -0,0 +1,76 @@ +{ + "$schema": "http://json-schema.org/draft-07/schema#", + "$id": "https://schemas.querymonitor.com/src/schemas/data/transients.json", + "title": "Transients", + "description": "Transients data transfer object.", + "type": "object", + "required": [ + "trans", + "has_type" + ], + "properties": { + "trans": { + "type": "array", + "items": { + "type": "object", + "properties": { + "name": { + "type": "string" + }, + "filtered_trace": { + "phpType": "array>", + "type": "array", + "items": { + "allOf": [ + { + "$ref": "../frameitem.json" + } + ] + } + }, + "component": { + "phpType": "QM_Component", + "type": "object", + "allOf": [ + { + "$ref": "../component.json" + } + ] + }, + "type": { + "type": "string" + }, + "value": {}, + "expiration": { + "type": "integer" + }, + "exp_diff": { + "type": "string" + }, + "size": { + "type": "integer" + }, + "size_formatted": { + "type": "string" + } + }, + "required": [ + "name", + "filtered_trace", + "component", + "type", + "value", + "expiration", + "exp_diff", + "size", + "size_formatted" + ], + "additionalProperties": false + } + }, + "has_type": { + "type": "boolean" + } + }, + "additionalProperties": false +} diff --git a/src/schemas/frameitem.json b/src/schemas/frameitem.json new file mode 100644 index 000000000..74b51d141 --- /dev/null +++ b/src/schemas/frameitem.json @@ -0,0 +1,47 @@ +{ + "$schema": "http://json-schema.org/draft-07/schema#", + "$id": "https://schemas.querymonitor.com/src/schemas/frameitem.json", + "title": "FrameItem", + "description": "Stack trace frame.", + "type": "object", + "required": [ + "display", + "args", + "calling_file", + "calling_line", + "file", + "function", + "id", + "line" + ], + "properties": { + "display": { + "type": "string" + }, + "args": { + "type": "array", + "items": { + "type": "string" + } + }, + "calling_file": { + "type": "string" + }, + "calling_line": { + "type": "integer" + }, + "file": { + "type": "string" + }, + "function": { + "type": "string" + }, + "id": { + "type": "string" + }, + "line": { + "type": "integer" + } + }, + "additionalProperties": false +} diff --git a/tests/integration/DispatcherHtmlTest.php b/tests/integration/DispatcherHtmlTest.php index d2ec1e972..35732f862 100644 --- a/tests/integration/DispatcherHtmlTest.php +++ b/tests/integration/DispatcherHtmlTest.php @@ -4,7 +4,7 @@ class DispatcherHtmlTest extends Test { - /** @var \QM_Dispatcher_Html|null */ + /** @var \QM_Dispatcher_Html|null $html */ protected $html = null; public function _before(): void { @@ -21,7 +21,7 @@ public function _before(): void { wp_set_current_user( $admin->ID ); - /** @var \QM_Dispatcher_Html */ + /** @var \QM_Dispatcher_Html $html */ $html = \QM_Dispatchers::get( 'html' ); $this->html = $html; @@ -33,6 +33,7 @@ public function _before(): void { * https://github.com/johnbillion/query-monitor/issues/137 */ public function testDispatcherRespectsLateChangeOfHttps(): void { + /** @var \WP_Scripts $wp_scripts */ global $wp_scripts; if ( isset( $_SERVER['HTTPS'] ) ) {
- { info[key] } + { infoLabels[key] } { db.info[key] || ( diff --git a/output/html/admin.tsx b/output/html/admin.tsx index ce409e291..979b1cd72 100644 --- a/output/html/admin.tsx +++ b/output/html/admin.tsx @@ -2,26 +2,15 @@ import { NonTabular, iPanelProps, } from 'qmi'; +import { + DataTypes, +} from 'qmi/data-types'; import * as React from 'react'; import { __ } from '@wordpress/i18n'; interface iAdminProps extends iPanelProps { - data: { - current_screen: { - [k: string]: string|boolean; - }; - hook_suffix: string; - pagenow: string; - taxnow: string; - typenow: string; - list_table?: { - columns_filter: string; - sortables_filter: string; - column_action: string; - class_name?: string; - }; - }; + data: DataTypes['Admin']; } class Admin extends React.Component> { @@ -51,7 +40,7 @@ class Admin extends React.Component> {
{ key } diff --git a/output/html/assets.php b/output/html/assets.php index 40fb7cbc1..a98a679dd 100644 --- a/output/html/assets.php +++ b/output/html/assets.php @@ -34,7 +34,7 @@ abstract public function get_type_labels(); */ public function output() { - /** @var QM_Data_Assets */ + /** @var QM_Data_Assets $data */ $data = $this->collector->get_data(); $type_label = $this->get_type_labels(); @@ -120,7 +120,7 @@ public function output() { * @return void */ protected function dependency_row( $handle, array $asset, $label ) { - /** @var QM_Data_Assets */ + /** @var QM_Data_Assets $data */ $data = $this->collector->get_data(); $highlight_deps = array_map( array( $this, '_prefix_type' ), $asset['dependencies'] ); @@ -132,7 +132,7 @@ protected function dependency_row( $handle, array $asset, $label ) { $dependency_output = array(); foreach ( $asset['dependencies'] as $dep ) { - if ( in_array( $dep, $data->missing_dependencies, true ) ) { + if ( isset( $data->missing_dependencies[ $dep ] ) ) { $warning = QueryMonitor::icon( 'warning' ); $dependency_output[] = sprintf( @@ -239,7 +239,7 @@ public function _prefix_type( $val ) { * @return array */ public function admin_class( array $class ) { - /** @var QM_Data_Assets */ + /** @var QM_Data_Assets $data */ $data = $this->collector->get_data(); if ( ! empty( $data->broken ) || ! empty( $data->missing ) ) { @@ -255,7 +255,7 @@ public function admin_class( array $class ) { * @return array */ public function admin_menu( array $menu ) { - /** @var QM_Data_Assets */ + /** @var QM_Data_Assets $data */ $data = $this->collector->get_data(); if ( empty( $data->assets ) ) { diff --git a/output/html/block_editor.php b/output/html/block_editor.php index df1cfcb3c..019264562 100644 --- a/output/html/block_editor.php +++ b/output/html/block_editor.php @@ -39,7 +39,7 @@ public function name() { * @return void */ public function output() { - /** @var QM_Data_Block_Editor */ + /** @var QM_Data_Block_Editor $data */ $data = $this->collector->get_data(); if ( empty( $data->block_editor_enabled ) || empty( $data->post_blocks ) ) { @@ -333,7 +333,7 @@ protected static function render_block( $i, array $block, QM_Data_Block_Editor $ * @return array */ public function admin_menu( array $menu ) { - /** @var QM_Data_Block_Editor */ + /** @var QM_Data_Block_Editor $data */ $data = $this->collector->get_data(); if ( empty( $data->block_editor_enabled ) || empty( $data->post_blocks ) ) { diff --git a/output/html/block_editor.tsx b/output/html/block_editor.tsx index 24033f0fd..5d48215f8 100644 --- a/output/html/block_editor.tsx +++ b/output/html/block_editor.tsx @@ -4,6 +4,9 @@ import { PanelFooter, Tabular, } from 'qmi'; +import { + DataTypes, +} from 'qmi/data-types'; import * as React from 'react'; import { @@ -26,22 +29,21 @@ interface iBlock { } interface iBlocksProps extends iPanelProps { - data: { - all_dynamic_blocks: string[]; - block_editor_enabled: boolean; - has_block_context: boolean; - has_block_timing: boolean; - post_blocks: iBlock[] | null; - post_has_blocks: boolean; - total_blocks: number; + data: Omit & { + post_blocks: iBlock[]; }; } + class BlockEditor extends React.Component> { render() { const { data } = this.props; - if ( ! data.post_blocks?.length ) { + if ( ! data.block_editor_enabled || ! data.post_blocks ) { + return null; + } + + if ( ! data.post_has_blocks ) { return (

{ __( 'This post contains no blocks.', 'query-monitor' ) }

diff --git a/output/html/caps.php b/output/html/caps.php index 2bc0471e6..6c09b2f74 100644 --- a/output/html/caps.php +++ b/output/html/caps.php @@ -62,7 +62,7 @@ public function output() { return; } - /** @var QM_Data_Caps */ + /** @var QM_Data_Caps $data */ $data = $this->collector->get_data(); if ( ! empty( $data->caps ) ) { diff --git a/output/html/caps.tsx b/output/html/caps.tsx index 045f6357f..7cf28836c 100644 --- a/output/html/caps.tsx +++ b/output/html/caps.tsx @@ -1,12 +1,14 @@ import { Caller, - FrameItem, iPanelProps, Notice, PanelFooter, QMComponent, Tabular, } from 'qmi'; +import { + DataTypes, +} from 'qmi/data-types'; import * as React from 'react'; import { @@ -16,17 +18,7 @@ import { } from '@wordpress/i18n'; interface iCapsProps extends iPanelProps { - data: { - caps: { - name: string; - args: any[]; - parts: string[]; - user: number; - result: boolean; - filtered_trace: FrameItem[]; - component: any; - }[]; - }; + data: DataTypes['Caps']; } class Caps extends React.Component> { diff --git a/output/html/conditionals.tsx b/output/html/conditionals.tsx index 3ae8d2007..5fe44a2d5 100644 --- a/output/html/conditionals.tsx +++ b/output/html/conditionals.tsx @@ -2,17 +2,15 @@ import { iPanelProps, NonTabular, } from 'qmi'; +import { + DataTypes, +} from 'qmi/data-types'; import * as React from 'react'; import { __ } from '@wordpress/i18n'; interface iConditionalsProps extends iPanelProps { - data: { - conds: { - 'true': string[]; - 'false': string[]; - }; - }; + data: DataTypes['Conditionals']; } class Conditionals extends React.Component> { diff --git a/output/html/db_callers.tsx b/output/html/db_callers.tsx index 2cb3d0142..5f29d2030 100644 --- a/output/html/db_callers.tsx +++ b/output/html/db_callers.tsx @@ -4,23 +4,15 @@ import { Time, TotalTime, } from 'qmi'; +import { + DataTypes, +} from 'qmi/data-types'; import * as React from 'react'; import { __ } from '@wordpress/i18n'; -interface iDBCallerTypeTimes { - [key: string]: number; -} - interface iDBCallersProps extends iPanelProps { - data: { - times?: { - caller: string; - ltime: number; - types: iDBCallerTypeTimes; - }[]; - types: iDBCallerTypeTimes; - }; + data: DataTypes['DB_Callers']; } class DBCallers extends React.Component> { diff --git a/output/html/db_components.tsx b/output/html/db_components.tsx index 850d7ce0b..dc35e7bfe 100644 --- a/output/html/db_components.tsx +++ b/output/html/db_components.tsx @@ -4,23 +4,15 @@ import { Time, TotalTime, } from 'qmi'; +import { + DataTypes, +} from 'qmi/data-types'; import * as React from 'react'; import { __ } from '@wordpress/i18n'; -interface iDBComponentTypeTimes { - [key: string]: number; -} - interface iDBComponentsProps extends iPanelProps { - data: { - times: { - component: string; - ltime: number; - types: iDBComponentTypeTimes; - }[]; - types: iDBComponentTypeTimes; - }; + data: DataTypes['DB_Components']; } class DBComponents extends React.Component> { diff --git a/output/html/db_dupes.tsx b/output/html/db_dupes.tsx index 6e1319980..d83e4dcef 100644 --- a/output/html/db_dupes.tsx +++ b/output/html/db_dupes.tsx @@ -2,6 +2,9 @@ import { iPanelProps, Tabular, } from 'qmi'; +import { + DataTypes, +} from 'qmi/data-types'; import * as React from 'react'; import { @@ -10,7 +13,11 @@ import { sprintf, } from '@wordpress/i18n'; -class DBDupes extends React.Component> { +interface iDBDupesProps extends iPanelProps { + data: DataTypes['DB_Dupes']; +} + +class DBDupes extends React.Component> { render() { const { data } = this.props; diff --git a/output/html/db_queries.php b/output/html/db_queries.php index 40de6a2a1..14cf417a6 100644 --- a/output/html/db_queries.php +++ b/output/html/db_queries.php @@ -9,6 +9,9 @@ exit; } +/** + * @phpstan-import-type QueryRow from QM_Data_DB_Queries + */ class QM_Output_Html_DB_Queries extends QM_Output_Html { /** @@ -162,7 +165,6 @@ protected function output_expensive_queries( array $expensive ) { protected function output_queries( QM_Data_DB_Queries $data ) { $this->query_row = 0; $span = 4; - $db = $data->wpdb; if ( $data->has_result ) { $span++; @@ -304,6 +306,7 @@ protected function output_queries( QM_Data_DB_Queries $data ) { /** * @param array $row + * @phpstan-param QueryRow $row * @param array $cols * @return void */ @@ -350,7 +353,7 @@ protected function output_query_row( array $row, array $cols ) { $caller_name = '' . esc_html__( 'Unknown', 'query-monitor' ) . ''; } - $stack = $row['stack']; + $stack = $row['stack'] ?? array(); array_shift( $stack ); $stack = array_map( function( $frame ) { return '' . esc_html( $frame ) . ''; diff --git a/output/html/db_queries.tsx b/output/html/db_queries.tsx index 8de0ee0e1..c145314c3 100644 --- a/output/html/db_queries.tsx +++ b/output/html/db_queries.tsx @@ -9,6 +9,9 @@ import { TotalTime, Utils, } from 'qmi'; +import { + DataTypes, +} from 'qmi/data-types'; import * as React from 'react'; import { @@ -17,49 +20,7 @@ import { } from '@wordpress/i18n'; interface iDBQueriesProps extends iPanelProps { - data: { - component_times: { - [component: string]: { - component: string; - ltime: number; - types: { - [type: string]: number; - }; - }; - } - dupes: { - [sql: string]: number[]; - }; - times: { - [caller: string]: { - caller: string; - ltime: number; - types: { - [type: string]: number; - }; - }; - }; - total_qs: number; - total_time: number; - types: { - [type: string]: number; - } - wpdb: { - has_result: boolean; - has_trace: boolean; - rows: { - caller: string; - caller_name: string; - is_main_query: boolean; - sql: string; - type: string; - result: number; - ltime: number; - filtered_trace: any[]; - component: any; - }[]; - }; - }; + data: DataTypes['DB_Queries']; } class DBQueries extends React.Component> { diff --git a/output/html/debug_bar.php b/output/html/debug_bar.php index 66628f42d..0a08d2c56 100644 --- a/output/html/debug_bar.php +++ b/output/html/debug_bar.php @@ -27,8 +27,10 @@ public function __construct( QM_Collector $collector ) { * @return string */ public function name() { - /** @var string */ - return $this->collector->get_panel()->title(); + /** @var string $title */ + $title = $this->collector->get_panel()->title(); + + return $title; } /** @@ -86,6 +88,7 @@ public function output() { * @return array */ function register_qm_output_html_debug_bar( array $output, QM_Collectors $collectors ) { + /** @var ?Debug_Bar $debug_bar */ global $debug_bar; if ( empty( $debug_bar ) ) { @@ -100,7 +103,7 @@ function register_qm_output_html_debug_bar( array $output, QM_Collectors $collec } $panel_id = strtolower( sanitize_html_class( $class ) ); - /** @var QM_Collector_Debug_Bar|null */ + /** @var QM_Collector_Debug_Bar|null $collector */ $collector = QM_Collectors::get( "debug_bar_{$panel_id}" ); if ( $collector && $collector->is_visible() ) { diff --git a/output/html/doing_it_wrong.php b/output/html/doing_it_wrong.php index 0b1e0589d..859bec38e 100644 --- a/output/html/doing_it_wrong.php +++ b/output/html/doing_it_wrong.php @@ -130,7 +130,7 @@ public function output() { * @return array */ public function admin_class( array $class ) { - /** @var QM_Data_Doing_It_Wrong */ + /** @var QM_Data_Doing_It_Wrong $data */ $data = $this->collector->get_data(); if ( ! empty( $data->actions ) ) { @@ -146,7 +146,7 @@ public function admin_class( array $class ) { * @return array */ public function admin_menu( array $menu ) { - /** @var QM_Data_Doing_It_Wrong */ + /** @var QM_Data_Doing_It_Wrong $data */ $data = $this->collector->get_data(); if ( empty( $data->actions ) ) { diff --git a/output/html/environment.tsx b/output/html/environment.tsx index a503bf790..cafb2d80c 100644 --- a/output/html/environment.tsx +++ b/output/html/environment.tsx @@ -2,6 +2,9 @@ import { iPanelProps, NonTabular, } from 'qmi'; +import { + DataTypes, +} from 'qmi/data-types'; import * as React from 'react'; import DB from '../db'; @@ -9,7 +12,11 @@ import PHP from '../php'; import Server from '../server'; import WordPress from '../wordpress'; -class Environment extends React.Component> { +interface iEnvironmentProps extends iPanelProps { + data: DataTypes['Environment']; +} + +class Environment extends React.Component> { render() { const { data } = this.props; @@ -17,13 +24,7 @@ class Environment extends React.Component> return ( - { data.db && ( - <> - { Object.keys( data.db ).map( key => - - ) } - - ) } + diff --git a/output/html/hooks.php b/output/html/hooks.php index d8d37765f..1e516074a 100644 --- a/output/html/hooks.php +++ b/output/html/hooks.php @@ -32,7 +32,7 @@ public function __construct( QM_Collector $collector ) { * @return string */ public function name() { - /** @var QM_Data_Hooks */ + /** @var QM_Data_Hooks $data */ $data = $this->collector->get_data(); $name = __( 'Hooks & Actions', 'query-monitor' ); @@ -48,7 +48,7 @@ public function name() { * @return void */ public function output() { - /** @var QM_Data_Hooks */ + /** @var QM_Data_Hooks $data */ $data = $this->collector->get_data(); if ( empty( $data->hooks ) ) { diff --git a/output/html/hooks.tsx b/output/html/hooks.tsx index a21036028..bf536d045 100644 --- a/output/html/hooks.tsx +++ b/output/html/hooks.tsx @@ -5,6 +5,9 @@ import { Tabular, Warning, } from 'qmi'; +import { + DataTypes, +} from 'qmi/data-types'; import * as React from 'react'; import { @@ -13,25 +16,7 @@ import { } from '@wordpress/i18n'; interface iHooksProps extends iPanelProps { - data: { - hooks: { - name: string; - actions: { - callback: { - accepted_args: number; - file: string; - line: number; - name: string; - component: { - context: string; - name: string; - type: string; - }; - }; - priority: number; - }[]; - }[]; - } + data: DataTypes['Hooks']; } class Hooks extends React.Component> { diff --git a/output/html/http.tsx b/output/html/http.tsx index 8e02f3293..7fa839f67 100644 --- a/output/html/http.tsx +++ b/output/html/http.tsx @@ -9,6 +9,9 @@ import { TotalTime, Utils, } from 'qmi'; +import { + DataTypes, +} from 'qmi/data-types'; import * as React from 'react'; import { @@ -16,7 +19,11 @@ import { _x, } from '@wordpress/i18n'; -class HTTP extends React.Component> { +interface iHTTPProps extends iPanelProps { + data: DataTypes['HTTP']; +} + +class HTTP extends React.Component> { render() { const { data } = this.props; diff --git a/output/html/languages.tsx b/output/html/languages.tsx index 911796868..d1de42e28 100644 --- a/output/html/languages.tsx +++ b/output/html/languages.tsx @@ -1,9 +1,11 @@ import { Caller, - FrameItem, iPanelProps, NonTabular, } from 'qmi'; +import { + DataTypes, +} from 'qmi/data-types'; import * as React from 'react'; import { @@ -12,26 +14,7 @@ import { } from '@wordpress/i18n'; interface iLanguagesProps extends iPanelProps { - data: { - determined_locale: string; - language_attributes: string; - languages: { - [textdomain: string]: { - [mofile: string]: { - caller: FrameItem; - domain: string; - file: string|false; - found: number|false; - handle: string|null; - type: 'gettext'|'jed'; - }; - }; - }; - locale: string; - mlp_language: string; - pll_language: string; - user_locale: string; - }; + data: DataTypes['Languages']; } class Languages extends React.Component> { diff --git a/output/html/logger.tsx b/output/html/logger.tsx index ce118d445..94d8fb178 100644 --- a/output/html/logger.tsx +++ b/output/html/logger.tsx @@ -6,23 +6,15 @@ import { Tabular, Warning, } from 'qmi'; +import { + DataTypes, +} from 'qmi/data-types'; import * as React from 'react'; import { __ } from '@wordpress/i18n'; -export interface LogItem { - level: string; - message: string; - filtered_trace: any[]; - component: any; -} - export interface iLoggerProps extends iPanelProps { - data: { - logs: LogItem[]; - levels: string[]; - warning_levels: string[]; - }; + data: DataTypes['Logger']; } class Logger extends React.Component> { diff --git a/output/html/php_errors.tsx b/output/html/php_errors.tsx index bef84cda1..8b0845d2a 100644 --- a/output/html/php_errors.tsx +++ b/output/html/php_errors.tsx @@ -5,11 +5,17 @@ import { Tabular, Warning, } from 'qmi'; +import { + DataTypes, +} from 'qmi/data-types'; import * as React from 'react'; import { __ } from '@wordpress/i18n'; -class PHPErrors extends React.Component> { +interface iPHP_ErrorsProps extends iPanelProps { + data: DataTypes['PHP_Errors']; +} +class PHPErrors extends React.Component> { render() { const { data } = this.props; diff --git a/output/html/request.php b/output/html/request.php index 343ea87f7..35526b8fb 100644 --- a/output/html/request.php +++ b/output/html/request.php @@ -153,7 +153,7 @@ public function output() { echo '

' . esc_html__( 'Response', 'query-monitor' ) . '

'; echo '

' . esc_html__( 'Queried Object', 'query-monitor' ) . '

'; - if ( ! empty( $data->queried_object ) ) { + if ( isset( $data->queried_object['data'] ) ) { $class = get_class( $data->queried_object['data'] ); $class = $class ?: __( 'Unknown', 'query-monitor' ); printf( diff --git a/output/html/request.tsx b/output/html/request.tsx index ee507d4c5..86d60b7ac 100644 --- a/output/html/request.tsx +++ b/output/html/request.tsx @@ -3,48 +3,15 @@ import { NonTabular, Utils, } from 'qmi'; -import * as React from 'react'; import { - WP_Network, - WP_Post_Type, - WP_Post, - WP_Site, - WP_Term, - WP_User, -} from 'wp-types'; + DataTypes, +} from 'qmi/data-types'; +import * as React from 'react'; import { sprintf, __ } from '@wordpress/i18n'; -interface iItems { - request: string; - matched_rule?: string; - matched_query?: string; - query_string?: string; -} - interface iRequestPanelProps extends iPanelProps { - data: { - request: iItems; - request_method: string; - user?: WP_User; - matching_rewrites?: { - [k: string]: string; - }; - qvars?: { - [k: string]: string; - }; - queried_object?: { - title: string; - type?: 'WP_Term' | 'WP_Post_Type' | 'WP_Post' | 'WP_User'; - data?: WP_Term | WP_Post_Type | WP_Post | WP_User; - }; - multisite?: { - current_site: WP_Site; - current_network?: WP_Network & { - id: number; - }; - }; - } + data: DataTypes['Request']; } class Request extends React.Component> { @@ -161,7 +128,7 @@ class Request extends React.Component

{ __( 'Current User', 'query-monitor' ) }

- { data.user ? ( + { data.user.data ? (

{ sprintf( /* translators: %d: User ID */ @@ -176,25 +143,16 @@ class Request extends React.Component - { data.multisite && ( + { data.multisite?.current_site && (

{ __( 'Multisite', 'query-monitor' ) }

{ sprintf( /* translators: %d: Multisite site ID */ __( 'Current Site: #%d', 'query-monitor' ), - data.multisite.current_site.blog_id + data.multisite.current_site.data.blog_id ) }

- { data.multisite.current_network && ( -

- { sprintf( - /* translators: %d: Multisite network ID */ - __( 'Current Network: #%d', 'query-monitor' ), - data.multisite.current_network.id - ) } -

- ) }
) } diff --git a/output/html/theme.tsx b/output/html/theme.tsx index 54887311f..d346fb460 100644 --- a/output/html/theme.tsx +++ b/output/html/theme.tsx @@ -2,6 +2,9 @@ import { iPanelProps, NonTabular, } from 'qmi'; +import { + DataTypes, +} from 'qmi/data-types'; import * as React from 'react'; import { @@ -14,12 +17,11 @@ interface iParts { [key: string]: string; } -interface iRequested { - name?: string; - slug: string; +interface iThemePanelProps extends iPanelProps { + data: DataTypes['Theme']; } -class Theme extends React.Component> { +class Theme extends React.Component> { render() { const { data } = this.props; @@ -116,35 +118,31 @@ class Theme extends React.Component> {

) } - { data.has_template_part_action && ( - <> -

- { __( 'Not Loaded', 'query-monitor' ) } -

- - { data.unsuccessful_template_parts ? ( -
    - { data.unsuccessful_template_parts.map( ( requested: iRequested ) => ( - <> - { requested.name && ( -
  • - { `${ requested.slug }-${ requested.name }.php` } -
  • - ) } -
  • - { `${ requested.slug }.php` } -
  • - - ) ) } -
- ) : ( -

- - { __( 'None', 'query-monitor' ) } - -

- ) } - +

+ { __( 'Not Loaded', 'query-monitor' ) } +

+ + { data.unsuccessful_template_parts ? ( +
    + { data.unsuccessful_template_parts.map( ( requested ) => ( + <> + { requested.name && ( +
  • + { `${ requested.slug }-${ requested.name }.php` } +
  • + ) } +
  • + { `${ requested.slug }.php` } +
  • + + ) ) } +
+ ) : ( +

+ + { __( 'None', 'query-monitor' ) } + +

) } diff --git a/output/html/timing.tsx b/output/html/timing.tsx index 763b12c32..6bed0f424 100644 --- a/output/html/timing.tsx +++ b/output/html/timing.tsx @@ -4,6 +4,9 @@ import { QMComponent, Tabular, } from 'qmi'; +import { + DataTypes, +} from 'qmi/data-types'; import * as React from 'react'; import { @@ -14,25 +17,7 @@ import { declare const QM_i18n: iQM_i18n; interface iTimingProps extends iPanelProps { - data: { - timing?: { - end_time: number; - function: string; - function_memory: number; - function_time: number; - laps: { - [k: string]: { - data: any; - memory: number; - memory_used: number; - time: number; - time_used: number; - }; - }; - start_time: number; - component: any; - }[]; - } + data: DataTypes['Timing']; } class Timing extends React.Component> { diff --git a/output/html/transients.tsx b/output/html/transients.tsx index f69db3579..6aea429f3 100644 --- a/output/html/transients.tsx +++ b/output/html/transients.tsx @@ -4,8 +4,10 @@ import { QMComponent, Tabular, iPanelProps, - FrameItem, } from 'qmi'; +import { + DataTypes, +} from 'qmi/data-types'; import * as React from 'react'; import { @@ -14,18 +16,7 @@ import { } from '@wordpress/i18n'; interface iTransientsProps extends iPanelProps { - data: { - trans: { - name: string; - type?: string; - expiration: number; - exp_diff: string; - size_formatted: string; - filtered_trace: FrameItem[]; - component: any; - }[]; - has_type: boolean; - } + data: DataTypes['Transients']; } class Transients extends React.Component> { diff --git a/output/php.tsx b/output/php.tsx index 930efec11..ac93fa798 100644 --- a/output/php.tsx +++ b/output/php.tsx @@ -1,11 +1,14 @@ import * as classNames from 'classnames'; import { Toggler, Warning, iQM_i18n } from 'qmi'; +import { + Environment as EnvironmentData, +} from 'qmi/data-types'; import * as React from 'react'; import { __ } from '@wordpress/i18n'; interface iPHPProps { - php: any; + php: EnvironmentData['php']; } declare const QM_i18n: iQM_i18n; @@ -68,7 +71,7 @@ class PHP extends React.Component> { { key }
- { php.variables[ key ].after } + { php.variables[ key ] }