{"version":3,"file":"custom-field.mjs","names":[],"sources":["../../../../../../src/libs/collection/custom-fields/fields/media/custom-field.ts"],"sourcesContent":["import z from \"zod\";\nimport type { ServiceResponse } from \"../../../../../types.js\";\nimport { copy } from \"../../../../i18n/index.js\";\nimport prefixGeneratedColName from \"../../../helpers/prefix-generated-column-name.js\";\nimport CustomField from \"../../custom-field.js\";\nimport type {\n\tCFConfig,\n\tCFProps,\n\tCFResponse,\n\tCustomFieldErrorItem,\n\tCustomFieldValidationError,\n\tGetSchemaDefinitionProps,\n\tSchemaDefinition,\n} from \"../../types.js\";\nimport keyToTitle from \"../../utils/key-to-title.js\";\nimport {\n\tclampRelationInputValue,\n\tnormalizeStoredRelationValues,\n} from \"../../utils/normalize-relation-values.js\";\nimport { validateRelationItemCount } from \"../../utils/relation-item-count-validation.js\";\nimport zodSafeParse from \"../../utils/zod-safe-parse.js\";\nimport { mediaFieldConfig } from \"./config.js\";\nimport type { MediaValidationData } from \"./types.js\";\n\nclass MediaCustomField extends CustomField<\"media\"> {\n\ttype = mediaFieldConfig.type;\n\tconfig;\n\tkey;\n\tprops;\n\tconstructor(key: string, props?: CFProps<\"media\">) {\n\t\tsuper();\n\t\tthis.key = key;\n\t\tthis.props = props;\n\t\tthis.config = {\n\t\t\tkey: this.key,\n\t\t\ttype: this.type,\n\t\t\tdetails: {\n\t\t\t\tlabel:\n\t\t\t\t\tthis.props?.details?.label ??\n\t\t\t\t\tcopy(`admin:fields.${this.type}.${this.key}.label`, {\n\t\t\t\t\t\tdefaultMessage: keyToTitle(this.key),\n\t\t\t\t\t}),\n\t\t\t\tsummary: this.props?.details?.summary,\n\t\t\t},\n\t\t\tlocalized: this.props?.localized ?? false,\n\t\t\tdefault: this.props?.default ?? [],\n\t\t\tindex: this.props?.index,\n\t\t\tmultiple: this.props?.multiple,\n\t\t\tui: {\n\t\t\t\thidden: this.props?.ui?.hidden,\n\t\t\t\tdisabled: this.props?.ui?.disabled,\n\t\t\t\tcondition: this.props?.ui?.condition,\n\t\t\t\twidth: this.props?.ui?.width,\n\t\t\t},\n\t\t\tvalidation: this.props?.validation,\n\t\t} satisfies CFConfig<\"media\">;\n\t}\n\toverride normalizeInputValue(value: unknown) {\n\t\treturn clampRelationInputValue(value, this.config.multiple);\n\t}\n\toverride get defaultValue(): unknown {\n\t\treturn normalizeStoredRelationValues(\n\t\t\tthis.config.default,\n\t\t\tthis.config.multiple,\n\t\t);\n\t}\n\toverride get errors(): {\n\t\tfieldType: CustomFieldErrorItem;\n\t\trequired: CustomFieldErrorItem;\n\t\tzod: CustomFieldErrorItem;\n\t} {\n\t\treturn {\n\t\t\t...super.errors,\n\t\t\trequired: {\n\t\t\t\tcondition: (value: unknown) =>\n\t\t\t\t\tvalue === undefined ||\n\t\t\t\t\tvalue === null ||\n\t\t\t\t\t(Array.isArray(value) && value.length === 0),\n\t\t\t\tmessage: copy(\"server:core.fields.validation.required\"),\n\t\t\t},\n\t\t};\n\t}\n\tgetSchemaDefinition(\n\t\tprops: GetSchemaDefinitionProps,\n\t): Awaited<ServiceResponse<SchemaDefinition>> {\n\t\treturn {\n\t\t\tdata: {\n\t\t\t\tcolumns: [\n\t\t\t\t\t{\n\t\t\t\t\t\tname: \"media_id\",\n\t\t\t\t\t\ttype: props.db.getDataType(\"integer\"),\n\t\t\t\t\t\tnullable: false,\n\t\t\t\t\t\tforeignKey: {\n\t\t\t\t\t\t\ttable: \"lucid_media\",\n\t\t\t\t\t\t\tcolumn: \"id\",\n\t\t\t\t\t\t\tonDelete: \"cascade\",\n\t\t\t\t\t\t},\n\t\t\t\t\t},\n\t\t\t\t],\n\t\t\t},\n\t\t\terror: undefined,\n\t\t};\n\t}\n\tformatResponseValue(value: unknown) {\n\t\treturn normalizeStoredRelationValues(\n\t\t\tvalue,\n\t\t\tthis.config.multiple,\n\t\t) satisfies CFResponse<\"media\">[\"value\"];\n\t}\n\toverride get relationValueColumn() {\n\t\treturn \"media_id\";\n\t}\n\toverride serializeRelationFieldValue(\n\t\tvalue: unknown,\n\t): Array<Record<string, unknown>> {\n\t\treturn normalizeStoredRelationValues(value, this.config.multiple).map(\n\t\t\t(mediaId) => ({\n\t\t\t\t[prefixGeneratedColName(\"media_id\")]: mediaId,\n\t\t\t}),\n\t\t);\n\t}\n\tuniqueValidation(value: unknown, refData?: MediaValidationData[]) {\n\t\tconst valueSchema = z.array(z.number());\n\t\tconst candidateValue = clampRelationInputValue(value, this.config.multiple);\n\t\tconst valueValidate = zodSafeParse(candidateValue, valueSchema);\n\t\tif (!valueValidate.valid) return valueValidate;\n\n\t\tconst normalizedValue = Array.isArray(candidateValue)\n\t\t\t? candidateValue.filter(\n\t\t\t\t\t(item): item is number => typeof item === \"number\",\n\t\t\t\t)\n\t\t\t: [];\n\t\tconst itemCountValidation = validateRelationItemCount({\n\t\t\tmultiple: this.config.multiple,\n\t\t\tlength: normalizedValue.length,\n\t\t\tvalidation: this.config.validation,\n\t\t});\n\t\tif (!itemCountValidation.valid) return itemCountValidation;\n\n\t\tconst errors: CustomFieldValidationError[] = [];\n\t\tfor (const [itemIndex, mediaId] of normalizedValue.entries()) {\n\t\t\tconst findMedia = refData?.find((m) => m.id === mediaId);\n\t\t\tif (findMedia === undefined) {\n\t\t\t\terrors.push({\n\t\t\t\t\titemIndex,\n\t\t\t\t\tmessage: copy(\"server:core.fields.media.validation.not.found\"),\n\t\t\t\t});\n\t\t\t\tcontinue;\n\t\t\t}\n\n\t\t\t// Check if value is in the options\n\t\t\tif (this.config.validation?.extensions?.length) {\n\t\t\t\tconst extension = findMedia.file_extension;\n\t\t\t\tif (!this.config.validation.extensions.includes(extension)) {\n\t\t\t\t\terrors.push({\n\t\t\t\t\t\titemIndex,\n\t\t\t\t\t\tmessage: copy(\n\t\t\t\t\t\t\t\"server:core.fields.media.validation.extension.invalid\",\n\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\tdata: {\n\t\t\t\t\t\t\t\t\textensions: this.config.validation.extensions.join(\", \"),\n\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t},\n\t\t\t\t\t\t),\n\t\t\t\t\t});\n\t\t\t\t}\n\t\t\t}\n\n\t\t\t// Check type\n\t\t\tif (this.config.validation?.type) {\n\t\t\t\tconst type = findMedia.type;\n\t\t\t\tif (!type) {\n\t\t\t\t\terrors.push({\n\t\t\t\t\t\titemIndex,\n\t\t\t\t\t\tmessage: copy(\"server:core.fields.media.validation.type.missing\"),\n\t\t\t\t\t});\n\t\t\t\t\tcontinue;\n\t\t\t\t}\n\n\t\t\t\tif (this.config.validation.type !== type) {\n\t\t\t\t\terrors.push({\n\t\t\t\t\t\titemIndex,\n\t\t\t\t\t\tmessage: copy(\"server:core.fields.media.validation.type.invalid\", {\n\t\t\t\t\t\t\tdata: {\n\t\t\t\t\t\t\t\ttype: this.config.validation.type,\n\t\t\t\t\t\t\t},\n\t\t\t\t\t\t}),\n\t\t\t\t\t});\n\t\t\t\t}\n\t\t\t}\n\n\t\t\t// Check width\n\t\t\tif (this.config.validation?.width && findMedia.type === \"image\") {\n\t\t\t\tconst width = findMedia.width;\n\t\t\t\tif (!width) {\n\t\t\t\t\terrors.push({\n\t\t\t\t\t\titemIndex,\n\t\t\t\t\t\tmessage: copy(\"server:core.fields.media.validation.width.missing\"),\n\t\t\t\t\t});\n\t\t\t\t\tcontinue;\n\t\t\t\t}\n\n\t\t\t\tif (\n\t\t\t\t\tthis.config.validation.width.min &&\n\t\t\t\t\twidth < this.config.validation.width.min\n\t\t\t\t) {\n\t\t\t\t\terrors.push({\n\t\t\t\t\t\titemIndex,\n\t\t\t\t\t\tmessage: copy(\"server:core.fields.media.validation.width.min\", {\n\t\t\t\t\t\t\tdata: {\n\t\t\t\t\t\t\t\tmin: this.config.validation.width.min,\n\t\t\t\t\t\t\t},\n\t\t\t\t\t\t}),\n\t\t\t\t\t});\n\t\t\t\t}\n\t\t\t\tif (\n\t\t\t\t\tthis.config.validation.width.max &&\n\t\t\t\t\twidth > this.config.validation.width.max\n\t\t\t\t) {\n\t\t\t\t\terrors.push({\n\t\t\t\t\t\titemIndex,\n\t\t\t\t\t\tmessage: copy(\"server:core.fields.media.validation.width.max\", {\n\t\t\t\t\t\t\tdata: {\n\t\t\t\t\t\t\t\tmax: this.config.validation.width.max,\n\t\t\t\t\t\t\t},\n\t\t\t\t\t\t}),\n\t\t\t\t\t});\n\t\t\t\t}\n\t\t\t}\n\n\t\t\t// Check height\n\t\t\tif (this.config.validation?.height && findMedia.type === \"image\") {\n\t\t\t\tconst height = findMedia.height;\n\t\t\t\tif (!height) {\n\t\t\t\t\terrors.push({\n\t\t\t\t\t\titemIndex,\n\t\t\t\t\t\tmessage: copy(\"server:core.fields.media.validation.height.missing\"),\n\t\t\t\t\t});\n\t\t\t\t\tcontinue;\n\t\t\t\t}\n\n\t\t\t\tif (\n\t\t\t\t\tthis.config.validation.height.min &&\n\t\t\t\t\theight < this.config.validation.height.min\n\t\t\t\t) {\n\t\t\t\t\terrors.push({\n\t\t\t\t\t\titemIndex,\n\t\t\t\t\t\tmessage: copy(\"server:core.fields.media.validation.height.min\", {\n\t\t\t\t\t\t\tdata: {\n\t\t\t\t\t\t\t\tmin: this.config.validation.height.min,\n\t\t\t\t\t\t\t},\n\t\t\t\t\t\t}),\n\t\t\t\t\t});\n\t\t\t\t}\n\t\t\t\tif (\n\t\t\t\t\tthis.config.validation.height.max &&\n\t\t\t\t\theight > this.config.validation.height.max\n\t\t\t\t) {\n\t\t\t\t\terrors.push({\n\t\t\t\t\t\titemIndex,\n\t\t\t\t\t\tmessage: copy(\"server:core.fields.media.validation.height.max\", {\n\t\t\t\t\t\t\tdata: {\n\t\t\t\t\t\t\t\tmax: this.config.validation.height.max,\n\t\t\t\t\t\t\t},\n\t\t\t\t\t\t}),\n\t\t\t\t\t});\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\tif (errors.length > 0) {\n\t\t\treturn {\n\t\t\t\tvalid: false,\n\t\t\t\terrors,\n\t\t\t};\n\t\t}\n\n\t\treturn { valid: true };\n\t}\n}\n\nexport default MediaCustomField;\n"],"mappings":"ugBAwBA,IAAM,EAAN,cAA+B,CAAqB,CACnD,KAAO,EAAiB,KACxB,OACA,IACA,MACA,YAAY,EAAa,EAA0B,CAClD,MAAM,EACN,KAAK,IAAM,EACX,KAAK,MAAQ,EACb,KAAK,OAAS,CACb,IAAK,KAAK,IACV,KAAM,KAAK,KACX,QAAS,CACR,MACC,KAAK,OAAO,SAAS,OACrB,EAAK,gBAAgB,KAAK,KAAK,GAAG,KAAK,IAAI,QAAS,CACnD,eAAgB,EAAW,KAAK,GAAG,CACpC,CAAC,EACF,QAAS,KAAK,OAAO,SAAS,OAC/B,EACA,UAAW,KAAK,OAAO,WAAa,GACpC,QAAS,KAAK,OAAO,SAAW,CAAC,EACjC,MAAO,KAAK,OAAO,MACnB,SAAU,KAAK,OAAO,SACtB,GAAI,CACH,OAAQ,KAAK,OAAO,IAAI,OACxB,SAAU,KAAK,OAAO,IAAI,SAC1B,UAAW,KAAK,OAAO,IAAI,UAC3B,MAAO,KAAK,OAAO,IAAI,KACxB,EACA,WAAY,KAAK,OAAO,UACzB,CACD,CACA,oBAA6B,EAAgB,CAC5C,OAAO,EAAwB,EAAO,KAAK,OAAO,QAAQ,CAC3D,CACA,IAAa,cAAwB,CACpC,OAAO,EACN,KAAK,OAAO,QACZ,KAAK,OAAO,QACb,CACD,CACA,IAAa,QAIX,CACD,MAAO,CACN,GAAG,MAAM,OACT,SAAU,CACT,UAAY,GACX,GACU,MACT,MAAM,QAAQ,CAAK,GAAK,EAAM,SAAW,EAC3C,QAAS,EAAK,wCAAwC,CACvD,CACD,CACD,CACA,oBACC,EAC6C,CAC7C,MAAO,CACN,KAAM,CACL,QAAS,CACR,CACC,KAAM,WACN,KAAM,EAAM,GAAG,YAAY,SAAS,EACpC,SAAU,GACV,WAAY,CACX,MAAO,cACP,OAAQ,KACR,SAAU,SACX,CACD,CACD,CACD,EACA,MAAO,IAAA,EACR,CACD,CACA,oBAAoB,EAAgB,CACnC,OAAO,EACN,EACA,KAAK,OAAO,QACb,CACD,CACA,IAAa,qBAAsB,CAClC,MAAO,UACR,CACA,4BACC,EACiC,CACjC,OAAO,EAA8B,EAAO,KAAK,OAAO,QAAQ,CAAC,CAAC,IAChE,IAAa,EACZ,EAAuB,UAAU,GAAI,CACvC,EACD,CACD,CACA,iBAAiB,EAAgB,EAAiC,CACjE,IAAM,EAAc,EAAE,MAAM,EAAE,OAAO,CAAC,EAChC,EAAiB,EAAwB,EAAO,KAAK,OAAO,QAAQ,EACpE,EAAgB,EAAa,EAAgB,CAAW,EAC9D,GAAI,CAAC,EAAc,MAAO,OAAO,EAEjC,IAAM,EAAkB,MAAM,QAAQ,CAAc,EACjD,EAAe,OACd,GAAyB,OAAO,GAAS,QAC3C,EACC,CAAC,EACE,EAAsB,EAA0B,CACrD,SAAU,KAAK,OAAO,SACtB,OAAQ,EAAgB,OACxB,WAAY,KAAK,OAAO,UACzB,CAAC,EACD,GAAI,CAAC,EAAoB,MAAO,OAAO,EAEvC,IAAM,EAAuC,CAAC,EAC9C,IAAK,GAAM,CAAC,EAAW,KAAY,EAAgB,QAAQ,EAAG,CAC7D,IAAM,EAAY,GAAS,KAAM,GAAM,EAAE,KAAO,CAAO,EACvD,GAAI,IAAc,IAAA,GAAW,CAC5B,EAAO,KAAK,CACX,YACA,QAAS,EAAK,+CAA+C,CAC9D,CAAC,EACD,QACD,CAGA,GAAI,KAAK,OAAO,YAAY,YAAY,OAAQ,CAC/C,IAAM,EAAY,EAAU,eACvB,KAAK,OAAO,WAAW,WAAW,SAAS,CAAS,GACxD,EAAO,KAAK,CACX,YACA,QAAS,EACR,wDACA,CACC,KAAM,CACL,WAAY,KAAK,OAAO,WAAW,WAAW,KAAK,IAAI,CACxD,CACD,CACD,CACD,CAAC,CAEH,CAGA,GAAI,KAAK,OAAO,YAAY,KAAM,CACjC,IAAM,EAAO,EAAU,KACvB,GAAI,CAAC,EAAM,CACV,EAAO,KAAK,CACX,YACA,QAAS,EAAK,kDAAkD,CACjE,CAAC,EACD,QACD,CAEI,KAAK,OAAO,WAAW,OAAS,GACnC,EAAO,KAAK,CACX,YACA,QAAS,EAAK,mDAAoD,CACjE,KAAM,CACL,KAAM,KAAK,OAAO,WAAW,IAC9B,CACD,CAAC,CACF,CAAC,CAEH,CAGA,GAAI,KAAK,OAAO,YAAY,OAAS,EAAU,OAAS,QAAS,CAChE,IAAM,EAAQ,EAAU,MACxB,GAAI,CAAC,EAAO,CACX,EAAO,KAAK,CACX,YACA,QAAS,EAAK,mDAAmD,CAClE,CAAC,EACD,QACD,CAGC,KAAK,OAAO,WAAW,MAAM,KAC7B,EAAQ,KAAK,OAAO,WAAW,MAAM,KAErC,EAAO,KAAK,CACX,YACA,QAAS,EAAK,gDAAiD,CAC9D,KAAM,CACL,IAAK,KAAK,OAAO,WAAW,MAAM,GACnC,CACD,CAAC,CACF,CAAC,EAGD,KAAK,OAAO,WAAW,MAAM,KAC7B,EAAQ,KAAK,OAAO,WAAW,MAAM,KAErC,EAAO,KAAK,CACX,YACA,QAAS,EAAK,gDAAiD,CAC9D,KAAM,CACL,IAAK,KAAK,OAAO,WAAW,MAAM,GACnC,CACD,CAAC,CACF,CAAC,CAEH,CAGA,GAAI,KAAK,OAAO,YAAY,QAAU,EAAU,OAAS,QAAS,CACjE,IAAM,EAAS,EAAU,OACzB,GAAI,CAAC,EAAQ,CACZ,EAAO,KAAK,CACX,YACA,QAAS,EAAK,oDAAoD,CACnE,CAAC,EACD,QACD,CAGC,KAAK,OAAO,WAAW,OAAO,KAC9B,EAAS,KAAK,OAAO,WAAW,OAAO,KAEvC,EAAO,KAAK,CACX,YACA,QAAS,EAAK,iDAAkD,CAC/D,KAAM,CACL,IAAK,KAAK,OAAO,WAAW,OAAO,GACpC,CACD,CAAC,CACF,CAAC,EAGD,KAAK,OAAO,WAAW,OAAO,KAC9B,EAAS,KAAK,OAAO,WAAW,OAAO,KAEvC,EAAO,KAAK,CACX,YACA,QAAS,EAAK,iDAAkD,CAC/D,KAAM,CACL,IAAK,KAAK,OAAO,WAAW,OAAO,GACpC,CACD,CAAC,CACF,CAAC,CAEH,CACD,CASA,OAPI,EAAO,OAAS,EACZ,CACN,MAAO,GACP,QACD,EAGM,CAAE,MAAO,EAAK,CACtB,CACD"}