@strapi/i18n 5.42.0 → 5.43.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/admin/components/CMHeaderActions.js +28 -25
- package/dist/admin/components/CMHeaderActions.js.map +1 -1
- package/dist/admin/components/CMHeaderActions.mjs +26 -23
- package/dist/admin/components/CMHeaderActions.mjs.map +1 -1
- package/dist/admin/index.js +1 -0
- package/dist/admin/index.js.map +1 -1
- package/dist/admin/index.mjs +1 -0
- package/dist/admin/index.mjs.map +1 -1
- package/dist/admin/services/fillFromLocale.js +21 -0
- package/dist/admin/services/fillFromLocale.js.map +1 -0
- package/dist/admin/services/fillFromLocale.mjs +18 -0
- package/dist/admin/services/fillFromLocale.mjs.map +1 -0
- package/dist/admin/services/settings.js +1 -1
- package/dist/admin/services/settings.js.map +1 -1
- package/dist/admin/services/settings.mjs +1 -1
- package/dist/admin/services/settings.mjs.map +1 -1
- package/dist/admin/src/services/aiLocalizationJobs.d.ts +1 -1
- package/dist/admin/src/services/api.d.ts +1 -1
- package/dist/admin/src/services/fillFromLocale.d.ts +2 -0
- package/dist/admin/src/services/locales.d.ts +1 -1
- package/dist/admin/src/services/relations.d.ts +1 -1
- package/dist/admin/src/services/settings.d.ts +2 -2
- package/dist/admin/translations/nl.json.js +91 -0
- package/dist/admin/translations/nl.json.js.map +1 -0
- package/dist/admin/translations/nl.json.mjs +89 -0
- package/dist/admin/translations/nl.json.mjs.map +1 -0
- package/dist/admin/translations/pl.json.js +48 -23
- package/dist/admin/translations/pl.json.js.map +1 -1
- package/dist/admin/translations/pl.json.mjs +48 -23
- package/dist/admin/translations/pl.json.mjs.map +1 -1
- package/dist/server/bootstrap.js +3 -1
- package/dist/server/bootstrap.js.map +1 -1
- package/dist/server/bootstrap.mjs +3 -1
- package/dist/server/bootstrap.mjs.map +1 -1
- package/dist/server/controllers/ai-localization-jobs.js +8 -0
- package/dist/server/controllers/ai-localization-jobs.js.map +1 -1
- package/dist/server/controllers/ai-localization-jobs.mjs +8 -0
- package/dist/server/controllers/ai-localization-jobs.mjs.map +1 -1
- package/dist/server/controllers/content-types.js +42 -2
- package/dist/server/controllers/content-types.js.map +1 -1
- package/dist/server/controllers/content-types.mjs +43 -3
- package/dist/server/controllers/content-types.mjs.map +1 -1
- package/dist/server/routes/admin.js +18 -0
- package/dist/server/routes/admin.js.map +1 -1
- package/dist/server/routes/admin.mjs +18 -0
- package/dist/server/routes/admin.mjs.map +1 -1
- package/dist/server/services/ai-localizations.js +3 -13
- package/dist/server/services/ai-localizations.js.map +1 -1
- package/dist/server/services/ai-localizations.mjs +3 -13
- package/dist/server/services/ai-localizations.mjs.map +1 -1
- package/dist/server/services/fill-from-locale.js +435 -0
- package/dist/server/services/fill-from-locale.js.map +1 -0
- package/dist/server/services/fill-from-locale.mjs +433 -0
- package/dist/server/services/fill-from-locale.mjs.map +1 -0
- package/dist/server/services/index.js +3 -1
- package/dist/server/services/index.js.map +1 -1
- package/dist/server/services/index.mjs +3 -1
- package/dist/server/services/index.mjs.map +1 -1
- package/dist/server/src/bootstrap.d.ts.map +1 -1
- package/dist/server/src/controllers/ai-localization-jobs.d.ts.map +1 -1
- package/dist/server/src/controllers/content-types.d.ts +1 -0
- package/dist/server/src/controllers/content-types.d.ts.map +1 -1
- package/dist/server/src/controllers/index.d.ts +1 -0
- package/dist/server/src/controllers/index.d.ts.map +1 -1
- package/dist/server/src/index.d.ts +7 -0
- package/dist/server/src/index.d.ts.map +1 -1
- package/dist/server/src/routes/admin.d.ts.map +1 -1
- package/dist/server/src/services/ai-localizations.d.ts.map +1 -1
- package/dist/server/src/services/fill-from-locale.d.ts +16 -0
- package/dist/server/src/services/fill-from-locale.d.ts.map +1 -0
- package/dist/server/src/services/index.d.ts +6 -0
- package/dist/server/src/services/index.d.ts.map +1 -1
- package/dist/server/src/utils/index.d.ts +2 -0
- package/dist/server/src/utils/index.d.ts.map +1 -1
- package/dist/server/src/validation/content-types.d.ts +2 -1
- package/dist/server/src/validation/content-types.d.ts.map +1 -1
- package/dist/server/utils/index.js.map +1 -1
- package/dist/server/utils/index.mjs.map +1 -1
- package/dist/server/validation/content-types.js +15 -0
- package/dist/server/validation/content-types.js.map +1 -1
- package/dist/server/validation/content-types.mjs +15 -1
- package/dist/server/validation/content-types.mjs.map +1 -1
- package/dist/shared/contracts/content-manager.d.ts +27 -0
- package/dist/shared/contracts/content-manager.d.ts.map +1 -0
- package/package.json +8 -8
- package/dist/admin/src/utils/clean.d.ts +0 -4
- package/dist/admin/utils/clean.js +0 -70
- package/dist/admin/utils/clean.js.map +0 -1
- package/dist/admin/utils/clean.mjs +0 -68
- package/dist/admin/utils/clean.mjs.map +0 -1
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"bootstrap.mjs","sources":["../../server/src/bootstrap.ts"],"sourcesContent":["import type { Schema } from '@strapi/types';\nimport { isEqual } from 'lodash/fp';\nimport { getService } from './utils';\n\nconst registerModelsHooks = () => {\n strapi.db.lifecycles.subscribe({\n models: ['plugin::i18n.locale'],\n\n async afterCreate() {\n await getService('permissions').actions.syncSuperAdminPermissionsWithLocales();\n },\n\n async afterDelete() {\n await getService('permissions').actions.syncSuperAdminPermissionsWithLocales();\n },\n });\n\n strapi.documents.use(async (context, next) => {\n const schema: Schema.ContentType = context.contentType;\n\n if (!['create', 'update', 'discardDraft', 'publish'].includes(context.action)) {\n return next();\n }\n\n if (!getService('content-types').isLocalizedContentType(schema)) {\n return next();\n }\n\n // Build a populate array for all non localized fields within the schema\n const { getNestedPopulateOfNonLocalizedAttributes, copyNonLocalizedAttributes } =\n getService('content-types');\n const attributesToPopulate = getNestedPopulateOfNonLocalizedAttributes(schema.uid);\n\n // Get original data before the update to compare what actually changed\n const originalData =\n 'documentId' in context.params && context.params.documentId\n ? await strapi.db.query(schema.uid).findOne({\n where: { documentId: context.params.documentId },\n populate: attributesToPopulate,\n })\n : null;\n\n // Get the result of the document service action\n const result = (await next()) as any;\n\n // We may not have received a result with everything populated that we need\n // Use the id and populate built from non localized fields to get the full\n // result\n let resultID;\n // TODO: fix bug where an empty array can be returned\n if (Array.isArray(result?.entries) && result.entries[0]?.id) {\n resultID = result.entries[0].id;\n } else if (result?.id) {\n resultID = result.id;\n } else {\n return result;\n }\n\n const populatedResult = await strapi.db.query(schema.uid).findOne({\n where: { id: resultID },\n populate: attributesToPopulate,\n });\n\n const originalFields = copyNonLocalizedAttributes(schema, originalData);\n const currentFields = copyNonLocalizedAttributes(schema, populatedResult);\n\n // Only sync if there are actual changes to non-localized fields\n const shouldSync =\n !originalData ||\n Object.keys(currentFields).some((key) => {\n return !isEqual(currentFields[key], originalFields[key]);\n });\n\n if (shouldSync) {\n await getService('localizations').syncNonLocalizedAttributes(populatedResult, schema);\n }\n\n return result;\n });\n};\n\nexport default async () => {\n const { sendDidInitializeEvent } = getService('metrics');\n const { initDefaultLocale } = getService('locales');\n const { sectionsBuilder, actions, engine } = getService('permissions');\n\n // Data\n await initDefaultLocale();\n\n // Sections Builder\n sectionsBuilder.registerLocalesPropertyHandler();\n\n // Actions\n await actions.registerI18nActions();\n actions.registerI18nActionsHooks();\n actions.updateActionsProperties();\n\n // Engine/Permissions\n engine.registerI18nPermissionsHandlers();\n\n // Hooks & Models\n registerModelsHooks();\n\n // AI Localizations\n getService('ai-localizations').setupMiddleware();\n\n sendDidInitializeEvent();\n};\n"],"names":["registerModelsHooks","strapi","db","lifecycles","subscribe","models","afterCreate","getService","actions","syncSuperAdminPermissionsWithLocales","afterDelete","documents","use","context","next","schema","contentType","includes","action","isLocalizedContentType","getNestedPopulateOfNonLocalizedAttributes","copyNonLocalizedAttributes","attributesToPopulate","uid","originalData","params","documentId","query","findOne","where","populate","result","resultID","Array","isArray","entries","id","populatedResult","originalFields","currentFields","shouldSync","Object","keys","some","key","isEqual","syncNonLocalizedAttributes","sendDidInitializeEvent","initDefaultLocale","sectionsBuilder","engine","registerLocalesPropertyHandler","registerI18nActions","registerI18nActionsHooks","updateActionsProperties","registerI18nPermissionsHandlers","setupMiddleware"],"mappings":"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
|
|
1
|
+
{"version":3,"file":"bootstrap.mjs","sources":["../../server/src/bootstrap.ts"],"sourcesContent":["import type { Schema } from '@strapi/types';\nimport { isEqual } from 'lodash/fp';\nimport { getService } from './utils';\n\nconst registerModelsHooks = () => {\n strapi.db.lifecycles.subscribe({\n models: ['plugin::i18n.locale'],\n\n async afterCreate() {\n await getService('permissions').actions.syncSuperAdminPermissionsWithLocales();\n },\n\n async afterDelete() {\n await getService('permissions').actions.syncSuperAdminPermissionsWithLocales();\n },\n });\n\n strapi.documents.use(async (context, next) => {\n const schema: Schema.ContentType = context.contentType;\n\n if (!['create', 'update', 'discardDraft', 'publish'].includes(context.action)) {\n return next();\n }\n\n if (!getService('content-types').isLocalizedContentType(schema)) {\n return next();\n }\n\n // Build a populate array for all non localized fields within the schema\n const { getNestedPopulateOfNonLocalizedAttributes, copyNonLocalizedAttributes } =\n getService('content-types');\n const attributesToPopulate = getNestedPopulateOfNonLocalizedAttributes(schema.uid);\n\n // Get original data before the update to compare what actually changed\n const originalData =\n 'documentId' in context.params && context.params.documentId\n ? await strapi.db.query(schema.uid).findOne({\n where: { documentId: context.params.documentId },\n populate: attributesToPopulate,\n })\n : null;\n\n // Get the result of the document service action\n const result = (await next()) as any;\n\n // We may not have received a result with everything populated that we need\n // Use the id and populate built from non localized fields to get the full\n // result\n let resultID;\n // TODO: fix bug where an empty array can be returned\n if (Array.isArray(result?.entries) && result.entries[0]?.id) {\n resultID = result.entries[0].id;\n } else if (result?.id) {\n resultID = result.id;\n } else {\n return result;\n }\n\n const populatedResult = await strapi.db.query(schema.uid).findOne({\n where: { id: resultID },\n populate: attributesToPopulate,\n });\n\n const originalFields = copyNonLocalizedAttributes(schema, originalData);\n const currentFields = copyNonLocalizedAttributes(schema, populatedResult);\n\n // Only sync if there are actual changes to non-localized fields\n const shouldSync =\n !originalData ||\n Object.keys(currentFields).some((key) => {\n return !isEqual(currentFields[key], originalFields[key]);\n });\n\n if (shouldSync) {\n await getService('localizations').syncNonLocalizedAttributes(populatedResult, schema);\n }\n\n return result;\n });\n};\n\nexport default async () => {\n const { sendDidInitializeEvent } = getService('metrics');\n const { initDefaultLocale } = getService('locales');\n const { sectionsBuilder, actions, engine } = getService('permissions');\n\n // Data\n await initDefaultLocale();\n\n // Sections Builder\n sectionsBuilder.registerLocalesPropertyHandler();\n\n // Actions\n await actions.registerI18nActions();\n actions.registerI18nActionsHooks();\n actions.updateActionsProperties();\n\n // Engine/Permissions\n engine.registerI18nPermissionsHandlers();\n\n // Hooks & Models\n registerModelsHooks();\n\n // AI Localizations\n if (strapi.ai.admin.isEnabled() === true) {\n getService('ai-localizations').setupMiddleware();\n }\n\n sendDidInitializeEvent();\n};\n"],"names":["registerModelsHooks","strapi","db","lifecycles","subscribe","models","afterCreate","getService","actions","syncSuperAdminPermissionsWithLocales","afterDelete","documents","use","context","next","schema","contentType","includes","action","isLocalizedContentType","getNestedPopulateOfNonLocalizedAttributes","copyNonLocalizedAttributes","attributesToPopulate","uid","originalData","params","documentId","query","findOne","where","populate","result","resultID","Array","isArray","entries","id","populatedResult","originalFields","currentFields","shouldSync","Object","keys","some","key","isEqual","syncNonLocalizedAttributes","sendDidInitializeEvent","initDefaultLocale","sectionsBuilder","engine","registerLocalesPropertyHandler","registerI18nActions","registerI18nActionsHooks","updateActionsProperties","registerI18nPermissionsHandlers","ai","admin","isEnabled","setupMiddleware"],"mappings":";;;AAIA,MAAMA,mBAAAA,GAAsB,IAAA;AAC1BC,IAAAA,MAAAA,CAAOC,EAAE,CAACC,UAAU,CAACC,SAAS,CAAC;QAC7BC,MAAAA,EAAQ;AAAC,YAAA;AAAsB,SAAA;QAE/B,MAAMC,WAAAA,CAAAA,GAAAA;AACJ,YAAA,MAAMC,UAAAA,CAAW,aAAA,CAAA,CAAeC,OAAO,CAACC,oCAAoC,EAAA;AAC9E,QAAA,CAAA;QAEA,MAAMC,WAAAA,CAAAA,GAAAA;AACJ,YAAA,MAAMH,UAAAA,CAAW,aAAA,CAAA,CAAeC,OAAO,CAACC,oCAAoC,EAAA;AAC9E,QAAA;AACF,KAAA,CAAA;AAEAR,IAAAA,MAAAA,CAAOU,SAAS,CAACC,GAAG,CAAC,OAAOC,OAAAA,EAASC,IAAAA,GAAAA;QACnC,MAAMC,MAAAA,GAA6BF,QAAQG,WAAW;AAEtD,QAAA,IAAI,CAAC;AAAC,YAAA,QAAA;AAAU,YAAA,QAAA;AAAU,YAAA,cAAA;AAAgB,YAAA;AAAU,SAAA,CAACC,QAAQ,CAACJ,OAAAA,CAAQK,MAAM,CAAA,EAAG;YAC7E,OAAOJ,IAAAA,EAAAA;AACT,QAAA;AAEA,QAAA,IAAI,CAACP,UAAAA,CAAW,eAAA,CAAA,CAAiBY,sBAAsB,CAACJ,MAAAA,CAAAA,EAAS;YAC/D,OAAOD,IAAAA,EAAAA;AACT,QAAA;;AAGA,QAAA,MAAM,EAAEM,yCAAyC,EAAEC,0BAA0B,EAAE,GAC7Ed,UAAAA,CAAW,eAAA,CAAA;QACb,MAAMe,oBAAAA,GAAuBF,yCAAAA,CAA0CL,MAAAA,CAAOQ,GAAG,CAAA;;QAGjF,MAAMC,YAAAA,GACJ,gBAAgBX,OAAAA,CAAQY,MAAM,IAAIZ,OAAAA,CAAQY,MAAM,CAACC,UAAU,GACvD,MAAMzB,MAAAA,CAAOC,EAAE,CAACyB,KAAK,CAACZ,OAAOQ,GAAG,CAAA,CAAEK,OAAO,CAAC;YACxCC,KAAAA,EAAO;gBAAEH,UAAAA,EAAYb,OAAAA,CAAQY,MAAM,CAACC;AAAW,aAAA;YAC/CI,QAAAA,EAAUR;SACZ,CAAA,GACA,IAAA;;AAGN,QAAA,MAAMS,SAAU,MAAMjB,IAAAA,EAAAA;;;;QAKtB,IAAIkB,QAAAA;;QAEJ,IAAIC,KAAAA,CAAMC,OAAO,CAACH,MAAAA,EAAQI,OAAAA,CAAAA,IAAYJ,OAAOI,OAAO,CAAC,CAAA,CAAE,EAAEC,EAAAA,EAAI;AAC3DJ,YAAAA,QAAAA,GAAWD,MAAAA,CAAOI,OAAO,CAAC,CAAA,CAAE,CAACC,EAAE;QACjC,CAAA,MAAO,IAAIL,QAAQK,EAAAA,EAAI;AACrBJ,YAAAA,QAAAA,GAAWD,OAAOK,EAAE;QACtB,CAAA,MAAO;YACL,OAAOL,MAAAA;AACT,QAAA;QAEA,MAAMM,eAAAA,GAAkB,MAAMpC,MAAAA,CAAOC,EAAE,CAACyB,KAAK,CAACZ,MAAAA,CAAOQ,GAAG,CAAA,CAAEK,OAAO,CAAC;YAChEC,KAAAA,EAAO;gBAAEO,EAAAA,EAAIJ;AAAS,aAAA;YACtBF,QAAAA,EAAUR;AACZ,SAAA,CAAA;QAEA,MAAMgB,cAAAA,GAAiBjB,2BAA2BN,MAAAA,EAAQS,YAAAA,CAAAA;QAC1D,MAAMe,aAAAA,GAAgBlB,2BAA2BN,MAAAA,EAAQsB,eAAAA,CAAAA;;QAGzD,MAAMG,UAAAA,GACJ,CAAChB,YAAAA,IACDiB,MAAAA,CAAOC,IAAI,CAACH,aAAAA,CAAAA,CAAeI,IAAI,CAAC,CAACC,GAAAA,GAAAA;YAC/B,OAAO,CAACC,QAAQN,aAAa,CAACK,IAAI,EAAEN,cAAc,CAACM,GAAAA,CAAI,CAAA;AACzD,QAAA,CAAA,CAAA;AAEF,QAAA,IAAIJ,UAAAA,EAAY;AACd,YAAA,MAAMjC,UAAAA,CAAW,eAAA,CAAA,CAAiBuC,0BAA0B,CAACT,eAAAA,EAAiBtB,MAAAA,CAAAA;AAChF,QAAA;QAEA,OAAOgB,MAAAA;AACT,IAAA,CAAA,CAAA;AACF,CAAA;AAEA,gBAAe,CAAA,UAAA;AACb,IAAA,MAAM,EAAEgB,sBAAsB,EAAE,GAAGxC,UAAAA,CAAW,SAAA,CAAA;AAC9C,IAAA,MAAM,EAAEyC,iBAAiB,EAAE,GAAGzC,UAAAA,CAAW,SAAA,CAAA;IACzC,MAAM,EAAE0C,eAAe,EAAEzC,OAAO,EAAE0C,MAAM,EAAE,GAAG3C,UAAAA,CAAW,aAAA,CAAA;;IAGxD,MAAMyC,iBAAAA,EAAAA;;AAGNC,IAAAA,eAAAA,CAAgBE,8BAA8B,EAAA;;AAG9C,IAAA,MAAM3C,QAAQ4C,mBAAmB,EAAA;AACjC5C,IAAAA,OAAAA,CAAQ6C,wBAAwB,EAAA;AAChC7C,IAAAA,OAAAA,CAAQ8C,uBAAuB,EAAA;;AAG/BJ,IAAAA,MAAAA,CAAOK,+BAA+B,EAAA;;AAGtCvD,IAAAA,mBAAAA,EAAAA;;AAGA,IAAA,IAAIC,OAAOuD,EAAE,CAACC,KAAK,CAACC,SAAS,OAAO,IAAA,EAAM;AACxCnD,QAAAA,UAAAA,CAAW,oBAAoBoD,eAAe,EAAA;AAChD,IAAA;AAEAZ,IAAAA,sBAAAA,EAAAA;AACF,CAAA;;;;"}
|
|
@@ -8,6 +8,10 @@ const createAILocalizationJobsController = ({ strapi })=>{
|
|
|
8
8
|
* Get a job for a singleType using the contentType
|
|
9
9
|
* There is only 1 job per contentType
|
|
10
10
|
*/ async getJobForSingleType (ctx) {
|
|
11
|
+
const aiLocalizationsService = getService('ai-localizations');
|
|
12
|
+
if (await aiLocalizationsService.isEnabled() === false) {
|
|
13
|
+
return ctx.notFound();
|
|
14
|
+
}
|
|
11
15
|
const { contentType } = ctx.params;
|
|
12
16
|
if (!contentType) {
|
|
13
17
|
return ctx.badRequest('contentType is required');
|
|
@@ -26,6 +30,10 @@ const createAILocalizationJobsController = ({ strapi })=>{
|
|
|
26
30
|
* Get a job for a collectionType using the documentId
|
|
27
31
|
* There is only 1 job per documentId
|
|
28
32
|
*/ async getJobForCollectionType (ctx) {
|
|
33
|
+
const aiLocalizationsService = getService('ai-localizations');
|
|
34
|
+
if (await aiLocalizationsService.isEnabled() === false) {
|
|
35
|
+
return ctx.notFound();
|
|
36
|
+
}
|
|
29
37
|
const { documentId, contentType } = ctx.params;
|
|
30
38
|
if (!documentId || !contentType) {
|
|
31
39
|
return ctx.badRequest('Document ID and contentType are required');
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"ai-localization-jobs.js","sources":["../../../server/src/controllers/ai-localization-jobs.ts"],"sourcesContent":["import type { Core } from '@strapi/types';\n\nconst createAILocalizationJobsController = ({ strapi }: { strapi: Core.Strapi }) => {\n const getService = (name: string) => strapi.plugin('i18n').service(name);\n const aiLocalizationJobsService = getService('ai-localization-jobs');\n\n return {\n /**\n * Get a job for a singleType using the contentType\n * There is only 1 job per contentType\n */\n async getJobForSingleType(ctx: any) {\n const { contentType } = ctx.params;\n\n if (!contentType) {\n return ctx.badRequest('contentType is required');\n }\n\n try {\n const job = await aiLocalizationJobsService.getJobByContentType(contentType);\n\n ctx.body = {\n data: job,\n };\n } catch (error) {\n strapi.log.error('[AI Localizations Jobs] Error fetching job:', error);\n ctx.internalServerError('Failed to fetch AI localizations job');\n }\n },\n /**\n * Get a job for a collectionType using the documentId\n * There is only 1 job per documentId\n */\n async getJobForCollectionType(ctx: any) {\n const { documentId, contentType } = ctx.params;\n\n if (!documentId || !contentType) {\n return ctx.badRequest('Document ID and contentType are required');\n }\n\n try {\n const job = await aiLocalizationJobsService.getJobByDocument(contentType, documentId);\n\n ctx.body = {\n data: job,\n };\n } catch (error) {\n strapi.log.error('[AI Localizations Jobs] Error fetching job:', error);\n ctx.internalServerError('Failed to fetch AI localizations job');\n }\n },\n };\n};\n\nexport default createAILocalizationJobsController;\n"],"names":["createAILocalizationJobsController","strapi","getService","name","plugin","service","aiLocalizationJobsService","getJobForSingleType","ctx","contentType","params","badRequest","job","getJobByContentType","body","data","error","log","internalServerError","getJobForCollectionType","documentId","getJobByDocument"],"mappings":";;AAEA,MAAMA,kCAAAA,GAAqC,CAAC,EAAEC,MAAM,EAA2B,GAAA;IAC7E,MAAMC,UAAAA,GAAa,CAACC,IAAAA,GAAiBF,MAAAA,CAAOG,MAAM,CAAC,MAAA,CAAA,CAAQC,OAAO,CAACF,IAAAA,CAAAA;AACnE,IAAA,MAAMG,4BAA4BJ,UAAAA,CAAW,sBAAA,CAAA;IAE7C,OAAO;AACL;;;QAIA,MAAMK,qBAAoBC,GAAQ,EAAA;AAChC,YAAA,MAAM,EAAEC,WAAW,EAAE,
|
|
1
|
+
{"version":3,"file":"ai-localization-jobs.js","sources":["../../../server/src/controllers/ai-localization-jobs.ts"],"sourcesContent":["import type { Core } from '@strapi/types';\n\nconst createAILocalizationJobsController = ({ strapi }: { strapi: Core.Strapi }) => {\n const getService = (name: string) => strapi.plugin('i18n').service(name);\n const aiLocalizationJobsService = getService('ai-localization-jobs');\n\n return {\n /**\n * Get a job for a singleType using the contentType\n * There is only 1 job per contentType\n */\n async getJobForSingleType(ctx: any) {\n const aiLocalizationsService = getService('ai-localizations');\n if ((await aiLocalizationsService.isEnabled()) === false) {\n return ctx.notFound();\n }\n\n const { contentType } = ctx.params;\n\n if (!contentType) {\n return ctx.badRequest('contentType is required');\n }\n\n try {\n const job = await aiLocalizationJobsService.getJobByContentType(contentType);\n\n ctx.body = {\n data: job,\n };\n } catch (error) {\n strapi.log.error('[AI Localizations Jobs] Error fetching job:', error);\n ctx.internalServerError('Failed to fetch AI localizations job');\n }\n },\n /**\n * Get a job for a collectionType using the documentId\n * There is only 1 job per documentId\n */\n async getJobForCollectionType(ctx: any) {\n const aiLocalizationsService = getService('ai-localizations');\n if ((await aiLocalizationsService.isEnabled()) === false) {\n return ctx.notFound();\n }\n\n const { documentId, contentType } = ctx.params;\n\n if (!documentId || !contentType) {\n return ctx.badRequest('Document ID and contentType are required');\n }\n\n try {\n const job = await aiLocalizationJobsService.getJobByDocument(contentType, documentId);\n\n ctx.body = {\n data: job,\n };\n } catch (error) {\n strapi.log.error('[AI Localizations Jobs] Error fetching job:', error);\n ctx.internalServerError('Failed to fetch AI localizations job');\n }\n },\n };\n};\n\nexport default createAILocalizationJobsController;\n"],"names":["createAILocalizationJobsController","strapi","getService","name","plugin","service","aiLocalizationJobsService","getJobForSingleType","ctx","aiLocalizationsService","isEnabled","notFound","contentType","params","badRequest","job","getJobByContentType","body","data","error","log","internalServerError","getJobForCollectionType","documentId","getJobByDocument"],"mappings":";;AAEA,MAAMA,kCAAAA,GAAqC,CAAC,EAAEC,MAAM,EAA2B,GAAA;IAC7E,MAAMC,UAAAA,GAAa,CAACC,IAAAA,GAAiBF,MAAAA,CAAOG,MAAM,CAAC,MAAA,CAAA,CAAQC,OAAO,CAACF,IAAAA,CAAAA;AACnE,IAAA,MAAMG,4BAA4BJ,UAAAA,CAAW,sBAAA,CAAA;IAE7C,OAAO;AACL;;;QAIA,MAAMK,qBAAoBC,GAAQ,EAAA;AAChC,YAAA,MAAMC,yBAAyBP,UAAAA,CAAW,kBAAA,CAAA;AAC1C,YAAA,IAAI,MAAOO,sBAAAA,CAAuBC,SAAS,OAAQ,KAAA,EAAO;AACxD,gBAAA,OAAOF,IAAIG,QAAQ,EAAA;AACrB,YAAA;AAEA,YAAA,MAAM,EAAEC,WAAW,EAAE,GAAGJ,IAAIK,MAAM;AAElC,YAAA,IAAI,CAACD,WAAAA,EAAa;gBAChB,OAAOJ,GAAAA,CAAIM,UAAU,CAAC,yBAAA,CAAA;AACxB,YAAA;YAEA,IAAI;AACF,gBAAA,MAAMC,GAAAA,GAAM,MAAMT,yBAAAA,CAA0BU,mBAAmB,CAACJ,WAAAA,CAAAA;AAEhEJ,gBAAAA,GAAAA,CAAIS,IAAI,GAAG;oBACTC,IAAAA,EAAMH;AACR,iBAAA;AACF,YAAA,CAAA,CAAE,OAAOI,KAAAA,EAAO;AACdlB,gBAAAA,MAAAA,CAAOmB,GAAG,CAACD,KAAK,CAAC,6CAAA,EAA+CA,KAAAA,CAAAA;AAChEX,gBAAAA,GAAAA,CAAIa,mBAAmB,CAAC,sCAAA,CAAA;AAC1B,YAAA;AACF,QAAA,CAAA;AACA;;;QAIA,MAAMC,yBAAwBd,GAAQ,EAAA;AACpC,YAAA,MAAMC,yBAAyBP,UAAAA,CAAW,kBAAA,CAAA;AAC1C,YAAA,IAAI,MAAOO,sBAAAA,CAAuBC,SAAS,OAAQ,KAAA,EAAO;AACxD,gBAAA,OAAOF,IAAIG,QAAQ,EAAA;AACrB,YAAA;AAEA,YAAA,MAAM,EAAEY,UAAU,EAAEX,WAAW,EAAE,GAAGJ,IAAIK,MAAM;YAE9C,IAAI,CAACU,UAAAA,IAAc,CAACX,WAAAA,EAAa;gBAC/B,OAAOJ,GAAAA,CAAIM,UAAU,CAAC,0CAAA,CAAA;AACxB,YAAA;YAEA,IAAI;AACF,gBAAA,MAAMC,GAAAA,GAAM,MAAMT,yBAAAA,CAA0BkB,gBAAgB,CAACZ,WAAAA,EAAaW,UAAAA,CAAAA;AAE1Ef,gBAAAA,GAAAA,CAAIS,IAAI,GAAG;oBACTC,IAAAA,EAAMH;AACR,iBAAA;AACF,YAAA,CAAA,CAAE,OAAOI,KAAAA,EAAO;AACdlB,gBAAAA,MAAAA,CAAOmB,GAAG,CAACD,KAAK,CAAC,6CAAA,EAA+CA,KAAAA,CAAAA;AAChEX,gBAAAA,GAAAA,CAAIa,mBAAmB,CAAC,sCAAA,CAAA;AAC1B,YAAA;AACF,QAAA;AACF,KAAA;AACF;;;;"}
|
|
@@ -6,6 +6,10 @@ const createAILocalizationJobsController = ({ strapi })=>{
|
|
|
6
6
|
* Get a job for a singleType using the contentType
|
|
7
7
|
* There is only 1 job per contentType
|
|
8
8
|
*/ async getJobForSingleType (ctx) {
|
|
9
|
+
const aiLocalizationsService = getService('ai-localizations');
|
|
10
|
+
if (await aiLocalizationsService.isEnabled() === false) {
|
|
11
|
+
return ctx.notFound();
|
|
12
|
+
}
|
|
9
13
|
const { contentType } = ctx.params;
|
|
10
14
|
if (!contentType) {
|
|
11
15
|
return ctx.badRequest('contentType is required');
|
|
@@ -24,6 +28,10 @@ const createAILocalizationJobsController = ({ strapi })=>{
|
|
|
24
28
|
* Get a job for a collectionType using the documentId
|
|
25
29
|
* There is only 1 job per documentId
|
|
26
30
|
*/ async getJobForCollectionType (ctx) {
|
|
31
|
+
const aiLocalizationsService = getService('ai-localizations');
|
|
32
|
+
if (await aiLocalizationsService.isEnabled() === false) {
|
|
33
|
+
return ctx.notFound();
|
|
34
|
+
}
|
|
27
35
|
const { documentId, contentType } = ctx.params;
|
|
28
36
|
if (!documentId || !contentType) {
|
|
29
37
|
return ctx.badRequest('Document ID and contentType are required');
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"ai-localization-jobs.mjs","sources":["../../../server/src/controllers/ai-localization-jobs.ts"],"sourcesContent":["import type { Core } from '@strapi/types';\n\nconst createAILocalizationJobsController = ({ strapi }: { strapi: Core.Strapi }) => {\n const getService = (name: string) => strapi.plugin('i18n').service(name);\n const aiLocalizationJobsService = getService('ai-localization-jobs');\n\n return {\n /**\n * Get a job for a singleType using the contentType\n * There is only 1 job per contentType\n */\n async getJobForSingleType(ctx: any) {\n const { contentType } = ctx.params;\n\n if (!contentType) {\n return ctx.badRequest('contentType is required');\n }\n\n try {\n const job = await aiLocalizationJobsService.getJobByContentType(contentType);\n\n ctx.body = {\n data: job,\n };\n } catch (error) {\n strapi.log.error('[AI Localizations Jobs] Error fetching job:', error);\n ctx.internalServerError('Failed to fetch AI localizations job');\n }\n },\n /**\n * Get a job for a collectionType using the documentId\n * There is only 1 job per documentId\n */\n async getJobForCollectionType(ctx: any) {\n const { documentId, contentType } = ctx.params;\n\n if (!documentId || !contentType) {\n return ctx.badRequest('Document ID and contentType are required');\n }\n\n try {\n const job = await aiLocalizationJobsService.getJobByDocument(contentType, documentId);\n\n ctx.body = {\n data: job,\n };\n } catch (error) {\n strapi.log.error('[AI Localizations Jobs] Error fetching job:', error);\n ctx.internalServerError('Failed to fetch AI localizations job');\n }\n },\n };\n};\n\nexport default createAILocalizationJobsController;\n"],"names":["createAILocalizationJobsController","strapi","getService","name","plugin","service","aiLocalizationJobsService","getJobForSingleType","ctx","contentType","params","badRequest","job","getJobByContentType","body","data","error","log","internalServerError","getJobForCollectionType","documentId","getJobByDocument"],"mappings":"AAEA,MAAMA,kCAAAA,GAAqC,CAAC,EAAEC,MAAM,EAA2B,GAAA;IAC7E,MAAMC,UAAAA,GAAa,CAACC,IAAAA,GAAiBF,MAAAA,CAAOG,MAAM,CAAC,MAAA,CAAA,CAAQC,OAAO,CAACF,IAAAA,CAAAA;AACnE,IAAA,MAAMG,4BAA4BJ,UAAAA,CAAW,sBAAA,CAAA;IAE7C,OAAO;AACL;;;QAIA,MAAMK,qBAAoBC,GAAQ,EAAA;AAChC,YAAA,MAAM,EAAEC,WAAW,EAAE,
|
|
1
|
+
{"version":3,"file":"ai-localization-jobs.mjs","sources":["../../../server/src/controllers/ai-localization-jobs.ts"],"sourcesContent":["import type { Core } from '@strapi/types';\n\nconst createAILocalizationJobsController = ({ strapi }: { strapi: Core.Strapi }) => {\n const getService = (name: string) => strapi.plugin('i18n').service(name);\n const aiLocalizationJobsService = getService('ai-localization-jobs');\n\n return {\n /**\n * Get a job for a singleType using the contentType\n * There is only 1 job per contentType\n */\n async getJobForSingleType(ctx: any) {\n const aiLocalizationsService = getService('ai-localizations');\n if ((await aiLocalizationsService.isEnabled()) === false) {\n return ctx.notFound();\n }\n\n const { contentType } = ctx.params;\n\n if (!contentType) {\n return ctx.badRequest('contentType is required');\n }\n\n try {\n const job = await aiLocalizationJobsService.getJobByContentType(contentType);\n\n ctx.body = {\n data: job,\n };\n } catch (error) {\n strapi.log.error('[AI Localizations Jobs] Error fetching job:', error);\n ctx.internalServerError('Failed to fetch AI localizations job');\n }\n },\n /**\n * Get a job for a collectionType using the documentId\n * There is only 1 job per documentId\n */\n async getJobForCollectionType(ctx: any) {\n const aiLocalizationsService = getService('ai-localizations');\n if ((await aiLocalizationsService.isEnabled()) === false) {\n return ctx.notFound();\n }\n\n const { documentId, contentType } = ctx.params;\n\n if (!documentId || !contentType) {\n return ctx.badRequest('Document ID and contentType are required');\n }\n\n try {\n const job = await aiLocalizationJobsService.getJobByDocument(contentType, documentId);\n\n ctx.body = {\n data: job,\n };\n } catch (error) {\n strapi.log.error('[AI Localizations Jobs] Error fetching job:', error);\n ctx.internalServerError('Failed to fetch AI localizations job');\n }\n },\n };\n};\n\nexport default createAILocalizationJobsController;\n"],"names":["createAILocalizationJobsController","strapi","getService","name","plugin","service","aiLocalizationJobsService","getJobForSingleType","ctx","aiLocalizationsService","isEnabled","notFound","contentType","params","badRequest","job","getJobByContentType","body","data","error","log","internalServerError","getJobForCollectionType","documentId","getJobByDocument"],"mappings":"AAEA,MAAMA,kCAAAA,GAAqC,CAAC,EAAEC,MAAM,EAA2B,GAAA;IAC7E,MAAMC,UAAAA,GAAa,CAACC,IAAAA,GAAiBF,MAAAA,CAAOG,MAAM,CAAC,MAAA,CAAA,CAAQC,OAAO,CAACF,IAAAA,CAAAA;AACnE,IAAA,MAAMG,4BAA4BJ,UAAAA,CAAW,sBAAA,CAAA;IAE7C,OAAO;AACL;;;QAIA,MAAMK,qBAAoBC,GAAQ,EAAA;AAChC,YAAA,MAAMC,yBAAyBP,UAAAA,CAAW,kBAAA,CAAA;AAC1C,YAAA,IAAI,MAAOO,sBAAAA,CAAuBC,SAAS,OAAQ,KAAA,EAAO;AACxD,gBAAA,OAAOF,IAAIG,QAAQ,EAAA;AACrB,YAAA;AAEA,YAAA,MAAM,EAAEC,WAAW,EAAE,GAAGJ,IAAIK,MAAM;AAElC,YAAA,IAAI,CAACD,WAAAA,EAAa;gBAChB,OAAOJ,GAAAA,CAAIM,UAAU,CAAC,yBAAA,CAAA;AACxB,YAAA;YAEA,IAAI;AACF,gBAAA,MAAMC,GAAAA,GAAM,MAAMT,yBAAAA,CAA0BU,mBAAmB,CAACJ,WAAAA,CAAAA;AAEhEJ,gBAAAA,GAAAA,CAAIS,IAAI,GAAG;oBACTC,IAAAA,EAAMH;AACR,iBAAA;AACF,YAAA,CAAA,CAAE,OAAOI,KAAAA,EAAO;AACdlB,gBAAAA,MAAAA,CAAOmB,GAAG,CAACD,KAAK,CAAC,6CAAA,EAA+CA,KAAAA,CAAAA;AAChEX,gBAAAA,GAAAA,CAAIa,mBAAmB,CAAC,sCAAA,CAAA;AAC1B,YAAA;AACF,QAAA,CAAA;AACA;;;QAIA,MAAMC,yBAAwBd,GAAQ,EAAA;AACpC,YAAA,MAAMC,yBAAyBP,UAAAA,CAAW,kBAAA,CAAA;AAC1C,YAAA,IAAI,MAAOO,sBAAAA,CAAuBC,SAAS,OAAQ,KAAA,EAAO;AACxD,gBAAA,OAAOF,IAAIG,QAAQ,EAAA;AACrB,YAAA;AAEA,YAAA,MAAM,EAAEY,UAAU,EAAEX,WAAW,EAAE,GAAGJ,IAAIK,MAAM;YAE9C,IAAI,CAACU,UAAAA,IAAc,CAACX,WAAAA,EAAa;gBAC/B,OAAOJ,GAAAA,CAAIM,UAAU,CAAC,0CAAA,CAAA;AACxB,YAAA;YAEA,IAAI;AACF,gBAAA,MAAMC,GAAAA,GAAM,MAAMT,yBAAAA,CAA0BkB,gBAAgB,CAACZ,WAAAA,EAAaW,UAAAA,CAAAA;AAE1Ef,gBAAAA,GAAAA,CAAIS,IAAI,GAAG;oBACTC,IAAAA,EAAMH;AACR,iBAAA;AACF,YAAA,CAAA,CAAE,OAAOI,KAAAA,EAAO;AACdlB,gBAAAA,MAAAA,CAAOmB,GAAG,CAACD,KAAK,CAAC,6CAAA,EAA+CA,KAAAA,CAAAA;AAChEX,gBAAAA,GAAAA,CAAIa,mBAAmB,CAAC,sCAAA,CAAA;AAC1B,YAAA;AACF,QAAA;AACF,KAAA;AACF;;;;"}
|
|
@@ -12,7 +12,7 @@ const getFieldsProperty = fp.prop('properties.fields');
|
|
|
12
12
|
const getFirstLevelPath = fp.map((path)=>path.split('.')[0]);
|
|
13
13
|
const controller = {
|
|
14
14
|
async getNonLocalizedAttributes (ctx) {
|
|
15
|
-
const { user } = ctx.state;
|
|
15
|
+
const { user, userAbility } = ctx.state;
|
|
16
16
|
const body = ctx.request.body;
|
|
17
17
|
const { model, id, locale } = body;
|
|
18
18
|
await contentTypes.validateGetNonLocalizedAttributesInput({
|
|
@@ -20,6 +20,13 @@ const controller = {
|
|
|
20
20
|
id,
|
|
21
21
|
locale
|
|
22
22
|
});
|
|
23
|
+
const permissionChecker = strapi.plugin('content-manager').service('permission-checker').create({
|
|
24
|
+
userAbility,
|
|
25
|
+
model
|
|
26
|
+
});
|
|
27
|
+
if (permissionChecker.cannot.read()) {
|
|
28
|
+
return ctx.forbidden();
|
|
29
|
+
}
|
|
23
30
|
const { copyNonLocalizedAttributes, isLocalizedContentType, getNestedPopulateOfNonLocalizedAttributes } = index.getService('content-types');
|
|
24
31
|
const { default: { READ_ACTION, CREATE_ACTION } } = strapi.service('admin::constants');
|
|
25
32
|
const modelDef = strapi.contentType(model);
|
|
@@ -52,7 +59,15 @@ const controller = {
|
|
|
52
59
|
const localePermissions = permissions.filter((perm)=>getLocalesProperty(perm).includes(locale)).map(getFieldsProperty);
|
|
53
60
|
const permittedFields = fp.pipe(fp.flatten, getFirstLevelPath, fp.uniq)(localePermissions);
|
|
54
61
|
const nonLocalizedFields = copyNonLocalizedAttributes(modelDef, entity);
|
|
55
|
-
const
|
|
62
|
+
const pickedFields = fp.pick(permittedFields, nonLocalizedFields);
|
|
63
|
+
// Guard relations: omit fields that point to content types the user cannot read
|
|
64
|
+
const sanitizedNonLocalizedFields = Object.fromEntries(Object.entries(pickedFields).filter(([key])=>{
|
|
65
|
+
const attribute = modelDef.attributes?.[key];
|
|
66
|
+
if (attribute?.type === 'relation' && attribute.target) {
|
|
67
|
+
return userAbility.can(READ_ACTION, attribute.target);
|
|
68
|
+
}
|
|
69
|
+
return true;
|
|
70
|
+
}));
|
|
56
71
|
const availableLocalesResult = await strapi.plugins['content-manager'].service('document-metadata').getMetadata(model, entity, {
|
|
57
72
|
availableLocales: true
|
|
58
73
|
});
|
|
@@ -69,6 +84,31 @@ const controller = {
|
|
|
69
84
|
PUBLISHED_AT_ATTRIBUTE
|
|
70
85
|
], entity))
|
|
71
86
|
};
|
|
87
|
+
},
|
|
88
|
+
async getFillFromLocaleData (ctx) {
|
|
89
|
+
const { userAbility } = ctx.state;
|
|
90
|
+
const { model } = ctx.params;
|
|
91
|
+
await contentTypes.validateFillFromLocaleInput(ctx.query);
|
|
92
|
+
const { documentId, sourceLocale, targetLocale } = ctx.query;
|
|
93
|
+
const permissionChecker = strapi.plugin('content-manager').service('permission-checker').create({
|
|
94
|
+
userAbility,
|
|
95
|
+
model
|
|
96
|
+
});
|
|
97
|
+
if (permissionChecker.cannot.read()) {
|
|
98
|
+
return ctx.forbidden();
|
|
99
|
+
}
|
|
100
|
+
const fillFromLocaleService = index.getService('fill-from-locale');
|
|
101
|
+
const rawDocument = await fillFromLocaleService.fetchRawDocument(model, sourceLocale, documentId);
|
|
102
|
+
if (!rawDocument) {
|
|
103
|
+
return ctx.notFound();
|
|
104
|
+
}
|
|
105
|
+
// Field-level filtering: strip fields the user cannot read on this content type
|
|
106
|
+
const sanitizedDocument = await permissionChecker.sanitizeOutput(rawDocument);
|
|
107
|
+
// Transform relations to target locale, skipping those the user cannot read
|
|
108
|
+
const data = await fillFromLocaleService.transformDocument(sanitizedDocument, model, targetLocale, userAbility);
|
|
109
|
+
ctx.body = {
|
|
110
|
+
data
|
|
111
|
+
};
|
|
72
112
|
}
|
|
73
113
|
};
|
|
74
114
|
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"content-types.js","sources":["../../../server/src/controllers/content-types.ts"],"sourcesContent":["import { pick, uniq, prop, getOr, flatten, pipe, map } from 'lodash/fp';\nimport { contentTypes as contentTypesUtils, errors } from '@strapi/utils';\nimport type { Core } from '@strapi/types';\nimport { getService } from '../utils';\nimport { validateGetNonLocalizedAttributesInput } from '../validation/content-types';\n\nconst { ApplicationError } = errors;\n\nconst { PUBLISHED_AT_ATTRIBUTE } = contentTypesUtils.constants;\n\nconst getLocalesProperty = getOr<string[]>([], 'properties.locales');\nconst getFieldsProperty = prop('properties.fields');\n\nconst getFirstLevelPath = map((path: string) => path.split('.')[0]);\n\nconst controller = {\n async getNonLocalizedAttributes(ctx) {\n const { user } = ctx.state;\n const body = ctx.request.body as any;\n const { model, id, locale } = body;\n\n await validateGetNonLocalizedAttributesInput({ model, id, locale });\n\n const {\n copyNonLocalizedAttributes,\n isLocalizedContentType,\n getNestedPopulateOfNonLocalizedAttributes,\n } = getService('content-types');\n\n const {\n default: { READ_ACTION, CREATE_ACTION },\n } = strapi.service('admin::constants');\n\n const modelDef = strapi.contentType(model);\n const attributesToPopulate = getNestedPopulateOfNonLocalizedAttributes(model);\n\n if (!isLocalizedContentType(modelDef)) {\n throw new ApplicationError(`Model ${model} is not localized`);\n }\n\n const params = modelDef.kind === 'singleType' ? {} : { id };\n\n const entity = await strapi.db\n .query(model)\n .findOne({ where: params, populate: attributesToPopulate });\n\n if (!entity) {\n return ctx.notFound();\n }\n\n const permissions = await strapi.admin.services.permission.findMany({\n where: {\n action: [READ_ACTION, CREATE_ACTION],\n subject: model,\n role: {\n id: user.roles.map(prop('id')),\n },\n },\n });\n\n const localePermissions = permissions\n .filter((perm: any) => getLocalesProperty(perm).includes(locale))\n .map(getFieldsProperty);\n\n const permittedFields = pipe(flatten, getFirstLevelPath, uniq)(localePermissions);\n\n const nonLocalizedFields = copyNonLocalizedAttributes(modelDef, entity);\n const sanitizedNonLocalizedFields = pick(permittedFields, nonLocalizedFields);\n\n const availableLocalesResult = await strapi.plugins['content-manager']\n .service('document-metadata')\n .getMetadata(model, entity, {\n availableLocales: true,\n });\n\n const availableLocales = availableLocalesResult.availableLocales.map((localeResult: any) =>\n pick(['id', 'locale', PUBLISHED_AT_ATTRIBUTE], localeResult)\n );\n\n ctx.body = {\n nonLocalizedFields: sanitizedNonLocalizedFields,\n localizations: availableLocales.concat(\n pick(['id', 'locale', PUBLISHED_AT_ATTRIBUTE], entity)\n ),\n };\n },\n} satisfies Core.Controller;\n\nexport default controller;\n"],"names":["ApplicationError","errors","PUBLISHED_AT_ATTRIBUTE","contentTypesUtils","constants","getLocalesProperty","getOr","getFieldsProperty","prop","getFirstLevelPath","map","path","split","controller","getNonLocalizedAttributes","ctx","user","state","body","request","model","id","locale","validateGetNonLocalizedAttributesInput","copyNonLocalizedAttributes","isLocalizedContentType","getNestedPopulateOfNonLocalizedAttributes","getService","default","READ_ACTION","CREATE_ACTION","strapi","service","modelDef","contentType","attributesToPopulate","params","kind","entity","db","query","findOne","where","populate","notFound","permissions","admin","services","permission","findMany","action","subject","role","roles","localePermissions","filter","perm","includes","permittedFields","pipe","flatten","uniq","nonLocalizedFields","sanitizedNonLocalizedFields","pick","availableLocalesResult","plugins","getMetadata","availableLocales","localeResult","localizations","concat"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"content-types.js","sources":["../../../server/src/controllers/content-types.ts"],"sourcesContent":["import { pick, uniq, prop, getOr, flatten, pipe, map } from 'lodash/fp';\nimport { contentTypes as contentTypesUtils, errors } from '@strapi/utils';\nimport type { Core, UID } from '@strapi/types';\nimport type { FillFromLocale } from '../../../shared/contracts/content-manager';\nimport { getService } from '../utils';\nimport {\n validateGetNonLocalizedAttributesInput,\n validateFillFromLocaleInput,\n} from '../validation/content-types';\n\nconst { ApplicationError } = errors;\n\nconst { PUBLISHED_AT_ATTRIBUTE } = contentTypesUtils.constants;\n\nconst getLocalesProperty = getOr<string[]>([], 'properties.locales');\nconst getFieldsProperty = prop('properties.fields');\n\nconst getFirstLevelPath = map((path: string) => path.split('.')[0]);\n\nconst controller = {\n async getNonLocalizedAttributes(ctx) {\n const { user, userAbility } = ctx.state;\n const body = ctx.request.body as any;\n const { model, id, locale } = body;\n\n await validateGetNonLocalizedAttributesInput({ model, id, locale });\n\n const permissionChecker = strapi\n .plugin('content-manager')\n .service('permission-checker')\n .create({ userAbility, model });\n\n if (permissionChecker.cannot.read()) {\n return ctx.forbidden();\n }\n\n const {\n copyNonLocalizedAttributes,\n isLocalizedContentType,\n getNestedPopulateOfNonLocalizedAttributes,\n } = getService('content-types');\n\n const {\n default: { READ_ACTION, CREATE_ACTION },\n } = strapi.service('admin::constants');\n\n const modelDef = strapi.contentType(model);\n const attributesToPopulate = getNestedPopulateOfNonLocalizedAttributes(model);\n\n if (!isLocalizedContentType(modelDef)) {\n throw new ApplicationError(`Model ${model} is not localized`);\n }\n\n const params = modelDef.kind === 'singleType' ? {} : { id };\n\n const entity = await strapi.db\n .query(model)\n .findOne({ where: params, populate: attributesToPopulate });\n\n if (!entity) {\n return ctx.notFound();\n }\n\n const permissions = await strapi.admin.services.permission.findMany({\n where: {\n action: [READ_ACTION, CREATE_ACTION],\n subject: model,\n role: {\n id: user.roles.map(prop('id')),\n },\n },\n });\n\n const localePermissions = permissions\n .filter((perm: any) => getLocalesProperty(perm).includes(locale))\n .map(getFieldsProperty);\n\n const permittedFields = pipe(flatten, getFirstLevelPath, uniq)(localePermissions);\n\n const nonLocalizedFields = copyNonLocalizedAttributes(modelDef, entity);\n const pickedFields = pick(permittedFields, nonLocalizedFields);\n\n // Guard relations: omit fields that point to content types the user cannot read\n const sanitizedNonLocalizedFields = Object.fromEntries(\n Object.entries(pickedFields).filter(([key]) => {\n const attribute = modelDef.attributes?.[key] as any;\n if (attribute?.type === 'relation' && attribute.target) {\n return userAbility.can(READ_ACTION, attribute.target);\n }\n return true;\n })\n );\n\n const availableLocalesResult = await strapi.plugins['content-manager']\n .service('document-metadata')\n .getMetadata(model, entity, {\n availableLocales: true,\n });\n\n const availableLocales = availableLocalesResult.availableLocales.map((localeResult: any) =>\n pick(['id', 'locale', PUBLISHED_AT_ATTRIBUTE], localeResult)\n );\n\n ctx.body = {\n nonLocalizedFields: sanitizedNonLocalizedFields,\n localizations: availableLocales.concat(\n pick(['id', 'locale', PUBLISHED_AT_ATTRIBUTE], entity)\n ),\n };\n },\n\n async getFillFromLocaleData(ctx) {\n const { userAbility } = ctx.state;\n const { model } = ctx.params;\n\n await validateFillFromLocaleInput(ctx.query);\n\n const { documentId, sourceLocale, targetLocale } = ctx.query as unknown as Omit<\n FillFromLocale.Params,\n 'model'\n >;\n\n const permissionChecker = strapi\n .plugin('content-manager')\n .service('permission-checker')\n .create({ userAbility, model });\n\n if (permissionChecker.cannot.read()) {\n return ctx.forbidden();\n }\n\n const fillFromLocaleService = getService('fill-from-locale');\n\n const rawDocument = await fillFromLocaleService.fetchRawDocument(\n model as UID.ContentType,\n sourceLocale,\n documentId\n );\n\n if (!rawDocument) {\n return ctx.notFound();\n }\n\n // Field-level filtering: strip fields the user cannot read on this content type\n const sanitizedDocument = await permissionChecker.sanitizeOutput(rawDocument);\n\n // Transform relations to target locale, skipping those the user cannot read\n const data = await fillFromLocaleService.transformDocument(\n sanitizedDocument as Record<string, unknown>,\n model as UID.ContentType,\n targetLocale,\n userAbility\n );\n\n ctx.body = { data };\n },\n} satisfies Core.Controller;\n\nexport default controller;\n"],"names":["ApplicationError","errors","PUBLISHED_AT_ATTRIBUTE","contentTypesUtils","constants","getLocalesProperty","getOr","getFieldsProperty","prop","getFirstLevelPath","map","path","split","controller","getNonLocalizedAttributes","ctx","user","userAbility","state","body","request","model","id","locale","validateGetNonLocalizedAttributesInput","permissionChecker","strapi","plugin","service","create","cannot","read","forbidden","copyNonLocalizedAttributes","isLocalizedContentType","getNestedPopulateOfNonLocalizedAttributes","getService","default","READ_ACTION","CREATE_ACTION","modelDef","contentType","attributesToPopulate","params","kind","entity","db","query","findOne","where","populate","notFound","permissions","admin","services","permission","findMany","action","subject","role","roles","localePermissions","filter","perm","includes","permittedFields","pipe","flatten","uniq","nonLocalizedFields","pickedFields","pick","sanitizedNonLocalizedFields","Object","fromEntries","entries","key","attribute","attributes","type","target","can","availableLocalesResult","plugins","getMetadata","availableLocales","localeResult","localizations","concat","getFillFromLocaleData","validateFillFromLocaleInput","documentId","sourceLocale","targetLocale","fillFromLocaleService","rawDocument","fetchRawDocument","sanitizedDocument","sanitizeOutput","data","transformDocument"],"mappings":"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"}
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { getOr, prop, map, pipe, flatten, uniq, pick } from 'lodash/fp';
|
|
2
2
|
import { errors, contentTypes } from '@strapi/utils';
|
|
3
3
|
import { getService } from '../utils/index.mjs';
|
|
4
|
-
import { validateGetNonLocalizedAttributesInput } from '../validation/content-types.mjs';
|
|
4
|
+
import { validateFillFromLocaleInput, validateGetNonLocalizedAttributesInput } from '../validation/content-types.mjs';
|
|
5
5
|
|
|
6
6
|
const { ApplicationError } = errors;
|
|
7
7
|
const { PUBLISHED_AT_ATTRIBUTE } = contentTypes.constants;
|
|
@@ -10,7 +10,7 @@ const getFieldsProperty = prop('properties.fields');
|
|
|
10
10
|
const getFirstLevelPath = map((path)=>path.split('.')[0]);
|
|
11
11
|
const controller = {
|
|
12
12
|
async getNonLocalizedAttributes (ctx) {
|
|
13
|
-
const { user } = ctx.state;
|
|
13
|
+
const { user, userAbility } = ctx.state;
|
|
14
14
|
const body = ctx.request.body;
|
|
15
15
|
const { model, id, locale } = body;
|
|
16
16
|
await validateGetNonLocalizedAttributesInput({
|
|
@@ -18,6 +18,13 @@ const controller = {
|
|
|
18
18
|
id,
|
|
19
19
|
locale
|
|
20
20
|
});
|
|
21
|
+
const permissionChecker = strapi.plugin('content-manager').service('permission-checker').create({
|
|
22
|
+
userAbility,
|
|
23
|
+
model
|
|
24
|
+
});
|
|
25
|
+
if (permissionChecker.cannot.read()) {
|
|
26
|
+
return ctx.forbidden();
|
|
27
|
+
}
|
|
21
28
|
const { copyNonLocalizedAttributes, isLocalizedContentType, getNestedPopulateOfNonLocalizedAttributes } = getService('content-types');
|
|
22
29
|
const { default: { READ_ACTION, CREATE_ACTION } } = strapi.service('admin::constants');
|
|
23
30
|
const modelDef = strapi.contentType(model);
|
|
@@ -50,7 +57,15 @@ const controller = {
|
|
|
50
57
|
const localePermissions = permissions.filter((perm)=>getLocalesProperty(perm).includes(locale)).map(getFieldsProperty);
|
|
51
58
|
const permittedFields = pipe(flatten, getFirstLevelPath, uniq)(localePermissions);
|
|
52
59
|
const nonLocalizedFields = copyNonLocalizedAttributes(modelDef, entity);
|
|
53
|
-
const
|
|
60
|
+
const pickedFields = pick(permittedFields, nonLocalizedFields);
|
|
61
|
+
// Guard relations: omit fields that point to content types the user cannot read
|
|
62
|
+
const sanitizedNonLocalizedFields = Object.fromEntries(Object.entries(pickedFields).filter(([key])=>{
|
|
63
|
+
const attribute = modelDef.attributes?.[key];
|
|
64
|
+
if (attribute?.type === 'relation' && attribute.target) {
|
|
65
|
+
return userAbility.can(READ_ACTION, attribute.target);
|
|
66
|
+
}
|
|
67
|
+
return true;
|
|
68
|
+
}));
|
|
54
69
|
const availableLocalesResult = await strapi.plugins['content-manager'].service('document-metadata').getMetadata(model, entity, {
|
|
55
70
|
availableLocales: true
|
|
56
71
|
});
|
|
@@ -67,6 +82,31 @@ const controller = {
|
|
|
67
82
|
PUBLISHED_AT_ATTRIBUTE
|
|
68
83
|
], entity))
|
|
69
84
|
};
|
|
85
|
+
},
|
|
86
|
+
async getFillFromLocaleData (ctx) {
|
|
87
|
+
const { userAbility } = ctx.state;
|
|
88
|
+
const { model } = ctx.params;
|
|
89
|
+
await validateFillFromLocaleInput(ctx.query);
|
|
90
|
+
const { documentId, sourceLocale, targetLocale } = ctx.query;
|
|
91
|
+
const permissionChecker = strapi.plugin('content-manager').service('permission-checker').create({
|
|
92
|
+
userAbility,
|
|
93
|
+
model
|
|
94
|
+
});
|
|
95
|
+
if (permissionChecker.cannot.read()) {
|
|
96
|
+
return ctx.forbidden();
|
|
97
|
+
}
|
|
98
|
+
const fillFromLocaleService = getService('fill-from-locale');
|
|
99
|
+
const rawDocument = await fillFromLocaleService.fetchRawDocument(model, sourceLocale, documentId);
|
|
100
|
+
if (!rawDocument) {
|
|
101
|
+
return ctx.notFound();
|
|
102
|
+
}
|
|
103
|
+
// Field-level filtering: strip fields the user cannot read on this content type
|
|
104
|
+
const sanitizedDocument = await permissionChecker.sanitizeOutput(rawDocument);
|
|
105
|
+
// Transform relations to target locale, skipping those the user cannot read
|
|
106
|
+
const data = await fillFromLocaleService.transformDocument(sanitizedDocument, model, targetLocale, userAbility);
|
|
107
|
+
ctx.body = {
|
|
108
|
+
data
|
|
109
|
+
};
|
|
70
110
|
}
|
|
71
111
|
};
|
|
72
112
|
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"content-types.mjs","sources":["../../../server/src/controllers/content-types.ts"],"sourcesContent":["import { pick, uniq, prop, getOr, flatten, pipe, map } from 'lodash/fp';\nimport { contentTypes as contentTypesUtils, errors } from '@strapi/utils';\nimport type { Core } from '@strapi/types';\nimport { getService } from '../utils';\nimport { validateGetNonLocalizedAttributesInput } from '../validation/content-types';\n\nconst { ApplicationError } = errors;\n\nconst { PUBLISHED_AT_ATTRIBUTE } = contentTypesUtils.constants;\n\nconst getLocalesProperty = getOr<string[]>([], 'properties.locales');\nconst getFieldsProperty = prop('properties.fields');\n\nconst getFirstLevelPath = map((path: string) => path.split('.')[0]);\n\nconst controller = {\n async getNonLocalizedAttributes(ctx) {\n const { user } = ctx.state;\n const body = ctx.request.body as any;\n const { model, id, locale } = body;\n\n await validateGetNonLocalizedAttributesInput({ model, id, locale });\n\n const {\n copyNonLocalizedAttributes,\n isLocalizedContentType,\n getNestedPopulateOfNonLocalizedAttributes,\n } = getService('content-types');\n\n const {\n default: { READ_ACTION, CREATE_ACTION },\n } = strapi.service('admin::constants');\n\n const modelDef = strapi.contentType(model);\n const attributesToPopulate = getNestedPopulateOfNonLocalizedAttributes(model);\n\n if (!isLocalizedContentType(modelDef)) {\n throw new ApplicationError(`Model ${model} is not localized`);\n }\n\n const params = modelDef.kind === 'singleType' ? {} : { id };\n\n const entity = await strapi.db\n .query(model)\n .findOne({ where: params, populate: attributesToPopulate });\n\n if (!entity) {\n return ctx.notFound();\n }\n\n const permissions = await strapi.admin.services.permission.findMany({\n where: {\n action: [READ_ACTION, CREATE_ACTION],\n subject: model,\n role: {\n id: user.roles.map(prop('id')),\n },\n },\n });\n\n const localePermissions = permissions\n .filter((perm: any) => getLocalesProperty(perm).includes(locale))\n .map(getFieldsProperty);\n\n const permittedFields = pipe(flatten, getFirstLevelPath, uniq)(localePermissions);\n\n const nonLocalizedFields = copyNonLocalizedAttributes(modelDef, entity);\n const sanitizedNonLocalizedFields = pick(permittedFields, nonLocalizedFields);\n\n const availableLocalesResult = await strapi.plugins['content-manager']\n .service('document-metadata')\n .getMetadata(model, entity, {\n availableLocales: true,\n });\n\n const availableLocales = availableLocalesResult.availableLocales.map((localeResult: any) =>\n pick(['id', 'locale', PUBLISHED_AT_ATTRIBUTE], localeResult)\n );\n\n ctx.body = {\n nonLocalizedFields: sanitizedNonLocalizedFields,\n localizations: availableLocales.concat(\n pick(['id', 'locale', PUBLISHED_AT_ATTRIBUTE], entity)\n ),\n };\n },\n} satisfies Core.Controller;\n\nexport default controller;\n"],"names":["ApplicationError","errors","PUBLISHED_AT_ATTRIBUTE","contentTypesUtils","constants","getLocalesProperty","getOr","getFieldsProperty","prop","getFirstLevelPath","map","path","split","controller","getNonLocalizedAttributes","ctx","user","state","body","request","model","id","locale","validateGetNonLocalizedAttributesInput","copyNonLocalizedAttributes","isLocalizedContentType","getNestedPopulateOfNonLocalizedAttributes","getService","default","READ_ACTION","CREATE_ACTION","strapi","service","modelDef","contentType","attributesToPopulate","params","kind","entity","db","query","findOne","where","populate","notFound","permissions","admin","services","permission","findMany","action","subject","role","roles","localePermissions","filter","perm","includes","permittedFields","pipe","flatten","uniq","nonLocalizedFields","sanitizedNonLocalizedFields","pick","availableLocalesResult","plugins","getMetadata","availableLocales","localeResult","localizations","concat"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"content-types.mjs","sources":["../../../server/src/controllers/content-types.ts"],"sourcesContent":["import { pick, uniq, prop, getOr, flatten, pipe, map } from 'lodash/fp';\nimport { contentTypes as contentTypesUtils, errors } from '@strapi/utils';\nimport type { Core, UID } from '@strapi/types';\nimport type { FillFromLocale } from '../../../shared/contracts/content-manager';\nimport { getService } from '../utils';\nimport {\n validateGetNonLocalizedAttributesInput,\n validateFillFromLocaleInput,\n} from '../validation/content-types';\n\nconst { ApplicationError } = errors;\n\nconst { PUBLISHED_AT_ATTRIBUTE } = contentTypesUtils.constants;\n\nconst getLocalesProperty = getOr<string[]>([], 'properties.locales');\nconst getFieldsProperty = prop('properties.fields');\n\nconst getFirstLevelPath = map((path: string) => path.split('.')[0]);\n\nconst controller = {\n async getNonLocalizedAttributes(ctx) {\n const { user, userAbility } = ctx.state;\n const body = ctx.request.body as any;\n const { model, id, locale } = body;\n\n await validateGetNonLocalizedAttributesInput({ model, id, locale });\n\n const permissionChecker = strapi\n .plugin('content-manager')\n .service('permission-checker')\n .create({ userAbility, model });\n\n if (permissionChecker.cannot.read()) {\n return ctx.forbidden();\n }\n\n const {\n copyNonLocalizedAttributes,\n isLocalizedContentType,\n getNestedPopulateOfNonLocalizedAttributes,\n } = getService('content-types');\n\n const {\n default: { READ_ACTION, CREATE_ACTION },\n } = strapi.service('admin::constants');\n\n const modelDef = strapi.contentType(model);\n const attributesToPopulate = getNestedPopulateOfNonLocalizedAttributes(model);\n\n if (!isLocalizedContentType(modelDef)) {\n throw new ApplicationError(`Model ${model} is not localized`);\n }\n\n const params = modelDef.kind === 'singleType' ? {} : { id };\n\n const entity = await strapi.db\n .query(model)\n .findOne({ where: params, populate: attributesToPopulate });\n\n if (!entity) {\n return ctx.notFound();\n }\n\n const permissions = await strapi.admin.services.permission.findMany({\n where: {\n action: [READ_ACTION, CREATE_ACTION],\n subject: model,\n role: {\n id: user.roles.map(prop('id')),\n },\n },\n });\n\n const localePermissions = permissions\n .filter((perm: any) => getLocalesProperty(perm).includes(locale))\n .map(getFieldsProperty);\n\n const permittedFields = pipe(flatten, getFirstLevelPath, uniq)(localePermissions);\n\n const nonLocalizedFields = copyNonLocalizedAttributes(modelDef, entity);\n const pickedFields = pick(permittedFields, nonLocalizedFields);\n\n // Guard relations: omit fields that point to content types the user cannot read\n const sanitizedNonLocalizedFields = Object.fromEntries(\n Object.entries(pickedFields).filter(([key]) => {\n const attribute = modelDef.attributes?.[key] as any;\n if (attribute?.type === 'relation' && attribute.target) {\n return userAbility.can(READ_ACTION, attribute.target);\n }\n return true;\n })\n );\n\n const availableLocalesResult = await strapi.plugins['content-manager']\n .service('document-metadata')\n .getMetadata(model, entity, {\n availableLocales: true,\n });\n\n const availableLocales = availableLocalesResult.availableLocales.map((localeResult: any) =>\n pick(['id', 'locale', PUBLISHED_AT_ATTRIBUTE], localeResult)\n );\n\n ctx.body = {\n nonLocalizedFields: sanitizedNonLocalizedFields,\n localizations: availableLocales.concat(\n pick(['id', 'locale', PUBLISHED_AT_ATTRIBUTE], entity)\n ),\n };\n },\n\n async getFillFromLocaleData(ctx) {\n const { userAbility } = ctx.state;\n const { model } = ctx.params;\n\n await validateFillFromLocaleInput(ctx.query);\n\n const { documentId, sourceLocale, targetLocale } = ctx.query as unknown as Omit<\n FillFromLocale.Params,\n 'model'\n >;\n\n const permissionChecker = strapi\n .plugin('content-manager')\n .service('permission-checker')\n .create({ userAbility, model });\n\n if (permissionChecker.cannot.read()) {\n return ctx.forbidden();\n }\n\n const fillFromLocaleService = getService('fill-from-locale');\n\n const rawDocument = await fillFromLocaleService.fetchRawDocument(\n model as UID.ContentType,\n sourceLocale,\n documentId\n );\n\n if (!rawDocument) {\n return ctx.notFound();\n }\n\n // Field-level filtering: strip fields the user cannot read on this content type\n const sanitizedDocument = await permissionChecker.sanitizeOutput(rawDocument);\n\n // Transform relations to target locale, skipping those the user cannot read\n const data = await fillFromLocaleService.transformDocument(\n sanitizedDocument as Record<string, unknown>,\n model as UID.ContentType,\n targetLocale,\n userAbility\n );\n\n ctx.body = { data };\n },\n} satisfies Core.Controller;\n\nexport default controller;\n"],"names":["ApplicationError","errors","PUBLISHED_AT_ATTRIBUTE","contentTypesUtils","constants","getLocalesProperty","getOr","getFieldsProperty","prop","getFirstLevelPath","map","path","split","controller","getNonLocalizedAttributes","ctx","user","userAbility","state","body","request","model","id","locale","validateGetNonLocalizedAttributesInput","permissionChecker","strapi","plugin","service","create","cannot","read","forbidden","copyNonLocalizedAttributes","isLocalizedContentType","getNestedPopulateOfNonLocalizedAttributes","getService","default","READ_ACTION","CREATE_ACTION","modelDef","contentType","attributesToPopulate","params","kind","entity","db","query","findOne","where","populate","notFound","permissions","admin","services","permission","findMany","action","subject","role","roles","localePermissions","filter","perm","includes","permittedFields","pipe","flatten","uniq","nonLocalizedFields","pickedFields","pick","sanitizedNonLocalizedFields","Object","fromEntries","entries","key","attribute","attributes","type","target","can","availableLocalesResult","plugins","getMetadata","availableLocales","localeResult","localizations","concat","getFillFromLocaleData","validateFillFromLocaleInput","documentId","sourceLocale","targetLocale","fillFromLocaleService","rawDocument","fetchRawDocument","sanitizedDocument","sanitizeOutput","data","transformDocument"],"mappings":";;;;;AAUA,MAAM,EAAEA,gBAAgB,EAAE,GAAGC,MAAAA;AAE7B,MAAM,EAAEC,sBAAsB,EAAE,GAAGC,aAAkBC,SAAS;AAE9D,MAAMC,kBAAAA,GAAqBC,KAAAA,CAAgB,EAAE,EAAE,oBAAA,CAAA;AAC/C,MAAMC,oBAAoBC,IAAAA,CAAK,mBAAA,CAAA;AAE/B,MAAMC,iBAAAA,GAAoBC,IAAI,CAACC,IAAAA,GAAiBA,KAAKC,KAAK,CAAC,GAAA,CAAI,CAAC,CAAA,CAAE,CAAA;AAElE,MAAMC,UAAAA,GAAa;AACjB,IAAA,MAAMC,2BAA0BC,GAAG,EAAA;AACjC,QAAA,MAAM,EAAEC,IAAI,EAAEC,WAAW,EAAE,GAAGF,IAAIG,KAAK;AACvC,QAAA,MAAMC,IAAAA,GAAOJ,GAAAA,CAAIK,OAAO,CAACD,IAAI;AAC7B,QAAA,MAAM,EAAEE,KAAK,EAAEC,EAAE,EAAEC,MAAM,EAAE,GAAGJ,IAAAA;AAE9B,QAAA,MAAMK,sCAAAA,CAAuC;AAAEH,YAAAA,KAAAA;AAAOC,YAAAA,EAAAA;AAAIC,YAAAA;AAAO,SAAA,CAAA;QAEjE,MAAME,iBAAAA,GAAoBC,OACvBC,MAAM,CAAC,mBACPC,OAAO,CAAC,oBAAA,CAAA,CACRC,MAAM,CAAC;AAAEZ,YAAAA,WAAAA;AAAaI,YAAAA;AAAM,SAAA,CAAA;AAE/B,QAAA,IAAII,iBAAAA,CAAkBK,MAAM,CAACC,IAAI,EAAA,EAAI;AACnC,YAAA,OAAOhB,IAAIiB,SAAS,EAAA;AACtB,QAAA;QAEA,MAAM,EACJC,0BAA0B,EAC1BC,sBAAsB,EACtBC,yCAAyC,EAC1C,GAAGC,UAAAA,CAAW,eAAA,CAAA;QAEf,MAAM,EACJC,OAAAA,EAAS,EAAEC,WAAW,EAAEC,aAAa,EAAE,EACxC,GAAGb,MAAAA,CAAOE,OAAO,CAAC,kBAAA,CAAA;QAEnB,MAAMY,QAAAA,GAAWd,MAAAA,CAAOe,WAAW,CAACpB,KAAAA,CAAAA;AACpC,QAAA,MAAMqB,uBAAuBP,yCAAAA,CAA0Cd,KAAAA,CAAAA;QAEvE,IAAI,CAACa,uBAAuBM,QAAAA,CAAAA,EAAW;AACrC,YAAA,MAAM,IAAIxC,gBAAAA,CAAiB,CAAC,MAAM,EAAEqB,KAAAA,CAAM,iBAAiB,CAAC,CAAA;AAC9D,QAAA;AAEA,QAAA,MAAMsB,SAASH,QAAAA,CAASI,IAAI,KAAK,YAAA,GAAe,EAAC,GAAI;AAAEtB,YAAAA;AAAG,SAAA;QAE1D,MAAMuB,MAAAA,GAAS,MAAMnB,MAAAA,CAAOoB,EAAE,CAC3BC,KAAK,CAAC1B,KAAAA,CAAAA,CACN2B,OAAO,CAAC;YAAEC,KAAAA,EAAON,MAAAA;YAAQO,QAAAA,EAAUR;AAAqB,SAAA,CAAA;AAE3D,QAAA,IAAI,CAACG,MAAAA,EAAQ;AACX,YAAA,OAAO9B,IAAIoC,QAAQ,EAAA;AACrB,QAAA;QAEA,MAAMC,WAAAA,GAAc,MAAM1B,MAAAA,CAAO2B,KAAK,CAACC,QAAQ,CAACC,UAAU,CAACC,QAAQ,CAAC;YAClEP,KAAAA,EAAO;gBACLQ,MAAAA,EAAQ;AAACnB,oBAAAA,WAAAA;AAAaC,oBAAAA;AAAc,iBAAA;gBACpCmB,OAAAA,EAASrC,KAAAA;gBACTsC,IAAAA,EAAM;AACJrC,oBAAAA,EAAAA,EAAIN,IAAAA,CAAK4C,KAAK,CAAClD,GAAG,CAACF,IAAAA,CAAK,IAAA,CAAA;AAC1B;AACF;AACF,SAAA,CAAA;AAEA,QAAA,MAAMqD,iBAAAA,GAAoBT,WAAAA,CACvBU,MAAM,CAAC,CAACC,IAAAA,GAAc1D,kBAAAA,CAAmB0D,IAAAA,CAAAA,CAAMC,QAAQ,CAACzC,MAAAA,CAAAA,CAAAA,CACxDb,GAAG,CAACH,iBAAAA,CAAAA;AAEP,QAAA,MAAM0D,eAAAA,GAAkBC,IAAAA,CAAKC,OAAAA,EAAS1D,iBAAAA,EAAmB2D,IAAAA,CAAAA,CAAMP,iBAAAA,CAAAA;QAE/D,MAAMQ,kBAAAA,GAAqBpC,2BAA2BO,QAAAA,EAAUK,MAAAA,CAAAA;QAChE,MAAMyB,YAAAA,GAAeC,KAAKN,eAAAA,EAAiBI,kBAAAA,CAAAA;;AAG3C,QAAA,MAAMG,2BAAAA,GAA8BC,MAAAA,CAAOC,WAAW,CACpDD,MAAAA,CAAOE,OAAO,CAACL,YAAAA,CAAAA,CAAcR,MAAM,CAAC,CAAC,CAACc,GAAAA,CAAI,GAAA;AACxC,YAAA,MAAMC,SAAAA,GAAYrC,QAAAA,CAASsC,UAAU,GAAGF,GAAAA,CAAI;AAC5C,YAAA,IAAIC,SAAAA,EAAWE,IAAAA,KAAS,UAAA,IAAcF,SAAAA,CAAUG,MAAM,EAAE;AACtD,gBAAA,OAAO/D,WAAAA,CAAYgE,GAAG,CAAC3C,WAAAA,EAAauC,UAAUG,MAAM,CAAA;AACtD,YAAA;YACA,OAAO,IAAA;AACT,QAAA,CAAA,CAAA,CAAA;AAGF,QAAA,MAAME,sBAAAA,GAAyB,MAAMxD,MAAAA,CAAOyD,OAAO,CAAC,iBAAA,CAAkB,CACnEvD,OAAO,CAAC,mBAAA,CAAA,CACRwD,WAAW,CAAC/D,OAAOwB,MAAAA,EAAQ;YAC1BwC,gBAAAA,EAAkB;AACpB,SAAA,CAAA;QAEF,MAAMA,gBAAAA,GAAmBH,uBAAuBG,gBAAgB,CAAC3E,GAAG,CAAC,CAAC4E,eACpEf,IAAAA,CAAK;AAAC,gBAAA,IAAA;AAAM,gBAAA,QAAA;AAAUrE,gBAAAA;aAAuB,EAAEoF,YAAAA,CAAAA,CAAAA;AAGjDvE,QAAAA,GAAAA,CAAII,IAAI,GAAG;YACTkD,kBAAAA,EAAoBG,2BAAAA;YACpBe,aAAAA,EAAeF,gBAAAA,CAAiBG,MAAM,CACpCjB,IAAAA,CAAK;AAAC,gBAAA,IAAA;AAAM,gBAAA,QAAA;AAAUrE,gBAAAA;aAAuB,EAAE2C,MAAAA,CAAAA;AAEnD,SAAA;AACF,IAAA,CAAA;AAEA,IAAA,MAAM4C,uBAAsB1E,GAAG,EAAA;AAC7B,QAAA,MAAM,EAAEE,WAAW,EAAE,GAAGF,IAAIG,KAAK;AACjC,QAAA,MAAM,EAAEG,KAAK,EAAE,GAAGN,IAAI4B,MAAM;QAE5B,MAAM+C,2BAAAA,CAA4B3E,IAAIgC,KAAK,CAAA;QAE3C,MAAM,EAAE4C,UAAU,EAAEC,YAAY,EAAEC,YAAY,EAAE,GAAG9E,GAAAA,CAAIgC,KAAK;QAK5D,MAAMtB,iBAAAA,GAAoBC,OACvBC,MAAM,CAAC,mBACPC,OAAO,CAAC,oBAAA,CAAA,CACRC,MAAM,CAAC;AAAEZ,YAAAA,WAAAA;AAAaI,YAAAA;AAAM,SAAA,CAAA;AAE/B,QAAA,IAAII,iBAAAA,CAAkBK,MAAM,CAACC,IAAI,EAAA,EAAI;AACnC,YAAA,OAAOhB,IAAIiB,SAAS,EAAA;AACtB,QAAA;AAEA,QAAA,MAAM8D,wBAAwB1D,UAAAA,CAAW,kBAAA,CAAA;AAEzC,QAAA,MAAM2D,cAAc,MAAMD,qBAAAA,CAAsBE,gBAAgB,CAC9D3E,OACAuE,YAAAA,EACAD,UAAAA,CAAAA;AAGF,QAAA,IAAI,CAACI,WAAAA,EAAa;AAChB,YAAA,OAAOhF,IAAIoC,QAAQ,EAAA;AACrB,QAAA;;AAGA,QAAA,MAAM8C,iBAAAA,GAAoB,MAAMxE,iBAAAA,CAAkByE,cAAc,CAACH,WAAAA,CAAAA;;AAGjE,QAAA,MAAMI,OAAO,MAAML,qBAAAA,CAAsBM,iBAAiB,CACxDH,iBAAAA,EACA5E,OACAwE,YAAAA,EACA5E,WAAAA,CAAAA;AAGFF,QAAAA,GAAAA,CAAII,IAAI,GAAG;AAAEgF,YAAAA;AAAK,SAAA;AACpB,IAAA;AACF;;;;"}
|
|
@@ -95,6 +95,24 @@ var admin = {
|
|
|
95
95
|
]
|
|
96
96
|
}
|
|
97
97
|
},
|
|
98
|
+
{
|
|
99
|
+
method: 'GET',
|
|
100
|
+
path: '/content-manager/get-fill-from-locale/:model',
|
|
101
|
+
handler: 'content-types.getFillFromLocaleData',
|
|
102
|
+
config: {
|
|
103
|
+
policies: [
|
|
104
|
+
'admin::isAuthenticatedAdmin',
|
|
105
|
+
{
|
|
106
|
+
name: 'plugin::content-manager.hasPermissions',
|
|
107
|
+
config: {
|
|
108
|
+
actions: [
|
|
109
|
+
'plugin::content-manager.explorer.read'
|
|
110
|
+
]
|
|
111
|
+
}
|
|
112
|
+
}
|
|
113
|
+
]
|
|
114
|
+
}
|
|
115
|
+
},
|
|
98
116
|
{
|
|
99
117
|
method: 'GET',
|
|
100
118
|
path: '/settings',
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"admin.js","sources":["../../../server/src/routes/admin.ts"],"sourcesContent":["export default {\n type: 'admin',\n routes: [\n {\n method: 'GET',\n path: '/iso-locales',\n handler: 'iso-locales.listIsoLocales',\n config: {\n policies: [\n 'admin::isAuthenticatedAdmin',\n {\n name: 'plugin::content-manager.hasPermissions',\n config: { actions: ['plugin::i18n.locale.read'] },\n },\n ],\n },\n },\n {\n method: 'GET',\n path: '/locales',\n handler: 'locales.listLocales',\n config: {\n policies: ['admin::isAuthenticatedAdmin'],\n },\n },\n {\n method: 'POST',\n path: '/locales',\n handler: 'locales.createLocale',\n config: {\n policies: [\n 'admin::isAuthenticatedAdmin',\n {\n name: 'plugin::content-manager.hasPermissions',\n config: { actions: ['plugin::i18n.locale.create'] },\n },\n ],\n },\n },\n {\n method: 'PUT',\n path: '/locales/:id',\n handler: 'locales.updateLocale',\n config: {\n policies: [\n 'admin::isAuthenticatedAdmin',\n {\n name: 'plugin::content-manager.hasPermissions',\n config: { actions: ['plugin::i18n.locale.update'] },\n },\n ],\n },\n },\n {\n method: 'DELETE',\n path: '/locales/:id',\n handler: 'locales.deleteLocale',\n config: {\n policies: [\n 'admin::isAuthenticatedAdmin',\n {\n name: 'plugin::content-manager.hasPermissions',\n config: { actions: ['plugin::i18n.locale.delete'] },\n },\n ],\n },\n },\n {\n method: 'POST',\n path: '/content-manager/actions/get-non-localized-fields',\n handler: 'content-types.getNonLocalizedAttributes',\n config: {\n policies: ['admin::isAuthenticatedAdmin'],\n },\n },\n {\n method: 'GET',\n path: '/settings',\n handler: 'settings.getSettings',\n config: {\n policies: ['admin::isAuthenticatedAdmin'],\n },\n },\n {\n method: 'PUT',\n path: '/settings',\n handler: 'settings.updateSettings',\n config: {\n policies: ['admin::isAuthenticatedAdmin'],\n },\n },\n {\n method: 'GET',\n path: '/ai-localization-jobs/collection-types/:contentType/:documentId',\n handler: 'ai-localization-jobs.getJobForCollectionType',\n config: {\n policies: ['admin::isAuthenticatedAdmin'],\n },\n },\n {\n method: 'GET',\n path: '/ai-localization-jobs/single-types/:contentType',\n handler: 'ai-localization-jobs.getJobForSingleType',\n config: {\n policies: ['admin::isAuthenticatedAdmin'],\n },\n },\n ],\n};\n"],"names":["type","routes","method","path","handler","config","policies","name","actions"],"mappings":";;AAAA,YAAe;IACbA,IAAAA,EAAM,OAAA;IACNC,MAAAA,EAAQ;AACN,QAAA;YACEC,MAAAA,EAAQ,KAAA;YACRC,IAAAA,EAAM,cAAA;YACNC,OAAAA,EAAS,4BAAA;YACTC,MAAAA,EAAQ;gBACNC,QAAAA,EAAU;AACR,oBAAA,6BAAA;AACA,oBAAA;wBACEC,IAAAA,EAAM,wCAAA;wBACNF,MAAAA,EAAQ;4BAAEG,OAAAA,EAAS;AAAC,gCAAA;AAA2B;AAAC;AAClD;AACD;AACH;AACF,SAAA;AACA,QAAA;YACEN,MAAAA,EAAQ,KAAA;YACRC,IAAAA,EAAM,UAAA;YACNC,OAAAA,EAAS,qBAAA;YACTC,MAAAA,EAAQ;gBACNC,QAAAA,EAAU;AAAC,oBAAA;AAA8B;AAC3C;AACF,SAAA;AACA,QAAA;YACEJ,MAAAA,EAAQ,MAAA;YACRC,IAAAA,EAAM,UAAA;YACNC,OAAAA,EAAS,sBAAA;YACTC,MAAAA,EAAQ;gBACNC,QAAAA,EAAU;AACR,oBAAA,6BAAA;AACA,oBAAA;wBACEC,IAAAA,EAAM,wCAAA;wBACNF,MAAAA,EAAQ;4BAAEG,OAAAA,EAAS;AAAC,gCAAA;AAA6B;AAAC;AACpD;AACD;AACH;AACF,SAAA;AACA,QAAA;YACEN,MAAAA,EAAQ,KAAA;YACRC,IAAAA,EAAM,cAAA;YACNC,OAAAA,EAAS,sBAAA;YACTC,MAAAA,EAAQ;gBACNC,QAAAA,EAAU;AACR,oBAAA,6BAAA;AACA,oBAAA;wBACEC,IAAAA,EAAM,wCAAA;wBACNF,MAAAA,EAAQ;4BAAEG,OAAAA,EAAS;AAAC,gCAAA;AAA6B;AAAC;AACpD;AACD;AACH;AACF,SAAA;AACA,QAAA;YACEN,MAAAA,EAAQ,QAAA;YACRC,IAAAA,EAAM,cAAA;YACNC,OAAAA,EAAS,sBAAA;YACTC,MAAAA,EAAQ;gBACNC,QAAAA,EAAU;AACR,oBAAA,6BAAA;AACA,oBAAA;wBACEC,IAAAA,EAAM,wCAAA;wBACNF,MAAAA,EAAQ;4BAAEG,OAAAA,EAAS;AAAC,gCAAA;AAA6B;AAAC;AACpD;AACD;AACH;AACF,SAAA;AACA,QAAA;YACEN,MAAAA,EAAQ,MAAA;YACRC,IAAAA,EAAM,mDAAA;YACNC,OAAAA,EAAS,yCAAA;YACTC,MAAAA,EAAQ;gBACNC,QAAAA,EAAU;AAAC,oBAAA;AAA8B;AAC3C;AACF,SAAA;AACA,QAAA;YACEJ,MAAAA,EAAQ,KAAA;YACRC,IAAAA,EAAM,WAAA;YACNC,OAAAA,EAAS,sBAAA;YACTC,MAAAA,EAAQ;gBACNC,QAAAA,EAAU;AAAC,oBAAA;AAA8B;AAC3C;AACF,SAAA;AACA,QAAA;YACEJ,MAAAA,EAAQ,KAAA;YACRC,IAAAA,EAAM,WAAA;YACNC,OAAAA,EAAS,yBAAA;YACTC,MAAAA,EAAQ;gBACNC,QAAAA,EAAU;AAAC,oBAAA;AAA8B;AAC3C;AACF,SAAA;AACA,QAAA;YACEJ,MAAAA,EAAQ,KAAA;YACRC,IAAAA,EAAM,iEAAA;YACNC,OAAAA,EAAS,8CAAA;YACTC,MAAAA,EAAQ;gBACNC,QAAAA,EAAU;AAAC,oBAAA;AAA8B;AAC3C;AACF,SAAA;AACA,QAAA;YACEJ,MAAAA,EAAQ,KAAA;YACRC,IAAAA,EAAM,iDAAA;YACNC,OAAAA,EAAS,0CAAA;YACTC,MAAAA,EAAQ;gBACNC,QAAAA,EAAU;AAAC,oBAAA;AAA8B;AAC3C;AACF;AACD;AACH,CAAA;;;;"}
|
|
1
|
+
{"version":3,"file":"admin.js","sources":["../../../server/src/routes/admin.ts"],"sourcesContent":["export default {\n type: 'admin',\n routes: [\n {\n method: 'GET',\n path: '/iso-locales',\n handler: 'iso-locales.listIsoLocales',\n config: {\n policies: [\n 'admin::isAuthenticatedAdmin',\n {\n name: 'plugin::content-manager.hasPermissions',\n config: { actions: ['plugin::i18n.locale.read'] },\n },\n ],\n },\n },\n {\n method: 'GET',\n path: '/locales',\n handler: 'locales.listLocales',\n config: {\n policies: ['admin::isAuthenticatedAdmin'],\n },\n },\n {\n method: 'POST',\n path: '/locales',\n handler: 'locales.createLocale',\n config: {\n policies: [\n 'admin::isAuthenticatedAdmin',\n {\n name: 'plugin::content-manager.hasPermissions',\n config: { actions: ['plugin::i18n.locale.create'] },\n },\n ],\n },\n },\n {\n method: 'PUT',\n path: '/locales/:id',\n handler: 'locales.updateLocale',\n config: {\n policies: [\n 'admin::isAuthenticatedAdmin',\n {\n name: 'plugin::content-manager.hasPermissions',\n config: { actions: ['plugin::i18n.locale.update'] },\n },\n ],\n },\n },\n {\n method: 'DELETE',\n path: '/locales/:id',\n handler: 'locales.deleteLocale',\n config: {\n policies: [\n 'admin::isAuthenticatedAdmin',\n {\n name: 'plugin::content-manager.hasPermissions',\n config: { actions: ['plugin::i18n.locale.delete'] },\n },\n ],\n },\n },\n {\n method: 'POST',\n path: '/content-manager/actions/get-non-localized-fields',\n handler: 'content-types.getNonLocalizedAttributes',\n config: {\n policies: ['admin::isAuthenticatedAdmin'],\n },\n },\n {\n method: 'GET',\n path: '/content-manager/get-fill-from-locale/:model',\n handler: 'content-types.getFillFromLocaleData',\n config: {\n policies: [\n 'admin::isAuthenticatedAdmin',\n {\n name: 'plugin::content-manager.hasPermissions',\n config: { actions: ['plugin::content-manager.explorer.read'] },\n },\n ],\n },\n },\n {\n method: 'GET',\n path: '/settings',\n handler: 'settings.getSettings',\n config: {\n policies: ['admin::isAuthenticatedAdmin'],\n },\n },\n {\n method: 'PUT',\n path: '/settings',\n handler: 'settings.updateSettings',\n config: {\n policies: ['admin::isAuthenticatedAdmin'],\n },\n },\n {\n method: 'GET',\n path: '/ai-localization-jobs/collection-types/:contentType/:documentId',\n handler: 'ai-localization-jobs.getJobForCollectionType',\n config: {\n policies: ['admin::isAuthenticatedAdmin'],\n },\n },\n {\n method: 'GET',\n path: '/ai-localization-jobs/single-types/:contentType',\n handler: 'ai-localization-jobs.getJobForSingleType',\n config: {\n policies: ['admin::isAuthenticatedAdmin'],\n },\n },\n ],\n};\n"],"names":["type","routes","method","path","handler","config","policies","name","actions"],"mappings":"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"}
|
|
@@ -93,6 +93,24 @@ var admin = {
|
|
|
93
93
|
]
|
|
94
94
|
}
|
|
95
95
|
},
|
|
96
|
+
{
|
|
97
|
+
method: 'GET',
|
|
98
|
+
path: '/content-manager/get-fill-from-locale/:model',
|
|
99
|
+
handler: 'content-types.getFillFromLocaleData',
|
|
100
|
+
config: {
|
|
101
|
+
policies: [
|
|
102
|
+
'admin::isAuthenticatedAdmin',
|
|
103
|
+
{
|
|
104
|
+
name: 'plugin::content-manager.hasPermissions',
|
|
105
|
+
config: {
|
|
106
|
+
actions: [
|
|
107
|
+
'plugin::content-manager.explorer.read'
|
|
108
|
+
]
|
|
109
|
+
}
|
|
110
|
+
}
|
|
111
|
+
]
|
|
112
|
+
}
|
|
113
|
+
},
|
|
96
114
|
{
|
|
97
115
|
method: 'GET',
|
|
98
116
|
path: '/settings',
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"admin.mjs","sources":["../../../server/src/routes/admin.ts"],"sourcesContent":["export default {\n type: 'admin',\n routes: [\n {\n method: 'GET',\n path: '/iso-locales',\n handler: 'iso-locales.listIsoLocales',\n config: {\n policies: [\n 'admin::isAuthenticatedAdmin',\n {\n name: 'plugin::content-manager.hasPermissions',\n config: { actions: ['plugin::i18n.locale.read'] },\n },\n ],\n },\n },\n {\n method: 'GET',\n path: '/locales',\n handler: 'locales.listLocales',\n config: {\n policies: ['admin::isAuthenticatedAdmin'],\n },\n },\n {\n method: 'POST',\n path: '/locales',\n handler: 'locales.createLocale',\n config: {\n policies: [\n 'admin::isAuthenticatedAdmin',\n {\n name: 'plugin::content-manager.hasPermissions',\n config: { actions: ['plugin::i18n.locale.create'] },\n },\n ],\n },\n },\n {\n method: 'PUT',\n path: '/locales/:id',\n handler: 'locales.updateLocale',\n config: {\n policies: [\n 'admin::isAuthenticatedAdmin',\n {\n name: 'plugin::content-manager.hasPermissions',\n config: { actions: ['plugin::i18n.locale.update'] },\n },\n ],\n },\n },\n {\n method: 'DELETE',\n path: '/locales/:id',\n handler: 'locales.deleteLocale',\n config: {\n policies: [\n 'admin::isAuthenticatedAdmin',\n {\n name: 'plugin::content-manager.hasPermissions',\n config: { actions: ['plugin::i18n.locale.delete'] },\n },\n ],\n },\n },\n {\n method: 'POST',\n path: '/content-manager/actions/get-non-localized-fields',\n handler: 'content-types.getNonLocalizedAttributes',\n config: {\n policies: ['admin::isAuthenticatedAdmin'],\n },\n },\n {\n method: 'GET',\n path: '/settings',\n handler: 'settings.getSettings',\n config: {\n policies: ['admin::isAuthenticatedAdmin'],\n },\n },\n {\n method: 'PUT',\n path: '/settings',\n handler: 'settings.updateSettings',\n config: {\n policies: ['admin::isAuthenticatedAdmin'],\n },\n },\n {\n method: 'GET',\n path: '/ai-localization-jobs/collection-types/:contentType/:documentId',\n handler: 'ai-localization-jobs.getJobForCollectionType',\n config: {\n policies: ['admin::isAuthenticatedAdmin'],\n },\n },\n {\n method: 'GET',\n path: '/ai-localization-jobs/single-types/:contentType',\n handler: 'ai-localization-jobs.getJobForSingleType',\n config: {\n policies: ['admin::isAuthenticatedAdmin'],\n },\n },\n ],\n};\n"],"names":["type","routes","method","path","handler","config","policies","name","actions"],"mappings":"AAAA,YAAe;IACbA,IAAAA,EAAM,OAAA;IACNC,MAAAA,EAAQ;AACN,QAAA;YACEC,MAAAA,EAAQ,KAAA;YACRC,IAAAA,EAAM,cAAA;YACNC,OAAAA,EAAS,4BAAA;YACTC,MAAAA,EAAQ;gBACNC,QAAAA,EAAU;AACR,oBAAA,6BAAA;AACA,oBAAA;wBACEC,IAAAA,EAAM,wCAAA;wBACNF,MAAAA,EAAQ;4BAAEG,OAAAA,EAAS;AAAC,gCAAA;AAA2B;AAAC;AAClD;AACD;AACH;AACF,SAAA;AACA,QAAA;YACEN,MAAAA,EAAQ,KAAA;YACRC,IAAAA,EAAM,UAAA;YACNC,OAAAA,EAAS,qBAAA;YACTC,MAAAA,EAAQ;gBACNC,QAAAA,EAAU;AAAC,oBAAA;AAA8B;AAC3C;AACF,SAAA;AACA,QAAA;YACEJ,MAAAA,EAAQ,MAAA;YACRC,IAAAA,EAAM,UAAA;YACNC,OAAAA,EAAS,sBAAA;YACTC,MAAAA,EAAQ;gBACNC,QAAAA,EAAU;AACR,oBAAA,6BAAA;AACA,oBAAA;wBACEC,IAAAA,EAAM,wCAAA;wBACNF,MAAAA,EAAQ;4BAAEG,OAAAA,EAAS;AAAC,gCAAA;AAA6B;AAAC;AACpD;AACD;AACH;AACF,SAAA;AACA,QAAA;YACEN,MAAAA,EAAQ,KAAA;YACRC,IAAAA,EAAM,cAAA;YACNC,OAAAA,EAAS,sBAAA;YACTC,MAAAA,EAAQ;gBACNC,QAAAA,EAAU;AACR,oBAAA,6BAAA;AACA,oBAAA;wBACEC,IAAAA,EAAM,wCAAA;wBACNF,MAAAA,EAAQ;4BAAEG,OAAAA,EAAS;AAAC,gCAAA;AAA6B;AAAC;AACpD;AACD;AACH;AACF,SAAA;AACA,QAAA;YACEN,MAAAA,EAAQ,QAAA;YACRC,IAAAA,EAAM,cAAA;YACNC,OAAAA,EAAS,sBAAA;YACTC,MAAAA,EAAQ;gBACNC,QAAAA,EAAU;AACR,oBAAA,6BAAA;AACA,oBAAA;wBACEC,IAAAA,EAAM,wCAAA;wBACNF,MAAAA,EAAQ;4BAAEG,OAAAA,EAAS;AAAC,gCAAA;AAA6B;AAAC;AACpD;AACD;AACH;AACF,SAAA;AACA,QAAA;YACEN,MAAAA,EAAQ,MAAA;YACRC,IAAAA,EAAM,mDAAA;YACNC,OAAAA,EAAS,yCAAA;YACTC,MAAAA,EAAQ;gBACNC,QAAAA,EAAU;AAAC,oBAAA;AAA8B;AAC3C;AACF,SAAA;AACA,QAAA;YACEJ,MAAAA,EAAQ,KAAA;YACRC,IAAAA,EAAM,WAAA;YACNC,OAAAA,EAAS,sBAAA;YACTC,MAAAA,EAAQ;gBACNC,QAAAA,EAAU;AAAC,oBAAA;AAA8B;AAC3C;AACF,SAAA;AACA,QAAA;YACEJ,MAAAA,EAAQ,KAAA;YACRC,IAAAA,EAAM,WAAA;YACNC,OAAAA,EAAS,yBAAA;YACTC,MAAAA,EAAQ;gBACNC,QAAAA,EAAU;AAAC,oBAAA;AAA8B;AAC3C;AACF,SAAA;AACA,QAAA;YACEJ,MAAAA,EAAQ,KAAA;YACRC,IAAAA,EAAM,iEAAA;YACNC,OAAAA,EAAS,8CAAA;YACTC,MAAAA,EAAQ;gBACNC,QAAAA,EAAU;AAAC,oBAAA;AAA8B;AAC3C;AACF,SAAA;AACA,QAAA;YACEJ,MAAAA,EAAQ,KAAA;YACRC,IAAAA,EAAM,iDAAA;YACNC,OAAAA,EAAS,0CAAA;YACTC,MAAAA,EAAQ;gBACNC,QAAAA,EAAU;AAAC,oBAAA;AAA8B;AAC3C;AACF;AACD;AACH,CAAA;;;;"}
|
|
1
|
+
{"version":3,"file":"admin.mjs","sources":["../../../server/src/routes/admin.ts"],"sourcesContent":["export default {\n type: 'admin',\n routes: [\n {\n method: 'GET',\n path: '/iso-locales',\n handler: 'iso-locales.listIsoLocales',\n config: {\n policies: [\n 'admin::isAuthenticatedAdmin',\n {\n name: 'plugin::content-manager.hasPermissions',\n config: { actions: ['plugin::i18n.locale.read'] },\n },\n ],\n },\n },\n {\n method: 'GET',\n path: '/locales',\n handler: 'locales.listLocales',\n config: {\n policies: ['admin::isAuthenticatedAdmin'],\n },\n },\n {\n method: 'POST',\n path: '/locales',\n handler: 'locales.createLocale',\n config: {\n policies: [\n 'admin::isAuthenticatedAdmin',\n {\n name: 'plugin::content-manager.hasPermissions',\n config: { actions: ['plugin::i18n.locale.create'] },\n },\n ],\n },\n },\n {\n method: 'PUT',\n path: '/locales/:id',\n handler: 'locales.updateLocale',\n config: {\n policies: [\n 'admin::isAuthenticatedAdmin',\n {\n name: 'plugin::content-manager.hasPermissions',\n config: { actions: ['plugin::i18n.locale.update'] },\n },\n ],\n },\n },\n {\n method: 'DELETE',\n path: '/locales/:id',\n handler: 'locales.deleteLocale',\n config: {\n policies: [\n 'admin::isAuthenticatedAdmin',\n {\n name: 'plugin::content-manager.hasPermissions',\n config: { actions: ['plugin::i18n.locale.delete'] },\n },\n ],\n },\n },\n {\n method: 'POST',\n path: '/content-manager/actions/get-non-localized-fields',\n handler: 'content-types.getNonLocalizedAttributes',\n config: {\n policies: ['admin::isAuthenticatedAdmin'],\n },\n },\n {\n method: 'GET',\n path: '/content-manager/get-fill-from-locale/:model',\n handler: 'content-types.getFillFromLocaleData',\n config: {\n policies: [\n 'admin::isAuthenticatedAdmin',\n {\n name: 'plugin::content-manager.hasPermissions',\n config: { actions: ['plugin::content-manager.explorer.read'] },\n },\n ],\n },\n },\n {\n method: 'GET',\n path: '/settings',\n handler: 'settings.getSettings',\n config: {\n policies: ['admin::isAuthenticatedAdmin'],\n },\n },\n {\n method: 'PUT',\n path: '/settings',\n handler: 'settings.updateSettings',\n config: {\n policies: ['admin::isAuthenticatedAdmin'],\n },\n },\n {\n method: 'GET',\n path: '/ai-localization-jobs/collection-types/:contentType/:documentId',\n handler: 'ai-localization-jobs.getJobForCollectionType',\n config: {\n policies: ['admin::isAuthenticatedAdmin'],\n },\n },\n {\n method: 'GET',\n path: '/ai-localization-jobs/single-types/:contentType',\n handler: 'ai-localization-jobs.getJobForSingleType',\n config: {\n policies: ['admin::isAuthenticatedAdmin'],\n },\n },\n ],\n};\n"],"names":["type","routes","method","path","handler","config","policies","name","actions"],"mappings":"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"}
|
|
@@ -111,22 +111,12 @@ const createAILocalizationsService = ({ strapi })=>{
|
|
|
111
111
|
return {
|
|
112
112
|
// Async to avoid changing the signature later (there will be a db check in the future)
|
|
113
113
|
async isEnabled () {
|
|
114
|
-
|
|
115
|
-
const isAIEnabled = strapi.config.get('admin.ai.enabled', true);
|
|
116
|
-
if (!isAIEnabled) {
|
|
117
|
-
return false;
|
|
118
|
-
}
|
|
119
|
-
// Check if the user's license grants access to AI features
|
|
120
|
-
const hasAccess = strapi.ee.features.isEnabled('cms-ai');
|
|
121
|
-
if (!hasAccess) {
|
|
114
|
+
if (strapi.ai.admin.isEnabled() === false) {
|
|
122
115
|
return false;
|
|
123
116
|
}
|
|
124
117
|
const settings = index.getService('settings');
|
|
125
118
|
const aiSettings = await settings.getSettings();
|
|
126
|
-
|
|
127
|
-
return false;
|
|
128
|
-
}
|
|
129
|
-
return true;
|
|
119
|
+
return aiSettings?.aiLocalizations === true;
|
|
130
120
|
},
|
|
131
121
|
/**
|
|
132
122
|
* Checks if there are localizations that need to be generated for the given document,
|
|
@@ -212,7 +202,7 @@ const createAILocalizationsService = ({ strapi })=>{
|
|
|
212
202
|
});
|
|
213
203
|
let token;
|
|
214
204
|
try {
|
|
215
|
-
const tokenData = await strapi.
|
|
205
|
+
const tokenData = await strapi.ai.admin.getAiToken();
|
|
216
206
|
token = tokenData.token;
|
|
217
207
|
} catch (error) {
|
|
218
208
|
await aiLocalizationJobsService.upsertJobForDocument({
|