@strapi/utils 5.51.2 → 5.52.1

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.
Files changed (34) hide show
  1. package/dist/content-types.d.ts.map +1 -1
  2. package/dist/content-types.js +39 -2
  3. package/dist/content-types.js.map +1 -1
  4. package/dist/content-types.mjs +39 -2
  5. package/dist/content-types.mjs.map +1 -1
  6. package/dist/convert-query-params.js +4 -4
  7. package/dist/convert-query-params.js.map +1 -1
  8. package/dist/index.js +1 -1
  9. package/dist/parse-type.d.ts +13 -0
  10. package/dist/parse-type.d.ts.map +1 -1
  11. package/dist/parse-type.js +42 -13
  12. package/dist/parse-type.js.map +1 -1
  13. package/dist/parse-type.mjs +39 -13
  14. package/dist/parse-type.mjs.map +1 -1
  15. package/dist/sanitize/sanitizers.d.ts.map +1 -1
  16. package/dist/sanitize/sanitizers.js +5 -3
  17. package/dist/sanitize/sanitizers.js.map +1 -1
  18. package/dist/sanitize/sanitizers.mjs +5 -3
  19. package/dist/sanitize/sanitizers.mjs.map +1 -1
  20. package/dist/sanitize/visitors/remove-restricted-relations.d.ts.map +1 -1
  21. package/dist/sanitize/visitors/remove-restricted-relations.js +128 -86
  22. package/dist/sanitize/visitors/remove-restricted-relations.js.map +1 -1
  23. package/dist/sanitize/visitors/remove-restricted-relations.mjs +128 -86
  24. package/dist/sanitize/visitors/remove-restricted-relations.mjs.map +1 -1
  25. package/dist/traverse-entity.d.ts.map +1 -1
  26. package/dist/traverse-entity.js +9 -1
  27. package/dist/traverse-entity.js.map +1 -1
  28. package/dist/traverse-entity.mjs +9 -1
  29. package/dist/traverse-entity.mjs.map +1 -1
  30. package/dist/validate/validators.js +12 -19
  31. package/dist/validate/validators.js.map +1 -1
  32. package/dist/validate/validators.mjs +13 -20
  33. package/dist/validate/validators.mjs.map +1 -1
  34. package/package.json +4 -4
@@ -1 +1 @@
1
- {"version":3,"file":"convert-query-params.js","sources":["../src/convert-query-params.ts"],"sourcesContent":["/* eslint-disable max-classes-per-file */\n\n/**\n * Converts the standard Strapi REST query params to a more usable format for querying\n * You can read more here: https://docs.strapi.io/developer-docs/latest/developer-resources/database-apis-reference/rest-api.html#filters\n */\n\nimport _ from 'lodash';\nimport {\n cloneDeep,\n get,\n isArray,\n isEmpty,\n isInteger,\n isNil,\n isObject,\n isString,\n toNumber,\n} from 'lodash/fp';\nimport {\n constants,\n hasDraftAndPublish,\n isDynamicZoneAttribute,\n isMorphToRelationalAttribute,\n} from './content-types';\nimport { PaginationError, ValidationError } from './errors';\nimport { isOperator } from './operators';\n\nimport parseType from './parse-type';\nimport type { PublicationFilterMode } from './publication-filter';\nimport {\n getMeaningfulSortSegments,\n hasSort,\n type SortParams,\n type SortParamsObject,\n} from './sort-query';\nimport { Model } from './types';\n\nexport type { SortParams, SortParamsObject } from './sort-query';\n\nconst { ID_ATTRIBUTE, DOC_ID_ATTRIBUTE, PUBLISHED_AT_ATTRIBUTE } = constants;\n\ntype SortOrder = 'asc' | 'desc';\n\nexport interface SortMap {\n [key: string]: SortOrder | SortMap;\n}\n\ntype FieldsParams = string | string[];\n\nconst isPlainObject = (value: unknown): value is Record<string, unknown> => _.isPlainObject(value);\n\nfunction isEmptySortMap(sortMap: SortMap): boolean {\n const keys = Object.keys(sortMap);\n\n if (keys.length === 0) {\n return true;\n }\n\n return keys.every((key) => {\n const value = sortMap[key];\n\n if (typeof value === 'string') {\n return value.trim().length === 0;\n }\n\n if (isPlainObject(value)) {\n return isEmptySortMap(value as SortMap);\n }\n\n return true;\n });\n}\n\n/** Drops empty sort maps so a trailing comma does not leave a truthy but meaningless `orderBy`. */\nfunction normalizeOrderBy(orderBy: OrderByQuery): OrderByQuery | undefined {\n if (Array.isArray(orderBy)) {\n const filtered = orderBy.filter((sortMap) => !isEmptySortMap(sortMap));\n\n return filtered.length > 0 ? filtered : undefined;\n }\n\n return isEmptySortMap(orderBy) ? undefined : orderBy;\n}\n\ntype FiltersParams = unknown;\n\nexport interface PopulateAttributesParams {\n [key: string]: boolean | PopulateObjectParams;\n}\n\nexport interface PopulateObjectParams {\n sort?: SortParams;\n fields?: FieldsParams;\n filters?: FiltersParams;\n populate?: string | string[] | PopulateAttributesParams;\n on?: PopulateAttributesParams;\n count?: boolean;\n ordering?: unknown;\n _q?: string;\n limit?: number | string;\n start?: number | string;\n page?: number | string;\n pageSize?: number | string;\n}\n\ntype PopulateParams = string | string[] | PopulateAttributesParams;\n\nexport interface Params {\n sort?: SortParams;\n fields?: FieldsParams;\n filters?: FiltersParams;\n populate?: PopulateParams;\n count?: boolean;\n ordering?: unknown;\n _q?: string;\n limit?: number | string;\n start?: number | string;\n page?: number | string;\n pageSize?: number | string;\n status?: 'draft' | 'published';\n publicationFilter?: PublicationFilterMode;\n /**\n * @deprecated Replaced by `publicationFilter` (`never-published`, `has-published-version`, …).\n * Retained for backward compatibility with existing REST and GraphQL clients.\n */\n hasPublishedVersion?: boolean | 'true' | 'false';\n}\n\ntype FiltersQuery = (options: { meta: Model }) => WhereQuery | undefined;\ntype OrderByQuery = SortMap | SortMap[];\ntype SelectQuery = string | string[];\n\nexport interface WhereQuery {\n [key: string]: any;\n}\n\ntype PopulateQuery =\n | boolean\n | string[]\n | {\n [key: string]: PopulateQuery;\n };\n\nexport interface Query {\n orderBy?: OrderByQuery;\n select?: SelectQuery;\n where?: WhereQuery;\n // NOTE: those are internal DB filters do not modify\n filters?: FiltersQuery;\n populate?: PopulateQuery;\n count?: boolean;\n ordering?: unknown;\n _q?: string;\n limit?: number;\n offset?: number;\n page?: number;\n pageSize?: number;\n}\n\nclass InvalidOrderError extends ValidationError {\n constructor() {\n super('Invalid order. order can only be one of asc|desc|ASC|DESC');\n }\n}\n\nclass InvalidSortError extends ValidationError {\n constructor() {\n super(\n 'Invalid sort parameter. Expected a string, an array of strings, a sort object or an array of sort objects'\n );\n }\n}\n\nclass InvalidPopulateError extends ValidationError {\n constructor() {\n super('Invalid populate parameter. Expected a string, an array of strings, a populate object');\n }\n}\n\nfunction validateOrder(order: string): asserts order is SortOrder {\n if (!isString(order) || !['asc', 'desc'].includes(order.toLocaleLowerCase())) {\n throw new InvalidOrderError();\n }\n}\n\nconst convertCountQueryParams = (countQuery: unknown): boolean => {\n return parseType({ type: 'boolean', value: countQuery });\n};\n\nconst convertOrderingQueryParams = (ordering: unknown) => {\n return ordering;\n};\n\nconst isStringArray = (value: unknown): value is string[] =>\n isArray(value) && value.every(isString);\n\ninterface TransformerOptions {\n getModel: (uid: string) => Model | undefined;\n}\n\nconst createTransformer = ({ getModel }: TransformerOptions) => {\n /**\n * Sort query parser\n */\n const convertSortQueryParams = (sortQuery: SortParams): OrderByQuery => {\n if (typeof sortQuery === 'string') {\n return convertStringSortQueryParam(sortQuery);\n }\n\n if (isStringArray(sortQuery)) {\n return sortQuery.flatMap((sortValue: string) => convertStringSortQueryParam(sortValue));\n }\n\n if (Array.isArray(sortQuery)) {\n return sortQuery.map((sortValue) => convertNestedSortQueryParam(sortValue));\n }\n\n if (isPlainObject(sortQuery)) {\n return convertNestedSortQueryParam(sortQuery);\n }\n\n throw new InvalidSortError();\n };\n\n const convertStringSortQueryParam = (sortQuery: string): SortMap[] => {\n return getMeaningfulSortSegments(sortQuery).map((segment) =>\n convertSingleSortQueryParam(segment)\n );\n };\n\n const convertSingleSortQueryParam = (sortQuery: string): SortMap => {\n const trimmed = sortQuery.trim();\n\n if (!trimmed) {\n return {};\n }\n\n if (!isString(trimmed)) {\n throw new ValidationError('Invalid sort query');\n }\n\n // split field and order param with default order to ascending\n const [rawField, order = 'asc'] = trimmed.split(':');\n const field = rawField.trim();\n\n if (field.length === 0) {\n throw new ValidationError('Field cannot be empty');\n }\n\n validateOrder(order.trim());\n\n // TODO: field should be a valid path on an object model\n\n return _.set({}, field, order.trim());\n };\n\n const convertNestedSortQueryParam = (sortQuery: SortParamsObject): SortMap => {\n const transformedSort: SortMap = {};\n for (const field of Object.keys(sortQuery)) {\n const order = sortQuery[field];\n\n // this is a deep sort\n if (isPlainObject(order)) {\n const nested = convertNestedSortQueryParam(order as SortParamsObject);\n\n if (!isEmptySortMap(nested)) {\n transformedSort[field] = nested;\n }\n } else if (typeof order === 'string') {\n const trimmedOrder = order.trim();\n\n if (trimmedOrder.length > 0) {\n validateOrder(trimmedOrder);\n transformedSort[field] = trimmedOrder;\n }\n } else {\n throw new ValidationError(\n `Invalid sort type expected object or string got ${typeof order}`\n );\n }\n }\n\n return transformedSort;\n };\n\n const applySortToQuery = (query: Query, sortParam?: SortParams | null) => {\n if (!hasSort(sortParam)) {\n return;\n }\n\n const orderBy = normalizeOrderBy(convertSortQueryParams(sortParam));\n\n if (orderBy !== undefined) {\n query.orderBy = orderBy;\n }\n };\n\n /**\n * Start query parser\n */\n const convertStartQueryParams = (startQuery: unknown): number => {\n const startAsANumber = toNumber(startQuery);\n\n if (!_.isInteger(startAsANumber) || startAsANumber < 0) {\n throw new ValidationError(\n `convertStartQueryParams expected a positive integer got ${startAsANumber}`\n );\n }\n\n return startAsANumber;\n };\n\n /**\n * Limit query parser\n */\n const convertLimitQueryParams = (limitQuery: unknown): number | undefined => {\n const limitAsANumber = toNumber(limitQuery);\n\n if (!_.isInteger(limitAsANumber) || (limitAsANumber !== -1 && limitAsANumber < 0)) {\n throw new ValidationError(\n `convertLimitQueryParams expected a positive integer got ${limitAsANumber}`\n );\n }\n\n if (limitAsANumber === -1) {\n return undefined;\n }\n\n return limitAsANumber;\n };\n\n const convertPageQueryParams = (page: unknown): number => {\n const pageVal = toNumber(page);\n\n if (!isInteger(pageVal) || pageVal <= 0) {\n throw new PaginationError(\n `Invalid 'page' parameter. Expected an integer > 0, received: ${page}`\n );\n }\n\n return pageVal;\n };\n\n // eslint-disable-next-line @typescript-eslint/no-unused-vars\n const convertPageSizeQueryParams = (pageSize: unknown, _page: unknown): number => {\n const pageSizeVal = toNumber(pageSize);\n\n if (!isInteger(pageSizeVal) || pageSizeVal <= 0) {\n throw new PaginationError(\n `Invalid 'pageSize' parameter. Expected an integer > 0, received: ${pageSize}`\n );\n }\n\n return pageSizeVal;\n };\n\n const validatePaginationParams = (\n page: unknown,\n pageSize: unknown,\n start: unknown,\n limit: unknown\n ) => {\n const isPagePagination = !isNil(page) || !isNil(pageSize);\n const isOffsetPagination = !isNil(start) || !isNil(limit);\n\n if (isPagePagination && isOffsetPagination) {\n throw new PaginationError(\n 'Invalid pagination attributes. The page parameters are incorrect and must be in the pagination object'\n );\n }\n };\n\n // NOTE: we could support foo.* or foo.bar.* etc later on\n const convertPopulateQueryParams = (\n populate: PopulateParams,\n schema?: Model,\n depth = 0\n ): PopulateQuery => {\n if (depth === 0 && populate === '*') {\n return true;\n }\n\n if (typeof populate === 'string') {\n return populate.split(',').map((value) => _.trim(value));\n }\n\n if (Array.isArray(populate)) {\n // map convert\n return _.uniq(\n populate.flatMap((value) => {\n if (typeof value !== 'string') {\n throw new InvalidPopulateError();\n }\n\n return value.split(',').map((value) => _.trim(value));\n })\n );\n }\n\n if (_.isPlainObject(populate)) {\n return convertPopulateObject(populate, schema);\n }\n\n throw new InvalidPopulateError();\n };\n\n const hasPopulateFragmentDefined = (\n populate: PopulateObjectParams\n ): populate is PopulateObjectParams & Required<Pick<PopulateObjectParams, 'on'>> => {\n return typeof populate === 'object' && 'on' in populate && !isNil(populate.on);\n };\n\n const hasCountDefined = (\n populate: PopulateObjectParams\n ): populate is PopulateObjectParams & { count: boolean } => {\n return (\n typeof populate === 'object' && 'count' in populate && typeof populate.count === 'boolean'\n );\n };\n\n const convertPopulateObject = (populate: PopulateAttributesParams, schema?: Model) => {\n if (!schema) {\n return {};\n }\n\n const { attributes } = schema;\n return Object.entries(populate).reduce((acc, [key, subPopulate]) => {\n // Try converting strings to regular booleans if possible\n if (_.isString(subPopulate)) {\n try {\n const subPopulateAsBoolean = parseType({ type: 'boolean', value: subPopulate });\n // Only true is accepted as a boolean populate value\n return subPopulateAsBoolean ? { ...acc, [key]: true } : acc;\n } catch {\n // ignore\n }\n }\n\n if (_.isBoolean(subPopulate)) {\n // Only true is accepted as a boolean populate value\n return subPopulate === true ? { ...acc, [key]: true } : acc;\n }\n\n const attribute = attributes[key];\n\n if (!attribute) {\n return acc;\n }\n\n // Allow adding an 'on' strategy to populate queries for morphTo relations and dynamic zones\n const isMorphLikeRelationalAttribute =\n isDynamicZoneAttribute(attribute) || isMorphToRelationalAttribute(attribute);\n\n if (isMorphLikeRelationalAttribute) {\n const hasInvalidProperties = Object.keys(subPopulate).some(\n (key) => !['populate', 'on', 'count'].includes(key)\n );\n\n if (hasInvalidProperties) {\n throw new ValidationError(\n `Invalid nested populate for ${schema.info?.singularName}.${key} (${schema.uid}). Expected a fragment (\"on\") or \"count\" but found ${JSON.stringify(subPopulate)}`\n );\n }\n\n /**\n * Validate nested population queries in the context of a polymorphic attribute (dynamic zone, morph relation).\n *\n * If 'populate' exists in subPopulate, its value should be constrained to a wildcard ('*').\n */\n if (\n 'populate' in subPopulate &&\n !isNil(subPopulate.populate) &&\n subPopulate.populate !== '*'\n ) {\n throw new ValidationError(\n `Invalid nested population query detected. When using 'populate' within polymorphic structures, ` +\n `its value must be '*' to indicate all second level links. Specific field targeting is not supported here. ` +\n `Consider using the fragment API for more granular population control.`\n );\n }\n\n // TODO: Remove the possibility to have multiple properties at the same time (on/count/populate)\n const newSubPopulate = {};\n\n // case: { populate: '*' }\n if ('populate' in subPopulate && subPopulate.populate === '*') {\n Object.assign(newSubPopulate, { populate: true });\n }\n\n // case: { on: { <clauses> } }\n if (hasPopulateFragmentDefined(subPopulate)) {\n // If the fragment API is used, it applies the transformation to every\n // sub-populate, then assign the result to the new sub-populate\n Object.assign(newSubPopulate, {\n on: Object.entries(subPopulate.on).reduce(\n (acc, [type, typeSubPopulate]) => ({\n ...acc,\n [type]: convertNestedPopulate(typeSubPopulate, getModel(type)),\n }),\n {}\n ),\n });\n }\n\n // case: { count: true | false }\n if (hasCountDefined(subPopulate)) {\n Object.assign(newSubPopulate, { count: subPopulate.count });\n }\n\n return { ...acc, [key]: newSubPopulate };\n }\n\n // Edge case when trying to use the fragment ('on') on a non-morph like attribute\n if (!isMorphLikeRelationalAttribute && hasPopulateFragmentDefined(subPopulate)) {\n throw new ValidationError(\n `Using fragments is not permitted to populate \"${key}\" in \"${schema.uid}\"`\n );\n }\n\n // NOTE: Retrieve the target schema UID.\n // Only handles basic relations, medias and component since it's not possible\n // to populate with options for a dynamic zone or a polymorphic relation\n let targetSchemaUID;\n\n if (attribute.type === 'relation') {\n targetSchemaUID = attribute.target;\n } else if (attribute.type === 'component') {\n targetSchemaUID = attribute.component;\n } else if (attribute.type === 'media') {\n targetSchemaUID = 'plugin::upload.file';\n } else {\n return acc;\n }\n\n const targetSchema = getModel(targetSchemaUID!);\n\n // ignore the sub-populate for the current key if there is no schema associated\n if (!targetSchema) {\n return acc;\n }\n\n const populateObject = convertNestedPopulate(subPopulate, targetSchema);\n\n if (!populateObject) {\n return acc;\n }\n\n return {\n ...acc,\n [key]: populateObject,\n };\n }, {});\n };\n\n const convertNestedPopulate = (subPopulate: boolean | PopulateObjectParams, schema?: Model) => {\n if (_.isString(subPopulate)) {\n return parseType({ type: 'boolean', value: subPopulate, forceCast: true });\n }\n\n if (_.isBoolean(subPopulate)) {\n return subPopulate;\n }\n\n if (!isPlainObject(subPopulate)) {\n throw new ValidationError(`Invalid nested populate. Expected '*' or an object`);\n }\n\n const { sort, filters, fields, populate, count, ordering, page, pageSize, start, limit } =\n subPopulate as PopulateObjectParams;\n\n const query: Query = {};\n\n applySortToQuery(query, sort);\n\n if (filters) {\n query.where = convertFiltersQueryParams(filters, schema);\n }\n\n if (fields) {\n query.select = convertFieldsQueryParams(fields, schema);\n }\n\n if (populate) {\n query.populate = convertPopulateQueryParams(populate, schema);\n }\n\n if (count) {\n query.count = convertCountQueryParams(count);\n }\n\n if (ordering) {\n query.ordering = convertOrderingQueryParams(ordering);\n }\n\n validatePaginationParams(page, pageSize, start, limit);\n\n if (!isNil(page)) {\n query.page = convertPageQueryParams(page);\n }\n\n if (!isNil(pageSize)) {\n query.pageSize = convertPageSizeQueryParams(pageSize, page);\n }\n\n if (!isNil(start)) {\n query.offset = convertStartQueryParams(start);\n }\n\n if (!isNil(limit)) {\n query.limit = convertLimitQueryParams(limit);\n }\n\n return query;\n };\n\n // TODO: ensure field is valid in content types (will probably have to check strapi.contentTypes since it can be a string.path)\n const convertFieldsQueryParams = (\n fields: FieldsParams,\n schema?: Model,\n depth = 0\n ): SelectQuery | undefined => {\n if (depth === 0 && fields === '*') {\n return undefined;\n }\n\n if (typeof fields === 'string') {\n const fieldsValues = fields.split(',').map((value) => _.trim(value));\n\n // NOTE: Only include the doc id if it's a content type\n if (schema?.modelType === 'contentType') {\n return _.uniq([ID_ATTRIBUTE, DOC_ID_ATTRIBUTE, ...fieldsValues]);\n }\n return _.uniq([ID_ATTRIBUTE, ...fieldsValues]);\n }\n\n if (isStringArray(fields)) {\n // map convert\n const fieldsValues = fields\n .flatMap((value) => convertFieldsQueryParams(value, schema, depth + 1))\n .filter((v) => !isNil(v)) as string[];\n\n // NOTE: Only include the doc id if it's a content type\n if (schema?.modelType === 'contentType') {\n return _.uniq([ID_ATTRIBUTE, DOC_ID_ATTRIBUTE, ...fieldsValues]);\n }\n return _.uniq([ID_ATTRIBUTE, ...fieldsValues]);\n }\n\n throw new ValidationError('Invalid fields parameter. Expected a string or an array of strings');\n };\n\n const isValidSchemaAttribute = (key: string, schema?: Model) => {\n if ([DOC_ID_ATTRIBUTE, ID_ATTRIBUTE].includes(key)) {\n return true;\n }\n\n if (!schema) {\n return false;\n }\n\n return Object.keys(schema.attributes).includes(key);\n };\n\n const convertFiltersQueryParams = (filters: FiltersParams, schema?: Model): WhereQuery => {\n // Filters need to be either an array or an object\n // Here we're only checking for 'object' type since typeof [] => object and typeof {} => object\n if (!isObject(filters)) {\n throw new ValidationError('The filters parameter must be an object or an array');\n }\n\n // Don't mutate the original object\n const filtersCopy = cloneDeep(filters);\n\n return convertAndSanitizeFilters(filtersCopy, schema);\n };\n\n const convertAndSanitizeFilters = (filters: FiltersParams, schema?: Model): WhereQuery => {\n if (Array.isArray(filters)) {\n return (\n filters\n // Sanitize each filter\n .map((filter) => convertAndSanitizeFilters(filter, schema))\n // Filter out empty filters\n .filter((filter) => !isPlainObject(filter) || !isEmpty(filter))\n );\n }\n\n if (!isPlainObject(filters)) {\n return filters as WhereQuery;\n }\n\n const removeOperator = (operator: string) => delete filters[operator];\n\n // Here, `key` can either be an operator or an attribute name\n for (const [key, value] of Object.entries(filters)) {\n const attribute = get(key, schema?.attributes);\n const validKey = isOperator(key) || isValidSchemaAttribute(key, schema);\n\n if (!validKey) {\n removeOperator(key);\n }\n // Handle attributes\n else if (attribute) {\n // Relations\n if (attribute.type === 'relation') {\n filters[key] = convertAndSanitizeFilters(value, getModel(attribute.target!));\n }\n\n // Components\n else if (attribute.type === 'component') {\n filters[key] = convertAndSanitizeFilters(value, getModel(attribute.component));\n }\n\n // Media\n else if (attribute.type === 'media') {\n filters[key] = convertAndSanitizeFilters(value, getModel('plugin::upload.file'));\n }\n\n // Dynamic Zones\n else if (attribute.type === 'dynamiczone') {\n removeOperator(key);\n }\n\n // Password attributes\n else if (attribute.type === 'password') {\n // Always remove password attributes from filters object\n removeOperator(key);\n }\n\n // Scalar attributes\n else {\n filters[key] = convertAndSanitizeFilters(value, schema);\n }\n }\n\n // Handle operators\n else if (['$null', '$notNull'].includes(key)) {\n filters[key] = parseType({ type: 'boolean', value: filters[key], forceCast: true });\n } else if (isObject(value)) {\n filters[key] = convertAndSanitizeFilters(value, schema);\n }\n\n // Remove empty objects & arrays\n if (isPlainObject(filters[key]) && isEmpty(filters[key])) {\n removeOperator(key);\n }\n }\n\n return filters;\n };\n\n const convertStatusParams = (status?: 'draft' | 'published', query: Query = {}) => {\n // NOTE: this is the query layer filters not the document/entity service filters\n query.filters = ({ meta }: { meta: Model }) => {\n const contentType = getModel(meta.uid);\n\n // Ignore if target model has disabled DP, as it doesn't make sense to filter by its status\n if (!contentType || !hasDraftAndPublish(contentType)) {\n return {};\n }\n\n return { [PUBLISHED_AT_ATTRIBUTE]: { $null: status === 'draft' } };\n };\n };\n\n const transformQueryParams = (uid: string, params: Params): Query => {\n // NOTE: can be a CT, a Compo or nothing in the case of polymorphism (DZ & morph relations)\n const schema = getModel(uid);\n\n const query: Query = {};\n\n const {\n _q: searchQuery,\n sort,\n filters,\n fields,\n populate,\n page,\n pageSize,\n start,\n limit,\n status,\n ...rest\n } = params;\n\n if (!isNil(status)) {\n convertStatusParams(status, query);\n }\n\n if (!isNil(searchQuery)) {\n query._q = searchQuery;\n }\n\n applySortToQuery(query, sort);\n\n if (!isNil(filters)) {\n query.where = convertFiltersQueryParams(filters, schema);\n }\n\n if (!isNil(fields)) {\n query.select = convertFieldsQueryParams(fields, schema);\n }\n\n if (!isNil(populate)) {\n query.populate = convertPopulateQueryParams(populate, schema);\n }\n\n validatePaginationParams(page, pageSize, start, limit);\n\n if (!isNil(page)) {\n query.page = convertPageQueryParams(page);\n }\n\n if (!isNil(pageSize)) {\n query.pageSize = convertPageSizeQueryParams(pageSize, page);\n }\n\n if (!isNil(start)) {\n query.offset = convertStartQueryParams(start);\n }\n\n if (!isNil(limit)) {\n query.limit = convertLimitQueryParams(limit);\n }\n\n return {\n ...rest,\n ...query,\n };\n };\n\n return {\n private_convertSortQueryParams: convertSortQueryParams,\n private_convertStartQueryParams: convertStartQueryParams,\n private_convertLimitQueryParams: convertLimitQueryParams,\n private_convertPopulateQueryParams: convertPopulateQueryParams,\n private_convertFiltersQueryParams: convertFiltersQueryParams,\n private_convertFieldsQueryParams: convertFieldsQueryParams,\n transformQueryParams,\n };\n};\n\nexport { createTransformer };\n"],"names":["ID_ATTRIBUTE","DOC_ID_ATTRIBUTE","PUBLISHED_AT_ATTRIBUTE","constants","isPlainObject","value","_","isEmptySortMap","sortMap","keys","Object","length","every","key","trim","normalizeOrderBy","orderBy","Array","isArray","filtered","filter","undefined","InvalidOrderError","ValidationError","InvalidSortError","InvalidPopulateError","validateOrder","order","isString","includes","toLocaleLowerCase","convertCountQueryParams","countQuery","parseType","type","convertOrderingQueryParams","ordering","isStringArray","createTransformer","getModel","convertSortQueryParams","sortQuery","convertStringSortQueryParam","flatMap","sortValue","map","convertNestedSortQueryParam","getMeaningfulSortSegments","segment","convertSingleSortQueryParam","trimmed","rawField","split","field","set","transformedSort","nested","trimmedOrder","applySortToQuery","query","sortParam","hasSort","convertStartQueryParams","startQuery","startAsANumber","toNumber","isInteger","convertLimitQueryParams","limitQuery","limitAsANumber","convertPageQueryParams","page","pageVal","PaginationError","convertPageSizeQueryParams","pageSize","_page","pageSizeVal","validatePaginationParams","start","limit","isPagePagination","isNil","isOffsetPagination","convertPopulateQueryParams","populate","schema","depth","uniq","convertPopulateObject","hasPopulateFragmentDefined","on","hasCountDefined","count","attributes","entries","reduce","acc","subPopulate","subPopulateAsBoolean","isBoolean","attribute","isMorphLikeRelationalAttribute","isDynamicZoneAttribute","isMorphToRelationalAttribute","hasInvalidProperties","some","info","singularName","uid","JSON","stringify","newSubPopulate","assign","typeSubPopulate","convertNestedPopulate","targetSchemaUID","target","component","targetSchema","populateObject","forceCast","sort","filters","fields","where","convertFiltersQueryParams","select","convertFieldsQueryParams","offset","fieldsValues","modelType","v","isValidSchemaAttribute","isObject","filtersCopy","cloneDeep","convertAndSanitizeFilters","isEmpty","removeOperator","operator","get","validKey","isOperator","convertStatusParams","status","meta","contentType","hasDraftAndPublish","$null","transformQueryParams","params","_q","searchQuery","rest","private_convertSortQueryParams","private_convertStartQueryParams","private_convertLimitQueryParams","private_convertPopulateQueryParams","private_convertFiltersQueryParams","private_convertFieldsQueryParams"],"mappings":"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"}
1
+ {"version":3,"file":"convert-query-params.js","sources":["../src/convert-query-params.ts"],"sourcesContent":["/* eslint-disable max-classes-per-file */\n\n/**\n * Converts the standard Strapi REST query params to a more usable format for querying\n * You can read more here: https://docs.strapi.io/developer-docs/latest/developer-resources/database-apis-reference/rest-api.html#filters\n */\n\nimport _ from 'lodash';\nimport {\n cloneDeep,\n get,\n isArray,\n isEmpty,\n isInteger,\n isNil,\n isObject,\n isString,\n toNumber,\n} from 'lodash/fp';\nimport {\n constants,\n hasDraftAndPublish,\n isDynamicZoneAttribute,\n isMorphToRelationalAttribute,\n} from './content-types';\nimport { PaginationError, ValidationError } from './errors';\nimport { isOperator } from './operators';\n\nimport parseType from './parse-type';\nimport type { PublicationFilterMode } from './publication-filter';\nimport {\n getMeaningfulSortSegments,\n hasSort,\n type SortParams,\n type SortParamsObject,\n} from './sort-query';\nimport { Model } from './types';\n\nexport type { SortParams, SortParamsObject } from './sort-query';\n\nconst { ID_ATTRIBUTE, DOC_ID_ATTRIBUTE, PUBLISHED_AT_ATTRIBUTE } = constants;\n\ntype SortOrder = 'asc' | 'desc';\n\nexport interface SortMap {\n [key: string]: SortOrder | SortMap;\n}\n\ntype FieldsParams = string | string[];\n\nconst isPlainObject = (value: unknown): value is Record<string, unknown> => _.isPlainObject(value);\n\nfunction isEmptySortMap(sortMap: SortMap): boolean {\n const keys = Object.keys(sortMap);\n\n if (keys.length === 0) {\n return true;\n }\n\n return keys.every((key) => {\n const value = sortMap[key];\n\n if (typeof value === 'string') {\n return value.trim().length === 0;\n }\n\n if (isPlainObject(value)) {\n return isEmptySortMap(value as SortMap);\n }\n\n return true;\n });\n}\n\n/** Drops empty sort maps so a trailing comma does not leave a truthy but meaningless `orderBy`. */\nfunction normalizeOrderBy(orderBy: OrderByQuery): OrderByQuery | undefined {\n if (Array.isArray(orderBy)) {\n const filtered = orderBy.filter((sortMap) => !isEmptySortMap(sortMap));\n\n return filtered.length > 0 ? filtered : undefined;\n }\n\n return isEmptySortMap(orderBy) ? undefined : orderBy;\n}\n\ntype FiltersParams = unknown;\n\nexport interface PopulateAttributesParams {\n [key: string]: boolean | PopulateObjectParams;\n}\n\nexport interface PopulateObjectParams {\n sort?: SortParams;\n fields?: FieldsParams;\n filters?: FiltersParams;\n populate?: string | string[] | PopulateAttributesParams;\n on?: PopulateAttributesParams;\n count?: boolean;\n ordering?: unknown;\n _q?: string;\n limit?: number | string;\n start?: number | string;\n page?: number | string;\n pageSize?: number | string;\n}\n\ntype PopulateParams = string | string[] | PopulateAttributesParams;\n\nexport interface Params {\n sort?: SortParams;\n fields?: FieldsParams;\n filters?: FiltersParams;\n populate?: PopulateParams;\n count?: boolean;\n ordering?: unknown;\n _q?: string;\n limit?: number | string;\n start?: number | string;\n page?: number | string;\n pageSize?: number | string;\n status?: 'draft' | 'published';\n publicationFilter?: PublicationFilterMode;\n /**\n * @deprecated Replaced by `publicationFilter` (`never-published`, `has-published-version`, …).\n * Retained for backward compatibility with existing REST and GraphQL clients.\n */\n hasPublishedVersion?: boolean | 'true' | 'false';\n}\n\ntype FiltersQuery = (options: { meta: Model }) => WhereQuery | undefined;\ntype OrderByQuery = SortMap | SortMap[];\ntype SelectQuery = string | string[];\n\nexport interface WhereQuery {\n [key: string]: any;\n}\n\ntype PopulateQuery =\n | boolean\n | string[]\n | {\n [key: string]: PopulateQuery;\n };\n\nexport interface Query {\n orderBy?: OrderByQuery;\n select?: SelectQuery;\n where?: WhereQuery;\n // NOTE: those are internal DB filters do not modify\n filters?: FiltersQuery;\n populate?: PopulateQuery;\n count?: boolean;\n ordering?: unknown;\n _q?: string;\n limit?: number;\n offset?: number;\n page?: number;\n pageSize?: number;\n}\n\nclass InvalidOrderError extends ValidationError {\n constructor() {\n super('Invalid order. order can only be one of asc|desc|ASC|DESC');\n }\n}\n\nclass InvalidSortError extends ValidationError {\n constructor() {\n super(\n 'Invalid sort parameter. Expected a string, an array of strings, a sort object or an array of sort objects'\n );\n }\n}\n\nclass InvalidPopulateError extends ValidationError {\n constructor() {\n super('Invalid populate parameter. Expected a string, an array of strings, a populate object');\n }\n}\n\nfunction validateOrder(order: string): asserts order is SortOrder {\n if (!isString(order) || !['asc', 'desc'].includes(order.toLocaleLowerCase())) {\n throw new InvalidOrderError();\n }\n}\n\nconst convertCountQueryParams = (countQuery: unknown): boolean => {\n return parseType({ type: 'boolean', value: countQuery });\n};\n\nconst convertOrderingQueryParams = (ordering: unknown) => {\n return ordering;\n};\n\nconst isStringArray = (value: unknown): value is string[] =>\n isArray(value) && value.every(isString);\n\ninterface TransformerOptions {\n getModel: (uid: string) => Model | undefined;\n}\n\nconst createTransformer = ({ getModel }: TransformerOptions) => {\n /**\n * Sort query parser\n */\n const convertSortQueryParams = (sortQuery: SortParams): OrderByQuery => {\n if (typeof sortQuery === 'string') {\n return convertStringSortQueryParam(sortQuery);\n }\n\n if (isStringArray(sortQuery)) {\n return sortQuery.flatMap((sortValue: string) => convertStringSortQueryParam(sortValue));\n }\n\n if (Array.isArray(sortQuery)) {\n return sortQuery.map((sortValue) => convertNestedSortQueryParam(sortValue));\n }\n\n if (isPlainObject(sortQuery)) {\n return convertNestedSortQueryParam(sortQuery);\n }\n\n throw new InvalidSortError();\n };\n\n const convertStringSortQueryParam = (sortQuery: string): SortMap[] => {\n return getMeaningfulSortSegments(sortQuery).map((segment) =>\n convertSingleSortQueryParam(segment)\n );\n };\n\n const convertSingleSortQueryParam = (sortQuery: string): SortMap => {\n const trimmed = sortQuery.trim();\n\n if (!trimmed) {\n return {};\n }\n\n if (!isString(trimmed)) {\n throw new ValidationError('Invalid sort query');\n }\n\n // split field and order param with default order to ascending\n const [rawField, order = 'asc'] = trimmed.split(':');\n const field = rawField.trim();\n\n if (field.length === 0) {\n throw new ValidationError('Field cannot be empty');\n }\n\n validateOrder(order.trim());\n\n // TODO: field should be a valid path on an object model\n\n return _.set({}, field, order.trim());\n };\n\n const convertNestedSortQueryParam = (sortQuery: SortParamsObject): SortMap => {\n const transformedSort: SortMap = {};\n for (const field of Object.keys(sortQuery)) {\n const order = sortQuery[field];\n\n // this is a deep sort\n if (isPlainObject(order)) {\n const nested = convertNestedSortQueryParam(order as SortParamsObject);\n\n if (!isEmptySortMap(nested)) {\n transformedSort[field] = nested;\n }\n } else if (typeof order === 'string') {\n const trimmedOrder = order.trim();\n\n if (trimmedOrder.length > 0) {\n validateOrder(trimmedOrder);\n transformedSort[field] = trimmedOrder;\n }\n } else {\n throw new ValidationError(\n `Invalid sort type expected object or string got ${typeof order}`\n );\n }\n }\n\n return transformedSort;\n };\n\n const applySortToQuery = (query: Query, sortParam?: SortParams | null) => {\n if (!hasSort(sortParam)) {\n return;\n }\n\n const orderBy = normalizeOrderBy(convertSortQueryParams(sortParam));\n\n if (orderBy !== undefined) {\n query.orderBy = orderBy;\n }\n };\n\n /**\n * Start query parser\n */\n const convertStartQueryParams = (startQuery: unknown): number => {\n const startAsANumber = toNumber(startQuery);\n\n if (!_.isInteger(startAsANumber) || startAsANumber < 0) {\n throw new ValidationError(\n `convertStartQueryParams expected a positive integer got ${startAsANumber}`\n );\n }\n\n return startAsANumber;\n };\n\n /**\n * Limit query parser\n */\n const convertLimitQueryParams = (limitQuery: unknown): number | undefined => {\n const limitAsANumber = toNumber(limitQuery);\n\n if (!_.isInteger(limitAsANumber) || (limitAsANumber !== -1 && limitAsANumber < 0)) {\n throw new ValidationError(\n `convertLimitQueryParams expected a positive integer got ${limitAsANumber}`\n );\n }\n\n if (limitAsANumber === -1) {\n return undefined;\n }\n\n return limitAsANumber;\n };\n\n const convertPageQueryParams = (page: unknown): number => {\n const pageVal = toNumber(page);\n\n if (!isInteger(pageVal) || pageVal <= 0) {\n throw new PaginationError(\n `Invalid 'page' parameter. Expected an integer > 0, received: ${page}`\n );\n }\n\n return pageVal;\n };\n\n // eslint-disable-next-line @typescript-eslint/no-unused-vars\n const convertPageSizeQueryParams = (pageSize: unknown, _page: unknown): number => {\n const pageSizeVal = toNumber(pageSize);\n\n if (!isInteger(pageSizeVal) || pageSizeVal <= 0) {\n throw new PaginationError(\n `Invalid 'pageSize' parameter. Expected an integer > 0, received: ${pageSize}`\n );\n }\n\n return pageSizeVal;\n };\n\n const validatePaginationParams = (\n page: unknown,\n pageSize: unknown,\n start: unknown,\n limit: unknown\n ) => {\n const isPagePagination = !isNil(page) || !isNil(pageSize);\n const isOffsetPagination = !isNil(start) || !isNil(limit);\n\n if (isPagePagination && isOffsetPagination) {\n throw new PaginationError(\n 'Invalid pagination attributes. The page parameters are incorrect and must be in the pagination object'\n );\n }\n };\n\n // NOTE: we could support foo.* or foo.bar.* etc later on\n const convertPopulateQueryParams = (\n populate: PopulateParams,\n schema?: Model,\n depth = 0\n ): PopulateQuery => {\n if (depth === 0 && populate === '*') {\n return true;\n }\n\n if (typeof populate === 'string') {\n return populate.split(',').map((value) => _.trim(value));\n }\n\n if (Array.isArray(populate)) {\n // map convert\n return _.uniq(\n populate.flatMap((value) => {\n if (typeof value !== 'string') {\n throw new InvalidPopulateError();\n }\n\n return value.split(',').map((value) => _.trim(value));\n })\n );\n }\n\n if (_.isPlainObject(populate)) {\n return convertPopulateObject(populate, schema);\n }\n\n throw new InvalidPopulateError();\n };\n\n const hasPopulateFragmentDefined = (\n populate: PopulateObjectParams\n ): populate is PopulateObjectParams & Required<Pick<PopulateObjectParams, 'on'>> => {\n return typeof populate === 'object' && 'on' in populate && !isNil(populate.on);\n };\n\n const hasCountDefined = (\n populate: PopulateObjectParams\n ): populate is PopulateObjectParams & { count: boolean } => {\n return (\n typeof populate === 'object' && 'count' in populate && typeof populate.count === 'boolean'\n );\n };\n\n const convertPopulateObject = (populate: PopulateAttributesParams, schema?: Model) => {\n if (!schema) {\n return {};\n }\n\n const { attributes } = schema;\n return Object.entries(populate).reduce((acc, [key, subPopulate]) => {\n // Try converting strings to regular booleans if possible\n if (_.isString(subPopulate)) {\n try {\n const subPopulateAsBoolean = parseType({ type: 'boolean', value: subPopulate });\n // Only true is accepted as a boolean populate value\n return subPopulateAsBoolean ? { ...acc, [key]: true } : acc;\n } catch {\n // ignore\n }\n }\n\n if (_.isBoolean(subPopulate)) {\n // Only true is accepted as a boolean populate value\n return subPopulate === true ? { ...acc, [key]: true } : acc;\n }\n\n const attribute = attributes[key];\n\n if (!attribute) {\n return acc;\n }\n\n // Allow adding an 'on' strategy to populate queries for morphTo relations and dynamic zones\n const isMorphLikeRelationalAttribute =\n isDynamicZoneAttribute(attribute) || isMorphToRelationalAttribute(attribute);\n\n if (isMorphLikeRelationalAttribute) {\n const hasInvalidProperties = Object.keys(subPopulate).some(\n (key) => !['populate', 'on', 'count'].includes(key)\n );\n\n if (hasInvalidProperties) {\n throw new ValidationError(\n `Invalid nested populate for ${schema.info?.singularName}.${key} (${schema.uid}). Expected a fragment (\"on\") or \"count\" but found ${JSON.stringify(subPopulate)}`\n );\n }\n\n /**\n * Validate nested population queries in the context of a polymorphic attribute (dynamic zone, morph relation).\n *\n * If 'populate' exists in subPopulate, its value should be constrained to a wildcard ('*').\n */\n if (\n 'populate' in subPopulate &&\n !isNil(subPopulate.populate) &&\n subPopulate.populate !== '*'\n ) {\n throw new ValidationError(\n `Invalid nested population query detected. When using 'populate' within polymorphic structures, ` +\n `its value must be '*' to indicate all second level links. Specific field targeting is not supported here. ` +\n `Consider using the fragment API for more granular population control.`\n );\n }\n\n // TODO: Remove the possibility to have multiple properties at the same time (on/count/populate)\n const newSubPopulate = {};\n\n // case: { populate: '*' }\n if ('populate' in subPopulate && subPopulate.populate === '*') {\n Object.assign(newSubPopulate, { populate: true });\n }\n\n // case: { on: { <clauses> } }\n if (hasPopulateFragmentDefined(subPopulate)) {\n // If the fragment API is used, it applies the transformation to every\n // sub-populate, then assign the result to the new sub-populate\n Object.assign(newSubPopulate, {\n on: Object.entries(subPopulate.on).reduce(\n (acc, [type, typeSubPopulate]) => ({\n ...acc,\n [type]: convertNestedPopulate(typeSubPopulate, getModel(type)),\n }),\n {}\n ),\n });\n }\n\n // case: { count: true | false }\n if (hasCountDefined(subPopulate)) {\n Object.assign(newSubPopulate, { count: subPopulate.count });\n }\n\n return { ...acc, [key]: newSubPopulate };\n }\n\n // Edge case when trying to use the fragment ('on') on a non-morph like attribute\n if (!isMorphLikeRelationalAttribute && hasPopulateFragmentDefined(subPopulate)) {\n throw new ValidationError(\n `Using fragments is not permitted to populate \"${key}\" in \"${schema.uid}\"`\n );\n }\n\n // NOTE: Retrieve the target schema UID.\n // Only handles basic relations, medias and component since it's not possible\n // to populate with options for a dynamic zone or a polymorphic relation\n let targetSchemaUID;\n\n if (attribute.type === 'relation') {\n targetSchemaUID = attribute.target;\n } else if (attribute.type === 'component') {\n targetSchemaUID = attribute.component;\n } else if (attribute.type === 'media') {\n targetSchemaUID = 'plugin::upload.file';\n } else {\n return acc;\n }\n\n const targetSchema = getModel(targetSchemaUID!);\n\n // ignore the sub-populate for the current key if there is no schema associated\n if (!targetSchema) {\n return acc;\n }\n\n const populateObject = convertNestedPopulate(subPopulate, targetSchema);\n\n if (!populateObject) {\n return acc;\n }\n\n return {\n ...acc,\n [key]: populateObject,\n };\n }, {});\n };\n\n const convertNestedPopulate = (subPopulate: boolean | PopulateObjectParams, schema?: Model) => {\n if (_.isString(subPopulate)) {\n return parseType({ type: 'boolean', value: subPopulate, forceCast: true });\n }\n\n if (_.isBoolean(subPopulate)) {\n return subPopulate;\n }\n\n if (!isPlainObject(subPopulate)) {\n throw new ValidationError(`Invalid nested populate. Expected '*' or an object`);\n }\n\n const { sort, filters, fields, populate, count, ordering, page, pageSize, start, limit } =\n subPopulate as PopulateObjectParams;\n\n const query: Query = {};\n\n applySortToQuery(query, sort);\n\n if (filters) {\n query.where = convertFiltersQueryParams(filters, schema);\n }\n\n if (fields) {\n query.select = convertFieldsQueryParams(fields, schema);\n }\n\n if (populate) {\n query.populate = convertPopulateQueryParams(populate, schema);\n }\n\n if (count) {\n query.count = convertCountQueryParams(count);\n }\n\n if (ordering) {\n query.ordering = convertOrderingQueryParams(ordering);\n }\n\n validatePaginationParams(page, pageSize, start, limit);\n\n if (!isNil(page)) {\n query.page = convertPageQueryParams(page);\n }\n\n if (!isNil(pageSize)) {\n query.pageSize = convertPageSizeQueryParams(pageSize, page);\n }\n\n if (!isNil(start)) {\n query.offset = convertStartQueryParams(start);\n }\n\n if (!isNil(limit)) {\n query.limit = convertLimitQueryParams(limit);\n }\n\n return query;\n };\n\n // TODO: ensure field is valid in content types (will probably have to check strapi.contentTypes since it can be a string.path)\n const convertFieldsQueryParams = (\n fields: FieldsParams,\n schema?: Model,\n depth = 0\n ): SelectQuery | undefined => {\n if (depth === 0 && fields === '*') {\n return undefined;\n }\n\n if (typeof fields === 'string') {\n const fieldsValues = fields.split(',').map((value) => _.trim(value));\n\n // NOTE: Only include the doc id if it's a content type\n if (schema?.modelType === 'contentType') {\n return _.uniq([ID_ATTRIBUTE, DOC_ID_ATTRIBUTE, ...fieldsValues]);\n }\n return _.uniq([ID_ATTRIBUTE, ...fieldsValues]);\n }\n\n if (isStringArray(fields)) {\n // map convert\n const fieldsValues = fields\n .flatMap((value) => convertFieldsQueryParams(value, schema, depth + 1))\n .filter((v) => !isNil(v)) as string[];\n\n // NOTE: Only include the doc id if it's a content type\n if (schema?.modelType === 'contentType') {\n return _.uniq([ID_ATTRIBUTE, DOC_ID_ATTRIBUTE, ...fieldsValues]);\n }\n return _.uniq([ID_ATTRIBUTE, ...fieldsValues]);\n }\n\n throw new ValidationError('Invalid fields parameter. Expected a string or an array of strings');\n };\n\n const isValidSchemaAttribute = (key: string, schema?: Model) => {\n if ([DOC_ID_ATTRIBUTE, ID_ATTRIBUTE].includes(key)) {\n return true;\n }\n\n if (!schema) {\n return false;\n }\n\n return Object.keys(schema.attributes).includes(key);\n };\n\n const convertFiltersQueryParams = (filters: FiltersParams, schema?: Model): WhereQuery => {\n // Filters need to be either an array or an object\n // Here we're only checking for 'object' type since typeof [] => object and typeof {} => object\n if (!isObject(filters)) {\n throw new ValidationError('The filters parameter must be an object or an array');\n }\n\n // Don't mutate the original object\n const filtersCopy = cloneDeep(filters);\n\n return convertAndSanitizeFilters(filtersCopy, schema);\n };\n\n const convertAndSanitizeFilters = (filters: FiltersParams, schema?: Model): WhereQuery => {\n if (Array.isArray(filters)) {\n return (\n filters\n // Sanitize each filter\n .map((filter) => convertAndSanitizeFilters(filter, schema))\n // Filter out empty filters\n .filter((filter) => !isPlainObject(filter) || !isEmpty(filter))\n );\n }\n\n if (!isPlainObject(filters)) {\n return filters as WhereQuery;\n }\n\n const removeOperator = (operator: string) => delete filters[operator];\n\n // Here, `key` can either be an operator or an attribute name\n for (const [key, value] of Object.entries(filters)) {\n const attribute = get(key, schema?.attributes);\n const validKey = isOperator(key) || isValidSchemaAttribute(key, schema);\n\n if (!validKey) {\n removeOperator(key);\n }\n // Handle attributes\n else if (attribute) {\n // Relations\n if (attribute.type === 'relation') {\n filters[key] = convertAndSanitizeFilters(value, getModel(attribute.target!));\n }\n\n // Components\n else if (attribute.type === 'component') {\n filters[key] = convertAndSanitizeFilters(value, getModel(attribute.component));\n }\n\n // Media\n else if (attribute.type === 'media') {\n filters[key] = convertAndSanitizeFilters(value, getModel('plugin::upload.file'));\n }\n\n // Dynamic Zones\n else if (attribute.type === 'dynamiczone') {\n removeOperator(key);\n }\n\n // Password attributes\n else if (attribute.type === 'password') {\n // Always remove password attributes from filters object\n removeOperator(key);\n }\n\n // Scalar attributes\n else {\n filters[key] = convertAndSanitizeFilters(value, schema);\n }\n }\n\n // Handle operators\n else if (['$null', '$notNull'].includes(key)) {\n filters[key] = parseType({ type: 'boolean', value: filters[key], forceCast: true });\n } else if (isObject(value)) {\n filters[key] = convertAndSanitizeFilters(value, schema);\n }\n\n // Remove empty objects & arrays\n if (isPlainObject(filters[key]) && isEmpty(filters[key])) {\n removeOperator(key);\n }\n }\n\n return filters;\n };\n\n const convertStatusParams = (status?: 'draft' | 'published', query: Query = {}) => {\n // NOTE: this is the query layer filters not the document/entity service filters\n query.filters = ({ meta }: { meta: Model }) => {\n const contentType = getModel(meta.uid);\n\n // Ignore if target model has disabled DP, as it doesn't make sense to filter by its status\n if (!contentType || !hasDraftAndPublish(contentType)) {\n return {};\n }\n\n return { [PUBLISHED_AT_ATTRIBUTE]: { $null: status === 'draft' } };\n };\n };\n\n const transformQueryParams = (uid: string, params: Params): Query => {\n // NOTE: can be a CT, a Compo or nothing in the case of polymorphism (DZ & morph relations)\n const schema = getModel(uid);\n\n const query: Query = {};\n\n const {\n _q: searchQuery,\n sort,\n filters,\n fields,\n populate,\n page,\n pageSize,\n start,\n limit,\n status,\n ...rest\n } = params;\n\n if (!isNil(status)) {\n convertStatusParams(status, query);\n }\n\n if (!isNil(searchQuery)) {\n query._q = searchQuery;\n }\n\n applySortToQuery(query, sort);\n\n if (!isNil(filters)) {\n query.where = convertFiltersQueryParams(filters, schema);\n }\n\n if (!isNil(fields)) {\n query.select = convertFieldsQueryParams(fields, schema);\n }\n\n if (!isNil(populate)) {\n query.populate = convertPopulateQueryParams(populate, schema);\n }\n\n validatePaginationParams(page, pageSize, start, limit);\n\n if (!isNil(page)) {\n query.page = convertPageQueryParams(page);\n }\n\n if (!isNil(pageSize)) {\n query.pageSize = convertPageSizeQueryParams(pageSize, page);\n }\n\n if (!isNil(start)) {\n query.offset = convertStartQueryParams(start);\n }\n\n if (!isNil(limit)) {\n query.limit = convertLimitQueryParams(limit);\n }\n\n return {\n ...rest,\n ...query,\n };\n };\n\n return {\n private_convertSortQueryParams: convertSortQueryParams,\n private_convertStartQueryParams: convertStartQueryParams,\n private_convertLimitQueryParams: convertLimitQueryParams,\n private_convertPopulateQueryParams: convertPopulateQueryParams,\n private_convertFiltersQueryParams: convertFiltersQueryParams,\n private_convertFieldsQueryParams: convertFieldsQueryParams,\n transformQueryParams,\n };\n};\n\nexport { createTransformer };\n"],"names":["ID_ATTRIBUTE","DOC_ID_ATTRIBUTE","PUBLISHED_AT_ATTRIBUTE","constants","isPlainObject","value","_","isEmptySortMap","sortMap","keys","Object","length","every","key","trim","normalizeOrderBy","orderBy","Array","isArray","filtered","filter","undefined","InvalidOrderError","ValidationError","InvalidSortError","InvalidPopulateError","validateOrder","order","isString","includes","toLocaleLowerCase","convertCountQueryParams","countQuery","parseType","type","convertOrderingQueryParams","ordering","isStringArray","createTransformer","getModel","convertSortQueryParams","sortQuery","convertStringSortQueryParam","flatMap","sortValue","map","convertNestedSortQueryParam","getMeaningfulSortSegments","segment","convertSingleSortQueryParam","trimmed","rawField","split","field","set","transformedSort","nested","trimmedOrder","applySortToQuery","query","sortParam","hasSort","convertStartQueryParams","startQuery","startAsANumber","toNumber","isInteger","convertLimitQueryParams","limitQuery","limitAsANumber","convertPageQueryParams","page","pageVal","PaginationError","convertPageSizeQueryParams","pageSize","_page","pageSizeVal","validatePaginationParams","start","limit","isPagePagination","isNil","isOffsetPagination","convertPopulateQueryParams","populate","schema","depth","uniq","convertPopulateObject","hasPopulateFragmentDefined","on","hasCountDefined","count","attributes","entries","reduce","acc","subPopulate","subPopulateAsBoolean","isBoolean","attribute","isMorphLikeRelationalAttribute","isDynamicZoneAttribute","isMorphToRelationalAttribute","hasInvalidProperties","some","info","singularName","uid","JSON","stringify","newSubPopulate","assign","typeSubPopulate","convertNestedPopulate","targetSchemaUID","target","component","targetSchema","populateObject","forceCast","sort","filters","fields","where","convertFiltersQueryParams","select","convertFieldsQueryParams","offset","fieldsValues","modelType","v","isValidSchemaAttribute","isObject","filtersCopy","cloneDeep","convertAndSanitizeFilters","isEmpty","removeOperator","operator","get","validKey","isOperator","convertStatusParams","status","meta","contentType","hasDraftAndPublish","$null","transformQueryParams","params","_q","searchQuery","rest","private_convertSortQueryParams","private_convertStartQueryParams","private_convertLimitQueryParams","private_convertPopulateQueryParams","private_convertFiltersQueryParams","private_convertFieldsQueryParams"],"mappings":"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"}
package/dist/index.js CHANGED
@@ -67,7 +67,7 @@ var z__namespace = /*#__PURE__*/_interopNamespace(z);
67
67
 
68
68
 
69
69
 
70
- exports.parseType = parseType;
70
+ exports.parseType = parseType.default;
71
71
  exports.env = envHelper;
72
72
  exports.setCreatorFields = setCreatorFields;
73
73
  exports.providerFactory = providerFactory;
@@ -14,9 +14,22 @@ export interface ParseTypeOptions<T extends keyof TypeMap> {
14
14
  value: unknown;
15
15
  forceCast?: boolean;
16
16
  }
17
+ /**
18
+ * Whether `parseBoolean` would accept this value without `forceCast`.
19
+ *
20
+ * Exists so callers can ask the question without using an exception as control flow.
21
+ * Query validation asked it once per populate key by calling `parseType` inside a
22
+ * `try`/`catch`, so every key that is not a boolean keyword — which is nearly all of
23
+ * them — built an Error and captured a stack trace only to discard it. Stack capture is
24
+ * the expensive part, and it made this the second hottest function in a read.
25
+ *
26
+ * Kept in lockstep with `parseBoolean`'s accept conditions below.
27
+ */
28
+ declare const isBooleanLike: (value: unknown) => boolean;
17
29
  /**
18
30
  * Cast basic values based on attribute type
19
31
  */
20
32
  declare const parseType: <Type extends keyof TypeMap>(options: ParseTypeOptions<Type>) => TypeMap[Type];
33
+ export { isBooleanLike };
21
34
  export default parseType;
22
35
  //# sourceMappingURL=parse-type.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"parse-type.d.ts","sourceRoot":"","sources":["../src/parse-type.ts"],"names":[],"mappings":"AAuEA,KAAK,OAAO,GAAG;IACb,OAAO,EAAE,OAAO,CAAC;IACjB,OAAO,EAAE,MAAM,CAAC;IAChB,UAAU,EAAE,MAAM,CAAC;IACnB,KAAK,EAAE,MAAM,CAAC;IACd,OAAO,EAAE,MAAM,CAAC;IAChB,IAAI,EAAE,MAAM,CAAC;IACb,IAAI,EAAE,MAAM,CAAC;IACb,SAAS,EAAE,IAAI,CAAC;IAChB,QAAQ,EAAE,IAAI,CAAC;CAChB,CAAC;AAEF,MAAM,WAAW,gBAAgB,CAAC,CAAC,SAAS,MAAM,OAAO;IACvD,IAAI,EAAE,CAAC,CAAC;IACR,KAAK,EAAE,OAAO,CAAC;IACf,SAAS,CAAC,EAAE,OAAO,CAAC;CACrB;AA0BD;;GAEG;AACH,QAAA,MAAM,SAAS,GAAI,IAAI,SAAS,MAAM,OAAO,EAAE,SAAS,gBAAgB,CAAC,IAAI,CAAC,KAAG,OAAO,CAAC,IAAI,CAyB5F,CAAC;AAEF,eAAe,SAAS,CAAC"}
1
+ {"version":3,"file":"parse-type.d.ts","sourceRoot":"","sources":["../src/parse-type.ts"],"names":[],"mappings":"AAuEA,KAAK,OAAO,GAAG;IACb,OAAO,EAAE,OAAO,CAAC;IACjB,OAAO,EAAE,MAAM,CAAC;IAChB,UAAU,EAAE,MAAM,CAAC;IACnB,KAAK,EAAE,MAAM,CAAC;IACd,OAAO,EAAE,MAAM,CAAC;IAChB,IAAI,EAAE,MAAM,CAAC;IACb,IAAI,EAAE,MAAM,CAAC;IACb,SAAS,EAAE,IAAI,CAAC;IAChB,QAAQ,EAAE,IAAI,CAAC;CAChB,CAAC;AAEF,MAAM,WAAW,gBAAgB,CAAC,CAAC,SAAS,MAAM,OAAO;IACvD,IAAI,EAAE,CAAC,CAAC;IACR,KAAK,EAAE,OAAO,CAAC;IACf,SAAS,CAAC,EAAE,OAAO,CAAC;CACrB;AAWD;;;;;;;;;;GAUG;AACH,QAAA,MAAM,aAAa,GAAI,OAAO,OAAO,KAAG,OAUvC,CAAC;AA0BF;;GAEG;AACH,QAAA,MAAM,SAAS,GAAI,IAAI,SAAS,MAAM,OAAO,EAAE,SAAS,gBAAgB,CAAC,IAAI,CAAC,KAAG,OAAO,CAAC,IAAI,CAyB5F,CAAC;AAEF,OAAO,EAAE,aAAa,EAAE,CAAC;AACzB,eAAe,SAAS,CAAC"}
@@ -1,5 +1,7 @@
1
1
  'use strict';
2
2
 
3
+ Object.defineProperty(exports, '__esModule', { value: true });
4
+
3
5
  var _ = require('lodash');
4
6
  var dates = require('date-fns');
5
7
 
@@ -75,26 +77,52 @@ const parseDateTimeOrTimestamp = (value)=>{
75
77
  throw new Error(`Invalid format, expected a timestamp or an ISO date`);
76
78
  }
77
79
  };
80
+ /**
81
+ * Hoisted out of `parseBoolean`, which allocated both of these arrays on every call.
82
+ * Query validation calls it once per node of the populate tree of every request, which
83
+ * made those two throwaway allocations one of the largest single sources of GC pressure
84
+ * in a read: 4.3% of on-CPU time in a profiled LaunchPad run.
85
+ */ const TRUTHY_INPUTS = [
86
+ 'true',
87
+ 't',
88
+ '1',
89
+ 1
90
+ ];
91
+ const FALSY_INPUTS = [
92
+ 'false',
93
+ 'f',
94
+ '0',
95
+ 0
96
+ ];
97
+ /**
98
+ * Whether `parseBoolean` would accept this value without `forceCast`.
99
+ *
100
+ * Exists so callers can ask the question without using an exception as control flow.
101
+ * Query validation asked it once per populate key by calling `parseType` inside a
102
+ * `try`/`catch`, so every key that is not a boolean keyword — which is nearly all of
103
+ * them — built an Error and captured a stack trace only to discard it. Stack capture is
104
+ * the expensive part, and it made this the second hottest function in a read.
105
+ *
106
+ * Kept in lockstep with `parseBoolean`'s accept conditions below.
107
+ */ const isBooleanLike = (value)=>{
108
+ if (typeof value === 'boolean') {
109
+ return true;
110
+ }
111
+ if (typeof value === 'string' || typeof value === 'number') {
112
+ return TRUTHY_INPUTS.includes(value) || FALSY_INPUTS.includes(value);
113
+ }
114
+ return false;
115
+ };
78
116
  const parseBoolean = (value, options)=>{
79
117
  const { forceCast = false } = options;
80
118
  if (typeof value === 'boolean') {
81
119
  return value;
82
120
  }
83
121
  if (typeof value === 'string' || typeof value === 'number') {
84
- if ([
85
- 'true',
86
- 't',
87
- '1',
88
- 1
89
- ].includes(value)) {
122
+ if (TRUTHY_INPUTS.includes(value)) {
90
123
  return true;
91
124
  }
92
- if ([
93
- 'false',
94
- 'f',
95
- '0',
96
- 0
97
- ].includes(value)) {
125
+ if (FALSY_INPUTS.includes(value)) {
98
126
  return false;
99
127
  }
100
128
  }
@@ -137,5 +165,6 @@ const parseBoolean = (value, options)=>{
137
165
  }
138
166
  };
139
167
 
140
- module.exports = parseType;
168
+ exports.default = parseType;
169
+ exports.isBooleanLike = isBooleanLike;
141
170
  //# sourceMappingURL=parse-type.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"parse-type.js","sources":["../src/parse-type.ts"],"sourcesContent":["import * as _ from 'lodash';\nimport * as dates from 'date-fns';\n\nconst timeRegex = /^(2[0-3]|[01][0-9]):([0-5][0-9]):([0-5][0-9])(.[0-9]{1,3})?$/;\n\nconst isDate = (v: unknown): v is Date => {\n return dates.isDate(v);\n};\n\nconst parseTime = (value: unknown): string => {\n if (isDate(value)) {\n return dates.format(value, 'HH:mm:ss.SSS');\n }\n\n if (typeof value !== 'string') {\n throw new Error(`Expected a string, got a ${typeof value}`);\n }\n const result = value.match(timeRegex);\n\n if (result === null) {\n throw new Error('Invalid time format, expected HH:mm:ss.SSS');\n }\n\n const [, hours, minutes, seconds, fraction = '.000'] = result;\n const fractionPart = _.padEnd(fraction.slice(1), 3, '0');\n\n return `${hours}:${minutes}:${seconds}.${fractionPart}`;\n};\n\nconst parseDate = (value: unknown) => {\n if (isDate(value)) {\n return dates.format(value, 'yyyy-MM-dd');\n }\n\n if (typeof value !== 'string') {\n throw new Error(`Expected a string, got a ${typeof value}`);\n }\n\n try {\n const date = dates.parseISO(value);\n\n if (dates.isValid(date)) return dates.format(date, 'yyyy-MM-dd');\n\n throw new Error(`Invalid format, expected an ISO compatible date`);\n } catch {\n throw new Error(`Invalid format, expected an ISO compatible date`);\n }\n};\n\nconst parseDateTimeOrTimestamp = (value: unknown) => {\n if (isDate(value)) {\n return value;\n }\n\n if (typeof value !== 'string') {\n throw new Error(`Expected a string, got a ${typeof value}`);\n }\n\n try {\n const date = dates.parseISO(value);\n if (dates.isValid(date)) return date;\n\n const milliUnixDate = dates.parse(value, 'T', new Date());\n if (dates.isValid(milliUnixDate)) return milliUnixDate;\n\n throw new Error(`Invalid format, expected a timestamp or an ISO date`);\n } catch {\n throw new Error(`Invalid format, expected a timestamp or an ISO date`);\n }\n};\n\ntype TypeMap = {\n boolean: boolean;\n integer: number;\n biginteger: number;\n float: number;\n decimal: number;\n time: string;\n date: string;\n timestamp: Date;\n datetime: Date;\n};\n\nexport interface ParseTypeOptions<T extends keyof TypeMap> {\n type: T;\n value: unknown;\n forceCast?: boolean;\n}\n\nconst parseBoolean = (value: unknown, options: { forceCast?: boolean }): boolean => {\n const { forceCast = false } = options;\n\n if (typeof value === 'boolean') {\n return value;\n }\n\n if (typeof value === 'string' || typeof value === 'number') {\n if (['true', 't', '1', 1].includes(value)) {\n return true;\n }\n\n if (['false', 'f', '0', 0].includes(value)) {\n return false;\n }\n }\n\n if (forceCast) {\n return Boolean(value);\n }\n\n throw new Error('Invalid boolean input. Expected \"t\",\"1\",\"true\",\"false\",\"0\",\"f\"');\n};\n\n/**\n * Cast basic values based on attribute type\n */\nconst parseType = <Type extends keyof TypeMap>(options: ParseTypeOptions<Type>): TypeMap[Type] => {\n const { type, value, forceCast } = options;\n\n switch (type) {\n case 'boolean':\n return parseBoolean(value, { forceCast }) as TypeMap[Type];\n case 'integer':\n case 'biginteger':\n case 'float':\n case 'decimal': {\n return _.toNumber(value) as TypeMap[Type];\n }\n case 'time': {\n return parseTime(value) as TypeMap[Type];\n }\n case 'date': {\n return parseDate(value) as TypeMap[Type];\n }\n case 'timestamp':\n case 'datetime': {\n return parseDateTimeOrTimestamp(value) as TypeMap[Type];\n }\n default:\n return value as TypeMap[Type];\n }\n};\n\nexport default parseType;\n"],"names":["timeRegex","isDate","v","dates","parseTime","value","format","Error","result","match","hours","minutes","seconds","fraction","fractionPart","_","padEnd","slice","parseDate","date","parseISO","isValid","parseDateTimeOrTimestamp","milliUnixDate","parse","Date","parseBoolean","options","forceCast","includes","Boolean","parseType","type","toNumber"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;AAGA,MAAMA,SAAAA,GAAY,8DAAA;AAElB,MAAMC,SAAS,CAACC,CAAAA,GAAAA;IACd,OAAOC,gBAAAA,CAAMF,MAAM,CAACC,CAAAA,CAAAA;AACtB,CAAA;AAEA,MAAME,YAAY,CAACC,KAAAA,GAAAA;AACjB,IAAA,IAAIJ,OAAOI,KAAAA,CAAAA,EAAQ;QACjB,OAAOF,gBAAAA,CAAMG,MAAM,CAACD,KAAAA,EAAO,cAAA,CAAA;AAC7B,IAAA;IAEA,IAAI,OAAOA,UAAU,QAAA,EAAU;AAC7B,QAAA,MAAM,IAAIE,KAAAA,CAAM,CAAC,yBAAyB,EAAE,OAAOF,KAAAA,CAAAA,CAAO,CAAA;AAC5D,IAAA;IACA,MAAMG,MAAAA,GAASH,KAAAA,CAAMI,KAAK,CAACT,SAAAA,CAAAA;AAE3B,IAAA,IAAIQ,WAAW,IAAA,EAAM;AACnB,QAAA,MAAM,IAAID,KAAAA,CAAM,4CAAA,CAAA;AAClB,IAAA;AAEA,IAAA,MAAM,GAAGG,KAAAA,EAAOC,OAAAA,EAASC,SAASC,QAAAA,GAAW,MAAM,CAAC,GAAGL,MAAAA;IACvD,MAAMM,YAAAA,GAAeC,aAAEC,MAAM,CAACH,SAASI,KAAK,CAAC,IAAI,CAAA,EAAG,GAAA,CAAA;IAEpD,OAAO,CAAA,EAAGP,KAAAA,CAAM,CAAC,EAAEC,OAAAA,CAAQ,CAAC,EAAEC,OAAAA,CAAQ,CAAC,EAAEE,YAAAA,CAAAA,CAAc;AACzD,CAAA;AAEA,MAAMI,YAAY,CAACb,KAAAA,GAAAA;AACjB,IAAA,IAAIJ,OAAOI,KAAAA,CAAAA,EAAQ;QACjB,OAAOF,gBAAAA,CAAMG,MAAM,CAACD,KAAAA,EAAO,YAAA,CAAA;AAC7B,IAAA;IAEA,IAAI,OAAOA,UAAU,QAAA,EAAU;AAC7B,QAAA,MAAM,IAAIE,KAAAA,CAAM,CAAC,yBAAyB,EAAE,OAAOF,KAAAA,CAAAA,CAAO,CAAA;AAC5D,IAAA;IAEA,IAAI;QACF,MAAMc,IAAAA,GAAOhB,gBAAAA,CAAMiB,QAAQ,CAACf,KAAAA,CAAAA;QAE5B,IAAIF,gBAAAA,CAAMkB,OAAO,CAACF,IAAAA,CAAAA,EAAO,OAAOhB,gBAAAA,CAAMG,MAAM,CAACa,IAAAA,EAAM,YAAA,CAAA;AAEnD,QAAA,MAAM,IAAIZ,KAAAA,CAAM,CAAC,+CAA+C,CAAC,CAAA;AACnE,IAAA,CAAA,CAAE,OAAM;AACN,QAAA,MAAM,IAAIA,KAAAA,CAAM,CAAC,+CAA+C,CAAC,CAAA;AACnE,IAAA;AACF,CAAA;AAEA,MAAMe,2BAA2B,CAACjB,KAAAA,GAAAA;AAChC,IAAA,IAAIJ,OAAOI,KAAAA,CAAAA,EAAQ;QACjB,OAAOA,KAAAA;AACT,IAAA;IAEA,IAAI,OAAOA,UAAU,QAAA,EAAU;AAC7B,QAAA,MAAM,IAAIE,KAAAA,CAAM,CAAC,yBAAyB,EAAE,OAAOF,KAAAA,CAAAA,CAAO,CAAA;AAC5D,IAAA;IAEA,IAAI;QACF,MAAMc,IAAAA,GAAOhB,gBAAAA,CAAMiB,QAAQ,CAACf,KAAAA,CAAAA;AAC5B,QAAA,IAAIF,gBAAAA,CAAMkB,OAAO,CAACF,IAAAA,CAAAA,EAAO,OAAOA,IAAAA;AAEhC,QAAA,MAAMI,gBAAgBpB,gBAAAA,CAAMqB,KAAK,CAACnB,KAAAA,EAAO,KAAK,IAAIoB,IAAAA,EAAAA,CAAAA;AAClD,QAAA,IAAItB,gBAAAA,CAAMkB,OAAO,CAACE,aAAAA,CAAAA,EAAgB,OAAOA,aAAAA;AAEzC,QAAA,MAAM,IAAIhB,KAAAA,CAAM,CAAC,mDAAmD,CAAC,CAAA;AACvE,IAAA,CAAA,CAAE,OAAM;AACN,QAAA,MAAM,IAAIA,KAAAA,CAAM,CAAC,mDAAmD,CAAC,CAAA;AACvE,IAAA;AACF,CAAA;AAoBA,MAAMmB,YAAAA,GAAe,CAACrB,KAAAA,EAAgBsB,OAAAA,GAAAA;AACpC,IAAA,MAAM,EAAEC,SAAAA,GAAY,KAAK,EAAE,GAAGD,OAAAA;IAE9B,IAAI,OAAOtB,UAAU,SAAA,EAAW;QAC9B,OAAOA,KAAAA;AACT,IAAA;AAEA,IAAA,IAAI,OAAOA,KAAAA,KAAU,QAAA,IAAY,OAAOA,UAAU,QAAA,EAAU;QAC1D,IAAI;AAAC,YAAA,MAAA;AAAQ,YAAA,GAAA;AAAK,YAAA,GAAA;AAAK,YAAA;SAAE,CAACwB,QAAQ,CAACxB,KAAAA,CAAAA,EAAQ;YACzC,OAAO,IAAA;AACT,QAAA;QAEA,IAAI;AAAC,YAAA,OAAA;AAAS,YAAA,GAAA;AAAK,YAAA,GAAA;AAAK,YAAA;SAAE,CAACwB,QAAQ,CAACxB,KAAAA,CAAAA,EAAQ;YAC1C,OAAO,KAAA;AACT,QAAA;AACF,IAAA;AAEA,IAAA,IAAIuB,SAAAA,EAAW;AACb,QAAA,OAAOE,OAAAA,CAAQzB,KAAAA,CAAAA;AACjB,IAAA;AAEA,IAAA,MAAM,IAAIE,KAAAA,CAAM,gEAAA,CAAA;AAClB,CAAA;AAEA;;IAGA,MAAMwB,YAAY,CAA6BJ,OAAAA,GAAAA;AAC7C,IAAA,MAAM,EAAEK,IAAI,EAAE3B,KAAK,EAAEuB,SAAS,EAAE,GAAGD,OAAAA;IAEnC,OAAQK,IAAAA;QACN,KAAK,SAAA;AACH,YAAA,OAAON,aAAarB,KAAAA,EAAO;AAAEuB,gBAAAA;AAAU,aAAA,CAAA;QACzC,KAAK,SAAA;QACL,KAAK,YAAA;QACL,KAAK,OAAA;QACL,KAAK,SAAA;AAAW,YAAA;gBACd,OAAOb,YAAAA,CAAEkB,QAAQ,CAAC5B,KAAAA,CAAAA;AACpB,YAAA;QACA,KAAK,MAAA;AAAQ,YAAA;AACX,gBAAA,OAAOD,SAAAA,CAAUC,KAAAA,CAAAA;AACnB,YAAA;QACA,KAAK,MAAA;AAAQ,YAAA;AACX,gBAAA,OAAOa,SAAAA,CAAUb,KAAAA,CAAAA;AACnB,YAAA;QACA,KAAK,WAAA;QACL,KAAK,UAAA;AAAY,YAAA;AACf,gBAAA,OAAOiB,wBAAAA,CAAyBjB,KAAAA,CAAAA;AAClC,YAAA;AACA,QAAA;YACE,OAAOA,KAAAA;AACX;AACF;;;;"}
1
+ {"version":3,"file":"parse-type.js","sources":["../src/parse-type.ts"],"sourcesContent":["import * as _ from 'lodash';\nimport * as dates from 'date-fns';\n\nconst timeRegex = /^(2[0-3]|[01][0-9]):([0-5][0-9]):([0-5][0-9])(.[0-9]{1,3})?$/;\n\nconst isDate = (v: unknown): v is Date => {\n return dates.isDate(v);\n};\n\nconst parseTime = (value: unknown): string => {\n if (isDate(value)) {\n return dates.format(value, 'HH:mm:ss.SSS');\n }\n\n if (typeof value !== 'string') {\n throw new Error(`Expected a string, got a ${typeof value}`);\n }\n const result = value.match(timeRegex);\n\n if (result === null) {\n throw new Error('Invalid time format, expected HH:mm:ss.SSS');\n }\n\n const [, hours, minutes, seconds, fraction = '.000'] = result;\n const fractionPart = _.padEnd(fraction.slice(1), 3, '0');\n\n return `${hours}:${minutes}:${seconds}.${fractionPart}`;\n};\n\nconst parseDate = (value: unknown) => {\n if (isDate(value)) {\n return dates.format(value, 'yyyy-MM-dd');\n }\n\n if (typeof value !== 'string') {\n throw new Error(`Expected a string, got a ${typeof value}`);\n }\n\n try {\n const date = dates.parseISO(value);\n\n if (dates.isValid(date)) return dates.format(date, 'yyyy-MM-dd');\n\n throw new Error(`Invalid format, expected an ISO compatible date`);\n } catch {\n throw new Error(`Invalid format, expected an ISO compatible date`);\n }\n};\n\nconst parseDateTimeOrTimestamp = (value: unknown) => {\n if (isDate(value)) {\n return value;\n }\n\n if (typeof value !== 'string') {\n throw new Error(`Expected a string, got a ${typeof value}`);\n }\n\n try {\n const date = dates.parseISO(value);\n if (dates.isValid(date)) return date;\n\n const milliUnixDate = dates.parse(value, 'T', new Date());\n if (dates.isValid(milliUnixDate)) return milliUnixDate;\n\n throw new Error(`Invalid format, expected a timestamp or an ISO date`);\n } catch {\n throw new Error(`Invalid format, expected a timestamp or an ISO date`);\n }\n};\n\ntype TypeMap = {\n boolean: boolean;\n integer: number;\n biginteger: number;\n float: number;\n decimal: number;\n time: string;\n date: string;\n timestamp: Date;\n datetime: Date;\n};\n\nexport interface ParseTypeOptions<T extends keyof TypeMap> {\n type: T;\n value: unknown;\n forceCast?: boolean;\n}\n\n/**\n * Hoisted out of `parseBoolean`, which allocated both of these arrays on every call.\n * Query validation calls it once per node of the populate tree of every request, which\n * made those two throwaway allocations one of the largest single sources of GC pressure\n * in a read: 4.3% of on-CPU time in a profiled LaunchPad run.\n */\nconst TRUTHY_INPUTS: ReadonlyArray<string | number> = ['true', 't', '1', 1];\nconst FALSY_INPUTS: ReadonlyArray<string | number> = ['false', 'f', '0', 0];\n\n/**\n * Whether `parseBoolean` would accept this value without `forceCast`.\n *\n * Exists so callers can ask the question without using an exception as control flow.\n * Query validation asked it once per populate key by calling `parseType` inside a\n * `try`/`catch`, so every key that is not a boolean keyword — which is nearly all of\n * them — built an Error and captured a stack trace only to discard it. Stack capture is\n * the expensive part, and it made this the second hottest function in a read.\n *\n * Kept in lockstep with `parseBoolean`'s accept conditions below.\n */\nconst isBooleanLike = (value: unknown): boolean => {\n if (typeof value === 'boolean') {\n return true;\n }\n\n if (typeof value === 'string' || typeof value === 'number') {\n return TRUTHY_INPUTS.includes(value) || FALSY_INPUTS.includes(value);\n }\n\n return false;\n};\n\nconst parseBoolean = (value: unknown, options: { forceCast?: boolean }): boolean => {\n const { forceCast = false } = options;\n\n if (typeof value === 'boolean') {\n return value;\n }\n\n if (typeof value === 'string' || typeof value === 'number') {\n if (TRUTHY_INPUTS.includes(value)) {\n return true;\n }\n\n if (FALSY_INPUTS.includes(value)) {\n return false;\n }\n }\n\n if (forceCast) {\n return Boolean(value);\n }\n\n throw new Error('Invalid boolean input. Expected \"t\",\"1\",\"true\",\"false\",\"0\",\"f\"');\n};\n\n/**\n * Cast basic values based on attribute type\n */\nconst parseType = <Type extends keyof TypeMap>(options: ParseTypeOptions<Type>): TypeMap[Type] => {\n const { type, value, forceCast } = options;\n\n switch (type) {\n case 'boolean':\n return parseBoolean(value, { forceCast }) as TypeMap[Type];\n case 'integer':\n case 'biginteger':\n case 'float':\n case 'decimal': {\n return _.toNumber(value) as TypeMap[Type];\n }\n case 'time': {\n return parseTime(value) as TypeMap[Type];\n }\n case 'date': {\n return parseDate(value) as TypeMap[Type];\n }\n case 'timestamp':\n case 'datetime': {\n return parseDateTimeOrTimestamp(value) as TypeMap[Type];\n }\n default:\n return value as TypeMap[Type];\n }\n};\n\nexport { isBooleanLike };\nexport default parseType;\n"],"names":["timeRegex","isDate","v","dates","parseTime","value","format","Error","result","match","hours","minutes","seconds","fraction","fractionPart","_","padEnd","slice","parseDate","date","parseISO","isValid","parseDateTimeOrTimestamp","milliUnixDate","parse","Date","TRUTHY_INPUTS","FALSY_INPUTS","isBooleanLike","includes","parseBoolean","options","forceCast","Boolean","parseType","type","toNumber"],"mappings":"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"}
@@ -52,26 +52,52 @@ const parseDateTimeOrTimestamp = (value)=>{
52
52
  throw new Error(`Invalid format, expected a timestamp or an ISO date`);
53
53
  }
54
54
  };
55
+ /**
56
+ * Hoisted out of `parseBoolean`, which allocated both of these arrays on every call.
57
+ * Query validation calls it once per node of the populate tree of every request, which
58
+ * made those two throwaway allocations one of the largest single sources of GC pressure
59
+ * in a read: 4.3% of on-CPU time in a profiled LaunchPad run.
60
+ */ const TRUTHY_INPUTS = [
61
+ 'true',
62
+ 't',
63
+ '1',
64
+ 1
65
+ ];
66
+ const FALSY_INPUTS = [
67
+ 'false',
68
+ 'f',
69
+ '0',
70
+ 0
71
+ ];
72
+ /**
73
+ * Whether `parseBoolean` would accept this value without `forceCast`.
74
+ *
75
+ * Exists so callers can ask the question without using an exception as control flow.
76
+ * Query validation asked it once per populate key by calling `parseType` inside a
77
+ * `try`/`catch`, so every key that is not a boolean keyword — which is nearly all of
78
+ * them — built an Error and captured a stack trace only to discard it. Stack capture is
79
+ * the expensive part, and it made this the second hottest function in a read.
80
+ *
81
+ * Kept in lockstep with `parseBoolean`'s accept conditions below.
82
+ */ const isBooleanLike = (value)=>{
83
+ if (typeof value === 'boolean') {
84
+ return true;
85
+ }
86
+ if (typeof value === 'string' || typeof value === 'number') {
87
+ return TRUTHY_INPUTS.includes(value) || FALSY_INPUTS.includes(value);
88
+ }
89
+ return false;
90
+ };
55
91
  const parseBoolean = (value, options)=>{
56
92
  const { forceCast = false } = options;
57
93
  if (typeof value === 'boolean') {
58
94
  return value;
59
95
  }
60
96
  if (typeof value === 'string' || typeof value === 'number') {
61
- if ([
62
- 'true',
63
- 't',
64
- '1',
65
- 1
66
- ].includes(value)) {
97
+ if (TRUTHY_INPUTS.includes(value)) {
67
98
  return true;
68
99
  }
69
- if ([
70
- 'false',
71
- 'f',
72
- '0',
73
- 0
74
- ].includes(value)) {
100
+ if (FALSY_INPUTS.includes(value)) {
75
101
  return false;
76
102
  }
77
103
  }
@@ -114,5 +140,5 @@ const parseBoolean = (value, options)=>{
114
140
  }
115
141
  };
116
142
 
117
- export { parseType as default };
143
+ export { parseType as default, isBooleanLike };
118
144
  //# sourceMappingURL=parse-type.mjs.map
@@ -1 +1 @@
1
- {"version":3,"file":"parse-type.mjs","sources":["../src/parse-type.ts"],"sourcesContent":["import * as _ from 'lodash';\nimport * as dates from 'date-fns';\n\nconst timeRegex = /^(2[0-3]|[01][0-9]):([0-5][0-9]):([0-5][0-9])(.[0-9]{1,3})?$/;\n\nconst isDate = (v: unknown): v is Date => {\n return dates.isDate(v);\n};\n\nconst parseTime = (value: unknown): string => {\n if (isDate(value)) {\n return dates.format(value, 'HH:mm:ss.SSS');\n }\n\n if (typeof value !== 'string') {\n throw new Error(`Expected a string, got a ${typeof value}`);\n }\n const result = value.match(timeRegex);\n\n if (result === null) {\n throw new Error('Invalid time format, expected HH:mm:ss.SSS');\n }\n\n const [, hours, minutes, seconds, fraction = '.000'] = result;\n const fractionPart = _.padEnd(fraction.slice(1), 3, '0');\n\n return `${hours}:${minutes}:${seconds}.${fractionPart}`;\n};\n\nconst parseDate = (value: unknown) => {\n if (isDate(value)) {\n return dates.format(value, 'yyyy-MM-dd');\n }\n\n if (typeof value !== 'string') {\n throw new Error(`Expected a string, got a ${typeof value}`);\n }\n\n try {\n const date = dates.parseISO(value);\n\n if (dates.isValid(date)) return dates.format(date, 'yyyy-MM-dd');\n\n throw new Error(`Invalid format, expected an ISO compatible date`);\n } catch {\n throw new Error(`Invalid format, expected an ISO compatible date`);\n }\n};\n\nconst parseDateTimeOrTimestamp = (value: unknown) => {\n if (isDate(value)) {\n return value;\n }\n\n if (typeof value !== 'string') {\n throw new Error(`Expected a string, got a ${typeof value}`);\n }\n\n try {\n const date = dates.parseISO(value);\n if (dates.isValid(date)) return date;\n\n const milliUnixDate = dates.parse(value, 'T', new Date());\n if (dates.isValid(milliUnixDate)) return milliUnixDate;\n\n throw new Error(`Invalid format, expected a timestamp or an ISO date`);\n } catch {\n throw new Error(`Invalid format, expected a timestamp or an ISO date`);\n }\n};\n\ntype TypeMap = {\n boolean: boolean;\n integer: number;\n biginteger: number;\n float: number;\n decimal: number;\n time: string;\n date: string;\n timestamp: Date;\n datetime: Date;\n};\n\nexport interface ParseTypeOptions<T extends keyof TypeMap> {\n type: T;\n value: unknown;\n forceCast?: boolean;\n}\n\nconst parseBoolean = (value: unknown, options: { forceCast?: boolean }): boolean => {\n const { forceCast = false } = options;\n\n if (typeof value === 'boolean') {\n return value;\n }\n\n if (typeof value === 'string' || typeof value === 'number') {\n if (['true', 't', '1', 1].includes(value)) {\n return true;\n }\n\n if (['false', 'f', '0', 0].includes(value)) {\n return false;\n }\n }\n\n if (forceCast) {\n return Boolean(value);\n }\n\n throw new Error('Invalid boolean input. Expected \"t\",\"1\",\"true\",\"false\",\"0\",\"f\"');\n};\n\n/**\n * Cast basic values based on attribute type\n */\nconst parseType = <Type extends keyof TypeMap>(options: ParseTypeOptions<Type>): TypeMap[Type] => {\n const { type, value, forceCast } = options;\n\n switch (type) {\n case 'boolean':\n return parseBoolean(value, { forceCast }) as TypeMap[Type];\n case 'integer':\n case 'biginteger':\n case 'float':\n case 'decimal': {\n return _.toNumber(value) as TypeMap[Type];\n }\n case 'time': {\n return parseTime(value) as TypeMap[Type];\n }\n case 'date': {\n return parseDate(value) as TypeMap[Type];\n }\n case 'timestamp':\n case 'datetime': {\n return parseDateTimeOrTimestamp(value) as TypeMap[Type];\n }\n default:\n return value as TypeMap[Type];\n }\n};\n\nexport default parseType;\n"],"names":["timeRegex","isDate","v","dates","parseTime","value","format","Error","result","match","hours","minutes","seconds","fraction","fractionPart","_","padEnd","slice","parseDate","date","parseISO","isValid","parseDateTimeOrTimestamp","milliUnixDate","parse","Date","parseBoolean","options","forceCast","includes","Boolean","parseType","type","toNumber"],"mappings":"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"}
1
+ {"version":3,"file":"parse-type.mjs","sources":["../src/parse-type.ts"],"sourcesContent":["import * as _ from 'lodash';\nimport * as dates from 'date-fns';\n\nconst timeRegex = /^(2[0-3]|[01][0-9]):([0-5][0-9]):([0-5][0-9])(.[0-9]{1,3})?$/;\n\nconst isDate = (v: unknown): v is Date => {\n return dates.isDate(v);\n};\n\nconst parseTime = (value: unknown): string => {\n if (isDate(value)) {\n return dates.format(value, 'HH:mm:ss.SSS');\n }\n\n if (typeof value !== 'string') {\n throw new Error(`Expected a string, got a ${typeof value}`);\n }\n const result = value.match(timeRegex);\n\n if (result === null) {\n throw new Error('Invalid time format, expected HH:mm:ss.SSS');\n }\n\n const [, hours, minutes, seconds, fraction = '.000'] = result;\n const fractionPart = _.padEnd(fraction.slice(1), 3, '0');\n\n return `${hours}:${minutes}:${seconds}.${fractionPart}`;\n};\n\nconst parseDate = (value: unknown) => {\n if (isDate(value)) {\n return dates.format(value, 'yyyy-MM-dd');\n }\n\n if (typeof value !== 'string') {\n throw new Error(`Expected a string, got a ${typeof value}`);\n }\n\n try {\n const date = dates.parseISO(value);\n\n if (dates.isValid(date)) return dates.format(date, 'yyyy-MM-dd');\n\n throw new Error(`Invalid format, expected an ISO compatible date`);\n } catch {\n throw new Error(`Invalid format, expected an ISO compatible date`);\n }\n};\n\nconst parseDateTimeOrTimestamp = (value: unknown) => {\n if (isDate(value)) {\n return value;\n }\n\n if (typeof value !== 'string') {\n throw new Error(`Expected a string, got a ${typeof value}`);\n }\n\n try {\n const date = dates.parseISO(value);\n if (dates.isValid(date)) return date;\n\n const milliUnixDate = dates.parse(value, 'T', new Date());\n if (dates.isValid(milliUnixDate)) return milliUnixDate;\n\n throw new Error(`Invalid format, expected a timestamp or an ISO date`);\n } catch {\n throw new Error(`Invalid format, expected a timestamp or an ISO date`);\n }\n};\n\ntype TypeMap = {\n boolean: boolean;\n integer: number;\n biginteger: number;\n float: number;\n decimal: number;\n time: string;\n date: string;\n timestamp: Date;\n datetime: Date;\n};\n\nexport interface ParseTypeOptions<T extends keyof TypeMap> {\n type: T;\n value: unknown;\n forceCast?: boolean;\n}\n\n/**\n * Hoisted out of `parseBoolean`, which allocated both of these arrays on every call.\n * Query validation calls it once per node of the populate tree of every request, which\n * made those two throwaway allocations one of the largest single sources of GC pressure\n * in a read: 4.3% of on-CPU time in a profiled LaunchPad run.\n */\nconst TRUTHY_INPUTS: ReadonlyArray<string | number> = ['true', 't', '1', 1];\nconst FALSY_INPUTS: ReadonlyArray<string | number> = ['false', 'f', '0', 0];\n\n/**\n * Whether `parseBoolean` would accept this value without `forceCast`.\n *\n * Exists so callers can ask the question without using an exception as control flow.\n * Query validation asked it once per populate key by calling `parseType` inside a\n * `try`/`catch`, so every key that is not a boolean keyword — which is nearly all of\n * them — built an Error and captured a stack trace only to discard it. Stack capture is\n * the expensive part, and it made this the second hottest function in a read.\n *\n * Kept in lockstep with `parseBoolean`'s accept conditions below.\n */\nconst isBooleanLike = (value: unknown): boolean => {\n if (typeof value === 'boolean') {\n return true;\n }\n\n if (typeof value === 'string' || typeof value === 'number') {\n return TRUTHY_INPUTS.includes(value) || FALSY_INPUTS.includes(value);\n }\n\n return false;\n};\n\nconst parseBoolean = (value: unknown, options: { forceCast?: boolean }): boolean => {\n const { forceCast = false } = options;\n\n if (typeof value === 'boolean') {\n return value;\n }\n\n if (typeof value === 'string' || typeof value === 'number') {\n if (TRUTHY_INPUTS.includes(value)) {\n return true;\n }\n\n if (FALSY_INPUTS.includes(value)) {\n return false;\n }\n }\n\n if (forceCast) {\n return Boolean(value);\n }\n\n throw new Error('Invalid boolean input. Expected \"t\",\"1\",\"true\",\"false\",\"0\",\"f\"');\n};\n\n/**\n * Cast basic values based on attribute type\n */\nconst parseType = <Type extends keyof TypeMap>(options: ParseTypeOptions<Type>): TypeMap[Type] => {\n const { type, value, forceCast } = options;\n\n switch (type) {\n case 'boolean':\n return parseBoolean(value, { forceCast }) as TypeMap[Type];\n case 'integer':\n case 'biginteger':\n case 'float':\n case 'decimal': {\n return _.toNumber(value) as TypeMap[Type];\n }\n case 'time': {\n return parseTime(value) as TypeMap[Type];\n }\n case 'date': {\n return parseDate(value) as TypeMap[Type];\n }\n case 'timestamp':\n case 'datetime': {\n return parseDateTimeOrTimestamp(value) as TypeMap[Type];\n }\n default:\n return value as TypeMap[Type];\n }\n};\n\nexport { isBooleanLike };\nexport default parseType;\n"],"names":["timeRegex","isDate","v","dates","parseTime","value","format","Error","result","match","hours","minutes","seconds","fraction","fractionPart","_","padEnd","slice","parseDate","date","parseISO","isValid","parseDateTimeOrTimestamp","milliUnixDate","parse","Date","TRUTHY_INPUTS","FALSY_INPUTS","isBooleanLike","includes","parseBoolean","options","forceCast","Boolean","parseType","type","toNumber"],"mappings":"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"}
@@ -1 +1 @@
1
- {"version":3,"file":"sanitizers.d.ts","sourceRoot":"","sources":["../../src/sanitize/sanitizers.ts"],"names":[],"mappings":"AAsBA,OAAO,KAAK,EAAE,KAAK,EAAE,IAAI,EAAE,MAAM,UAAU,CAAC;AAC5C,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,qBAAqB,CAAC;AAElD,UAAU,OAAO;IACf,MAAM,EAAE,KAAK,CAAC;IACd,QAAQ,EAAE,CAAC,KAAK,EAAE,MAAM,KAAK,KAAK,CAAC;IACnC,MAAM,CAAC,EAAE,MAAM,CAAC;CACjB;AAID,QAAA,MAAM,iBAAiB,GAAI,KAAK,OAAO,MAAY,QAAQ,IAAI,kBAM9D,CAAC;AAEF,QAAA,MAAM,qBAAqB,GAAU,KAAK,OAAO,EAAE,QAAQ,IAAI,kBAa9D,CAAC;AAEF,QAAA,MAAM,sBAAsB,uEAsC1B,CAAC;AAEH,QAAA,MAAM,mBAAmB,uEAuCvB,CAAC;AAEH,QAAA,MAAM,qBAAqB,uEAyBzB,CAAC;AAEH,QAAA,MAAM,uBAAuB,uEAiC3B,CAAC;AAEH,OAAO,EACL,iBAAiB,EACjB,qBAAqB,EACrB,sBAAsB,EACtB,mBAAmB,EACnB,qBAAqB,EACrB,uBAAuB,GACxB,CAAC"}
1
+ {"version":3,"file":"sanitizers.d.ts","sourceRoot":"","sources":["../../src/sanitize/sanitizers.ts"],"names":[],"mappings":"AAsBA,OAAO,KAAK,EAAE,KAAK,EAAE,IAAI,EAAE,MAAM,UAAU,CAAC;AAC5C,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,qBAAqB,CAAC;AAElD,UAAU,OAAO;IACf,MAAM,EAAE,KAAK,CAAC;IACd,QAAQ,EAAE,CAAC,KAAK,EAAE,MAAM,KAAK,KAAK,CAAC;IACnC,MAAM,CAAC,EAAE,MAAM,CAAC;CACjB;AAID,QAAA,MAAM,iBAAiB,GAAI,KAAK,OAAO,MAAY,QAAQ,IAAI,kBAM9D,CAAC;AAEF,QAAA,MAAM,qBAAqB,GAAU,KAAK,OAAO,EAAE,QAAQ,IAAI,kBAe9D,CAAC;AAEF,QAAA,MAAM,sBAAsB,uEAsC1B,CAAC;AAEH,QAAA,MAAM,mBAAmB,uEAuCvB,CAAC;AAEH,QAAA,MAAM,qBAAqB,uEAyBzB,CAAC;AAEH,QAAA,MAAM,uBAAuB,uEAiC3B,CAAC;AAEH,OAAO,EACL,iBAAiB,EACjB,qBAAqB,EACrB,sBAAsB,EACtB,mBAAmB,EACnB,qBAAqB,EACrB,uBAAuB,GACxB,CAAC"}
@@ -27,9 +27,11 @@ const defaultSanitizeOutput = async (ctx, entity)=>{
27
27
  if (!ctx.schema) {
28
28
  throw new Error('Missing schema in defaultSanitizeOutput');
29
29
  }
30
- return traverseEntity((...args)=>{
31
- removePassword(...args);
32
- removePrivate(...args);
30
+ // Named parameters rather than a rest-spread: this runs once per key, per node, per
31
+ // entity, and `(...args)` allocated a fresh array on every call.
32
+ return traverseEntity((visitorOptions, visitorUtils)=>{
33
+ removePassword(visitorOptions, visitorUtils);
34
+ removePrivate(visitorOptions, visitorUtils);
33
35
  }, ctx, entity);
34
36
  };
35
37
  const defaultSanitizeFilters = fp.curry((ctx, filters)=>{
@@ -1 +1 @@
1
- {"version":3,"file":"sanitizers.js","sources":["../../src/sanitize/sanitizers.ts"],"sourcesContent":["import { curry, isEmpty, isNil, isArray, isPlainObject } from 'lodash/fp';\n\nimport { pipe as pipeAsync } from '../async';\nimport traverseEntity from '../traverse-entity';\nimport { isScalarAttribute, constants } from '../content-types';\n\nimport {\n traverseQueryFilters,\n traverseQuerySort,\n traverseQueryPopulate,\n traverseQueryFields,\n} from '../traverse';\n\nimport {\n removePassword,\n removePrivate,\n removeDynamicZones,\n removeMorphToRelations,\n expandWildcardPopulate,\n} from './visitors';\nimport { isOperator } from '../operators';\n\nimport type { Model, Data } from '../types';\nimport type { Parent } from '../traverse/factory';\n\ninterface Context {\n schema: Model;\n getModel: (model: string) => Model;\n parent?: Parent;\n}\n\nconst { ID_ATTRIBUTE, DOC_ID_ATTRIBUTE } = constants;\n\nconst sanitizePasswords = (ctx: Context) => async (entity: Data) => {\n if (!ctx.schema) {\n throw new Error('Missing schema in sanitizePasswords');\n }\n\n return traverseEntity(removePassword, ctx, entity);\n};\n\nconst defaultSanitizeOutput = async (ctx: Context, entity: Data) => {\n if (!ctx.schema) {\n throw new Error('Missing schema in defaultSanitizeOutput');\n }\n\n return traverseEntity(\n (...args) => {\n removePassword(...args);\n removePrivate(...args);\n },\n ctx,\n entity\n );\n};\n\nconst defaultSanitizeFilters = curry((ctx: Context, filters: unknown) => {\n if (!ctx.schema) {\n throw new Error('Missing schema in defaultSanitizeFilters');\n }\n\n return pipeAsync(\n // Remove keys that are not attributes or valid operators\n traverseQueryFilters(({ key, attribute }, { remove }) => {\n const isAttribute = !!attribute;\n\n // ID is not an attribute per se, so we need to make\n // an extra check to ensure we're not checking it\n if ([ID_ATTRIBUTE, DOC_ID_ATTRIBUTE].includes(key)) {\n return;\n }\n\n if (!isAttribute && !isOperator(key)) {\n remove(key);\n }\n }, ctx),\n // Remove dynamic zones from filters\n traverseQueryFilters(removeDynamicZones, ctx),\n // Remove morpTo relations from filters\n traverseQueryFilters(removeMorphToRelations, ctx),\n // Remove passwords from filters\n traverseQueryFilters(removePassword, ctx),\n // Remove private from filters\n traverseQueryFilters(removePrivate, ctx),\n // Remove empty plain objects and empty arrays. Do not use lodash isObject+isEmpty: built-ins with no\n // enumerable keys (Date, RegExp, boxed primitives, etc.) are \"empty\" and would wrongly drop valid operands.\n traverseQueryFilters(({ key, value }, { remove }) => {\n const isEmptyPlainObject = isPlainObject(value) && isEmpty(value);\n const isEmptyArrayOperand = isArray(value) && isEmpty(value);\n if (isEmptyPlainObject || isEmptyArrayOperand) {\n remove(key);\n }\n }, ctx)\n )(filters);\n});\n\nconst defaultSanitizeSort = curry((ctx: Context, sort: unknown) => {\n if (!ctx.schema) {\n throw new Error('Missing schema in defaultSanitizeSort');\n }\n\n return pipeAsync(\n // Remove non attribute keys\n traverseQuerySort(({ key, attribute }, { remove }) => {\n // ID is not an attribute per se, so we need to make\n // an extra check to ensure we're not checking it\n if ([ID_ATTRIBUTE, DOC_ID_ATTRIBUTE].includes(key)) {\n return;\n }\n\n if (!attribute) {\n remove(key);\n }\n }, ctx),\n // Remove dynamic zones from sort\n traverseQuerySort(removeDynamicZones, ctx),\n // Remove morpTo relations from sort\n traverseQuerySort(removeMorphToRelations, ctx),\n // Remove private from sort\n traverseQuerySort(removePrivate, ctx),\n // Remove passwords from filters\n traverseQuerySort(removePassword, ctx),\n // Remove keys for empty non-scalar values\n traverseQuerySort(({ key, attribute, value }, { remove }) => {\n // ID is not an attribute per se, so we need to make\n // an extra check to ensure we're not removing it\n if ([ID_ATTRIBUTE, DOC_ID_ATTRIBUTE].includes(key)) {\n return;\n }\n\n if (!isScalarAttribute(attribute) && isEmpty(value)) {\n remove(key);\n }\n }, ctx)\n )(sort);\n});\n\nconst defaultSanitizeFields = curry((ctx: Context, fields: unknown) => {\n if (!ctx.schema) {\n throw new Error('Missing schema in defaultSanitizeFields');\n }\n\n return pipeAsync(\n // Only keep scalar attributes\n traverseQueryFields(({ key, attribute }, { remove }) => {\n // ID is not an attribute per se, so we need to make\n // an extra check to ensure we're not checking it\n if ([ID_ATTRIBUTE, DOC_ID_ATTRIBUTE].includes(key)) {\n return;\n }\n\n if (isNil(attribute) || !isScalarAttribute(attribute)) {\n remove(key);\n }\n }, ctx),\n // Remove private fields\n traverseQueryFields(removePrivate, ctx),\n // Remove password fields\n traverseQueryFields(removePassword, ctx),\n // Remove nil values from fields array\n (value) => (isArray(value) ? value.filter((field) => !isNil(field)) : value)\n )(fields);\n});\n\nconst defaultSanitizePopulate = curry((ctx: Context, populate: unknown) => {\n if (!ctx.schema) {\n throw new Error('Missing schema in defaultSanitizePopulate');\n }\n\n return pipeAsync(\n traverseQueryPopulate(expandWildcardPopulate, ctx),\n traverseQueryPopulate(async ({ key, value, schema, attribute, getModel, path }, { set }) => {\n if (attribute) {\n return;\n }\n\n const parent = { key, path, schema, attribute } satisfies Parent;\n\n if (key === 'sort') {\n set(key, await defaultSanitizeSort({ schema, getModel, parent }, value));\n }\n\n if (key === 'filters') {\n set(key, await defaultSanitizeFilters({ schema, getModel, parent }, value));\n }\n\n if (key === 'fields') {\n set(key, await defaultSanitizeFields({ schema, getModel, parent }, value));\n }\n\n if (key === 'populate') {\n set(key, await defaultSanitizePopulate({ schema, getModel, parent }, value));\n }\n }, ctx),\n // Remove private fields\n traverseQueryPopulate(removePrivate, ctx)\n )(populate);\n});\n\nexport {\n sanitizePasswords,\n defaultSanitizeOutput,\n defaultSanitizeFilters,\n defaultSanitizeSort,\n defaultSanitizeFields,\n defaultSanitizePopulate,\n};\n"],"names":["ID_ATTRIBUTE","DOC_ID_ATTRIBUTE","constants","sanitizePasswords","ctx","entity","schema","Error","traverseEntity","removePassword","defaultSanitizeOutput","args","removePrivate","defaultSanitizeFilters","curry","filters","pipeAsync","traverseQueryFilters","key","attribute","remove","isAttribute","includes","isOperator","removeDynamicZones","removeMorphToRelations","value","isEmptyPlainObject","isPlainObject","isEmpty","isEmptyArrayOperand","isArray","defaultSanitizeSort","sort","traverseQuerySort","isScalarAttribute","defaultSanitizeFields","fields","traverseQueryFields","isNil","filter","field","defaultSanitizePopulate","populate","traverseQueryPopulate","expandWildcardPopulate","getModel","path","set","parent"],"mappings":"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"}
1
+ {"version":3,"file":"sanitizers.js","sources":["../../src/sanitize/sanitizers.ts"],"sourcesContent":["import { curry, isEmpty, isNil, isArray, isPlainObject } from 'lodash/fp';\n\nimport { pipe as pipeAsync } from '../async';\nimport traverseEntity from '../traverse-entity';\nimport { isScalarAttribute, constants } from '../content-types';\n\nimport {\n traverseQueryFilters,\n traverseQuerySort,\n traverseQueryPopulate,\n traverseQueryFields,\n} from '../traverse';\n\nimport {\n removePassword,\n removePrivate,\n removeDynamicZones,\n removeMorphToRelations,\n expandWildcardPopulate,\n} from './visitors';\nimport { isOperator } from '../operators';\n\nimport type { Model, Data } from '../types';\nimport type { Parent } from '../traverse/factory';\n\ninterface Context {\n schema: Model;\n getModel: (model: string) => Model;\n parent?: Parent;\n}\n\nconst { ID_ATTRIBUTE, DOC_ID_ATTRIBUTE } = constants;\n\nconst sanitizePasswords = (ctx: Context) => async (entity: Data) => {\n if (!ctx.schema) {\n throw new Error('Missing schema in sanitizePasswords');\n }\n\n return traverseEntity(removePassword, ctx, entity);\n};\n\nconst defaultSanitizeOutput = async (ctx: Context, entity: Data) => {\n if (!ctx.schema) {\n throw new Error('Missing schema in defaultSanitizeOutput');\n }\n\n // Named parameters rather than a rest-spread: this runs once per key, per node, per\n // entity, and `(...args)` allocated a fresh array on every call.\n return traverseEntity(\n (visitorOptions, visitorUtils) => {\n removePassword(visitorOptions, visitorUtils);\n removePrivate(visitorOptions, visitorUtils);\n },\n ctx,\n entity\n );\n};\n\nconst defaultSanitizeFilters = curry((ctx: Context, filters: unknown) => {\n if (!ctx.schema) {\n throw new Error('Missing schema in defaultSanitizeFilters');\n }\n\n return pipeAsync(\n // Remove keys that are not attributes or valid operators\n traverseQueryFilters(({ key, attribute }, { remove }) => {\n const isAttribute = !!attribute;\n\n // ID is not an attribute per se, so we need to make\n // an extra check to ensure we're not checking it\n if ([ID_ATTRIBUTE, DOC_ID_ATTRIBUTE].includes(key)) {\n return;\n }\n\n if (!isAttribute && !isOperator(key)) {\n remove(key);\n }\n }, ctx),\n // Remove dynamic zones from filters\n traverseQueryFilters(removeDynamicZones, ctx),\n // Remove morpTo relations from filters\n traverseQueryFilters(removeMorphToRelations, ctx),\n // Remove passwords from filters\n traverseQueryFilters(removePassword, ctx),\n // Remove private from filters\n traverseQueryFilters(removePrivate, ctx),\n // Remove empty plain objects and empty arrays. Do not use lodash isObject+isEmpty: built-ins with no\n // enumerable keys (Date, RegExp, boxed primitives, etc.) are \"empty\" and would wrongly drop valid operands.\n traverseQueryFilters(({ key, value }, { remove }) => {\n const isEmptyPlainObject = isPlainObject(value) && isEmpty(value);\n const isEmptyArrayOperand = isArray(value) && isEmpty(value);\n if (isEmptyPlainObject || isEmptyArrayOperand) {\n remove(key);\n }\n }, ctx)\n )(filters);\n});\n\nconst defaultSanitizeSort = curry((ctx: Context, sort: unknown) => {\n if (!ctx.schema) {\n throw new Error('Missing schema in defaultSanitizeSort');\n }\n\n return pipeAsync(\n // Remove non attribute keys\n traverseQuerySort(({ key, attribute }, { remove }) => {\n // ID is not an attribute per se, so we need to make\n // an extra check to ensure we're not checking it\n if ([ID_ATTRIBUTE, DOC_ID_ATTRIBUTE].includes(key)) {\n return;\n }\n\n if (!attribute) {\n remove(key);\n }\n }, ctx),\n // Remove dynamic zones from sort\n traverseQuerySort(removeDynamicZones, ctx),\n // Remove morpTo relations from sort\n traverseQuerySort(removeMorphToRelations, ctx),\n // Remove private from sort\n traverseQuerySort(removePrivate, ctx),\n // Remove passwords from filters\n traverseQuerySort(removePassword, ctx),\n // Remove keys for empty non-scalar values\n traverseQuerySort(({ key, attribute, value }, { remove }) => {\n // ID is not an attribute per se, so we need to make\n // an extra check to ensure we're not removing it\n if ([ID_ATTRIBUTE, DOC_ID_ATTRIBUTE].includes(key)) {\n return;\n }\n\n if (!isScalarAttribute(attribute) && isEmpty(value)) {\n remove(key);\n }\n }, ctx)\n )(sort);\n});\n\nconst defaultSanitizeFields = curry((ctx: Context, fields: unknown) => {\n if (!ctx.schema) {\n throw new Error('Missing schema in defaultSanitizeFields');\n }\n\n return pipeAsync(\n // Only keep scalar attributes\n traverseQueryFields(({ key, attribute }, { remove }) => {\n // ID is not an attribute per se, so we need to make\n // an extra check to ensure we're not checking it\n if ([ID_ATTRIBUTE, DOC_ID_ATTRIBUTE].includes(key)) {\n return;\n }\n\n if (isNil(attribute) || !isScalarAttribute(attribute)) {\n remove(key);\n }\n }, ctx),\n // Remove private fields\n traverseQueryFields(removePrivate, ctx),\n // Remove password fields\n traverseQueryFields(removePassword, ctx),\n // Remove nil values from fields array\n (value) => (isArray(value) ? value.filter((field) => !isNil(field)) : value)\n )(fields);\n});\n\nconst defaultSanitizePopulate = curry((ctx: Context, populate: unknown) => {\n if (!ctx.schema) {\n throw new Error('Missing schema in defaultSanitizePopulate');\n }\n\n return pipeAsync(\n traverseQueryPopulate(expandWildcardPopulate, ctx),\n traverseQueryPopulate(async ({ key, value, schema, attribute, getModel, path }, { set }) => {\n if (attribute) {\n return;\n }\n\n const parent = { key, path, schema, attribute } satisfies Parent;\n\n if (key === 'sort') {\n set(key, await defaultSanitizeSort({ schema, getModel, parent }, value));\n }\n\n if (key === 'filters') {\n set(key, await defaultSanitizeFilters({ schema, getModel, parent }, value));\n }\n\n if (key === 'fields') {\n set(key, await defaultSanitizeFields({ schema, getModel, parent }, value));\n }\n\n if (key === 'populate') {\n set(key, await defaultSanitizePopulate({ schema, getModel, parent }, value));\n }\n }, ctx),\n // Remove private fields\n traverseQueryPopulate(removePrivate, ctx)\n )(populate);\n});\n\nexport {\n sanitizePasswords,\n defaultSanitizeOutput,\n defaultSanitizeFilters,\n defaultSanitizeSort,\n defaultSanitizeFields,\n defaultSanitizePopulate,\n};\n"],"names":["ID_ATTRIBUTE","DOC_ID_ATTRIBUTE","constants","sanitizePasswords","ctx","entity","schema","Error","traverseEntity","removePassword","defaultSanitizeOutput","visitorOptions","visitorUtils","removePrivate","defaultSanitizeFilters","curry","filters","pipeAsync","traverseQueryFilters","key","attribute","remove","isAttribute","includes","isOperator","removeDynamicZones","removeMorphToRelations","value","isEmptyPlainObject","isPlainObject","isEmpty","isEmptyArrayOperand","isArray","defaultSanitizeSort","sort","traverseQuerySort","isScalarAttribute","defaultSanitizeFields","fields","traverseQueryFields","isNil","filter","field","defaultSanitizePopulate","populate","traverseQueryPopulate","expandWildcardPopulate","getModel","path","set","parent"],"mappings":"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"}