Skip to content

Commit

Permalink
feat: validate sidebar sort config
Browse files Browse the repository at this point in the history
  • Loading branch information
DavieReid committed Nov 3, 2023
1 parent 5c83b60 commit 3de820f
Show file tree
Hide file tree
Showing 4 changed files with 33 additions and 23 deletions.
16 changes: 14 additions & 2 deletions packages/plugins/src/SidebarPlugin.ts
Original file line number Diff line number Diff line change
@@ -1,8 +1,9 @@
import path from 'path';
import type { Plugin as PluginType, Page } from '@jpmorganchase/mosaic-types';
import { sidebarSortConfigSchema, type SortConfig } from '@jpmorganchase/mosaic-schemas';
import { cloneDeep } from 'lodash-es';

import { type SortConfig, type SidebarDataNode, sortSidebarData } from './utils/sortSidebarData.js';
import { type SidebarDataNode, sortSidebarData } from './utils/sortSidebarData.js';

function createFileGlob(patterns, pageExtensions) {
if (Array.isArray(patterns)) {
Expand Down Expand Up @@ -149,7 +150,18 @@ const SidebarPlugin: PluginType<SidebarPluginPage, SidebarPluginOptions, Sidebar
const sharedSortConfig = page?.sharedConfig?.sidebar?.sort;

if (sharedSortConfig) {
sortConfigPages[`${path.posix.dirname(page.fullPath)}`] = sharedSortConfig;
try {
sidebarSortConfigSchema.parse(sharedSortConfig);
sortConfigPages[`${path.posix.dirname(page.fullPath)}`] = sharedSortConfig;
} catch (e) {
/**
* Don't throw a PluginError here as this will stop the sidebar being generated.
* Plugins need a way to log errors/warnings without exceptions
*/
console.error(
`[Mosaic] SidebarPlugin - Invalid sidebar sort config found in ${page.fullPath}`
);
}
}

const priority = page.sidebar?.priority;
Expand Down
30 changes: 9 additions & 21 deletions packages/plugins/src/utils/sortSidebarData.ts
Original file line number Diff line number Diff line change
@@ -1,12 +1,6 @@
type FieldData = string | number;
type SortConfigDataType = 'string' | 'number' | 'date';

export interface SortConfig {
field: string;
dataType: SortConfigDataType;
arrange: 'asc' | 'desc';
}
import type { SortConfig } from '@jpmorganchase/mosaic-schemas';

type FieldData = string | number;
interface SortConfigWithValue extends SortConfig {
fieldData: FieldData;
}
Expand All @@ -21,9 +15,11 @@ export interface SidebarDataNode {
sharedSortConfig?: SortConfigWithValue;
}

function doSort(dataType: SortConfigDataType, a: FieldData, b: FieldData) {
if (dataType === 'number' || dataType === 'date') {
return (a as number) - (b as number);
const isNumber = (fieldData: FieldData): fieldData is number => typeof fieldData === 'number';

function doSort(a: FieldData, b: FieldData) {
if (isNumber(a) && isNumber(b)) {
return a - b;
}
if (a > b) {
return 1;
Expand All @@ -40,18 +36,10 @@ function sortBySharedSortConfig(pageA: SidebarDataNode, pageB: SidebarDataNode)
}

if (pageA.sharedSortConfig?.arrange === 'asc') {
return doSort(
pageA.sharedSortConfig.dataType,
pageA.sharedSortConfig.fieldData,
pageB.sharedSortConfig.fieldData
);
return doSort(pageA.sharedSortConfig.fieldData, pageB.sharedSortConfig.fieldData);
}

return doSort(
pageB.sharedSortConfig.dataType,
pageB.sharedSortConfig.fieldData,
pageA.sharedSortConfig.fieldData
);
return doSort(pageB.sharedSortConfig.fieldData, pageA.sharedSortConfig.fieldData);
}

export function sortSidebarData(sidebarData: SidebarDataNode[]) {
Expand Down
1 change: 1 addition & 0 deletions packages/schemas/src/index.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
export * from './breadcrumbsLayoutSchema.js';
export * from './credentialsSchema.js';
export * from './fileExtensionSchema.js';
export * from './sidebarSortConfigSchema.js';
export * from './validate.js';

export * from './SnapshotFileEnvSchema.js';
Expand Down
9 changes: 9 additions & 0 deletions packages/schemas/src/sidebarSortConfigSchema.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
import { z } from 'zod';

export const sidebarSortConfigSchema = z.object({
field: z.string(),
dataType: z.union([z.literal('string'), z.literal('number'), z.literal('date')]),
arrange: z.union([z.literal('asc'), z.literal('desc')])
});

export type SortConfig = z.infer<typeof sidebarSortConfigSchema>;

0 comments on commit 3de820f

Please sign in to comment.