{"version":3,"file":"sort-schema.mjs","sources":["../../../../server/src/mcp/schemas/sort-schema.ts"],"sourcesContent":["import { z } from '@strapi/utils';\nimport type { Struct } from '@strapi/types';\n\n/** Attribute types considered scalar for sorting and filtering (excludes relations, components, media, json, blocks). */\nexport const SCALAR_ATTRIBUTE_TYPES = new Set([\n 'string',\n 'text',\n 'richtext',\n 'email',\n 'password',\n 'uid',\n 'integer',\n 'biginteger',\n 'decimal',\n 'float',\n 'boolean',\n 'date',\n 'datetime',\n 'time',\n 'timestamp',\n 'enumeration',\n]);\n\n/**\n * Returns the list of scalar attribute keys from a content type's attributes.\n * Relation, component, dynamiczone, media, json, and blocks are excluded because\n * they cannot be meaningfully sorted or filtered via simple operators.\n */\nexport const getScalarAttributeKeys = (\n attributes: Struct.SchemaAttributes,\n permittedFields?: Set | null\n): string[] => {\n let keys = Object.entries(attributes)\n .filter(\n ([, attr]) =>\n SCALAR_ATTRIBUTE_TYPES.has(attr.type) && (attr as { private?: boolean }).private !== true\n )\n .map(([key]) => key);\n\n if (permittedFields !== null && permittedFields !== undefined) {\n keys = keys.filter((key) => permittedFields.has(key));\n }\n\n return keys;\n};\n\n/**\n * Builds a per-content-type sort Zod schema constrained to the model's scalar fields.\n *\n * Supports all four Strapi sort notations:\n * - string: \"title:asc\"\n * - string[]: [\"title:asc\", \"createdAt:desc\"]\n * - object: { title: \"asc\" }\n * - object[]: [{ title: \"asc\" }, { createdAt: \"desc\" }]\n *\n * Object forms have their keys constrained to known scalar attribute names.\n * If the model has no scalar attributes, the schema is z.never() (sort not allowed).\n */\nexport const buildSortSchema = (\n attributes: Struct.SchemaAttributes,\n permittedFields?: Set | null\n): z.ZodTypeAny => {\n const scalarKeys = getScalarAttributeKeys(attributes, permittedFields);\n\n if (scalarKeys.length === 0) {\n return z.never();\n }\n\n const directionSchema = z.enum(['asc', 'desc']);\n const sortObjectSchema = z\n .object(Object.fromEntries(scalarKeys.map((key) => [key, directionSchema.optional()])))\n .strict();\n\n const sortStringPattern = /^([^:]+):(asc|desc)$/;\n const isPermittedSortString = (value: string): boolean => {\n const match = sortStringPattern.exec(value);\n if (match === null) {\n return true;\n }\n return scalarKeys.includes(match[1]);\n };\n\n const stringSortSchema = z.string().refine(isPermittedSortString, {\n message: `Sort field must be one of: ${scalarKeys.join(', ')}`,\n });\n\n return z\n .union([\n stringSortSchema,\n z.array(stringSortSchema),\n sortObjectSchema,\n z.array(sortObjectSchema),\n ])\n .optional()\n .describe(\n `Sort expression. String: \"field:asc\". Array: [\"field:asc\"]. Object: { field: \"asc\" }. ` +\n `Valid fields: ${scalarKeys.join(', ')}.`\n );\n};\n"],"names":["SCALAR_ATTRIBUTE_TYPES","Set","getScalarAttributeKeys","attributes","permittedFields","keys","Object","entries","filter","attr","has","type","private","map","key","undefined","buildSortSchema","scalarKeys","length","z","never","directionSchema","enum","sortObjectSchema","object","fromEntries","optional","strict","sortStringPattern","isPermittedSortString","value","match","exec","includes","stringSortSchema","string","refine","message","join","union","array","describe"],"mappings":"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"}