diff --git a/packages/hydrooj/package.json b/packages/hydrooj/package.json index 6e429796..f3d4b8fb 100644 --- a/packages/hydrooj/package.json +++ b/packages/hydrooj/package.json @@ -49,7 +49,6 @@ "require-resolve-hook": "^1.1.0", "saslprep": "^1.0.3", "schemastery": "^3.11.1", - "search-query-parser": "^1.6.0", "semver": "^7.5.4", "serialize-javascript": "^6.0.1", "superagent": "^8.0.9", diff --git a/packages/hydrooj/src/handler/problem.ts b/packages/hydrooj/src/handler/problem.ts index 14dcd7db..0d49eb20 100644 --- a/packages/hydrooj/src/handler/problem.ts +++ b/packages/hydrooj/src/handler/problem.ts @@ -5,7 +5,7 @@ import { } from 'lodash'; import { Filter, ObjectId } from 'mongodb'; import { nanoid } from 'nanoid'; -import parser from 'search-query-parser'; +import parser from '@hydrooj/utils/lib/search'; import { sortFiles, streamToBuffer } from '@hydrooj/utils/lib/utils'; import { BadRequestError, ContestNotAttendedError, ContestNotEndedError, ContestNotFoundError, ContestNotLiveError, diff --git a/packages/ui-default/package.json b/packages/ui-default/package.json index 06e9a291..5c47fa9c 100644 --- a/packages/ui-default/package.json +++ b/packages/ui-default/package.json @@ -126,7 +126,6 @@ "markdown-it-table-of-contents": "^0.6.0", "nunjucks": "^3.2.4", "schemastery-jsonschema": "^1.0.3", - "search-query-parser": "^1.6.0", "streamsaver": "^2.0.6", "xss": "^1.0.14" } diff --git a/packages/ui-default/pages/problem_main.page.ts b/packages/ui-default/pages/problem_main.page.ts index bbfad2ff..2c5af165 100644 --- a/packages/ui-default/pages/problem_main.page.ts +++ b/packages/ui-default/pages/problem_main.page.ts @@ -1,6 +1,6 @@ +import parser, { SearchParserResult } from '@hydrooj/utils/lib/search'; import $ from 'jquery'; import _ from 'lodash'; -import parser from 'search-query-parser'; import DomainSelectAutoComplete from 'vj/components/autocomplete/DomainSelectAutoComplete'; import { ActionDialog, ConfirmDialog } from 'vj/components/dialog'; import Dropdown from 'vj/components/dropdown/Dropdown'; @@ -30,7 +30,7 @@ const parserOptions = { function writeSelectionToInput() { const currentValue = $('[name="q"]').val() as string; - const parsedCurrentValue = parser.parse(currentValue, parserOptions) as parser.SearchParserResult; + const parsedCurrentValue = parser.parse(currentValue, parserOptions) as SearchParserResult; const q = parser.stringify({ ...parsedCurrentValue, category: selections, @@ -138,7 +138,7 @@ function buildCategoryFilter() { } function parseCategorySelection() { - const parsed = parser.parse($('[name="q"]').val() as string || '', parserOptions) as parser.SearchParserResult; + const parsed = parser.parse($('[name="q"]').val() as string || '', parserOptions) as SearchParserResult; selections = _.uniq(parsed.category || []); updateSelection(); } diff --git a/packages/utils/lib/search.ts b/packages/utils/lib/search.ts new file mode 100644 index 00000000..e4f5dbd5 --- /dev/null +++ b/packages/utils/lib/search.ts @@ -0,0 +1,36 @@ +import { parse, SearchParserOptions, SearchParserResult } from 'search-query-parser'; + +export { parse, SearchParserOptions, SearchParserResult } from 'search-query-parser'; + +export function stringify(queryObject: SearchParserResult, options: SearchParserOptions = {}, prefix = ''): string { + if (!Object.keys(queryObject || {}).length) return ''; + prefix ||= ''; + const toArray = (val: string | string[]) => (typeof val === 'string' ? [val] : val); + const addQuotes = (s: string) => (s.indexOf(' ') > -1 ? JSON.stringify(s) : s); + const addPrefix = (s: string) => prefix + s; + const parts = []; + if (queryObject.text) { + const value = toArray(queryObject.text); + if (value.length) parts.push(value.map(addQuotes).map(addPrefix).join(' ')); + } + for (const range of options.ranges || []) { + if (!queryObject[range]) continue; + let value = queryObject[range].from; + const to = queryObject[range].to; + if (to) value = `${value}-${to}`; + if (value) parts.push(addPrefix(`${range}:${value}`)); + } + for (const keyword of options.keywords || []) { + if (!queryObject[keyword]) continue; + const value = toArray(queryObject[keyword]); + if (value.length > 0) { + parts.push(addPrefix(`${keyword}:${addQuotes(value.join(','))}`)); + } + } + if (Object.keys(queryObject.exclude || {}).length) { + parts.push(stringify(queryObject.exclude, options, '-')); + } + return parts.join(' '); +} + +export default { stringify, parse }; diff --git a/packages/utils/package.json b/packages/utils/package.json index 82bb5be6..f1d08be0 100644 --- a/packages/utils/package.json +++ b/packages/utils/package.json @@ -15,6 +15,7 @@ "moment-timezone": "^0.5.43", "mongodb": "^5.7.0", "reggol": "^1.4.4", + "search-query-parser": "^1.6.0", "source-map-support": "^0.5.21", "systeminformation": "^5.18.8" },