198 lines
5.5 KiB
TypeScript
198 lines
5.5 KiB
TypeScript
import type { LocationQuery } from 'vue-router';
|
|
|
|
const DEFAULT_PLUGIN_PAGE_NUMBER = 1;
|
|
const DEFAULT_PLUGIN_PAGE_SIZE = 12;
|
|
const DEFAULT_PLUGIN_CATEGORY_ID = '0';
|
|
const PLUGIN_PAGE_SIZES = new Set([12, 24, 36, 48]);
|
|
|
|
const DEFAULT_TOOL_PAGE_NUMBER = 1;
|
|
const DEFAULT_TOOL_PAGE_SIZE = 10;
|
|
const TOOL_PAGE_SIZES = new Set([10, 20, 50, 100]);
|
|
|
|
const PLUGIN_LIST_QUERY_KEYS = {
|
|
categoryId: 'categoryId',
|
|
keyword: 'keyword',
|
|
pageNumber: 'pageNumber',
|
|
pageSize: 'pageSize',
|
|
} as const;
|
|
|
|
const PLUGIN_RETURN_QUERY_KEYS = {
|
|
categoryId: 'returnCategoryId',
|
|
keyword: 'returnKeyword',
|
|
pageNumber: 'returnPageNumber',
|
|
pageSize: 'returnPageSize',
|
|
} as const;
|
|
|
|
const TOOL_LIST_QUERY_KEYS = {
|
|
keyword: 'toolKeyword',
|
|
pageNumber: 'toolPageNumber',
|
|
pageSize: 'toolPageSize',
|
|
} as const;
|
|
|
|
interface PluginListRouteState {
|
|
categoryId: string;
|
|
keyword: string;
|
|
pageNumber: number;
|
|
pageSize: number;
|
|
}
|
|
|
|
interface PluginToolListRouteState {
|
|
keyword: string;
|
|
pageNumber: number;
|
|
pageSize: number;
|
|
}
|
|
|
|
function readQueryValue(query: LocationQuery, key: string): string {
|
|
const value = query[key];
|
|
const normalized = Array.isArray(value) ? value[0] : value;
|
|
return normalized === null || normalized === undefined
|
|
? ''
|
|
: String(normalized);
|
|
}
|
|
|
|
function parsePositiveInteger(value: string, fallback: number): number {
|
|
if (!/^\d+$/.test(value)) {
|
|
return fallback;
|
|
}
|
|
const parsed = Number(value);
|
|
return Number.isSafeInteger(parsed) && parsed > 0 ? parsed : fallback;
|
|
}
|
|
|
|
function parsePluginState(
|
|
query: LocationQuery,
|
|
keys: typeof PLUGIN_LIST_QUERY_KEYS | typeof PLUGIN_RETURN_QUERY_KEYS,
|
|
): PluginListRouteState {
|
|
const pageSize = parsePositiveInteger(
|
|
readQueryValue(query, keys.pageSize),
|
|
DEFAULT_PLUGIN_PAGE_SIZE,
|
|
);
|
|
return {
|
|
categoryId:
|
|
readQueryValue(query, keys.categoryId) || DEFAULT_PLUGIN_CATEGORY_ID,
|
|
keyword: readQueryValue(query, keys.keyword),
|
|
pageNumber: parsePositiveInteger(
|
|
readQueryValue(query, keys.pageNumber),
|
|
DEFAULT_PLUGIN_PAGE_NUMBER,
|
|
),
|
|
pageSize: PLUGIN_PAGE_SIZES.has(pageSize)
|
|
? pageSize
|
|
: DEFAULT_PLUGIN_PAGE_SIZE,
|
|
};
|
|
}
|
|
|
|
function buildPluginStateQuery(
|
|
state: PluginListRouteState,
|
|
keys: typeof PLUGIN_LIST_QUERY_KEYS | typeof PLUGIN_RETURN_QUERY_KEYS,
|
|
): LocationQuery {
|
|
return {
|
|
...(state.pageNumber === DEFAULT_PLUGIN_PAGE_NUMBER
|
|
? {}
|
|
: { [keys.pageNumber]: String(state.pageNumber) }),
|
|
...(state.pageSize === DEFAULT_PLUGIN_PAGE_SIZE
|
|
? {}
|
|
: { [keys.pageSize]: String(state.pageSize) }),
|
|
...(state.categoryId === DEFAULT_PLUGIN_CATEGORY_ID
|
|
? {}
|
|
: { [keys.categoryId]: state.categoryId }),
|
|
...(state.keyword ? { [keys.keyword]: state.keyword } : {}),
|
|
};
|
|
}
|
|
|
|
function parsePluginListRouteState(query: LocationQuery): PluginListRouteState {
|
|
return parsePluginState(query, PLUGIN_LIST_QUERY_KEYS);
|
|
}
|
|
|
|
function parsePluginToolsReturnState(
|
|
query: LocationQuery,
|
|
): PluginListRouteState {
|
|
return parsePluginState(query, PLUGIN_RETURN_QUERY_KEYS);
|
|
}
|
|
|
|
function buildPluginListRouteQuery(state: PluginListRouteState): LocationQuery {
|
|
return buildPluginStateQuery(state, PLUGIN_LIST_QUERY_KEYS);
|
|
}
|
|
|
|
function buildPluginToolsReturnQuery(
|
|
state: PluginListRouteState,
|
|
): LocationQuery {
|
|
return buildPluginStateQuery(state, PLUGIN_RETURN_QUERY_KEYS);
|
|
}
|
|
|
|
function mergePluginListRouteQuery(
|
|
query: LocationQuery,
|
|
state: PluginListRouteState,
|
|
): LocationQuery {
|
|
const listKeys = new Set<string>(Object.values(PLUGIN_LIST_QUERY_KEYS));
|
|
return {
|
|
...Object.fromEntries(
|
|
Object.entries(query).filter(([key]) => !listKeys.has(key)),
|
|
),
|
|
...buildPluginListRouteQuery(state),
|
|
};
|
|
}
|
|
|
|
function parsePluginToolListRouteState(
|
|
query: LocationQuery,
|
|
): PluginToolListRouteState {
|
|
const pageSize = parsePositiveInteger(
|
|
readQueryValue(query, TOOL_LIST_QUERY_KEYS.pageSize),
|
|
DEFAULT_TOOL_PAGE_SIZE,
|
|
);
|
|
return {
|
|
keyword: readQueryValue(query, TOOL_LIST_QUERY_KEYS.keyword),
|
|
pageNumber: parsePositiveInteger(
|
|
readQueryValue(query, TOOL_LIST_QUERY_KEYS.pageNumber),
|
|
DEFAULT_TOOL_PAGE_NUMBER,
|
|
),
|
|
pageSize: TOOL_PAGE_SIZES.has(pageSize) ? pageSize : DEFAULT_TOOL_PAGE_SIZE,
|
|
};
|
|
}
|
|
|
|
function buildPluginToolListRouteQuery(
|
|
state: PluginToolListRouteState,
|
|
): LocationQuery {
|
|
return {
|
|
...(state.pageNumber === DEFAULT_TOOL_PAGE_NUMBER
|
|
? {}
|
|
: { [TOOL_LIST_QUERY_KEYS.pageNumber]: String(state.pageNumber) }),
|
|
...(state.pageSize === DEFAULT_TOOL_PAGE_SIZE
|
|
? {}
|
|
: { [TOOL_LIST_QUERY_KEYS.pageSize]: String(state.pageSize) }),
|
|
...(state.keyword ? { [TOOL_LIST_QUERY_KEYS.keyword]: state.keyword } : {}),
|
|
};
|
|
}
|
|
|
|
function mergePluginToolListRouteQuery(
|
|
query: LocationQuery,
|
|
state: PluginToolListRouteState,
|
|
): LocationQuery {
|
|
const listKeys = new Set<string>(Object.values(TOOL_LIST_QUERY_KEYS));
|
|
return {
|
|
...Object.fromEntries(
|
|
Object.entries(query).filter(([key]) => !listKeys.has(key)),
|
|
),
|
|
...buildPluginToolListRouteQuery(state),
|
|
};
|
|
}
|
|
|
|
function buildPluginToolsRouteQueryFromEdit(
|
|
query: LocationQuery,
|
|
pluginId: string,
|
|
): LocationQuery {
|
|
const nextQuery: LocationQuery = { ...query, id: pluginId };
|
|
delete nextQuery.pluginId;
|
|
return nextQuery;
|
|
}
|
|
|
|
export {
|
|
buildPluginListRouteQuery,
|
|
buildPluginToolsReturnQuery,
|
|
buildPluginToolsRouteQueryFromEdit,
|
|
mergePluginListRouteQuery,
|
|
mergePluginToolListRouteQuery,
|
|
parsePluginListRouteState,
|
|
parsePluginToolListRouteState,
|
|
parsePluginToolsReturnState,
|
|
};
|
|
export type { PluginListRouteState, PluginToolListRouteState };
|