/** * WordPress dependencies */ import { createSelector } from '@safe-wordpress/data'; import { addQueryArgs } from '@safe-wordpress/url'; /** * External dependencies */ import { filter, uniqBy, values } from 'lodash'; import { make } from 'ts-brand'; import { EMPTY_ARRAY } from '@nelio-content/constants'; import { date } from '@nelio-content/date'; import { isDefined, createIndexedSelector } from '@nelio-content/utils'; import type { Dict, Maybe, PostCapability, PostStatus, PostType, PostTypeContext, PostTypeName, Role, RoleId, Url, Uuid, } from '@nelio-content/types'; /** * Internal dependencies */ import { canCurrentUser } from '../user/selectors'; import type { State } from '../../config'; export function getActivePlugins( state: State ): ReadonlyArray< string > { return state.meta.site.activePlugins; } export function getToday( state: State ): string { return date( 'Y-m-d', state.meta.site.now ); } export function getUtcNow( state: State ): string { return state.meta.site.now; } export function getSiteId( state: State ): Uuid { return state.meta.site.id; } export function getHomeUrl( state: State ): Url { return state.meta.site.homeUrl; } export function getRestUrl( state: State, path = '/' ): Url { const url = state.meta.site.restUrl; return make< Url >()( url.includes( 'rest_route=' ) ? url.replace( 'rest_route=', `rest_route=${ path }` ) : `${ url }${ path }` ); } export function getAdminUrl( state: State, path = '', args: Dict< string > = {} ): Url { const adminUrl = state.meta.site.adminUrl; return make< Url >()( addQueryArgs( adminUrl + path, args ) ); } export function getFirstDayOfWeek( state: State ): number { return state.meta.site.firstDayOfWeek || 0; } export function isMultiAuthor( state: State ): boolean { return !! state.meta.site.isMultiAuthor; } export function isStaging( state: State ): boolean { return !! state.meta.site.isStaging; } export function canViewAllCalendarPosts( state: State ): boolean { return !! state.meta.site.canViewAllCalendarPosts; } export const getPostTypes = createIndexedSelector( ( state: State, context: PostTypeContext, capability: 'any' | PostCapability = 'any' ): ReadonlyArray< PostType > => { const typeNames = state.meta.site.postTypesByContext[ context ]; const types = typeNames .map( ( n ) => getPostType( state, n ) ) .filter( isDefined ); if ( 'any' === capability ) { return types; } return filter( types, ( { name } ) => canCurrentUser( state, capability, name ) ); }, ( state: State, context: PostTypeContext, capability: 'any' | PostCapability = 'any' ) => ( { key: `${ context }-${ capability }`, dependants: [ state.meta.site.postTypesByContext[ context ], state.meta.site.postTypes, state.meta.user.postTypeCapabilities, ], } ) ); export const getPostTypeOptions = createIndexedSelector( ( state: State, contexts: readonly PostTypeContext[], capability: 'any' | PostCapability = 'any' ): readonly { label: string; value: PostTypeName }[] => { contexts = [ ...contexts ].sort(); const postTypes = contexts.flatMap( ( c ) => getPostTypes( state, c, capability ) ); const unique = uniqBy( postTypes, 'name' ); return unique.map( ( { name, labels: { singular } } ) => ( { label: singular, value: name, } ) ); }, ( state: State, contexts: readonly PostTypeContext[], capability: 'any' | PostCapability = 'any' ) => ( { key: `${ [ ...contexts ].sort().join( ',' ) }-${ capability }`, dependants: [ ...contexts.map( ( c ) => state.meta.site.postTypesByContext[ c ] ), state.meta.site.postTypes, state.meta.user.postTypeCapabilities, ], } ) ); export function getRole( state: State, role: RoleId ): Maybe< Role > { return state.meta.site.roles[ role ]; } export const getRoles = createSelector( ( state: State ): ReadonlyArray< Role > => { return Object.values( state.meta.site.roles ); }, ( state: State ) => [ state.meta.site.roles ] ); export const getPostStatuses = createIndexedSelector( ( state: State, postType?: PostTypeName ): ReadonlyArray< PostStatus > => { if ( postType ) { return ( state.meta.site.postTypes[ postType ]?.statuses ?? EMPTY_ARRAY ); } return values( state.meta.site.postTypes ) .map( ( pt ) => pt.statuses ) .flatMap( ( statuses ) => statuses ) .reduce( ( r, ns ) => r.every( ( es ) => es.slug !== ns.slug ) ? [ ...r, ns ] : r, [] as ReadonlyArray< PostStatus > ); }, ( state: State, postType?: PostTypeName ) => ( { key: postType || '', dependants: [ state.meta.site.postTypes ], } ) ); export function getPostType( state: State, name: PostTypeName ): Maybe< PostType > { return state.meta.site.postTypes[ name ]; } export function getSiteTimezone( state: State ): string { return state.meta.site.timezone; } export function getSiteLanguage( state: State ): string { return state.meta.site.language; } export function getWordsPerMinute( state: State ): number { return state.meta.site.wordsPerMinute; }