Merge pull request #32755 from woocommerce/refactor/woo-data-types
Make `@woocommerce/data` tidy
This commit is contained in:
commit
eb21a4dc8c
|
@ -3,6 +3,70 @@
|
|||
*/
|
||||
import '@wordpress/core-data';
|
||||
|
||||
// Export store names
|
||||
export { SETTINGS_STORE_NAME } from './settings';
|
||||
export { PLUGINS_STORE_NAME } from './plugins';
|
||||
export { ONBOARDING_STORE_NAME } from './onboarding';
|
||||
export { USER_STORE_NAME } from './user';
|
||||
export { REVIEWS_STORE_NAME } from './reviews';
|
||||
export { NOTES_STORE_NAME } from './notes';
|
||||
export { REPORTS_STORE_NAME } from './reports';
|
||||
export { COUNTRIES_STORE_NAME } from './countries';
|
||||
export { NAVIGATION_STORE_NAME } from './navigation';
|
||||
export { OPTIONS_STORE_NAME } from './options';
|
||||
export { ITEMS_STORE_NAME } from './items';
|
||||
export { PAYMENT_GATEWAYS_STORE_NAME } from './payment-gateways';
|
||||
|
||||
// Export hooks
|
||||
export { withSettingsHydration } from './settings/with-settings-hydration';
|
||||
export { withOnboardingHydration } from './onboarding/with-onboarding-hydration';
|
||||
export { withCurrentUserHydration } from './user/with-current-user-hydration';
|
||||
export { withNavigationHydration } from './navigation/with-navigation-hydration';
|
||||
export { withPluginsHydration } from './plugins/with-plugins-hydration';
|
||||
export {
|
||||
withOptionsHydration,
|
||||
useOptionsHydration,
|
||||
} from './options/with-options-hydration';
|
||||
export { useSettings } from './settings/use-settings';
|
||||
export { useUserPreferences } from './user/use-user-preferences';
|
||||
export { useUser } from './user/use-user';
|
||||
|
||||
// Export utils
|
||||
export { getVisibleTasks } from './onboarding/utils';
|
||||
export { getLeaderboard, searchItemsByString } from './items/utils';
|
||||
export {
|
||||
getFilterQuery,
|
||||
getSummaryNumbers,
|
||||
getReportTableData,
|
||||
getReportTableQuery,
|
||||
getReportChartData,
|
||||
getTooltipValueFormat,
|
||||
} from './reports/utils';
|
||||
|
||||
// Export constants
|
||||
export { pluginNames } from './plugins/constants';
|
||||
export { EXPORT_STORE_NAME } from './export';
|
||||
export { IMPORT_STORE_NAME } from './import';
|
||||
export {
|
||||
MAX_PER_PAGE,
|
||||
QUERY_DEFAULTS,
|
||||
NAMESPACE,
|
||||
WC_ADMIN_NAMESPACE,
|
||||
WCS_NAMESPACE,
|
||||
SECOND,
|
||||
MINUTE,
|
||||
HOUR,
|
||||
DAY,
|
||||
WEEK,
|
||||
MONTH,
|
||||
} from './constants';
|
||||
|
||||
// Export types
|
||||
export * from './types';
|
||||
export * from './countries/types';
|
||||
export * from './onboarding/types';
|
||||
export * from './plugins/types';
|
||||
|
||||
/**
|
||||
* Internal dependencies
|
||||
*/
|
||||
|
@ -18,82 +82,6 @@ import type { REPORTS_STORE_NAME } from './reports';
|
|||
import type { ITEMS_STORE_NAME } from './items';
|
||||
import type { COUNTRIES_STORE_NAME } from './countries';
|
||||
import type { PAYMENT_GATEWAYS_STORE_NAME } from './payment-gateways';
|
||||
import { OnboardingSelectors } from './onboarding/selectors';
|
||||
import { PaymentSelectors } from './payment-gateways/selectors';
|
||||
import { WPDataSelectors } from './types';
|
||||
import { PluginSelectors } from './plugins/selectors';
|
||||
|
||||
export * from './types';
|
||||
export { SETTINGS_STORE_NAME } from './settings';
|
||||
export { withSettingsHydration } from './settings/with-settings-hydration';
|
||||
export { useSettings } from './settings/use-settings';
|
||||
|
||||
export { PLUGINS_STORE_NAME } from './plugins';
|
||||
export type { Plugin } from './plugins/types';
|
||||
export type { InstallPluginsResponse } from './plugins/actions';
|
||||
export { ActionDispatchers as PluginsStoreActions } from './plugins/actions';
|
||||
export { pluginNames } from './plugins/constants';
|
||||
export { withPluginsHydration } from './plugins/with-plugins-hydration';
|
||||
|
||||
export { ONBOARDING_STORE_NAME } from './onboarding';
|
||||
export { withOnboardingHydration } from './onboarding/with-onboarding-hydration';
|
||||
export { getVisibleTasks } from './onboarding/utils';
|
||||
export type { TaskType, TaskListType } from './onboarding/types';
|
||||
export type { Extension, ExtensionList } from './onboarding/selectors';
|
||||
|
||||
export { USER_STORE_NAME } from './user';
|
||||
export { withCurrentUserHydration } from './user/with-current-user-hydration';
|
||||
export { useUser } from './user/use-user';
|
||||
export { useUserPreferences } from './user/use-user-preferences';
|
||||
|
||||
export { OPTIONS_STORE_NAME } from './options';
|
||||
export {
|
||||
withOptionsHydration,
|
||||
useOptionsHydration,
|
||||
} from './options/with-options-hydration';
|
||||
|
||||
export { REVIEWS_STORE_NAME } from './reviews';
|
||||
|
||||
export { NOTES_STORE_NAME } from './notes';
|
||||
|
||||
export { REPORTS_STORE_NAME } from './reports';
|
||||
|
||||
export { ITEMS_STORE_NAME } from './items';
|
||||
export { getLeaderboard, searchItemsByString } from './items/utils';
|
||||
|
||||
export { COUNTRIES_STORE_NAME } from './countries';
|
||||
|
||||
export { NAVIGATION_STORE_NAME } from './navigation';
|
||||
export { withNavigationHydration } from './navigation/with-navigation-hydration';
|
||||
|
||||
export { PAYMENT_GATEWAYS_STORE_NAME } from './payment-gateways';
|
||||
|
||||
export {
|
||||
getFilterQuery,
|
||||
getSummaryNumbers,
|
||||
getReportTableData,
|
||||
getReportTableQuery,
|
||||
getReportChartData,
|
||||
getTooltipValueFormat,
|
||||
} from './reports/utils';
|
||||
|
||||
export {
|
||||
MAX_PER_PAGE,
|
||||
QUERY_DEFAULTS,
|
||||
NAMESPACE,
|
||||
WC_ADMIN_NAMESPACE,
|
||||
WCS_NAMESPACE,
|
||||
SECOND,
|
||||
MINUTE,
|
||||
HOUR,
|
||||
DAY,
|
||||
WEEK,
|
||||
MONTH,
|
||||
} from './constants';
|
||||
|
||||
export { EXPORT_STORE_NAME } from './export';
|
||||
|
||||
export { IMPORT_STORE_NAME } from './import';
|
||||
|
||||
export type WCDataStoreName =
|
||||
| typeof REVIEWS_STORE_NAME
|
||||
|
@ -109,6 +97,14 @@ export type WCDataStoreName =
|
|||
| typeof COUNTRIES_STORE_NAME
|
||||
| typeof PAYMENT_GATEWAYS_STORE_NAME;
|
||||
|
||||
/**
|
||||
* Internal dependencies
|
||||
*/
|
||||
import { WPDataSelectors } from './types';
|
||||
import { PaymentSelectors } from './payment-gateways/selectors';
|
||||
import { PluginSelectors } from './plugins/selectors';
|
||||
import { OnboardingSelectors } from './onboarding/selectors';
|
||||
|
||||
// As we add types to all the package selectors we can fill out these unknown types with real ones. See one
|
||||
// of the already typed selectors for an example of how you can do this.
|
||||
export type WCSelectorType< T > = T extends typeof REVIEWS_STORE_NAME
|
||||
|
@ -140,6 +136,6 @@ export type WCSelectorType< T > = T extends typeof REVIEWS_STORE_NAME
|
|||
export interface WCDataSelector {
|
||||
< T extends WCDataStoreName >( storeName: T ): WCSelectorType< T >;
|
||||
}
|
||||
export * from './onboarding/selectors';
|
||||
export * from './onboarding/types';
|
||||
export * from './countries/types';
|
||||
|
||||
// Other exports
|
||||
export { ActionDispatchers as PluginsStoreActions } from './plugins/actions';
|
||||
|
|
|
@ -6,7 +6,14 @@ import createSelector from 'rememo';
|
|||
/**
|
||||
* Internal dependencies
|
||||
*/
|
||||
import { TaskType, TaskListType } from './types';
|
||||
import {
|
||||
TaskType,
|
||||
TaskListType,
|
||||
OnboardingState,
|
||||
ExtensionList,
|
||||
ProfileItemsState,
|
||||
Product,
|
||||
} from './types';
|
||||
import { WPDataSelectors } from '../types';
|
||||
import { Plugin } from '../plugins/types';
|
||||
|
||||
|
@ -22,8 +29,6 @@ export const getProfileItems = (
|
|||
return state.profileItems || {};
|
||||
};
|
||||
|
||||
const EMPTY_ARRAY: Product[] = [];
|
||||
|
||||
export const getTaskLists = createSelector(
|
||||
( state: OnboardingState ): TaskListType[] => {
|
||||
return Object.values( state.taskLists );
|
||||
|
@ -88,10 +93,9 @@ export const getEmailPrefill = ( state: OnboardingState ): string => {
|
|||
};
|
||||
|
||||
export const getProductTypes = ( state: OnboardingState ): Product[] => {
|
||||
return state.productTypes || EMPTY_ARRAY;
|
||||
return state.productTypes || [];
|
||||
};
|
||||
|
||||
// Types
|
||||
export type OnboardingSelectors = {
|
||||
getProfileItems: () => ReturnType< typeof getProfileItems >;
|
||||
getPaymentGatewaySuggestions: () => ReturnType<
|
||||
|
@ -106,104 +110,3 @@ export type OnboardingSelectors = {
|
|||
getTaskList: ( id: string ) => ReturnType< typeof getTaskList >;
|
||||
getFreeExtensions: () => ReturnType< typeof getFreeExtensions >;
|
||||
} & WPDataSelectors;
|
||||
|
||||
export type OnboardingState = {
|
||||
freeExtensions: ExtensionList[];
|
||||
profileItems: ProfileItemsState;
|
||||
taskLists: Record< string, TaskListType >;
|
||||
paymentMethods: Plugin[];
|
||||
productTypes: Product[];
|
||||
emailPrefill: string;
|
||||
// TODO clarify what the error record's type is
|
||||
errors: Record< string, unknown >;
|
||||
requesting: Record< string, boolean >;
|
||||
};
|
||||
|
||||
export type Industry = {
|
||||
slug: string;
|
||||
};
|
||||
|
||||
export type ProductCount = '0' | '1-10' | '11-100' | '101 - 1000' | '1000+';
|
||||
|
||||
export type ProductTypeSlug =
|
||||
| 'physical'
|
||||
| 'bookings'
|
||||
| 'download'
|
||||
| 'memberships'
|
||||
| 'product-add-ons'
|
||||
| 'product-bundles'
|
||||
| 'subscriptions';
|
||||
|
||||
export type OtherPlatformSlug =
|
||||
| 'shopify'
|
||||
| 'bigcommerce'
|
||||
| 'wix'
|
||||
| 'amazon'
|
||||
| 'ebay'
|
||||
| 'etsy'
|
||||
| 'squarespace'
|
||||
| 'other';
|
||||
|
||||
export type RevenueTypeSlug =
|
||||
| 'none'
|
||||
| 'rather-not-say'
|
||||
| 'up-to-2500'
|
||||
| '2500-10000'
|
||||
| '10000-50000'
|
||||
| '50000-250000'
|
||||
| 'more-than-250000';
|
||||
|
||||
export type ProfileItemsState = {
|
||||
business_extensions: [ ] | null;
|
||||
completed: boolean | null;
|
||||
industry: Industry[] | null;
|
||||
number_employees: string | null;
|
||||
other_platform: OtherPlatformSlug | null;
|
||||
other_platform_name: string | null;
|
||||
product_count: ProductCount | null;
|
||||
product_types: ProductTypeSlug[] | null;
|
||||
revenue: RevenueTypeSlug | null;
|
||||
selling_venues: string | null;
|
||||
setup_client: boolean | null;
|
||||
skipped: boolean | null;
|
||||
theme: string | null;
|
||||
wccom_connected: boolean | null;
|
||||
is_agree_marketing: boolean | null;
|
||||
store_email: string | null;
|
||||
};
|
||||
|
||||
export type FieldLocale = {
|
||||
locale: string;
|
||||
label: string;
|
||||
};
|
||||
|
||||
export type MethodFields = {
|
||||
name: string;
|
||||
option?: string;
|
||||
label?: string;
|
||||
locales?: FieldLocale[];
|
||||
type?: string;
|
||||
value?: string;
|
||||
};
|
||||
|
||||
export type Product = {
|
||||
default?: boolean;
|
||||
label: string;
|
||||
product?: number;
|
||||
};
|
||||
|
||||
export type ExtensionList = {
|
||||
key: string;
|
||||
title: string;
|
||||
plugins: Extension[];
|
||||
};
|
||||
|
||||
export type Extension = {
|
||||
description: string;
|
||||
key: string;
|
||||
image_url: string;
|
||||
manage_url: string;
|
||||
name: string;
|
||||
is_built_by_wc: boolean;
|
||||
is_visible: boolean;
|
||||
};
|
||||
|
|
|
@ -1,3 +1,8 @@
|
|||
/**
|
||||
* Internal dependencies
|
||||
*/
|
||||
import { Plugin } from '../plugins/types';
|
||||
|
||||
export type TaskType = {
|
||||
actionLabel?: string;
|
||||
actionUrl?: string;
|
||||
|
@ -51,3 +56,103 @@ export type TaskListType = {
|
|||
isCollapsible?: boolean;
|
||||
isExpandable?: boolean;
|
||||
};
|
||||
|
||||
export type OnboardingState = {
|
||||
freeExtensions: ExtensionList[];
|
||||
profileItems: ProfileItemsState;
|
||||
taskLists: Record< string, TaskListType >;
|
||||
paymentMethods: Plugin[];
|
||||
productTypes: Product[];
|
||||
emailPrefill: string;
|
||||
// TODO clarify what the error record's type is
|
||||
errors: Record< string, unknown >;
|
||||
requesting: Record< string, boolean >;
|
||||
};
|
||||
|
||||
export type Industry = {
|
||||
slug: string;
|
||||
};
|
||||
|
||||
export type ProductCount = '0' | '1-10' | '11-100' | '101 - 1000' | '1000+';
|
||||
|
||||
export type ProductTypeSlug =
|
||||
| 'physical'
|
||||
| 'bookings'
|
||||
| 'download'
|
||||
| 'memberships'
|
||||
| 'product-add-ons'
|
||||
| 'product-bundles'
|
||||
| 'subscriptions';
|
||||
|
||||
export type OtherPlatformSlug =
|
||||
| 'shopify'
|
||||
| 'bigcommerce'
|
||||
| 'wix'
|
||||
| 'amazon'
|
||||
| 'ebay'
|
||||
| 'etsy'
|
||||
| 'squarespace'
|
||||
| 'other';
|
||||
|
||||
export type RevenueTypeSlug =
|
||||
| 'none'
|
||||
| 'rather-not-say'
|
||||
| 'up-to-2500'
|
||||
| '2500-10000'
|
||||
| '10000-50000'
|
||||
| '50000-250000'
|
||||
| 'more-than-250000';
|
||||
|
||||
export type ProfileItemsState = {
|
||||
business_extensions: [ ] | null;
|
||||
completed: boolean | null;
|
||||
industry: Industry[] | null;
|
||||
number_employees: string | null;
|
||||
other_platform: OtherPlatformSlug | null;
|
||||
other_platform_name: string | null;
|
||||
product_count: ProductCount | null;
|
||||
product_types: ProductTypeSlug[] | null;
|
||||
revenue: RevenueTypeSlug | null;
|
||||
selling_venues: string | null;
|
||||
setup_client: boolean | null;
|
||||
skipped: boolean | null;
|
||||
theme: string | null;
|
||||
wccom_connected: boolean | null;
|
||||
is_agree_marketing: boolean | null;
|
||||
store_email: string | null;
|
||||
};
|
||||
|
||||
export type FieldLocale = {
|
||||
locale: string;
|
||||
label: string;
|
||||
};
|
||||
|
||||
export type MethodFields = {
|
||||
name: string;
|
||||
option?: string;
|
||||
label?: string;
|
||||
locales?: FieldLocale[];
|
||||
type?: string;
|
||||
value?: string;
|
||||
};
|
||||
|
||||
export type Product = {
|
||||
default?: boolean;
|
||||
label: string;
|
||||
product?: number;
|
||||
};
|
||||
|
||||
export type ExtensionList = {
|
||||
key: string;
|
||||
title: string;
|
||||
plugins: Extension[];
|
||||
};
|
||||
|
||||
export type Extension = {
|
||||
description: string;
|
||||
key: string;
|
||||
image_url: string;
|
||||
manage_url: string;
|
||||
name: string;
|
||||
is_built_by_wc: boolean;
|
||||
};
|
||||
|
|
|
@ -13,7 +13,7 @@ import { controls } from '@wordpress/data';
|
|||
/**
|
||||
* Internal dependencies
|
||||
*/
|
||||
import { pluginNames, STORE_NAME } from './constants';
|
||||
import { STORE_NAME } from './constants';
|
||||
import { ACTION_TYPES as TYPES } from './action-types';
|
||||
import { WC_ADMIN_NAMESPACE } from '../constants';
|
||||
import { WPError } from '../types';
|
||||
|
@ -22,6 +22,8 @@ import {
|
|||
PluginNames,
|
||||
SelectorKeysWithActions,
|
||||
RecommendedTypes,
|
||||
InstallPluginsResponse,
|
||||
ActivatePluginsResponse,
|
||||
} from './types';
|
||||
|
||||
// Can be removed in WP 5.9, wp.data is supported in >5.7.
|
||||
|
@ -30,63 +32,12 @@ const dispatch =
|
|||
const resolveSelect =
|
||||
controls && controls.resolveSelect ? controls.resolveSelect : select;
|
||||
|
||||
type PluginsResponse< PluginData > = {
|
||||
data: PluginData;
|
||||
errors: WPError< PluginNames >;
|
||||
success: boolean;
|
||||
message: string;
|
||||
} & Response;
|
||||
|
||||
export type InstallPluginsResponse = PluginsResponse< {
|
||||
installed: string[];
|
||||
results: Record< string, boolean >;
|
||||
install_time?: Record< string, number >;
|
||||
} >;
|
||||
|
||||
type ActivatePluginsResponse = PluginsResponse< {
|
||||
activated: string[];
|
||||
active: string[];
|
||||
} >;
|
||||
|
||||
function isWPError(
|
||||
error: WPError< PluginNames > | Error | string
|
||||
): error is WPError< PluginNames > {
|
||||
return ( error as WPError ).errors !== undefined;
|
||||
}
|
||||
|
||||
class PluginError extends Error {
|
||||
constructor( message: string, public data: unknown ) {
|
||||
super( message );
|
||||
}
|
||||
}
|
||||
|
||||
function formatErrors(
|
||||
response: WPError< PluginNames > | Error | string
|
||||
): string {
|
||||
if ( isWPError( response ) ) {
|
||||
// Replace the slug with a plugin name if a constant exists.
|
||||
( Object.keys( response.errors ) as PluginNames[] ).forEach(
|
||||
( plugin ) => {
|
||||
response.errors[ plugin ] = response.errors[ plugin ].map(
|
||||
( pluginError ) => {
|
||||
return pluginNames[ plugin ]
|
||||
? pluginError.replace(
|
||||
`\`${ plugin }\``,
|
||||
pluginNames[ plugin ]
|
||||
)
|
||||
: pluginError;
|
||||
}
|
||||
);
|
||||
}
|
||||
);
|
||||
} else if ( typeof response === 'string' ) {
|
||||
return response;
|
||||
} else {
|
||||
return response.message;
|
||||
}
|
||||
return '';
|
||||
}
|
||||
|
||||
const formatErrorMessage = (
|
||||
pluginErrors: Record< PluginNames, string[] >,
|
||||
actionType = 'install'
|
||||
|
@ -170,6 +121,43 @@ export function updateJetpackConnectUrl(
|
|||
};
|
||||
}
|
||||
|
||||
export const createErrorNotice = (
|
||||
errorMessage: string
|
||||
): {
|
||||
type: 'CREATE_NOTICE';
|
||||
[ key: string ]: unknown;
|
||||
} => {
|
||||
return dispatch( 'core/notices', 'createNotice', 'error', errorMessage );
|
||||
};
|
||||
|
||||
export function setPaypalOnboardingStatus(
|
||||
status: Partial< PaypalOnboardingStatus >
|
||||
): {
|
||||
type: TYPES.SET_PAYPAL_ONBOARDING_STATUS;
|
||||
paypalOnboardingStatus: Partial< PaypalOnboardingStatus >;
|
||||
} {
|
||||
return {
|
||||
type: TYPES.SET_PAYPAL_ONBOARDING_STATUS as const,
|
||||
paypalOnboardingStatus: status,
|
||||
};
|
||||
}
|
||||
|
||||
export function setRecommendedPlugins(
|
||||
type: string,
|
||||
plugins: Plugin[]
|
||||
): {
|
||||
type: TYPES.SET_RECOMMENDED_PLUGINS;
|
||||
recommendedType: string;
|
||||
plugins: Plugin[];
|
||||
} {
|
||||
return {
|
||||
type: TYPES.SET_RECOMMENDED_PLUGINS as const,
|
||||
recommendedType: type,
|
||||
plugins,
|
||||
};
|
||||
}
|
||||
|
||||
// Action Creator Generators
|
||||
export function* installPlugins( plugins: string[] ) {
|
||||
yield setIsRequesting( 'installPlugins', true );
|
||||
|
||||
|
@ -258,15 +246,6 @@ export function* installAndActivatePlugins( plugins: string[] ) {
|
|||
}
|
||||
}
|
||||
|
||||
export const createErrorNotice = (
|
||||
errorMessage: string
|
||||
): {
|
||||
type: 'CREATE_NOTICE';
|
||||
[ key: string ]: unknown;
|
||||
} => {
|
||||
return dispatch( 'core/notices', 'createNotice', 'error', errorMessage );
|
||||
};
|
||||
|
||||
export function* connectToJetpack(
|
||||
getAdminLink: ( endpoint: string ) => string
|
||||
) {
|
||||
|
@ -335,33 +314,6 @@ export function* connectToJetpackWithFailureRedirect(
|
|||
}
|
||||
}
|
||||
|
||||
export function setPaypalOnboardingStatus(
|
||||
status: Partial< PaypalOnboardingStatus >
|
||||
): {
|
||||
type: TYPES.SET_PAYPAL_ONBOARDING_STATUS;
|
||||
paypalOnboardingStatus: Partial< PaypalOnboardingStatus >;
|
||||
} {
|
||||
return {
|
||||
type: TYPES.SET_PAYPAL_ONBOARDING_STATUS as const,
|
||||
paypalOnboardingStatus: status,
|
||||
};
|
||||
}
|
||||
|
||||
export function setRecommendedPlugins(
|
||||
type: string,
|
||||
plugins: Plugin[]
|
||||
): {
|
||||
type: TYPES.SET_RECOMMENDED_PLUGINS;
|
||||
recommendedType: string;
|
||||
plugins: Plugin[];
|
||||
} {
|
||||
return {
|
||||
type: TYPES.SET_RECOMMENDED_PLUGINS as const,
|
||||
recommendedType: type,
|
||||
plugins,
|
||||
};
|
||||
}
|
||||
|
||||
const SUPPORTED_TYPES = [ 'payments' ];
|
||||
export function* dismissRecommendedPlugins( type: RecommendedTypes ) {
|
||||
if ( ! SUPPORTED_TYPES.includes( type ) ) {
|
||||
|
|
|
@ -2,6 +2,7 @@
|
|||
* Internal dependencies
|
||||
*/
|
||||
import { pluginNames } from './constants';
|
||||
import { WPError } from '../types';
|
||||
|
||||
export type RecommendedTypes = 'payments';
|
||||
|
||||
|
@ -61,3 +62,21 @@ export type PaypalOnboardingStatus = {
|
|||
onboarded: boolean;
|
||||
};
|
||||
};
|
||||
|
||||
type PluginsResponse< PluginData > = {
|
||||
data: PluginData;
|
||||
errors: WPError< PluginNames >;
|
||||
success: boolean;
|
||||
message: string;
|
||||
} & Response;
|
||||
|
||||
export type InstallPluginsResponse = PluginsResponse< {
|
||||
installed: string[];
|
||||
results: Record< string, boolean >;
|
||||
install_time?: Record< string, number >;
|
||||
} >;
|
||||
|
||||
export type ActivatePluginsResponse = PluginsResponse< {
|
||||
activated: string[];
|
||||
active: string[];
|
||||
} >;
|
||||
|
|
Loading…
Reference in New Issue