@react-querybuilder/core 8.12.0 → 8.13.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/{basic-o1-sYjK6.d.ts → basic-Cw014pDc.d.mts} +85 -95
- package/dist/{basic-DbvrfPNz.d.mts → basic-_KlsCAyT.d.ts} +85 -95
- package/dist/{chunk-BxBTb9qk.js → chunk-U64pC571.js} +13 -11
- package/dist/cjs/react-querybuilder_core.cjs.development.d.ts +97 -96
- package/dist/cjs/react-querybuilder_core.cjs.development.js +15 -9
- package/dist/cjs/react-querybuilder_core.cjs.development.js.map +1 -1
- package/dist/cjs/react-querybuilder_core.cjs.production.d.ts +97 -96
- package/dist/cjs/react-querybuilder_core.cjs.production.js +1 -1
- package/dist/cjs/react-querybuilder_core.cjs.production.js.map +1 -1
- package/dist/{convertQuery-Cj4t-LT4.mjs → convertQuery-DAj92cbM.mjs} +3 -3
- package/dist/{convertQuery-Cj4t-LT4.mjs.map → convertQuery-DAj92cbM.mjs.map} +1 -1
- package/dist/{convertQuery-DuY_BJHy.js → convertQuery-DRldbzhZ.js} +4 -4
- package/dist/{convertQuery-DuY_BJHy.js.map → convertQuery-DRldbzhZ.js.map} +1 -1
- package/dist/{export-CCULKoP4.d.mts → export-CffjLxEe.d.mts} +2 -2
- package/dist/{export-WDHFbiPz.d.ts → export-DRA8O1Wz.d.ts} +2 -2
- package/dist/formatQuery.d.mts +2 -2
- package/dist/formatQuery.d.ts +2 -2
- package/dist/formatQuery.js +19 -13
- package/dist/formatQuery.js.map +1 -1
- package/dist/formatQuery.mjs +18 -12
- package/dist/formatQuery.mjs.map +1 -1
- package/dist/{import-BSWb9Vgd.d.ts → import-CWYJkN_w.d.ts} +2 -2
- package/dist/{import-CLyHpgk8.d.mts → import-DjHGaGhJ.d.mts} +2 -2
- package/dist/{isRuleGroup-Do9KKsmt.js → isRuleGroup-Cjk1Q2mj.js} +2 -2
- package/dist/{isRuleGroup-Do9KKsmt.js.map → isRuleGroup-Cjk1Q2mj.js.map} +1 -1
- package/dist/{isRuleGroup-BcfwGaIN.mjs → isRuleGroup-DztIOOKa.mjs} +1 -1
- package/dist/{isRuleGroup-BcfwGaIN.mjs.map → isRuleGroup-DztIOOKa.mjs.map} +1 -1
- package/dist/parseCEL.d.mts +2 -2
- package/dist/parseCEL.d.ts +2 -2
- package/dist/parseCEL.js +4 -4
- package/dist/parseCEL.js.map +1 -1
- package/dist/parseCEL.mjs +3 -3
- package/dist/parseCEL.mjs.map +1 -1
- package/dist/parseJSONata.d.mts +2 -2
- package/dist/parseJSONata.d.ts +2 -2
- package/dist/parseJSONata.js +12 -6
- package/dist/parseJSONata.js.map +1 -1
- package/dist/parseJSONata.mjs +3 -3
- package/dist/parseJsonLogic.d.mts +3 -3
- package/dist/parseJsonLogic.d.ts +3 -3
- package/dist/parseJsonLogic.js +4 -4
- package/dist/parseJsonLogic.mjs +4 -4
- package/dist/parseMongoDB.d.mts +2 -2
- package/dist/parseMongoDB.d.ts +2 -2
- package/dist/parseMongoDB.js +5 -5
- package/dist/parseMongoDB.js.map +1 -1
- package/dist/parseMongoDB.mjs +5 -5
- package/dist/parseMongoDB.mjs.map +1 -1
- package/dist/parseSQL.d.mts +2 -2
- package/dist/parseSQL.d.ts +2 -2
- package/dist/parseSQL.js +4 -4
- package/dist/parseSQL.mjs +3 -3
- package/dist/parseSpEL.d.mts +2 -2
- package/dist/parseSpEL.d.ts +2 -2
- package/dist/parseSpEL.js +58 -7
- package/dist/parseSpEL.js.map +1 -1
- package/dist/parseSpEL.mjs +3 -3
- package/dist/{prepareQueryObjects-BfnyRV5t.mjs → prepareQueryObjects-6Bxx4Bs1.mjs} +3 -3
- package/dist/{prepareQueryObjects-BfnyRV5t.mjs.map → prepareQueryObjects-6Bxx4Bs1.mjs.map} +1 -1
- package/dist/{prepareQueryObjects-DCtJJrF5.js → prepareQueryObjects-CkN0bTKm.js} +4 -4
- package/dist/{prepareQueryObjects-DCtJJrF5.js.map → prepareQueryObjects-CkN0bTKm.js.map} +1 -1
- package/dist/react-querybuilder_core.d.mts +97 -96
- package/dist/react-querybuilder_core.legacy-esm.d.ts +97 -96
- package/dist/react-querybuilder_core.legacy-esm.js +21 -15
- package/dist/react-querybuilder_core.legacy-esm.js.map +1 -1
- package/dist/react-querybuilder_core.mjs +15 -9
- package/dist/react-querybuilder_core.mjs.map +1 -1
- package/dist/react-querybuilder_core.production.d.mts +97 -96
- package/dist/react-querybuilder_core.production.mjs +1 -1
- package/dist/react-querybuilder_core.production.mjs.map +1 -1
- package/dist/{transformQuery-DvJTAvkh.js → transformQuery-ClBRfnFg.js} +3 -3
- package/dist/{transformQuery-DvJTAvkh.js.map → transformQuery-ClBRfnFg.js.map} +1 -1
- package/dist/{transformQuery-Bq4iyYsE.mjs → transformQuery-DUpbpqjX.mjs} +2 -2
- package/dist/{transformQuery-Bq4iyYsE.mjs.map → transformQuery-DUpbpqjX.mjs.map} +1 -1
- package/dist/transformQuery.d.mts +1 -1
- package/dist/transformQuery.d.ts +1 -1
- package/dist/transformQuery.js +2 -2
- package/dist/transformQuery.mjs +2 -2
- package/dist/{utils-CoYbYnVo.js → utils-CR1ToTMW.js} +3 -3
- package/dist/{utils-CoYbYnVo.js.map → utils-CR1ToTMW.js.map} +1 -1
- package/dist/{utils-DxH23QtE.mjs → utils-nQU7WCM9.mjs} +2 -2
- package/dist/{utils-DxH23QtE.mjs.map → utils-nQU7WCM9.mjs.map} +1 -1
- package/package.json +9 -8
- package/dist/chunk-DrjzjjTJ.mjs +0 -23
- package/dist/chunk-Dv2ph0Ay.js +0 -23
package/dist/parseSpEL.mjs
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
|
-
import { D as joinWith } from "./utils-
|
|
2
|
-
import { t as isRuleGroup } from "./isRuleGroup-
|
|
3
|
-
import { n as fieldIsValidUtil, r as getFieldsArray, t as prepareRuleGroup } from "./prepareQueryObjects-
|
|
1
|
+
import { D as joinWith } from "./utils-nQU7WCM9.mjs";
|
|
2
|
+
import { t as isRuleGroup } from "./isRuleGroup-DztIOOKa.mjs";
|
|
3
|
+
import { n as fieldIsValidUtil, r as getFieldsArray, t as prepareRuleGroup } from "./prepareQueryObjects-6Bxx4Bs1.mjs";
|
|
4
4
|
import { SpelExpressionEvaluator } from "spel2js";
|
|
5
5
|
|
|
6
6
|
//#region src/utils/parseSpEL/utils.ts
|
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import { C as toFullOption, S as toFlatOptionArray, b as isFlexibleOptionArray, g as processMatchMode, w as toFullOptionList, x as isFlexibleOptionGroupArray } from "./utils-
|
|
2
|
-
import { a as lc, t as isRuleGroup } from "./isRuleGroup-
|
|
1
|
+
import { C as toFullOption, S as toFlatOptionArray, b as isFlexibleOptionArray, g as processMatchMode, w as toFullOptionList, x as isFlexibleOptionGroupArray } from "./utils-nQU7WCM9.mjs";
|
|
2
|
+
import { a as lc, t as isRuleGroup } from "./isRuleGroup-DztIOOKa.mjs";
|
|
3
3
|
import { produce } from "immer";
|
|
4
4
|
|
|
5
5
|
//#region src/utils/filterFieldsByComparator.ts
|
|
@@ -151,4 +151,4 @@ const prepareRuleGroup = (queryObject, { idGenerator = generateID } = {}) => pro
|
|
|
151
151
|
|
|
152
152
|
//#endregion
|
|
153
153
|
export { fieldIsValidUtil as n, getFieldsArray as r, prepareRuleGroup as t };
|
|
154
|
-
//# sourceMappingURL=prepareQueryObjects-
|
|
154
|
+
//# sourceMappingURL=prepareQueryObjects-6Bxx4Bs1.mjs.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"prepareQueryObjects-BfnyRV5t.mjs","names":["defaultValueSourcesArray: ValueSourceFullOptions","valueSourcesNEW:\n | false\n | ValueSources\n | ValueSourceFlexibleOptions\n | ((operator: string) => ValueSources | ValueSourceFlexibleOptions)"],"sources":["../src/utils/filterFieldsByComparator.ts","../src/utils/getValueSourcesUtil.ts","../src/utils/parserUtils.ts","../src/utils/generateID.ts","../src/utils/prepareQueryObjects.ts"],"sourcesContent":["import type { FullField, OptionList, WithUnknownIndex } from '../types';\nimport { isFlexibleOptionGroupArray, toFullOption } from './optGroupUtils';\n\nconst filterByComparator = (field: FullField, operator: string, fieldToCompare: FullField) => {\n const fullField = toFullOption(field);\n const fullFieldToCompare = toFullOption(fieldToCompare);\n if (fullField.value === fullFieldToCompare.value) {\n return false;\n }\n if (typeof fullField.comparator === 'string') {\n return fullField[fullField.comparator] === fullFieldToCompare[fullField.comparator];\n }\n return fullField.comparator?.(fullFieldToCompare, operator) ?? /* istanbul ignore next */ false;\n};\n\n/**\n * For a given {@link FullField}, returns the `fields` list filtered for\n * other fields that match by `comparator`. Only fields *other than the\n * one in question* will ever be included, even if `comparator` is `null`\n * or `undefined`. If `comparator` is a string, fields with the same value\n * for that property will be included. If `comparator` is a function, each\n * field will be passed to the function along with the `operator` and fields\n * for which the function returns `true` will be included.\n *\n * @group Option Lists\n */\nexport const filterFieldsByComparator = (\n /** The field in question. */\n field: FullField,\n /** The full {@link FullField} list to be filtered. */\n fields: OptionList<FullField>,\n operator: string\n):\n | FullField[]\n | {\n options: WithUnknownIndex<FullField>[];\n label: string;\n }[] => {\n if (!field.comparator) {\n const filterOutSameField = (f: FullField) =>\n (f.value ?? /* istanbul ignore next */ f.name) !==\n (field.value ?? /* istanbul ignore next */ field.name);\n if (isFlexibleOptionGroupArray(fields)) {\n return fields.map(og => ({\n ...og,\n options: og.options.filter(v => filterOutSameField(v)),\n }));\n }\n return fields.filter(v => filterOutSameField(v));\n }\n\n if (isFlexibleOptionGroupArray(fields)) {\n return fields\n .map(og => ({\n ...og,\n options: og.options.filter(f => filterByComparator(field, operator, f)),\n }))\n .filter(og => og.options.length > 0);\n }\n\n return fields.filter(f => filterByComparator(field, operator, f));\n};\n","import type {\n FullField,\n GetOptionIdentifierType,\n ValueSourceFlexibleOptions,\n ValueSourceFullOptions,\n ValueSources,\n} from '../types';\nimport { lc } from './misc';\nimport { isFlexibleOptionArray, toFullOption, toFullOptionList } from './optGroupUtils';\n\nconst defaultValueSourcesArray: ValueSourceFullOptions = [\n { name: 'value', value: 'value', label: 'value' },\n];\n\nconst dummyFD = {\n name: 'name',\n value: 'name',\n valueSources: null,\n label: 'label',\n};\n\n/**\n * Utility function to get the value sources array for the given\n * field and operator. If the field definition does not define a\n * `valueSources` property, the `getValueSources` prop is used.\n * Returns `[FullOption<\"value\">]` by default.\n */\nexport const getValueSourcesUtil = <F extends FullField, O extends string>(\n fieldData: F,\n operator: string,\n getValueSources?: (\n field: GetOptionIdentifierType<F>,\n operator: O,\n misc: { fieldData: F }\n ) => ValueSources | ValueSourceFlexibleOptions\n): ValueSourceFullOptions => {\n // TypeScript doesn't allow it directly, but in practice\n // `fieldData` can end up being undefined or null. The nullish\n // coalescing assignment below avoids errors like\n // \"TypeError: Cannot read properties of undefined (reading 'name')\"\n const fd = fieldData ? toFullOption(fieldData) : dummyFD;\n\n let valueSourcesNEW:\n | false\n | ValueSources\n | ValueSourceFlexibleOptions\n | ((operator: string) => ValueSources | ValueSourceFlexibleOptions) = fd.valueSources ?? false;\n\n if (typeof valueSourcesNEW === 'function') {\n valueSourcesNEW = valueSourcesNEW(operator as O);\n }\n\n if (!valueSourcesNEW && getValueSources) {\n valueSourcesNEW = getValueSources(fd.value as GetOptionIdentifierType<F>, operator as O, {\n fieldData: fd as F,\n });\n }\n\n if (!valueSourcesNEW) {\n return defaultValueSourcesArray;\n }\n\n if (isFlexibleOptionArray(valueSourcesNEW)) {\n return toFullOptionList(valueSourcesNEW as ValueSourceFullOptions) as ValueSourceFullOptions;\n }\n\n return valueSourcesNEW.map(\n vs =>\n defaultValueSourcesArray.find(dmm => dmm.value === lc(vs)) ?? {\n name: vs,\n value: vs,\n label: vs,\n }\n ) as ValueSourceFullOptions;\n};\n","import type {\n DefaultOperatorName,\n FullField,\n FullOption,\n OptionList,\n ValueSource,\n ValueSourceFlexibleOptions,\n ValueSources,\n} from '../types';\nimport { filterFieldsByComparator } from './filterFieldsByComparator';\nimport { getValueSourcesUtil } from './getValueSourcesUtil';\nimport { isFlexibleOptionArray, toFlatOptionArray, toFullOption } from './optGroupUtils';\n\nexport const getFieldsArray = (\n fields?: OptionList<FullField> | Record<string, FullField>\n): FullOption[] => {\n const fieldsArray = fields\n ? Array.isArray(fields)\n ? fields\n : Object.keys(fields)\n .map(fld => ({ ...fields[fld], name: fld }))\n // oxlint-disable-next-line no-array-sort\n .sort((a, b) => a.label.localeCompare(b.label))\n : [];\n return toFlatOptionArray(fieldsArray);\n};\n\nexport function fieldIsValidUtil(params: {\n fieldsFlat: FullField[];\n getValueSources?: (field: string, operator: string) => ValueSources | ValueSourceFlexibleOptions;\n fieldName: string;\n operator: DefaultOperatorName;\n subordinateFieldName?: string;\n}): boolean {\n const { fieldsFlat, fieldName, operator, subordinateFieldName, getValueSources } = params;\n\n const vsIncludes = (vs: ValueSource) => {\n const vss = getValueSourcesUtil(primaryField, operator, getValueSources);\n return isFlexibleOptionArray(vss) && vss.some(vso => vso.value === vs || vso.name === vs);\n };\n\n // If fields option was an empty array or undefined, then all identifiers\n // are considered valid.\n if (fieldsFlat.length === 0) return true;\n\n let valid = false;\n\n const primaryField = toFullOption(fieldsFlat.find(ff => ff.name === fieldName)!);\n if (primaryField) {\n valid = !(\n !subordinateFieldName &&\n operator !== 'notNull' &&\n operator !== 'null' &&\n !vsIncludes('value')\n );\n\n if (valid && !!subordinateFieldName) {\n if (vsIncludes('field') && fieldName !== subordinateFieldName) {\n const validSubordinateFields = filterFieldsByComparator(\n primaryField,\n fieldsFlat,\n operator\n ) as FullField[];\n if (!validSubordinateFields.some(vsf => vsf.name === subordinateFieldName)) {\n valid = false;\n }\n } else {\n valid = false;\n }\n }\n }\n\n return valid;\n}\n","// import type { UUID } from 'node:crypto';\ntype UUID = `${string}-${string}-${string}-${string}-${string}`;\n\nconst cryptoModule = globalThis.crypto;\n\n/**\n * Default `id` generator. Generates a valid v4 UUID. Uses `crypto.randomUUID()`\n * when available, otherwise uses an alternate method based on `getRandomValues`.\n * The returned string is guaranteed to match this regex:\n * ```\n * /^[0-9A-F]{8}-[0-9A-F]{4}-4[0-9A-F]{3}-[89AB][0-9A-F]{3}-[0-9A-F]{12}$/i\n * ```\n * @returns Valid v4 UUID\n */\n// Default implementation adapted from https://stackoverflow.com/a/68141099/217579\n// istanbul ignore next\nexport let generateID = (): UUID =>\n '00-0-4-2-000'.replaceAll(/[^-]/g, s =>\n (((Math.random() + Math.trunc(s as unknown as number)) * 0x1_00_00) >> Number.parseInt(s))\n .toString(16)\n .padStart(4, '0')\n ) as UUID;\n\n// Improve on the default implementation by using the crypto package if it's available\n// istanbul ignore else\nif (cryptoModule) {\n // istanbul ignore else\n if (typeof cryptoModule.randomUUID === 'function') {\n generateID = () => cryptoModule.randomUUID();\n } else if (typeof cryptoModule.getRandomValues === 'function') {\n // `randomUUID` is much simpler and faster, but it's only guaranteed to be\n // available in secure contexts (server-side, https, etc.). `generateID`\n // doesn't really need to be cryptographically secure, it only needs a\n // fairly low chance of collisions. We fall back to the always-available\n // `getRandomValues` here (while still generating a valid v4 UUID) when\n // `randomUUID` is not available.\n const position19vals = '89ab';\n const container = new Uint32Array(32);\n\n generateID = () => {\n cryptoModule.getRandomValues(container);\n let id = (container[0] % 16).toString(16);\n for (let i = 1; i < 32; i++) {\n if (i === 12) {\n id = `${id}${'4'}`;\n } else if (i === 16) {\n id = `${id}${position19vals[container[17] % 4]}`;\n } else {\n id = `${id}${(container[i] % 16).toString(16)}`;\n }\n\n if (i === 7 || i === 11 || i === 15 || i === 19) {\n id = `${id}${'-'}`;\n }\n }\n return id as UUID;\n };\n }\n}\n","import { produce } from 'immer';\nimport type {\n RuleGroupArray,\n RuleGroupICArray,\n RuleGroupType,\n RuleGroupTypeAny,\n RuleGroupTypeIC,\n RuleType,\n} from '../types';\nimport { processMatchMode } from './formatQuery/utils';\nimport { generateID } from './generateID';\nimport { isRuleGroup } from './isRuleGroup';\n\n/**\n * Options for {@link prepareRule}/{@link prepareRuleGroup}.\n */\nexport interface PreparerOptions {\n idGenerator?: () => string;\n}\n\n/**\n * Ensures that a rule is valid by adding an `id` property if it does not already exist.\n */\nexport const prepareRule = (\n rule: RuleType,\n { idGenerator = generateID }: PreparerOptions = {}\n): RuleType =>\n produce(rule, draft => {\n if (!draft.id) {\n draft.id = idGenerator();\n }\n if (processMatchMode(draft)) {\n draft.value = prepareRuleGroup(draft.value, { idGenerator });\n }\n });\n\n/**\n * Ensures that a rule group is valid by recursively adding an `id` property to the group itself\n * and all its rules and subgroups where one does not already exist.\n */\nexport const prepareRuleGroup = <RG extends RuleGroupTypeAny>(\n queryObject: RG,\n { idGenerator = generateID }: PreparerOptions = {}\n): RG =>\n produce(queryObject, draft => {\n if (!draft.id) {\n draft.id = idGenerator();\n }\n draft.rules = draft.rules.map(r =>\n typeof r === 'string'\n ? r\n : isRuleGroup(r)\n ? prepareRuleGroup(r, { idGenerator })\n : prepareRule(r, { idGenerator })\n ) as RuleGroupArray | RuleGroupICArray;\n });\n\n/**\n * Ensures that a rule or group is valid. See {@link prepareRule} and {@link prepareRuleGroup}.\n */\nexport const prepareRuleOrGroup = <RG extends RuleGroupTypeAny>(\n rg: RG | RuleType,\n { idGenerator = generateID }: PreparerOptions = {}\n): RuleGroupType | RuleGroupTypeIC | RuleType =>\n isRuleGroup(rg) ? prepareRuleGroup(rg, { idGenerator }) : prepareRule(rg, { idGenerator });\n"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"prepareQueryObjects-6Bxx4Bs1.mjs","names":["defaultValueSourcesArray: ValueSourceFullOptions","valueSourcesNEW:\n | false\n | ValueSources\n | ValueSourceFlexibleOptions\n | ((operator: string) => ValueSources | ValueSourceFlexibleOptions)"],"sources":["../src/utils/filterFieldsByComparator.ts","../src/utils/getValueSourcesUtil.ts","../src/utils/parserUtils.ts","../src/utils/generateID.ts","../src/utils/prepareQueryObjects.ts"],"sourcesContent":["import type { FullField, OptionList, WithUnknownIndex } from '../types';\nimport { isFlexibleOptionGroupArray, toFullOption } from './optGroupUtils';\n\nconst filterByComparator = (field: FullField, operator: string, fieldToCompare: FullField) => {\n const fullField = toFullOption(field);\n const fullFieldToCompare = toFullOption(fieldToCompare);\n if (fullField.value === fullFieldToCompare.value) {\n return false;\n }\n if (typeof fullField.comparator === 'string') {\n return fullField[fullField.comparator] === fullFieldToCompare[fullField.comparator];\n }\n return fullField.comparator?.(fullFieldToCompare, operator) ?? /* istanbul ignore next */ false;\n};\n\n/**\n * For a given {@link FullField}, returns the `fields` list filtered for\n * other fields that match by `comparator`. Only fields *other than the\n * one in question* will ever be included, even if `comparator` is `null`\n * or `undefined`. If `comparator` is a string, fields with the same value\n * for that property will be included. If `comparator` is a function, each\n * field will be passed to the function along with the `operator` and fields\n * for which the function returns `true` will be included.\n *\n * @group Option Lists\n */\nexport const filterFieldsByComparator = (\n /** The field in question. */\n field: FullField,\n /** The full {@link FullField} list to be filtered. */\n fields: OptionList<FullField>,\n operator: string\n):\n | FullField[]\n | {\n options: WithUnknownIndex<FullField>[];\n label: string;\n }[] => {\n if (!field.comparator) {\n const filterOutSameField = (f: FullField) =>\n (f.value ?? /* istanbul ignore next */ f.name) !==\n (field.value ?? /* istanbul ignore next */ field.name);\n if (isFlexibleOptionGroupArray(fields)) {\n return fields.map(og => ({\n ...og,\n options: og.options.filter(v => filterOutSameField(v)),\n }));\n }\n return fields.filter(v => filterOutSameField(v));\n }\n\n if (isFlexibleOptionGroupArray(fields)) {\n return fields\n .map(og => ({\n ...og,\n options: og.options.filter(f => filterByComparator(field, operator, f)),\n }))\n .filter(og => og.options.length > 0);\n }\n\n return fields.filter(f => filterByComparator(field, operator, f));\n};\n","import type {\n FullField,\n GetOptionIdentifierType,\n ValueSourceFlexibleOptions,\n ValueSourceFullOptions,\n ValueSources,\n} from '../types';\nimport { lc } from './misc';\nimport { isFlexibleOptionArray, toFullOption, toFullOptionList } from './optGroupUtils';\n\nconst defaultValueSourcesArray: ValueSourceFullOptions = [\n { name: 'value', value: 'value', label: 'value' },\n];\n\nconst dummyFD = {\n name: 'name',\n value: 'name',\n valueSources: null,\n label: 'label',\n};\n\n/**\n * Utility function to get the value sources array for the given\n * field and operator. If the field definition does not define a\n * `valueSources` property, the `getValueSources` prop is used.\n * Returns `[FullOption<\"value\">]` by default.\n */\nexport const getValueSourcesUtil = <F extends FullField, O extends string>(\n fieldData: F,\n operator: string,\n getValueSources?: (\n field: GetOptionIdentifierType<F>,\n operator: O,\n misc: { fieldData: F }\n ) => ValueSources | ValueSourceFlexibleOptions\n): ValueSourceFullOptions => {\n // TypeScript doesn't allow it directly, but in practice\n // `fieldData` can end up being undefined or null. The nullish\n // coalescing assignment below avoids errors like\n // \"TypeError: Cannot read properties of undefined (reading 'name')\"\n const fd = fieldData ? toFullOption(fieldData) : dummyFD;\n\n let valueSourcesNEW:\n | false\n | ValueSources\n | ValueSourceFlexibleOptions\n | ((operator: string) => ValueSources | ValueSourceFlexibleOptions) = fd.valueSources ?? false;\n\n if (typeof valueSourcesNEW === 'function') {\n valueSourcesNEW = valueSourcesNEW(operator as O);\n }\n\n if (!valueSourcesNEW && getValueSources) {\n valueSourcesNEW = getValueSources(fd.value as GetOptionIdentifierType<F>, operator as O, {\n fieldData: fd as F,\n });\n }\n\n if (!valueSourcesNEW) {\n return defaultValueSourcesArray;\n }\n\n if (isFlexibleOptionArray(valueSourcesNEW)) {\n return toFullOptionList(valueSourcesNEW as ValueSourceFullOptions) as ValueSourceFullOptions;\n }\n\n return valueSourcesNEW.map(\n vs =>\n defaultValueSourcesArray.find(dmm => dmm.value === lc(vs)) ?? {\n name: vs,\n value: vs,\n label: vs,\n }\n ) as ValueSourceFullOptions;\n};\n","import type {\n DefaultOperatorName,\n FullField,\n FullOption,\n OptionList,\n ValueSource,\n ValueSourceFlexibleOptions,\n ValueSources,\n} from '../types';\nimport { filterFieldsByComparator } from './filterFieldsByComparator';\nimport { getValueSourcesUtil } from './getValueSourcesUtil';\nimport { isFlexibleOptionArray, toFlatOptionArray, toFullOption } from './optGroupUtils';\n\nexport const getFieldsArray = (\n fields?: OptionList<FullField> | Record<string, FullField>\n): FullOption[] => {\n const fieldsArray = fields\n ? Array.isArray(fields)\n ? fields\n : Object.keys(fields)\n .map(fld => ({ ...fields[fld], name: fld }))\n // oxlint-disable-next-line no-array-sort\n .sort((a, b) => a.label.localeCompare(b.label))\n : [];\n return toFlatOptionArray(fieldsArray);\n};\n\nexport function fieldIsValidUtil(params: {\n fieldsFlat: FullField[];\n getValueSources?: (field: string, operator: string) => ValueSources | ValueSourceFlexibleOptions;\n fieldName: string;\n operator: DefaultOperatorName;\n subordinateFieldName?: string;\n}): boolean {\n const { fieldsFlat, fieldName, operator, subordinateFieldName, getValueSources } = params;\n\n const vsIncludes = (vs: ValueSource) => {\n const vss = getValueSourcesUtil(primaryField, operator, getValueSources);\n return isFlexibleOptionArray(vss) && vss.some(vso => vso.value === vs || vso.name === vs);\n };\n\n // If fields option was an empty array or undefined, then all identifiers\n // are considered valid.\n if (fieldsFlat.length === 0) return true;\n\n let valid = false;\n\n const primaryField = toFullOption(fieldsFlat.find(ff => ff.name === fieldName)!);\n if (primaryField) {\n valid = !(\n !subordinateFieldName &&\n operator !== 'notNull' &&\n operator !== 'null' &&\n !vsIncludes('value')\n );\n\n if (valid && !!subordinateFieldName) {\n if (vsIncludes('field') && fieldName !== subordinateFieldName) {\n const validSubordinateFields = filterFieldsByComparator(\n primaryField,\n fieldsFlat,\n operator\n ) as FullField[];\n if (!validSubordinateFields.some(vsf => vsf.name === subordinateFieldName)) {\n valid = false;\n }\n } else {\n valid = false;\n }\n }\n }\n\n return valid;\n}\n","// import type { UUID } from 'node:crypto';\ntype UUID = `${string}-${string}-${string}-${string}-${string}`;\n\nconst cryptoModule = globalThis.crypto;\n\n/**\n * Default `id` generator. Generates a valid v4 UUID. Uses `crypto.randomUUID()`\n * when available, otherwise uses an alternate method based on `getRandomValues`.\n * The returned string is guaranteed to match this regex:\n * ```\n * /^[0-9A-F]{8}-[0-9A-F]{4}-4[0-9A-F]{3}-[89AB][0-9A-F]{3}-[0-9A-F]{12}$/i\n * ```\n * @returns Valid v4 UUID\n */\n// Default implementation adapted from https://stackoverflow.com/a/68141099/217579\n// istanbul ignore next\nexport let generateID = (): UUID =>\n '00-0-4-2-000'.replaceAll(/[^-]/g, s =>\n (((Math.random() + Math.trunc(s as unknown as number)) * 0x1_00_00) >> Number.parseInt(s))\n .toString(16)\n .padStart(4, '0')\n ) as UUID;\n\n// Improve on the default implementation by using the crypto package if it's available\n// istanbul ignore else\nif (cryptoModule) {\n // istanbul ignore else\n if (typeof cryptoModule.randomUUID === 'function') {\n generateID = () => cryptoModule.randomUUID();\n } else if (typeof cryptoModule.getRandomValues === 'function') {\n // `randomUUID` is much simpler and faster, but it's only guaranteed to be\n // available in secure contexts (server-side, https, etc.). `generateID`\n // doesn't really need to be cryptographically secure, it only needs a\n // fairly low chance of collisions. We fall back to the always-available\n // `getRandomValues` here (while still generating a valid v4 UUID) when\n // `randomUUID` is not available.\n const position19vals = '89ab';\n const container = new Uint32Array(32);\n\n generateID = () => {\n cryptoModule.getRandomValues(container);\n let id = (container[0] % 16).toString(16);\n for (let i = 1; i < 32; i++) {\n if (i === 12) {\n id = `${id}${'4'}`;\n } else if (i === 16) {\n id = `${id}${position19vals[container[17] % 4]}`;\n } else {\n id = `${id}${(container[i] % 16).toString(16)}`;\n }\n\n if (i === 7 || i === 11 || i === 15 || i === 19) {\n id = `${id}${'-'}`;\n }\n }\n return id as UUID;\n };\n }\n}\n","import { produce } from 'immer';\nimport type {\n RuleGroupArray,\n RuleGroupICArray,\n RuleGroupType,\n RuleGroupTypeAny,\n RuleGroupTypeIC,\n RuleType,\n} from '../types';\nimport { processMatchMode } from './formatQuery/utils';\nimport { generateID } from './generateID';\nimport { isRuleGroup } from './isRuleGroup';\n\n/**\n * Options for {@link prepareRule}/{@link prepareRuleGroup}.\n */\nexport interface PreparerOptions {\n idGenerator?: () => string;\n}\n\n/**\n * Ensures that a rule is valid by adding an `id` property if it does not already exist.\n */\nexport const prepareRule = (\n rule: RuleType,\n { idGenerator = generateID }: PreparerOptions = {}\n): RuleType =>\n produce(rule, draft => {\n if (!draft.id) {\n draft.id = idGenerator();\n }\n if (processMatchMode(draft)) {\n draft.value = prepareRuleGroup(draft.value, { idGenerator });\n }\n });\n\n/**\n * Ensures that a rule group is valid by recursively adding an `id` property to the group itself\n * and all its rules and subgroups where one does not already exist.\n */\nexport const prepareRuleGroup = <RG extends RuleGroupTypeAny>(\n queryObject: RG,\n { idGenerator = generateID }: PreparerOptions = {}\n): RG =>\n produce(queryObject, draft => {\n if (!draft.id) {\n draft.id = idGenerator();\n }\n draft.rules = draft.rules.map(r =>\n typeof r === 'string'\n ? r\n : isRuleGroup(r)\n ? prepareRuleGroup(r, { idGenerator })\n : prepareRule(r, { idGenerator })\n ) as RuleGroupArray | RuleGroupICArray;\n });\n\n/**\n * Ensures that a rule or group is valid. See {@link prepareRule} and {@link prepareRuleGroup}.\n */\nexport const prepareRuleOrGroup = <RG extends RuleGroupTypeAny>(\n rg: RG | RuleType,\n { idGenerator = generateID }: PreparerOptions = {}\n): RuleGroupType | RuleGroupTypeIC | RuleType =>\n isRuleGroup(rg) ? prepareRuleGroup(rg, { idGenerator }) : prepareRule(rg, { idGenerator });\n"],"mappings":"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"}
|
|
@@ -1,6 +1,6 @@
|
|
|
1
|
-
const require_chunk = require('./chunk-
|
|
2
|
-
const require_utils = require('./utils-
|
|
3
|
-
const require_isRuleGroup = require('./isRuleGroup-
|
|
1
|
+
const require_chunk = require('./chunk-U64pC571.js');
|
|
2
|
+
const require_utils = require('./utils-CR1ToTMW.js');
|
|
3
|
+
const require_isRuleGroup = require('./isRuleGroup-Cjk1Q2mj.js');
|
|
4
4
|
let immer = require("immer");
|
|
5
5
|
|
|
6
6
|
//#region src/utils/filterFieldsByComparator.ts
|
|
@@ -169,4 +169,4 @@ Object.defineProperty(exports, 'prepareRuleGroup', {
|
|
|
169
169
|
return prepareRuleGroup;
|
|
170
170
|
}
|
|
171
171
|
});
|
|
172
|
-
//# sourceMappingURL=prepareQueryObjects-
|
|
172
|
+
//# sourceMappingURL=prepareQueryObjects-CkN0bTKm.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"prepareQueryObjects-DCtJJrF5.js","names":["toFullOption","isFlexibleOptionGroupArray","defaultValueSourcesArray: ValueSourceFullOptions","toFullOption","valueSourcesNEW:\n | false\n | ValueSources\n | ValueSourceFlexibleOptions\n | ((operator: string) => ValueSources | ValueSourceFlexibleOptions)","isFlexibleOptionArray","toFullOptionList","lc","toFlatOptionArray","isFlexibleOptionArray","toFullOption","processMatchMode","isRuleGroup"],"sources":["../src/utils/filterFieldsByComparator.ts","../src/utils/getValueSourcesUtil.ts","../src/utils/parserUtils.ts","../src/utils/generateID.ts","../src/utils/prepareQueryObjects.ts"],"sourcesContent":["import type { FullField, OptionList, WithUnknownIndex } from '../types';\nimport { isFlexibleOptionGroupArray, toFullOption } from './optGroupUtils';\n\nconst filterByComparator = (field: FullField, operator: string, fieldToCompare: FullField) => {\n const fullField = toFullOption(field);\n const fullFieldToCompare = toFullOption(fieldToCompare);\n if (fullField.value === fullFieldToCompare.value) {\n return false;\n }\n if (typeof fullField.comparator === 'string') {\n return fullField[fullField.comparator] === fullFieldToCompare[fullField.comparator];\n }\n return fullField.comparator?.(fullFieldToCompare, operator) ?? /* istanbul ignore next */ false;\n};\n\n/**\n * For a given {@link FullField}, returns the `fields` list filtered for\n * other fields that match by `comparator`. Only fields *other than the\n * one in question* will ever be included, even if `comparator` is `null`\n * or `undefined`. If `comparator` is a string, fields with the same value\n * for that property will be included. If `comparator` is a function, each\n * field will be passed to the function along with the `operator` and fields\n * for which the function returns `true` will be included.\n *\n * @group Option Lists\n */\nexport const filterFieldsByComparator = (\n /** The field in question. */\n field: FullField,\n /** The full {@link FullField} list to be filtered. */\n fields: OptionList<FullField>,\n operator: string\n):\n | FullField[]\n | {\n options: WithUnknownIndex<FullField>[];\n label: string;\n }[] => {\n if (!field.comparator) {\n const filterOutSameField = (f: FullField) =>\n (f.value ?? /* istanbul ignore next */ f.name) !==\n (field.value ?? /* istanbul ignore next */ field.name);\n if (isFlexibleOptionGroupArray(fields)) {\n return fields.map(og => ({\n ...og,\n options: og.options.filter(v => filterOutSameField(v)),\n }));\n }\n return fields.filter(v => filterOutSameField(v));\n }\n\n if (isFlexibleOptionGroupArray(fields)) {\n return fields\n .map(og => ({\n ...og,\n options: og.options.filter(f => filterByComparator(field, operator, f)),\n }))\n .filter(og => og.options.length > 0);\n }\n\n return fields.filter(f => filterByComparator(field, operator, f));\n};\n","import type {\n FullField,\n GetOptionIdentifierType,\n ValueSourceFlexibleOptions,\n ValueSourceFullOptions,\n ValueSources,\n} from '../types';\nimport { lc } from './misc';\nimport { isFlexibleOptionArray, toFullOption, toFullOptionList } from './optGroupUtils';\n\nconst defaultValueSourcesArray: ValueSourceFullOptions = [\n { name: 'value', value: 'value', label: 'value' },\n];\n\nconst dummyFD = {\n name: 'name',\n value: 'name',\n valueSources: null,\n label: 'label',\n};\n\n/**\n * Utility function to get the value sources array for the given\n * field and operator. If the field definition does not define a\n * `valueSources` property, the `getValueSources` prop is used.\n * Returns `[FullOption<\"value\">]` by default.\n */\nexport const getValueSourcesUtil = <F extends FullField, O extends string>(\n fieldData: F,\n operator: string,\n getValueSources?: (\n field: GetOptionIdentifierType<F>,\n operator: O,\n misc: { fieldData: F }\n ) => ValueSources | ValueSourceFlexibleOptions\n): ValueSourceFullOptions => {\n // TypeScript doesn't allow it directly, but in practice\n // `fieldData` can end up being undefined or null. The nullish\n // coalescing assignment below avoids errors like\n // \"TypeError: Cannot read properties of undefined (reading 'name')\"\n const fd = fieldData ? toFullOption(fieldData) : dummyFD;\n\n let valueSourcesNEW:\n | false\n | ValueSources\n | ValueSourceFlexibleOptions\n | ((operator: string) => ValueSources | ValueSourceFlexibleOptions) = fd.valueSources ?? false;\n\n if (typeof valueSourcesNEW === 'function') {\n valueSourcesNEW = valueSourcesNEW(operator as O);\n }\n\n if (!valueSourcesNEW && getValueSources) {\n valueSourcesNEW = getValueSources(fd.value as GetOptionIdentifierType<F>, operator as O, {\n fieldData: fd as F,\n });\n }\n\n if (!valueSourcesNEW) {\n return defaultValueSourcesArray;\n }\n\n if (isFlexibleOptionArray(valueSourcesNEW)) {\n return toFullOptionList(valueSourcesNEW as ValueSourceFullOptions) as ValueSourceFullOptions;\n }\n\n return valueSourcesNEW.map(\n vs =>\n defaultValueSourcesArray.find(dmm => dmm.value === lc(vs)) ?? {\n name: vs,\n value: vs,\n label: vs,\n }\n ) as ValueSourceFullOptions;\n};\n","import type {\n DefaultOperatorName,\n FullField,\n FullOption,\n OptionList,\n ValueSource,\n ValueSourceFlexibleOptions,\n ValueSources,\n} from '../types';\nimport { filterFieldsByComparator } from './filterFieldsByComparator';\nimport { getValueSourcesUtil } from './getValueSourcesUtil';\nimport { isFlexibleOptionArray, toFlatOptionArray, toFullOption } from './optGroupUtils';\n\nexport const getFieldsArray = (\n fields?: OptionList<FullField> | Record<string, FullField>\n): FullOption[] => {\n const fieldsArray = fields\n ? Array.isArray(fields)\n ? fields\n : Object.keys(fields)\n .map(fld => ({ ...fields[fld], name: fld }))\n // oxlint-disable-next-line no-array-sort\n .sort((a, b) => a.label.localeCompare(b.label))\n : [];\n return toFlatOptionArray(fieldsArray);\n};\n\nexport function fieldIsValidUtil(params: {\n fieldsFlat: FullField[];\n getValueSources?: (field: string, operator: string) => ValueSources | ValueSourceFlexibleOptions;\n fieldName: string;\n operator: DefaultOperatorName;\n subordinateFieldName?: string;\n}): boolean {\n const { fieldsFlat, fieldName, operator, subordinateFieldName, getValueSources } = params;\n\n const vsIncludes = (vs: ValueSource) => {\n const vss = getValueSourcesUtil(primaryField, operator, getValueSources);\n return isFlexibleOptionArray(vss) && vss.some(vso => vso.value === vs || vso.name === vs);\n };\n\n // If fields option was an empty array or undefined, then all identifiers\n // are considered valid.\n if (fieldsFlat.length === 0) return true;\n\n let valid = false;\n\n const primaryField = toFullOption(fieldsFlat.find(ff => ff.name === fieldName)!);\n if (primaryField) {\n valid = !(\n !subordinateFieldName &&\n operator !== 'notNull' &&\n operator !== 'null' &&\n !vsIncludes('value')\n );\n\n if (valid && !!subordinateFieldName) {\n if (vsIncludes('field') && fieldName !== subordinateFieldName) {\n const validSubordinateFields = filterFieldsByComparator(\n primaryField,\n fieldsFlat,\n operator\n ) as FullField[];\n if (!validSubordinateFields.some(vsf => vsf.name === subordinateFieldName)) {\n valid = false;\n }\n } else {\n valid = false;\n }\n }\n }\n\n return valid;\n}\n","// import type { UUID } from 'node:crypto';\ntype UUID = `${string}-${string}-${string}-${string}-${string}`;\n\nconst cryptoModule = globalThis.crypto;\n\n/**\n * Default `id` generator. Generates a valid v4 UUID. Uses `crypto.randomUUID()`\n * when available, otherwise uses an alternate method based on `getRandomValues`.\n * The returned string is guaranteed to match this regex:\n * ```\n * /^[0-9A-F]{8}-[0-9A-F]{4}-4[0-9A-F]{3}-[89AB][0-9A-F]{3}-[0-9A-F]{12}$/i\n * ```\n * @returns Valid v4 UUID\n */\n// Default implementation adapted from https://stackoverflow.com/a/68141099/217579\n// istanbul ignore next\nexport let generateID = (): UUID =>\n '00-0-4-2-000'.replaceAll(/[^-]/g, s =>\n (((Math.random() + Math.trunc(s as unknown as number)) * 0x1_00_00) >> Number.parseInt(s))\n .toString(16)\n .padStart(4, '0')\n ) as UUID;\n\n// Improve on the default implementation by using the crypto package if it's available\n// istanbul ignore else\nif (cryptoModule) {\n // istanbul ignore else\n if (typeof cryptoModule.randomUUID === 'function') {\n generateID = () => cryptoModule.randomUUID();\n } else if (typeof cryptoModule.getRandomValues === 'function') {\n // `randomUUID` is much simpler and faster, but it's only guaranteed to be\n // available in secure contexts (server-side, https, etc.). `generateID`\n // doesn't really need to be cryptographically secure, it only needs a\n // fairly low chance of collisions. We fall back to the always-available\n // `getRandomValues` here (while still generating a valid v4 UUID) when\n // `randomUUID` is not available.\n const position19vals = '89ab';\n const container = new Uint32Array(32);\n\n generateID = () => {\n cryptoModule.getRandomValues(container);\n let id = (container[0] % 16).toString(16);\n for (let i = 1; i < 32; i++) {\n if (i === 12) {\n id = `${id}${'4'}`;\n } else if (i === 16) {\n id = `${id}${position19vals[container[17] % 4]}`;\n } else {\n id = `${id}${(container[i] % 16).toString(16)}`;\n }\n\n if (i === 7 || i === 11 || i === 15 || i === 19) {\n id = `${id}${'-'}`;\n }\n }\n return id as UUID;\n };\n }\n}\n","import { produce } from 'immer';\nimport type {\n RuleGroupArray,\n RuleGroupICArray,\n RuleGroupType,\n RuleGroupTypeAny,\n RuleGroupTypeIC,\n RuleType,\n} from '../types';\nimport { processMatchMode } from './formatQuery/utils';\nimport { generateID } from './generateID';\nimport { isRuleGroup } from './isRuleGroup';\n\n/**\n * Options for {@link prepareRule}/{@link prepareRuleGroup}.\n */\nexport interface PreparerOptions {\n idGenerator?: () => string;\n}\n\n/**\n * Ensures that a rule is valid by adding an `id` property if it does not already exist.\n */\nexport const prepareRule = (\n rule: RuleType,\n { idGenerator = generateID }: PreparerOptions = {}\n): RuleType =>\n produce(rule, draft => {\n if (!draft.id) {\n draft.id = idGenerator();\n }\n if (processMatchMode(draft)) {\n draft.value = prepareRuleGroup(draft.value, { idGenerator });\n }\n });\n\n/**\n * Ensures that a rule group is valid by recursively adding an `id` property to the group itself\n * and all its rules and subgroups where one does not already exist.\n */\nexport const prepareRuleGroup = <RG extends RuleGroupTypeAny>(\n queryObject: RG,\n { idGenerator = generateID }: PreparerOptions = {}\n): RG =>\n produce(queryObject, draft => {\n if (!draft.id) {\n draft.id = idGenerator();\n }\n draft.rules = draft.rules.map(r =>\n typeof r === 'string'\n ? r\n : isRuleGroup(r)\n ? prepareRuleGroup(r, { idGenerator })\n : prepareRule(r, { idGenerator })\n ) as RuleGroupArray | RuleGroupICArray;\n });\n\n/**\n * Ensures that a rule or group is valid. See {@link prepareRule} and {@link prepareRuleGroup}.\n */\nexport const prepareRuleOrGroup = <RG extends RuleGroupTypeAny>(\n rg: RG | RuleType,\n { idGenerator = generateID }: PreparerOptions = {}\n): RuleGroupType | RuleGroupTypeIC | RuleType =>\n isRuleGroup(rg) ? prepareRuleGroup(rg, { idGenerator }) : prepareRule(rg, { idGenerator });\n"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"prepareQueryObjects-CkN0bTKm.js","names":["toFullOption","isFlexibleOptionGroupArray","defaultValueSourcesArray: ValueSourceFullOptions","toFullOption","valueSourcesNEW:\n | false\n | ValueSources\n | ValueSourceFlexibleOptions\n | ((operator: string) => ValueSources | ValueSourceFlexibleOptions)","isFlexibleOptionArray","toFullOptionList","lc","toFlatOptionArray","isFlexibleOptionArray","toFullOption","processMatchMode","isRuleGroup"],"sources":["../src/utils/filterFieldsByComparator.ts","../src/utils/getValueSourcesUtil.ts","../src/utils/parserUtils.ts","../src/utils/generateID.ts","../src/utils/prepareQueryObjects.ts"],"sourcesContent":["import type { FullField, OptionList, WithUnknownIndex } from '../types';\nimport { isFlexibleOptionGroupArray, toFullOption } from './optGroupUtils';\n\nconst filterByComparator = (field: FullField, operator: string, fieldToCompare: FullField) => {\n const fullField = toFullOption(field);\n const fullFieldToCompare = toFullOption(fieldToCompare);\n if (fullField.value === fullFieldToCompare.value) {\n return false;\n }\n if (typeof fullField.comparator === 'string') {\n return fullField[fullField.comparator] === fullFieldToCompare[fullField.comparator];\n }\n return fullField.comparator?.(fullFieldToCompare, operator) ?? /* istanbul ignore next */ false;\n};\n\n/**\n * For a given {@link FullField}, returns the `fields` list filtered for\n * other fields that match by `comparator`. Only fields *other than the\n * one in question* will ever be included, even if `comparator` is `null`\n * or `undefined`. If `comparator` is a string, fields with the same value\n * for that property will be included. If `comparator` is a function, each\n * field will be passed to the function along with the `operator` and fields\n * for which the function returns `true` will be included.\n *\n * @group Option Lists\n */\nexport const filterFieldsByComparator = (\n /** The field in question. */\n field: FullField,\n /** The full {@link FullField} list to be filtered. */\n fields: OptionList<FullField>,\n operator: string\n):\n | FullField[]\n | {\n options: WithUnknownIndex<FullField>[];\n label: string;\n }[] => {\n if (!field.comparator) {\n const filterOutSameField = (f: FullField) =>\n (f.value ?? /* istanbul ignore next */ f.name) !==\n (field.value ?? /* istanbul ignore next */ field.name);\n if (isFlexibleOptionGroupArray(fields)) {\n return fields.map(og => ({\n ...og,\n options: og.options.filter(v => filterOutSameField(v)),\n }));\n }\n return fields.filter(v => filterOutSameField(v));\n }\n\n if (isFlexibleOptionGroupArray(fields)) {\n return fields\n .map(og => ({\n ...og,\n options: og.options.filter(f => filterByComparator(field, operator, f)),\n }))\n .filter(og => og.options.length > 0);\n }\n\n return fields.filter(f => filterByComparator(field, operator, f));\n};\n","import type {\n FullField,\n GetOptionIdentifierType,\n ValueSourceFlexibleOptions,\n ValueSourceFullOptions,\n ValueSources,\n} from '../types';\nimport { lc } from './misc';\nimport { isFlexibleOptionArray, toFullOption, toFullOptionList } from './optGroupUtils';\n\nconst defaultValueSourcesArray: ValueSourceFullOptions = [\n { name: 'value', value: 'value', label: 'value' },\n];\n\nconst dummyFD = {\n name: 'name',\n value: 'name',\n valueSources: null,\n label: 'label',\n};\n\n/**\n * Utility function to get the value sources array for the given\n * field and operator. If the field definition does not define a\n * `valueSources` property, the `getValueSources` prop is used.\n * Returns `[FullOption<\"value\">]` by default.\n */\nexport const getValueSourcesUtil = <F extends FullField, O extends string>(\n fieldData: F,\n operator: string,\n getValueSources?: (\n field: GetOptionIdentifierType<F>,\n operator: O,\n misc: { fieldData: F }\n ) => ValueSources | ValueSourceFlexibleOptions\n): ValueSourceFullOptions => {\n // TypeScript doesn't allow it directly, but in practice\n // `fieldData` can end up being undefined or null. The nullish\n // coalescing assignment below avoids errors like\n // \"TypeError: Cannot read properties of undefined (reading 'name')\"\n const fd = fieldData ? toFullOption(fieldData) : dummyFD;\n\n let valueSourcesNEW:\n | false\n | ValueSources\n | ValueSourceFlexibleOptions\n | ((operator: string) => ValueSources | ValueSourceFlexibleOptions) = fd.valueSources ?? false;\n\n if (typeof valueSourcesNEW === 'function') {\n valueSourcesNEW = valueSourcesNEW(operator as O);\n }\n\n if (!valueSourcesNEW && getValueSources) {\n valueSourcesNEW = getValueSources(fd.value as GetOptionIdentifierType<F>, operator as O, {\n fieldData: fd as F,\n });\n }\n\n if (!valueSourcesNEW) {\n return defaultValueSourcesArray;\n }\n\n if (isFlexibleOptionArray(valueSourcesNEW)) {\n return toFullOptionList(valueSourcesNEW as ValueSourceFullOptions) as ValueSourceFullOptions;\n }\n\n return valueSourcesNEW.map(\n vs =>\n defaultValueSourcesArray.find(dmm => dmm.value === lc(vs)) ?? {\n name: vs,\n value: vs,\n label: vs,\n }\n ) as ValueSourceFullOptions;\n};\n","import type {\n DefaultOperatorName,\n FullField,\n FullOption,\n OptionList,\n ValueSource,\n ValueSourceFlexibleOptions,\n ValueSources,\n} from '../types';\nimport { filterFieldsByComparator } from './filterFieldsByComparator';\nimport { getValueSourcesUtil } from './getValueSourcesUtil';\nimport { isFlexibleOptionArray, toFlatOptionArray, toFullOption } from './optGroupUtils';\n\nexport const getFieldsArray = (\n fields?: OptionList<FullField> | Record<string, FullField>\n): FullOption[] => {\n const fieldsArray = fields\n ? Array.isArray(fields)\n ? fields\n : Object.keys(fields)\n .map(fld => ({ ...fields[fld], name: fld }))\n // oxlint-disable-next-line no-array-sort\n .sort((a, b) => a.label.localeCompare(b.label))\n : [];\n return toFlatOptionArray(fieldsArray);\n};\n\nexport function fieldIsValidUtil(params: {\n fieldsFlat: FullField[];\n getValueSources?: (field: string, operator: string) => ValueSources | ValueSourceFlexibleOptions;\n fieldName: string;\n operator: DefaultOperatorName;\n subordinateFieldName?: string;\n}): boolean {\n const { fieldsFlat, fieldName, operator, subordinateFieldName, getValueSources } = params;\n\n const vsIncludes = (vs: ValueSource) => {\n const vss = getValueSourcesUtil(primaryField, operator, getValueSources);\n return isFlexibleOptionArray(vss) && vss.some(vso => vso.value === vs || vso.name === vs);\n };\n\n // If fields option was an empty array or undefined, then all identifiers\n // are considered valid.\n if (fieldsFlat.length === 0) return true;\n\n let valid = false;\n\n const primaryField = toFullOption(fieldsFlat.find(ff => ff.name === fieldName)!);\n if (primaryField) {\n valid = !(\n !subordinateFieldName &&\n operator !== 'notNull' &&\n operator !== 'null' &&\n !vsIncludes('value')\n );\n\n if (valid && !!subordinateFieldName) {\n if (vsIncludes('field') && fieldName !== subordinateFieldName) {\n const validSubordinateFields = filterFieldsByComparator(\n primaryField,\n fieldsFlat,\n operator\n ) as FullField[];\n if (!validSubordinateFields.some(vsf => vsf.name === subordinateFieldName)) {\n valid = false;\n }\n } else {\n valid = false;\n }\n }\n }\n\n return valid;\n}\n","// import type { UUID } from 'node:crypto';\ntype UUID = `${string}-${string}-${string}-${string}-${string}`;\n\nconst cryptoModule = globalThis.crypto;\n\n/**\n * Default `id` generator. Generates a valid v4 UUID. Uses `crypto.randomUUID()`\n * when available, otherwise uses an alternate method based on `getRandomValues`.\n * The returned string is guaranteed to match this regex:\n * ```\n * /^[0-9A-F]{8}-[0-9A-F]{4}-4[0-9A-F]{3}-[89AB][0-9A-F]{3}-[0-9A-F]{12}$/i\n * ```\n * @returns Valid v4 UUID\n */\n// Default implementation adapted from https://stackoverflow.com/a/68141099/217579\n// istanbul ignore next\nexport let generateID = (): UUID =>\n '00-0-4-2-000'.replaceAll(/[^-]/g, s =>\n (((Math.random() + Math.trunc(s as unknown as number)) * 0x1_00_00) >> Number.parseInt(s))\n .toString(16)\n .padStart(4, '0')\n ) as UUID;\n\n// Improve on the default implementation by using the crypto package if it's available\n// istanbul ignore else\nif (cryptoModule) {\n // istanbul ignore else\n if (typeof cryptoModule.randomUUID === 'function') {\n generateID = () => cryptoModule.randomUUID();\n } else if (typeof cryptoModule.getRandomValues === 'function') {\n // `randomUUID` is much simpler and faster, but it's only guaranteed to be\n // available in secure contexts (server-side, https, etc.). `generateID`\n // doesn't really need to be cryptographically secure, it only needs a\n // fairly low chance of collisions. We fall back to the always-available\n // `getRandomValues` here (while still generating a valid v4 UUID) when\n // `randomUUID` is not available.\n const position19vals = '89ab';\n const container = new Uint32Array(32);\n\n generateID = () => {\n cryptoModule.getRandomValues(container);\n let id = (container[0] % 16).toString(16);\n for (let i = 1; i < 32; i++) {\n if (i === 12) {\n id = `${id}${'4'}`;\n } else if (i === 16) {\n id = `${id}${position19vals[container[17] % 4]}`;\n } else {\n id = `${id}${(container[i] % 16).toString(16)}`;\n }\n\n if (i === 7 || i === 11 || i === 15 || i === 19) {\n id = `${id}${'-'}`;\n }\n }\n return id as UUID;\n };\n }\n}\n","import { produce } from 'immer';\nimport type {\n RuleGroupArray,\n RuleGroupICArray,\n RuleGroupType,\n RuleGroupTypeAny,\n RuleGroupTypeIC,\n RuleType,\n} from '../types';\nimport { processMatchMode } from './formatQuery/utils';\nimport { generateID } from './generateID';\nimport { isRuleGroup } from './isRuleGroup';\n\n/**\n * Options for {@link prepareRule}/{@link prepareRuleGroup}.\n */\nexport interface PreparerOptions {\n idGenerator?: () => string;\n}\n\n/**\n * Ensures that a rule is valid by adding an `id` property if it does not already exist.\n */\nexport const prepareRule = (\n rule: RuleType,\n { idGenerator = generateID }: PreparerOptions = {}\n): RuleType =>\n produce(rule, draft => {\n if (!draft.id) {\n draft.id = idGenerator();\n }\n if (processMatchMode(draft)) {\n draft.value = prepareRuleGroup(draft.value, { idGenerator });\n }\n });\n\n/**\n * Ensures that a rule group is valid by recursively adding an `id` property to the group itself\n * and all its rules and subgroups where one does not already exist.\n */\nexport const prepareRuleGroup = <RG extends RuleGroupTypeAny>(\n queryObject: RG,\n { idGenerator = generateID }: PreparerOptions = {}\n): RG =>\n produce(queryObject, draft => {\n if (!draft.id) {\n draft.id = idGenerator();\n }\n draft.rules = draft.rules.map(r =>\n typeof r === 'string'\n ? r\n : isRuleGroup(r)\n ? prepareRuleGroup(r, { idGenerator })\n : prepareRule(r, { idGenerator })\n ) as RuleGroupArray | RuleGroupICArray;\n });\n\n/**\n * Ensures that a rule or group is valid. See {@link prepareRule} and {@link prepareRuleGroup}.\n */\nexport const prepareRuleOrGroup = <RG extends RuleGroupTypeAny>(\n rg: RG | RuleType,\n { idGenerator = generateID }: PreparerOptions = {}\n): RuleGroupType | RuleGroupTypeIC | RuleType =>\n isRuleGroup(rg) ? prepareRuleGroup(rg, { idGenerator }) : prepareRule(rg, { idGenerator });\n"],"mappings":"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"}
|
|
@@ -26,34 +26,6 @@ type Intersection = UnionToIntersection<Union>;
|
|
|
26
26
|
//=> {the(): void; great(arg: string): void; escape: boolean};
|
|
27
27
|
```
|
|
28
28
|
|
|
29
|
-
A more applicable example which could make its way into your library code follows.
|
|
30
|
-
|
|
31
|
-
@example
|
|
32
|
-
```
|
|
33
|
-
import type {UnionToIntersection} from 'type-fest';
|
|
34
|
-
|
|
35
|
-
class CommandOne {
|
|
36
|
-
commands: {
|
|
37
|
-
a1: () => undefined,
|
|
38
|
-
b1: () => undefined,
|
|
39
|
-
}
|
|
40
|
-
}
|
|
41
|
-
|
|
42
|
-
class CommandTwo {
|
|
43
|
-
commands: {
|
|
44
|
-
a2: (argA: string) => undefined,
|
|
45
|
-
b2: (argB: string) => undefined,
|
|
46
|
-
}
|
|
47
|
-
}
|
|
48
|
-
|
|
49
|
-
const union = [new CommandOne(), new CommandTwo()].map(instance => instance.commands);
|
|
50
|
-
type Union = typeof union;
|
|
51
|
-
//=> {a1(): void; b1(): void} | {a2(argA: string): void; b2(argB: string): void}
|
|
52
|
-
|
|
53
|
-
type Intersection = UnionToIntersection<Union>;
|
|
54
|
-
//=> {a1(): void; b1(): void; a2(argA: string): void; b2(argB: string): void}
|
|
55
|
-
```
|
|
56
|
-
|
|
57
29
|
@category Type
|
|
58
30
|
*/
|
|
59
31
|
type UnionToIntersection<Union> = (
|
|
@@ -129,8 +101,8 @@ import type {IsAny} from 'type-fest';
|
|
|
129
101
|
const typedObject = {a: 1, b: 2} as const;
|
|
130
102
|
const anyObject: any = {a: 1, b: 2};
|
|
131
103
|
|
|
132
|
-
function get<O extends (IsAny<O> extends true ? {} : Record<string, number>), K extends keyof O = keyof O>(
|
|
133
|
-
return
|
|
104
|
+
function get<O extends (IsAny<O> extends true ? {} : Record<string, number>), K extends keyof O = keyof O>(object: O, key: K) {
|
|
105
|
+
return object[key];
|
|
134
106
|
}
|
|
135
107
|
|
|
136
108
|
const typedA = get(typedObject, 'a');
|
|
@@ -155,17 +127,17 @@ This is useful when writing utility types or schema validators that need to diff
|
|
|
155
127
|
```
|
|
156
128
|
import type {IsOptionalKeyOf} from 'type-fest';
|
|
157
129
|
|
|
158
|
-
|
|
130
|
+
type User = {
|
|
159
131
|
name: string;
|
|
160
132
|
surname: string;
|
|
161
133
|
|
|
162
134
|
luckyNumber?: number;
|
|
163
|
-
}
|
|
135
|
+
};
|
|
164
136
|
|
|
165
|
-
|
|
137
|
+
type Admin = {
|
|
166
138
|
name: string;
|
|
167
139
|
surname?: string;
|
|
168
|
-
}
|
|
140
|
+
};
|
|
169
141
|
|
|
170
142
|
type T1 = IsOptionalKeyOf<User, 'luckyNumber'>;
|
|
171
143
|
//=> true
|
|
@@ -198,12 +170,12 @@ This is useful when you want to create a new type that contains different type v
|
|
|
198
170
|
```
|
|
199
171
|
import type {OptionalKeysOf, Except} from 'type-fest';
|
|
200
172
|
|
|
201
|
-
|
|
173
|
+
type User = {
|
|
202
174
|
name: string;
|
|
203
175
|
surname: string;
|
|
204
176
|
|
|
205
177
|
luckyNumber?: number;
|
|
206
|
-
}
|
|
178
|
+
};
|
|
207
179
|
|
|
208
180
|
const REMOVE_FIELD = Symbol('remove field symbol');
|
|
209
181
|
type UpdateOperation<Entity extends object> = Except<Partial<Entity>, OptionalKeysOf<Entity>> & {
|
|
@@ -211,12 +183,12 @@ type UpdateOperation<Entity extends object> = Except<Partial<Entity>, OptionalKe
|
|
|
211
183
|
};
|
|
212
184
|
|
|
213
185
|
const update1: UpdateOperation<User> = {
|
|
214
|
-
name: 'Alice'
|
|
186
|
+
name: 'Alice',
|
|
215
187
|
};
|
|
216
188
|
|
|
217
189
|
const update2: UpdateOperation<User> = {
|
|
218
190
|
name: 'Bob',
|
|
219
|
-
luckyNumber: REMOVE_FIELD
|
|
191
|
+
luckyNumber: REMOVE_FIELD,
|
|
220
192
|
};
|
|
221
193
|
```
|
|
222
194
|
|
|
@@ -236,17 +208,23 @@ This is useful when you want to create a new type that contains different type v
|
|
|
236
208
|
```
|
|
237
209
|
import type {RequiredKeysOf} from 'type-fest';
|
|
238
210
|
|
|
239
|
-
declare function createValidation<
|
|
211
|
+
declare function createValidation<
|
|
212
|
+
Entity extends object,
|
|
213
|
+
Key extends RequiredKeysOf<Entity> = RequiredKeysOf<Entity>,
|
|
214
|
+
>(field: Key, validator: (value: Entity[Key]) => boolean): (entity: Entity) => boolean;
|
|
240
215
|
|
|
241
|
-
|
|
216
|
+
type User = {
|
|
242
217
|
name: string;
|
|
243
218
|
surname: string;
|
|
244
|
-
|
|
245
219
|
luckyNumber?: number;
|
|
246
|
-
}
|
|
220
|
+
};
|
|
247
221
|
|
|
248
222
|
const validator1 = createValidation<User>('name', value => value.length < 25);
|
|
249
223
|
const validator2 = createValidation<User>('surname', value => value.length < 25);
|
|
224
|
+
|
|
225
|
+
// @ts-expect-error
|
|
226
|
+
const validator3 = createValidation<User>('luckyNumber', value => value > 0);
|
|
227
|
+
// Error: Argument of type '"luckyNumber"' is not assignable to parameter of type '"name" | "surname"'.
|
|
250
228
|
```
|
|
251
229
|
|
|
252
230
|
@category Utilities
|
|
@@ -268,29 +246,41 @@ Useful in type utilities, such as checking if something does not occur.
|
|
|
268
246
|
```
|
|
269
247
|
import type {IsNever, And} from 'type-fest';
|
|
270
248
|
|
|
271
|
-
|
|
272
|
-
|
|
273
|
-
And<
|
|
274
|
-
IsNever<Exclude<A, B>> extends true ? true : false,
|
|
275
|
-
IsNever<Exclude<B, A>> extends true ? true : false
|
|
276
|
-
>;
|
|
277
|
-
|
|
278
|
-
type EndIfEqual<I extends string, O extends string> =
|
|
279
|
-
AreStringsEqual<I, O> extends true
|
|
280
|
-
? never
|
|
281
|
-
: void;
|
|
282
|
-
|
|
283
|
-
function endIfEqual<I extends string, O extends string>(input: I, output: O): EndIfEqual<I, O> {
|
|
284
|
-
if (input === output) {
|
|
285
|
-
process.exit(0);
|
|
286
|
-
}
|
|
287
|
-
}
|
|
249
|
+
type A = IsNever<never>;
|
|
250
|
+
//=> true
|
|
288
251
|
|
|
289
|
-
|
|
290
|
-
//=>
|
|
252
|
+
type B = IsNever<any>;
|
|
253
|
+
//=> false
|
|
254
|
+
|
|
255
|
+
type C = IsNever<unknown>;
|
|
256
|
+
//=> false
|
|
257
|
+
|
|
258
|
+
type D = IsNever<never[]>;
|
|
259
|
+
//=> false
|
|
260
|
+
|
|
261
|
+
type E = IsNever<object>;
|
|
262
|
+
//=> false
|
|
263
|
+
|
|
264
|
+
type F = IsNever<string>;
|
|
265
|
+
//=> false
|
|
266
|
+
```
|
|
291
267
|
|
|
292
|
-
|
|
293
|
-
|
|
268
|
+
@example
|
|
269
|
+
```
|
|
270
|
+
import type {IsNever} from 'type-fest';
|
|
271
|
+
|
|
272
|
+
type IsTrue<T> = T extends true ? true : false;
|
|
273
|
+
|
|
274
|
+
// When a distributive conditional is instantiated with `never`, the entire conditional results in `never`.
|
|
275
|
+
type A = IsTrue<never>;
|
|
276
|
+
// ^? type A = never
|
|
277
|
+
|
|
278
|
+
// If you don't want that behaviour, you can explicitly add an `IsNever` check before the distributive conditional.
|
|
279
|
+
type IsTrueFixed<T> =
|
|
280
|
+
IsNever<T> extends true ? false : T extends true ? true : false;
|
|
281
|
+
|
|
282
|
+
type B = IsTrueFixed<never>;
|
|
283
|
+
// ^? type B = false
|
|
294
284
|
```
|
|
295
285
|
|
|
296
286
|
@category Type Guard
|
|
@@ -311,7 +301,7 @@ Note:
|
|
|
311
301
|
|
|
312
302
|
@example
|
|
313
303
|
```
|
|
314
|
-
import {If} from 'type-fest';
|
|
304
|
+
import type {If} from 'type-fest';
|
|
315
305
|
|
|
316
306
|
type A = If<true, 'yes', 'no'>;
|
|
317
307
|
//=> 'yes'
|
|
@@ -331,7 +321,7 @@ type E = If<never, 'yes', 'no'>;
|
|
|
331
321
|
|
|
332
322
|
@example
|
|
333
323
|
```
|
|
334
|
-
import {If, IsAny, IsNever} from 'type-fest';
|
|
324
|
+
import type {If, IsAny, IsNever} from 'type-fest';
|
|
335
325
|
|
|
336
326
|
type A = If<IsAny<unknown>, 'is any', 'not any'>;
|
|
337
327
|
//=> 'not any'
|
|
@@ -342,7 +332,7 @@ type B = If<IsNever<never>, 'is never', 'not never'>;
|
|
|
342
332
|
|
|
343
333
|
@example
|
|
344
334
|
```
|
|
345
|
-
import {If, IsEqual} from 'type-fest';
|
|
335
|
+
import type {If, IsEqual} from 'type-fest';
|
|
346
336
|
|
|
347
337
|
type IfEqual<T, U, IfBranch, ElseBranch> = If<IsEqual<T, U>, IfBranch, ElseBranch>;
|
|
348
338
|
|
|
@@ -535,10 +525,11 @@ const literal = {foo: 123, bar: 'hello', baz: 456};
|
|
|
535
525
|
const someType: SomeType = literal;
|
|
536
526
|
const someInterface: SomeInterface = literal;
|
|
537
527
|
|
|
538
|
-
function fn(object: Record<string, unknown>): void
|
|
528
|
+
declare function fn(object: Record<string, unknown>): void;
|
|
539
529
|
|
|
540
530
|
fn(literal); // Good: literal object type is sealed
|
|
541
531
|
fn(someType); // Good: type is sealed
|
|
532
|
+
// @ts-expect-error
|
|
542
533
|
fn(someInterface); // Error: Index signature for type 'string' is missing in type 'someInterface'. Because `interface` can be re-opened
|
|
543
534
|
fn(someInterface as Simplify<SomeInterface>); // Good: transform an `interface` into a `type`
|
|
544
535
|
```
|
|
@@ -576,7 +567,7 @@ type Includes<Value extends readonly any[], Item> =
|
|
|
576
567
|
@category Type Guard
|
|
577
568
|
@category Utilities
|
|
578
569
|
*/
|
|
579
|
-
type IsEqual<A$1, B$1> = [A$1
|
|
570
|
+
type IsEqual<A$1, B$1> = [A$1] extends [B$1] ? [B$1] extends [A$1] ? _IsEqual<A$1, B$1> : false : false;
|
|
580
571
|
// This version fails the `equalWrappedTupleIntersectionToBeNeverAndNeverExpanded` test in `test-d/is-equal.ts`.
|
|
581
572
|
type _IsEqual<A$1, B$1> = (<G>() => G extends A$1 & G | G ? 1 : 2) extends (<G>() => G extends B$1 & G | G ? 1 : 2) ? true : false;
|
|
582
573
|
//#endregion
|
|
@@ -598,6 +589,7 @@ It relies on the fact that an empty object (`{}`) is assignable to an object wit
|
|
|
598
589
|
```
|
|
599
590
|
const indexed: Record<string, unknown> = {}; // Allowed
|
|
600
591
|
|
|
592
|
+
// @ts-expect-error
|
|
601
593
|
const keyed: Record<'foo', unknown> = {}; // Error
|
|
602
594
|
// => TS2739: Type '{}' is missing the following properties from type 'Record<"foo" | "bar", unknown>': foo, bar
|
|
603
595
|
```
|
|
@@ -611,16 +603,14 @@ type Indexed = {} extends Record<string, unknown>
|
|
|
611
603
|
// => '✅ `{}` is assignable to `Record<string, unknown>`'
|
|
612
604
|
|
|
613
605
|
type Keyed = {} extends Record<'foo' | 'bar', unknown>
|
|
614
|
-
?
|
|
615
|
-
:
|
|
606
|
+
? '✅ `{}` is assignable to `Record<\'foo\' | \'bar\', unknown>`'
|
|
607
|
+
: '❌ `{}` is NOT assignable to `Record<\'foo\' | \'bar\', unknown>`';
|
|
616
608
|
// => "❌ `{}` is NOT assignable to `Record<'foo' | 'bar', unknown>`"
|
|
617
609
|
```
|
|
618
610
|
|
|
619
611
|
Using a [mapped type](https://www.typescriptlang.org/docs/handbook/2/mapped-types.html#further-exploration), you can then check for each `KeyType` of `ObjectType`...
|
|
620
612
|
|
|
621
613
|
```
|
|
622
|
-
import type {OmitIndexSignature} from 'type-fest';
|
|
623
|
-
|
|
624
614
|
type OmitIndexSignature<ObjectType> = {
|
|
625
615
|
[KeyType in keyof ObjectType // Map each key of `ObjectType`...
|
|
626
616
|
]: ObjectType[KeyType]; // ...to its original value, i.e. `OmitIndexSignature<Foo> == Foo`.
|
|
@@ -630,14 +620,12 @@ type OmitIndexSignature<ObjectType> = {
|
|
|
630
620
|
...whether an empty object (`{}`) would be assignable to an object with that `KeyType` (`Record<KeyType, unknown>`)...
|
|
631
621
|
|
|
632
622
|
```
|
|
633
|
-
import type {OmitIndexSignature} from 'type-fest';
|
|
634
|
-
|
|
635
623
|
type OmitIndexSignature<ObjectType> = {
|
|
636
624
|
[KeyType in keyof ObjectType
|
|
637
|
-
|
|
638
|
-
|
|
639
|
-
|
|
640
|
-
|
|
625
|
+
// Is `{}` assignable to `Record<KeyType, unknown>`?
|
|
626
|
+
as {} extends Record<KeyType, unknown>
|
|
627
|
+
? never // ✅ `{}` is assignable to `Record<KeyType, unknown>`
|
|
628
|
+
: KeyType // ❌ `{}` is NOT assignable to `Record<KeyType, unknown>`
|
|
641
629
|
]: ObjectType[KeyType];
|
|
642
630
|
};
|
|
643
631
|
```
|
|
@@ -648,21 +636,21 @@ If `{}` is assignable, it means that `KeyType` is an index signature and we want
|
|
|
648
636
|
```
|
|
649
637
|
import type {OmitIndexSignature} from 'type-fest';
|
|
650
638
|
|
|
651
|
-
|
|
639
|
+
type Example = {
|
|
652
640
|
// These index signatures will be removed.
|
|
653
|
-
[x: string]: any
|
|
654
|
-
[x: number]: any
|
|
655
|
-
[x: symbol]: any
|
|
656
|
-
[x: `head-${string}`]: string
|
|
657
|
-
[x: `${string}-tail`]: string
|
|
658
|
-
[x: `head-${string}-tail`]: string
|
|
659
|
-
[x: `${bigint}`]: string
|
|
660
|
-
[x: `embedded-${number}`]: string
|
|
641
|
+
[x: string]: any;
|
|
642
|
+
[x: number]: any;
|
|
643
|
+
[x: symbol]: any;
|
|
644
|
+
[x: `head-${string}`]: string;
|
|
645
|
+
[x: `${string}-tail`]: string;
|
|
646
|
+
[x: `head-${string}-tail`]: string;
|
|
647
|
+
[x: `${bigint}`]: string;
|
|
648
|
+
[x: `embedded-${number}`]: string;
|
|
661
649
|
|
|
662
650
|
// These explicitly defined keys will remain.
|
|
663
651
|
foo: 'bar';
|
|
664
652
|
qux?: 'baz';
|
|
665
|
-
}
|
|
653
|
+
};
|
|
666
654
|
|
|
667
655
|
type ExampleWithoutIndexSignatures = OmitIndexSignature<Example>;
|
|
668
656
|
// => { foo: 'bar'; qux?: 'baz' | undefined; }
|
|
@@ -732,12 +720,12 @@ Merge two types into a new type. Keys of the second type overrides keys of the f
|
|
|
732
720
|
```
|
|
733
721
|
import type {Merge} from 'type-fest';
|
|
734
722
|
|
|
735
|
-
|
|
723
|
+
type Foo = {
|
|
736
724
|
[x: string]: unknown;
|
|
737
725
|
[x: number]: unknown;
|
|
738
726
|
foo: string;
|
|
739
727
|
bar: symbol;
|
|
740
|
-
}
|
|
728
|
+
};
|
|
741
729
|
|
|
742
730
|
type Bar = {
|
|
743
731
|
[x: number]: number;
|
|
@@ -916,12 +904,14 @@ type Foo = {
|
|
|
916
904
|
type FooWithoutA = Except<Foo, 'a'>;
|
|
917
905
|
//=> {b: string}
|
|
918
906
|
|
|
907
|
+
// @ts-expect-error
|
|
919
908
|
const fooWithoutA: FooWithoutA = {a: 1, b: '2'};
|
|
920
909
|
//=> errors: 'a' does not exist in type '{ b: string; }'
|
|
921
910
|
|
|
922
911
|
type FooWithoutB = Except<Foo, 'b', {requireExactProps: true}>;
|
|
923
912
|
//=> {a: number} & Partial<Record<"b", never>>
|
|
924
913
|
|
|
914
|
+
// @ts-expect-error
|
|
925
915
|
const fooWithoutB: FooWithoutB = {a: 1, b: '2'};
|
|
926
916
|
//=> errors at 'b': Type 'string' is not assignable to type 'undefined'.
|
|
927
917
|
|
|
@@ -938,12 +928,12 @@ type UserData = {
|
|
|
938
928
|
|
|
939
929
|
// `Omit` clearly doesn't behave as expected in this case:
|
|
940
930
|
type PostPayload = Omit<UserData, 'email'>;
|
|
941
|
-
//=>
|
|
931
|
+
//=> { [x: string]: string; [x: number]: string; }
|
|
942
932
|
|
|
943
933
|
// In situations like this, `Except` works better.
|
|
944
934
|
// It simply removes the `email` key while preserving all the other keys.
|
|
945
|
-
type
|
|
946
|
-
//=>
|
|
935
|
+
type PostPayloadFixed = Except<UserData, 'email'>;
|
|
936
|
+
//=> { [x: string]: string; name: string; role: 'admin' | 'user'; }
|
|
947
937
|
```
|
|
948
938
|
|
|
949
939
|
@category Object
|
|
@@ -967,7 +957,7 @@ type Responder = {
|
|
|
967
957
|
|
|
968
958
|
const responder: RequireAtLeastOne<Responder, 'text' | 'json'> = {
|
|
969
959
|
json: () => '{"message": "ok"}',
|
|
970
|
-
secure: true
|
|
960
|
+
secure: true,
|
|
971
961
|
};
|
|
972
962
|
```
|
|
973
963
|
|
|
@@ -1042,7 +1032,7 @@ type Foo = {
|
|
|
1042
1032
|
a: number;
|
|
1043
1033
|
b?: string;
|
|
1044
1034
|
c: boolean;
|
|
1045
|
-
}
|
|
1035
|
+
};
|
|
1046
1036
|
|
|
1047
1037
|
type SomeOptional = SetOptional<Foo, 'b' | 'c'>;
|
|
1048
1038
|
// type SomeOptional = {
|
|
@@ -1076,7 +1066,7 @@ type Foo = {
|
|
|
1076
1066
|
a?: number;
|
|
1077
1067
|
b: string;
|
|
1078
1068
|
c?: boolean;
|
|
1079
|
-
}
|
|
1069
|
+
};
|
|
1080
1070
|
|
|
1081
1071
|
type SomeRequired = SetRequired<Foo, 'b' | 'c'>;
|
|
1082
1072
|
// type SomeRequired = {
|
|
@@ -3922,6 +3912,17 @@ declare const getCommonAncestorPath: (path1: Path, path2: Path) => Path;
|
|
|
3922
3912
|
*/
|
|
3923
3913
|
declare const pathIsDisabled: (path: Path, query: RuleGroupTypeAny) => boolean;
|
|
3924
3914
|
//#endregion
|
|
3915
|
+
//#region ../react-querybuilder/src/redux/getRqbStore.d.ts
|
|
3916
|
+
declare global {
|
|
3917
|
+
var __RQB_DEVTOOLS__: boolean | undefined;
|
|
3918
|
+
}
|
|
3919
|
+
/**
|
|
3920
|
+
* Gets the singleton React Query Builder store instance.
|
|
3921
|
+
* DevTools are enabled if either:
|
|
3922
|
+
* - globalThis.__RQB_DEVTOOLS__ is truthy
|
|
3923
|
+
* - window.__RQB_DEVTOOLS__ is truthy
|
|
3924
|
+
*/
|
|
3925
|
+
//#endregion
|
|
3925
3926
|
//#region src/utils/preferProp.d.ts
|
|
3926
3927
|
/**
|
|
3927
3928
|
* For given default, prop, and context values, return the first provided of prop,
|