{"version":3,"file":"uid.mjs","sources":["../../../server/src/services/uid.ts"],"sourcesContent":["import _ from 'lodash';\nimport slugify from '@sindresorhus/slugify';\n\nimport type { Core, Schema, UID } from '@strapi/types';\n\nexport default ({ strapi }: { strapi: Core.Strapi }) => ({\n  async generateUIDField({\n    contentTypeUID,\n    field,\n    data,\n    locale,\n  }: {\n    contentTypeUID: UID.ContentType;\n    field: string;\n    data: Record<string, any>;\n    locale?: string;\n  }) {\n    const contentType = strapi.contentTypes[contentTypeUID];\n    const { attributes } = contentType;\n\n    const {\n      targetField,\n      default: defaultValue,\n      options,\n    } = attributes[field] as Schema.Attribute.UID;\n\n    // @ts-expect-error targetField can be undefined\n    const targetValue = _.get(data, targetField);\n\n    if (!_.isEmpty(targetValue)) {\n      return this.findUniqueUID({\n        contentTypeUID,\n        field,\n        value: slugify(targetValue, options),\n        locale,\n      });\n    }\n\n    return this.findUniqueUID({\n      contentTypeUID,\n      field,\n      value: slugify(\n        _.isFunction(defaultValue) ? defaultValue() : defaultValue || contentType.modelName,\n        options\n      ),\n      locale,\n    });\n  },\n\n  async findUniqueUID({\n    contentTypeUID,\n    field,\n    value,\n    locale,\n  }: {\n    contentTypeUID: UID.ContentType;\n    field: string;\n    value: string;\n    locale?: string;\n  }) {\n    const foundDocuments = await strapi.documents(contentTypeUID).findMany({\n      filters: {\n        [field]: { $startsWith: value },\n      },\n      locale,\n      // TODO: Check UX. When modifying an entry, it only makes sense to check for collisions with other drafts\n      // However, when publishing this \"available\" UID might collide with another published entry\n      status: 'draft',\n    });\n\n    if (!foundDocuments || foundDocuments.length === 0) {\n      // If there are no documents found we can return the value as is\n      return value;\n    }\n\n    let possibleCollisions: string[];\n    if (!Array.isArray(foundDocuments)) {\n      possibleCollisions = [foundDocuments[field]];\n    } else {\n      possibleCollisions = foundDocuments.map((doc: any) => doc[field]);\n    }\n\n    // If there are no documents sharing the proposed UID, we can return the value as is\n    if (!possibleCollisions.includes(value)) {\n      return value;\n    }\n\n    let i = 1;\n    let tmpUId = `${value}-${i}`;\n    while (possibleCollisions.includes(tmpUId)) {\n      // While there are documents sharing the proposed UID, we need to find a new one\n      // by incrementing the suffix until we find a unique one\n      i += 1;\n      tmpUId = `${value}-${i}`;\n    }\n\n    return tmpUId;\n  },\n\n  async checkUIDAvailability({\n    contentTypeUID,\n    field,\n    value,\n    locale,\n  }: {\n    contentTypeUID: UID.ContentType;\n    field: string;\n    value: string;\n    locale?: string;\n  }) {\n    const documentCount = await strapi.documents(contentTypeUID).count({\n      filters: {\n        [field]: value,\n      },\n      locale,\n      // TODO: Check UX. When modifying an entry, it only makes sense to check for collisions with other drafts\n      // However, when publishing this \"available\" UID might collide with another published entry\n      status: 'draft',\n    });\n\n    if (documentCount && documentCount > 0) {\n      // If there are documents sharing the proposed UID, we can return false\n      return false;\n    }\n\n    return true;\n  },\n});\n"],"names":["strapi","generateUIDField","contentTypeUID","field","data","locale","contentType","contentTypes","attributes","targetField","default","defaultValue","options","targetValue","_","get","isEmpty","findUniqueUID","value","slugify","isFunction","modelName","foundDocuments","documents","findMany","filters","$startsWith","status","length","possibleCollisions","Array","isArray","map","doc","includes","i","tmpUId","checkUIDAvailability","documentCount","count"],"mappings":";;;AAKA,UAAe,CAAA,CAAC,EAAEA,MAAM,EAA2B,IAAM;QACvD,MAAMC,gBAAAA,CAAAA,CAAiB,EACrBC,cAAc,EACdC,KAAK,EACLC,IAAI,EACJC,MAAM,EAMP,EAAA;AACC,YAAA,MAAMC,WAAcN,GAAAA,MAAAA,CAAOO,YAAY,CAACL,cAAe,CAAA;YACvD,MAAM,EAAEM,UAAU,EAAE,GAAGF,WAAAA;YAEvB,MAAM,EACJG,WAAW,EACXC,OAASC,EAAAA,YAAY,EACrBC,OAAO,EACR,GAAGJ,UAAU,CAACL,KAAM,CAAA;;AAGrB,YAAA,MAAMU,WAAcC,GAAAA,CAAAA,CAAEC,GAAG,CAACX,IAAMK,EAAAA,WAAAA,CAAAA;AAEhC,YAAA,IAAI,CAACK,CAAAA,CAAEE,OAAO,CAACH,WAAc,CAAA,EAAA;gBAC3B,OAAO,IAAI,CAACI,aAAa,CAAC;AACxBf,oBAAAA,cAAAA;AACAC,oBAAAA,KAAAA;AACAe,oBAAAA,KAAAA,EAAOC,QAAQN,WAAaD,EAAAA,OAAAA,CAAAA;AAC5BP,oBAAAA;AACF,iBAAA,CAAA;AACF;YAEA,OAAO,IAAI,CAACY,aAAa,CAAC;AACxBf,gBAAAA,cAAAA;AACAC,gBAAAA,KAAAA;gBACAe,KAAOC,EAAAA,OAAAA,CACLL,EAAEM,UAAU,CAACT,gBAAgBA,YAAiBA,EAAAA,GAAAA,YAAAA,IAAgBL,WAAYe,CAAAA,SAAS,EACnFT,OAAAA,CAAAA;AAEFP,gBAAAA;AACF,aAAA,CAAA;AACF,SAAA;QAEA,MAAMY,aAAAA,CAAAA,CAAc,EAClBf,cAAc,EACdC,KAAK,EACLe,KAAK,EACLb,MAAM,EAMP,EAAA;AACC,YAAA,MAAMiB,iBAAiB,MAAMtB,MAAAA,CAAOuB,SAAS,CAACrB,cAAAA,CAAAA,CAAgBsB,QAAQ,CAAC;gBACrEC,OAAS,EAAA;AACP,oBAAA,CAACtB,QAAQ;wBAAEuB,WAAaR,EAAAA;AAAM;AAChC,iBAAA;AACAb,gBAAAA,MAAAA;;;gBAGAsB,MAAQ,EAAA;AACV,aAAA,CAAA;AAEA,YAAA,IAAI,CAACL,cAAAA,IAAkBA,cAAeM,CAAAA,MAAM,KAAK,CAAG,EAAA;;gBAElD,OAAOV,KAAAA;AACT;YAEA,IAAIW,kBAAAA;AACJ,YAAA,IAAI,CAACC,KAAAA,CAAMC,OAAO,CAACT,cAAiB,CAAA,EAAA;gBAClCO,kBAAqB,GAAA;AAACP,oBAAAA,cAAc,CAACnB,KAAM;AAAC,iBAAA;aACvC,MAAA;AACL0B,gBAAAA,kBAAAA,GAAqBP,eAAeU,GAAG,CAAC,CAACC,GAAaA,GAAAA,GAAG,CAAC9B,KAAM,CAAA,CAAA;AAClE;;AAGA,YAAA,IAAI,CAAC0B,kBAAAA,CAAmBK,QAAQ,CAAChB,KAAQ,CAAA,EAAA;gBACvC,OAAOA,KAAAA;AACT;AAEA,YAAA,IAAIiB,CAAI,GAAA,CAAA;AACR,YAAA,IAAIC,MAAS,GAAA,CAAA,EAAGlB,KAAM,CAAA,CAAC,EAAEiB,CAAG,CAAA,CAAA;YAC5B,MAAON,kBAAAA,CAAmBK,QAAQ,CAACE,MAAS,CAAA,CAAA;;;gBAG1CD,CAAK,IAAA,CAAA;AACLC,gBAAAA,MAAAA,GAAS,CAAGlB,EAAAA,KAAAA,CAAM,CAAC,EAAEiB,CAAG,CAAA,CAAA;AAC1B;YAEA,OAAOC,MAAAA;AACT,SAAA;QAEA,MAAMC,oBAAAA,CAAAA,CAAqB,EACzBnC,cAAc,EACdC,KAAK,EACLe,KAAK,EACLb,MAAM,EAMP,EAAA;AACC,YAAA,MAAMiC,gBAAgB,MAAMtC,MAAAA,CAAOuB,SAAS,CAACrB,cAAAA,CAAAA,CAAgBqC,KAAK,CAAC;gBACjEd,OAAS,EAAA;AACP,oBAAA,CAACtB,QAAQe;AACX,iBAAA;AACAb,gBAAAA,MAAAA;;;gBAGAsB,MAAQ,EAAA;AACV,aAAA,CAAA;YAEA,IAAIW,aAAAA,IAAiBA,gBAAgB,CAAG,EAAA;;gBAEtC,OAAO,KAAA;AACT;YAEA,OAAO,IAAA;AACT;AACF,KAAA,CAAC;;;;"}