@strapi/i18n 5.49.0 → 5.50.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/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/src/contentReleasesHooks/releaseDetailsView.d.ts +1 -1
- package/dist/admin/src/services/relations.d.ts +2 -2
- package/dist/admin/src/services/settings.d.ts +1 -1
- package/dist/admin/src/utils/schemas.d.ts +6 -6
- package/dist/admin/translations/ja.json.js +92 -0
- package/dist/admin/translations/ja.json.js.map +1 -0
- package/dist/admin/translations/ja.json.mjs +90 -0
- package/dist/admin/translations/ja.json.mjs.map +1 -0
- package/dist/server/register.js +4 -0
- package/dist/server/register.js.map +1 -1
- package/dist/server/register.mjs +4 -0
- package/dist/server/register.mjs.map +1 -1
- package/dist/server/services/permissions/actions.js +95 -1
- package/dist/server/services/permissions/actions.js.map +1 -1
- package/dist/server/services/permissions/actions.mjs +95 -1
- package/dist/server/services/permissions/actions.mjs.map +1 -1
- package/dist/server/services/permissions/sections-builder.js +6 -4
- package/dist/server/services/permissions/sections-builder.js.map +1 -1
- package/dist/server/services/permissions/sections-builder.mjs +6 -4
- package/dist/server/services/permissions/sections-builder.mjs.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 +2 -3
- package/dist/server/src/controllers/content-types.d.ts.map +1 -1
- package/dist/server/src/controllers/index.d.ts +2 -3
- package/dist/server/src/controllers/index.d.ts.map +1 -1
- package/dist/server/src/domain/locale.d.ts.map +1 -1
- package/dist/server/src/graphql.d.ts.map +1 -1
- package/dist/server/src/index.d.ts +11 -10
- package/dist/server/src/index.d.ts.map +1 -1
- package/dist/server/src/register.d.ts.map +1 -1
- package/dist/server/src/services/ai-localization-jobs.d.ts +1 -1
- package/dist/server/src/services/ai-localization-jobs.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.map +1 -1
- package/dist/server/src/services/index.d.ts +9 -7
- package/dist/server/src/services/index.d.ts.map +1 -1
- package/dist/server/src/services/localizations.d.ts.map +1 -1
- package/dist/server/src/services/permissions/actions.d.ts +5 -0
- package/dist/server/src/services/permissions/actions.d.ts.map +1 -1
- package/dist/server/src/services/permissions/conditions.d.ts.map +1 -1
- package/dist/server/src/services/permissions/engine.d.ts.map +1 -1
- package/dist/server/src/services/permissions/sections-builder.d.ts.map +1 -1
- package/dist/server/src/services/permissions.d.ts +5 -0
- package/dist/server/src/services/permissions.d.ts.map +1 -1
- package/dist/server/src/services/sanitize/index.d.ts +0 -1
- package/dist/server/src/services/sanitize/index.d.ts.map +1 -1
- package/dist/server/src/services/settings.d.ts.map +1 -1
- package/dist/server/src/utils/index.d.ts +15 -15
- package/dist/server/src/utils/index.d.ts.map +1 -1
- package/dist/server/src/validation/content-types.d.ts +2 -2
- package/dist/server/src/validation/content-types.d.ts.map +1 -1
- package/dist/server/src/validation/locales.d.ts +2 -2
- package/dist/server/src/validation/settings.d.ts +1 -1
- package/package.json +9 -9
|
@@ -88,6 +88,97 @@ const addAllLocalesToPermissions = async (permissions)=>{
|
|
|
88
88
|
};
|
|
89
89
|
}));
|
|
90
90
|
};
|
|
91
|
+
/**
|
|
92
|
+
* `properties.locales === null` means access to all locales (see engine handler) — do not patch.
|
|
93
|
+
*/ const needsLocalesPatch = (properties = {})=>{
|
|
94
|
+
if (!('locales' in properties)) {
|
|
95
|
+
return true;
|
|
96
|
+
}
|
|
97
|
+
const { locales } = properties;
|
|
98
|
+
if (locales === null) {
|
|
99
|
+
return false;
|
|
100
|
+
}
|
|
101
|
+
return Array.isArray(locales) && locales.length === 0;
|
|
102
|
+
};
|
|
103
|
+
const normalizeRolePermissionsLocales = async (permissions)=>{
|
|
104
|
+
const { isLocalizedContentType } = index.getService('content-types');
|
|
105
|
+
const { actionProvider } = strapi.service('admin::permission');
|
|
106
|
+
const defaultLocale = await index.getService('locales').getDefaultLocale();
|
|
107
|
+
return Promise.all(permissions.map(async (permission)=>{
|
|
108
|
+
const { subject, action, properties = {} } = permission;
|
|
109
|
+
if (!subject) {
|
|
110
|
+
return permission;
|
|
111
|
+
}
|
|
112
|
+
const model = strapi.getModel(subject);
|
|
113
|
+
if (!model || !isLocalizedContentType(model)) {
|
|
114
|
+
return permission;
|
|
115
|
+
}
|
|
116
|
+
const appliesToLocales = await actionProvider.appliesToProperty('locales', action, subject);
|
|
117
|
+
if (!appliesToLocales) {
|
|
118
|
+
return permission;
|
|
119
|
+
}
|
|
120
|
+
// null means access to all locales — same semantics as the permission engine handler
|
|
121
|
+
if (properties.locales === null) {
|
|
122
|
+
return permission;
|
|
123
|
+
}
|
|
124
|
+
if (needsLocalesPatch(properties) && defaultLocale) {
|
|
125
|
+
return {
|
|
126
|
+
...permission,
|
|
127
|
+
properties: {
|
|
128
|
+
...properties,
|
|
129
|
+
locales: [
|
|
130
|
+
defaultLocale
|
|
131
|
+
]
|
|
132
|
+
}
|
|
133
|
+
};
|
|
134
|
+
}
|
|
135
|
+
return permission;
|
|
136
|
+
}));
|
|
137
|
+
};
|
|
138
|
+
/**
|
|
139
|
+
* Repairs role permissions on content types that just had i18n enabled in this sync.
|
|
140
|
+
* Only patches permissions where `properties.locales` is missing or `[]`; leaves `null` alone.
|
|
141
|
+
* Safe to run at `afterSync` time because it does not depend on the actionProvider.
|
|
142
|
+
*/ const repairPermissionsForNewlyLocalizedTypes = async ({ oldContentTypes, contentTypes })=>{
|
|
143
|
+
if (!oldContentTypes) {
|
|
144
|
+
return;
|
|
145
|
+
}
|
|
146
|
+
const { isLocalizedContentType } = index.getService('content-types');
|
|
147
|
+
const newlyLocalizedUids = Object.keys(contentTypes).filter((uid)=>oldContentTypes[uid] && !isLocalizedContentType(oldContentTypes[uid]) && isLocalizedContentType(contentTypes[uid]));
|
|
148
|
+
if (newlyLocalizedUids.length === 0) {
|
|
149
|
+
return;
|
|
150
|
+
}
|
|
151
|
+
try {
|
|
152
|
+
const defaultLocaleCode = await index.getService('locales').getDefaultLocale();
|
|
153
|
+
if (!defaultLocaleCode) {
|
|
154
|
+
return;
|
|
155
|
+
}
|
|
156
|
+
const permissionService = strapi.service('admin::permission');
|
|
157
|
+
const allPermissions = await permissionService.findMany({
|
|
158
|
+
where: {
|
|
159
|
+
subject: {
|
|
160
|
+
$in: newlyLocalizedUids
|
|
161
|
+
}
|
|
162
|
+
}
|
|
163
|
+
});
|
|
164
|
+
const results = await Promise.allSettled(allPermissions.filter((permission)=>needsLocalesPatch(permission.properties)).map((permission)=>strapi.db.query('admin::permission').update({
|
|
165
|
+
where: {
|
|
166
|
+
id: permission.id
|
|
167
|
+
},
|
|
168
|
+
data: {
|
|
169
|
+
properties: {
|
|
170
|
+
...permission.properties,
|
|
171
|
+
locales: [
|
|
172
|
+
defaultLocaleCode
|
|
173
|
+
]
|
|
174
|
+
}
|
|
175
|
+
}
|
|
176
|
+
})));
|
|
177
|
+
results.filter((r)=>r.status === 'rejected').forEach((r)=>strapi.log.error('Failed to patch i18n permission during newly-localized type repair.', r.reason));
|
|
178
|
+
} catch (error) {
|
|
179
|
+
strapi.log.error('Failed to repair i18n permissions for newly localized content types.', error);
|
|
180
|
+
}
|
|
181
|
+
};
|
|
91
182
|
const syncSuperAdminPermissionsWithLocales = async ()=>{
|
|
92
183
|
const roleService = strapi.service('admin::role');
|
|
93
184
|
const permissionService = strapi.service('admin::permission');
|
|
@@ -114,6 +205,7 @@ const registerI18nActionsHooks = ()=>{
|
|
|
114
205
|
const { hooks } = strapi.service('admin::role');
|
|
115
206
|
actionProvider.hooks.appliesPropertyToSubject.register(shouldApplyLocalesPropertyToSubject);
|
|
116
207
|
hooks.willResetSuperAdminPermissions.register(addAllLocalesToPermissions);
|
|
208
|
+
hooks.willValidateUpdatePermissions.register(normalizeRolePermissionsLocales);
|
|
117
209
|
};
|
|
118
210
|
const updateActionsProperties = ()=>{
|
|
119
211
|
const { actionProvider } = strapi.service('admin::permission');
|
|
@@ -129,7 +221,9 @@ var i18nActionsService = {
|
|
|
129
221
|
registerI18nActions,
|
|
130
222
|
registerI18nActionsHooks,
|
|
131
223
|
updateActionsProperties,
|
|
132
|
-
syncSuperAdminPermissionsWithLocales
|
|
224
|
+
syncSuperAdminPermissionsWithLocales,
|
|
225
|
+
repairPermissionsForNewlyLocalizedTypes,
|
|
226
|
+
normalizeRolePermissionsLocales
|
|
133
227
|
};
|
|
134
228
|
|
|
135
229
|
module.exports = i18nActionsService;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"actions.js","sources":["../../../../server/src/services/permissions/actions.ts"],"sourcesContent":["import { isArray, getOr, prop } from 'lodash/fp';\nimport { getService } from '../../utils';\n\nconst actions = [\n {\n section: 'settings',\n category: 'Internationalization',\n subCategory: 'Locales',\n pluginName: 'i18n',\n displayName: 'Create',\n uid: 'locale.create',\n },\n {\n section: 'settings',\n category: 'Internationalization',\n subCategory: 'Locales',\n pluginName: 'i18n',\n displayName: 'Read',\n uid: 'locale.read',\n aliases: [\n { actionId: 'plugin::content-manager.explorer.read', subjects: ['plugin::i18n.locale'] },\n ],\n },\n {\n section: 'settings',\n category: 'Internationalization',\n subCategory: 'Locales',\n pluginName: 'i18n',\n displayName: 'Update',\n uid: 'locale.update',\n },\n {\n section: 'settings',\n category: 'Internationalization',\n subCategory: 'Locales',\n pluginName: 'i18n',\n displayName: 'Delete',\n uid: 'locale.delete',\n },\n];\n\nconst addLocalesPropertyIfNeeded = ({ value: action }: any) => {\n const {\n section,\n options: { applyToProperties },\n } = action;\n\n // Only add the locales property to contentTypes' actions\n if (section !== 'contentTypes') {\n return;\n }\n\n // If the 'locales' property is already declared within the applyToProperties array, then ignore the next steps\n if (isArray(applyToProperties) && applyToProperties.includes('locales')) {\n return;\n }\n\n // Add the 'locales' property to the applyToProperties array (create it if necessary)\n action.options.applyToProperties = isArray(applyToProperties)\n ? applyToProperties.concat('locales')\n : ['locales'];\n};\n\nconst shouldApplyLocalesPropertyToSubject = ({ property, subject }: any) => {\n if (property === 'locales') {\n const model = strapi.getModel(subject);\n\n return getService('content-types').isLocalizedContentType(model);\n }\n\n return true;\n};\n\nconst addAllLocalesToPermissions = async (permissions: any) => {\n const { actionProvider } = strapi.service('admin::permission');\n const { find: findAllLocales } = getService('locales');\n\n const allLocales = await findAllLocales();\n const allLocalesCode = allLocales.map(prop('code'));\n\n return Promise.all(\n permissions.map(async (permission: any) => {\n const { action, subject } = permission;\n\n const appliesToLocalesProperty = await actionProvider.appliesToProperty(\n 'locales',\n action,\n subject\n );\n\n if (!appliesToLocalesProperty) {\n return permission;\n }\n\n const oldPermissionProperties = getOr({}, 'properties', permission);\n\n return { ...permission, properties: { ...oldPermissionProperties, locales: allLocalesCode } };\n })\n );\n};\n\nconst syncSuperAdminPermissionsWithLocales = async () => {\n const roleService = strapi.service('admin::role');\n const permissionService = strapi.service('admin::permission');\n\n const superAdminRole = await roleService.getSuperAdmin();\n\n if (!superAdminRole) {\n return;\n }\n\n const superAdminPermissions = await permissionService.findMany({\n where: {\n role: {\n id: superAdminRole.id,\n },\n },\n });\n\n const newSuperAdminPermissions = await addAllLocalesToPermissions(superAdminPermissions);\n\n await roleService.assignPermissions(superAdminRole.id, newSuperAdminPermissions);\n};\n\nconst registerI18nActions = async () => {\n const { actionProvider } = strapi.service('admin::permission');\n\n await actionProvider.registerMany(actions);\n};\n\nconst registerI18nActionsHooks = () => {\n const { actionProvider } = strapi.service('admin::permission');\n const { hooks } = strapi.service('admin::role');\n\n actionProvider.hooks.appliesPropertyToSubject.register(shouldApplyLocalesPropertyToSubject);\n hooks.willResetSuperAdminPermissions.register(addAllLocalesToPermissions);\n};\n\nconst updateActionsProperties = () => {\n const { actionProvider } = strapi.service('admin::permission');\n\n // Register the transformation for every new action\n actionProvider.hooks.willRegister.register(addLocalesPropertyIfNeeded);\n\n // Handle already registered actions\n actionProvider.values().forEach((action: any) => addLocalesPropertyIfNeeded({ value: action }));\n};\n\nexport default {\n actions,\n registerI18nActions,\n registerI18nActionsHooks,\n updateActionsProperties,\n syncSuperAdminPermissionsWithLocales,\n};\n"],"names":["actions","section","category","subCategory","pluginName","displayName","uid","aliases","actionId","subjects","addLocalesPropertyIfNeeded","value","action","options","applyToProperties","isArray","includes","concat","shouldApplyLocalesPropertyToSubject","property","subject","model","strapi","getModel","getService","isLocalizedContentType","addAllLocalesToPermissions","permissions","actionProvider","service","find","findAllLocales","allLocales","allLocalesCode","map","prop","Promise","all","permission","appliesToLocalesProperty","appliesToProperty","oldPermissionProperties","getOr","properties","locales","syncSuperAdminPermissionsWithLocales","roleService","permissionService","superAdminRole","getSuperAdmin","superAdminPermissions","findMany","where","role","id","newSuperAdminPermissions","assignPermissions","registerI18nActions","registerMany","registerI18nActionsHooks","hooks","appliesPropertyToSubject","register","willResetSuperAdminPermissions","updateActionsProperties","willRegister","values","forEach"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"actions.js","sources":["../../../../server/src/services/permissions/actions.ts"],"sourcesContent":["import { isArray, getOr, prop } from 'lodash/fp';\nimport { getService } from '../../utils';\n\nconst actions = [\n {\n section: 'settings',\n category: 'Internationalization',\n subCategory: 'Locales',\n pluginName: 'i18n',\n displayName: 'Create',\n uid: 'locale.create',\n },\n {\n section: 'settings',\n category: 'Internationalization',\n subCategory: 'Locales',\n pluginName: 'i18n',\n displayName: 'Read',\n uid: 'locale.read',\n aliases: [\n { actionId: 'plugin::content-manager.explorer.read', subjects: ['plugin::i18n.locale'] },\n ],\n },\n {\n section: 'settings',\n category: 'Internationalization',\n subCategory: 'Locales',\n pluginName: 'i18n',\n displayName: 'Update',\n uid: 'locale.update',\n },\n {\n section: 'settings',\n category: 'Internationalization',\n subCategory: 'Locales',\n pluginName: 'i18n',\n displayName: 'Delete',\n uid: 'locale.delete',\n },\n];\n\nconst addLocalesPropertyIfNeeded = ({ value: action }: any) => {\n const {\n section,\n options: { applyToProperties },\n } = action;\n\n // Only add the locales property to contentTypes' actions\n if (section !== 'contentTypes') {\n return;\n }\n\n // If the 'locales' property is already declared within the applyToProperties array, then ignore the next steps\n if (isArray(applyToProperties) && applyToProperties.includes('locales')) {\n return;\n }\n\n // Add the 'locales' property to the applyToProperties array (create it if necessary)\n action.options.applyToProperties = isArray(applyToProperties)\n ? applyToProperties.concat('locales')\n : ['locales'];\n};\n\nconst shouldApplyLocalesPropertyToSubject = ({ property, subject }: any) => {\n if (property === 'locales') {\n const model = strapi.getModel(subject);\n\n return getService('content-types').isLocalizedContentType(model);\n }\n\n return true;\n};\n\nconst addAllLocalesToPermissions = async (permissions: any) => {\n const { actionProvider } = strapi.service('admin::permission');\n const { find: findAllLocales } = getService('locales');\n\n const allLocales = await findAllLocales();\n const allLocalesCode = allLocales.map(prop('code'));\n\n return Promise.all(\n permissions.map(async (permission: any) => {\n const { action, subject } = permission;\n\n const appliesToLocalesProperty = await actionProvider.appliesToProperty(\n 'locales',\n action,\n subject\n );\n\n if (!appliesToLocalesProperty) {\n return permission;\n }\n\n const oldPermissionProperties = getOr({}, 'properties', permission);\n\n return { ...permission, properties: { ...oldPermissionProperties, locales: allLocalesCode } };\n })\n );\n};\n\n/**\n * `properties.locales === null` means access to all locales (see engine handler) — do not patch.\n */\nconst needsLocalesPatch = (properties: Record<string, unknown> = {}) => {\n if (!('locales' in properties)) {\n return true;\n }\n\n const { locales } = properties;\n\n if (locales === null) {\n return false;\n }\n\n return Array.isArray(locales) && locales.length === 0;\n};\n\nconst normalizeRolePermissionsLocales = async (permissions: any[]): Promise<any[]> => {\n const { isLocalizedContentType } = getService('content-types');\n const { actionProvider } = strapi.service('admin::permission');\n const defaultLocale = await getService('locales').getDefaultLocale();\n\n return Promise.all(\n permissions.map(async (permission) => {\n const { subject, action, properties = {} } = permission;\n\n if (!subject) {\n return permission;\n }\n\n const model = strapi.getModel(subject);\n\n if (!model || !isLocalizedContentType(model)) {\n return permission;\n }\n\n const appliesToLocales = await actionProvider.appliesToProperty('locales', action, subject);\n\n if (!appliesToLocales) {\n return permission;\n }\n\n // null means access to all locales — same semantics as the permission engine handler\n if (properties.locales === null) {\n return permission;\n }\n\n if (needsLocalesPatch(properties) && defaultLocale) {\n return { ...permission, properties: { ...properties, locales: [defaultLocale] } };\n }\n\n return permission;\n })\n );\n};\n\n/**\n * Repairs role permissions on content types that just had i18n enabled in this sync.\n * Only patches permissions where `properties.locales` is missing or `[]`; leaves `null` alone.\n * Safe to run at `afterSync` time because it does not depend on the actionProvider.\n */\nconst repairPermissionsForNewlyLocalizedTypes = async ({\n oldContentTypes,\n contentTypes,\n}: {\n oldContentTypes: Record<string, any> | null | undefined;\n contentTypes: Record<string, any>;\n}) => {\n if (!oldContentTypes) {\n return;\n }\n\n const { isLocalizedContentType } = getService('content-types');\n\n const newlyLocalizedUids = Object.keys(contentTypes).filter(\n (uid) =>\n oldContentTypes[uid] &&\n !isLocalizedContentType(oldContentTypes[uid]) &&\n isLocalizedContentType(contentTypes[uid])\n );\n\n if (newlyLocalizedUids.length === 0) {\n return;\n }\n\n try {\n const defaultLocaleCode = await getService('locales').getDefaultLocale();\n if (!defaultLocaleCode) {\n return;\n }\n\n const permissionService = strapi.service('admin::permission');\n const allPermissions = await permissionService.findMany({\n where: { subject: { $in: newlyLocalizedUids } },\n });\n\n const results = await Promise.allSettled(\n allPermissions\n .filter((permission: any) => needsLocalesPatch(permission.properties))\n .map((permission: any) =>\n strapi.db.query('admin::permission').update({\n where: { id: permission.id },\n data: {\n properties: { ...permission.properties, locales: [defaultLocaleCode] },\n },\n })\n )\n );\n\n results\n .filter((r): r is PromiseRejectedResult => r.status === 'rejected')\n .forEach((r) =>\n strapi.log.error(\n 'Failed to patch i18n permission during newly-localized type repair.',\n r.reason\n )\n );\n } catch (error) {\n strapi.log.error('Failed to repair i18n permissions for newly localized content types.', error);\n }\n};\n\nconst syncSuperAdminPermissionsWithLocales = async () => {\n const roleService = strapi.service('admin::role');\n const permissionService = strapi.service('admin::permission');\n\n const superAdminRole = await roleService.getSuperAdmin();\n\n if (!superAdminRole) {\n return;\n }\n\n const superAdminPermissions = await permissionService.findMany({\n where: {\n role: {\n id: superAdminRole.id,\n },\n },\n });\n\n const newSuperAdminPermissions = await addAllLocalesToPermissions(superAdminPermissions);\n\n await roleService.assignPermissions(superAdminRole.id, newSuperAdminPermissions);\n};\n\nconst registerI18nActions = async () => {\n const { actionProvider } = strapi.service('admin::permission');\n\n await actionProvider.registerMany(actions);\n};\n\nconst registerI18nActionsHooks = () => {\n const { actionProvider } = strapi.service('admin::permission');\n const { hooks } = strapi.service('admin::role');\n\n actionProvider.hooks.appliesPropertyToSubject.register(shouldApplyLocalesPropertyToSubject);\n hooks.willResetSuperAdminPermissions.register(addAllLocalesToPermissions);\n hooks.willValidateUpdatePermissions.register(normalizeRolePermissionsLocales);\n};\n\nconst updateActionsProperties = () => {\n const { actionProvider } = strapi.service('admin::permission');\n\n // Register the transformation for every new action\n actionProvider.hooks.willRegister.register(addLocalesPropertyIfNeeded);\n\n // Handle already registered actions\n actionProvider.values().forEach((action: any) => addLocalesPropertyIfNeeded({ value: action }));\n};\n\nexport default {\n actions,\n registerI18nActions,\n registerI18nActionsHooks,\n updateActionsProperties,\n syncSuperAdminPermissionsWithLocales,\n repairPermissionsForNewlyLocalizedTypes,\n normalizeRolePermissionsLocales,\n};\n"],"names":["actions","section","category","subCategory","pluginName","displayName","uid","aliases","actionId","subjects","addLocalesPropertyIfNeeded","value","action","options","applyToProperties","isArray","includes","concat","shouldApplyLocalesPropertyToSubject","property","subject","model","strapi","getModel","getService","isLocalizedContentType","addAllLocalesToPermissions","permissions","actionProvider","service","find","findAllLocales","allLocales","allLocalesCode","map","prop","Promise","all","permission","appliesToLocalesProperty","appliesToProperty","oldPermissionProperties","getOr","properties","locales","needsLocalesPatch","Array","length","normalizeRolePermissionsLocales","defaultLocale","getDefaultLocale","appliesToLocales","repairPermissionsForNewlyLocalizedTypes","oldContentTypes","contentTypes","newlyLocalizedUids","Object","keys","filter","defaultLocaleCode","permissionService","allPermissions","findMany","where","$in","results","allSettled","db","query","update","id","data","r","status","forEach","log","error","reason","syncSuperAdminPermissionsWithLocales","roleService","superAdminRole","getSuperAdmin","superAdminPermissions","role","newSuperAdminPermissions","assignPermissions","registerI18nActions","registerMany","registerI18nActionsHooks","hooks","appliesPropertyToSubject","register","willResetSuperAdminPermissions","willValidateUpdatePermissions","updateActionsProperties","willRegister","values"],"mappings":"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"}
|
|
@@ -86,6 +86,97 @@ const addAllLocalesToPermissions = async (permissions)=>{
|
|
|
86
86
|
};
|
|
87
87
|
}));
|
|
88
88
|
};
|
|
89
|
+
/**
|
|
90
|
+
* `properties.locales === null` means access to all locales (see engine handler) — do not patch.
|
|
91
|
+
*/ const needsLocalesPatch = (properties = {})=>{
|
|
92
|
+
if (!('locales' in properties)) {
|
|
93
|
+
return true;
|
|
94
|
+
}
|
|
95
|
+
const { locales } = properties;
|
|
96
|
+
if (locales === null) {
|
|
97
|
+
return false;
|
|
98
|
+
}
|
|
99
|
+
return Array.isArray(locales) && locales.length === 0;
|
|
100
|
+
};
|
|
101
|
+
const normalizeRolePermissionsLocales = async (permissions)=>{
|
|
102
|
+
const { isLocalizedContentType } = getService('content-types');
|
|
103
|
+
const { actionProvider } = strapi.service('admin::permission');
|
|
104
|
+
const defaultLocale = await getService('locales').getDefaultLocale();
|
|
105
|
+
return Promise.all(permissions.map(async (permission)=>{
|
|
106
|
+
const { subject, action, properties = {} } = permission;
|
|
107
|
+
if (!subject) {
|
|
108
|
+
return permission;
|
|
109
|
+
}
|
|
110
|
+
const model = strapi.getModel(subject);
|
|
111
|
+
if (!model || !isLocalizedContentType(model)) {
|
|
112
|
+
return permission;
|
|
113
|
+
}
|
|
114
|
+
const appliesToLocales = await actionProvider.appliesToProperty('locales', action, subject);
|
|
115
|
+
if (!appliesToLocales) {
|
|
116
|
+
return permission;
|
|
117
|
+
}
|
|
118
|
+
// null means access to all locales — same semantics as the permission engine handler
|
|
119
|
+
if (properties.locales === null) {
|
|
120
|
+
return permission;
|
|
121
|
+
}
|
|
122
|
+
if (needsLocalesPatch(properties) && defaultLocale) {
|
|
123
|
+
return {
|
|
124
|
+
...permission,
|
|
125
|
+
properties: {
|
|
126
|
+
...properties,
|
|
127
|
+
locales: [
|
|
128
|
+
defaultLocale
|
|
129
|
+
]
|
|
130
|
+
}
|
|
131
|
+
};
|
|
132
|
+
}
|
|
133
|
+
return permission;
|
|
134
|
+
}));
|
|
135
|
+
};
|
|
136
|
+
/**
|
|
137
|
+
* Repairs role permissions on content types that just had i18n enabled in this sync.
|
|
138
|
+
* Only patches permissions where `properties.locales` is missing or `[]`; leaves `null` alone.
|
|
139
|
+
* Safe to run at `afterSync` time because it does not depend on the actionProvider.
|
|
140
|
+
*/ const repairPermissionsForNewlyLocalizedTypes = async ({ oldContentTypes, contentTypes })=>{
|
|
141
|
+
if (!oldContentTypes) {
|
|
142
|
+
return;
|
|
143
|
+
}
|
|
144
|
+
const { isLocalizedContentType } = getService('content-types');
|
|
145
|
+
const newlyLocalizedUids = Object.keys(contentTypes).filter((uid)=>oldContentTypes[uid] && !isLocalizedContentType(oldContentTypes[uid]) && isLocalizedContentType(contentTypes[uid]));
|
|
146
|
+
if (newlyLocalizedUids.length === 0) {
|
|
147
|
+
return;
|
|
148
|
+
}
|
|
149
|
+
try {
|
|
150
|
+
const defaultLocaleCode = await getService('locales').getDefaultLocale();
|
|
151
|
+
if (!defaultLocaleCode) {
|
|
152
|
+
return;
|
|
153
|
+
}
|
|
154
|
+
const permissionService = strapi.service('admin::permission');
|
|
155
|
+
const allPermissions = await permissionService.findMany({
|
|
156
|
+
where: {
|
|
157
|
+
subject: {
|
|
158
|
+
$in: newlyLocalizedUids
|
|
159
|
+
}
|
|
160
|
+
}
|
|
161
|
+
});
|
|
162
|
+
const results = await Promise.allSettled(allPermissions.filter((permission)=>needsLocalesPatch(permission.properties)).map((permission)=>strapi.db.query('admin::permission').update({
|
|
163
|
+
where: {
|
|
164
|
+
id: permission.id
|
|
165
|
+
},
|
|
166
|
+
data: {
|
|
167
|
+
properties: {
|
|
168
|
+
...permission.properties,
|
|
169
|
+
locales: [
|
|
170
|
+
defaultLocaleCode
|
|
171
|
+
]
|
|
172
|
+
}
|
|
173
|
+
}
|
|
174
|
+
})));
|
|
175
|
+
results.filter((r)=>r.status === 'rejected').forEach((r)=>strapi.log.error('Failed to patch i18n permission during newly-localized type repair.', r.reason));
|
|
176
|
+
} catch (error) {
|
|
177
|
+
strapi.log.error('Failed to repair i18n permissions for newly localized content types.', error);
|
|
178
|
+
}
|
|
179
|
+
};
|
|
89
180
|
const syncSuperAdminPermissionsWithLocales = async ()=>{
|
|
90
181
|
const roleService = strapi.service('admin::role');
|
|
91
182
|
const permissionService = strapi.service('admin::permission');
|
|
@@ -112,6 +203,7 @@ const registerI18nActionsHooks = ()=>{
|
|
|
112
203
|
const { hooks } = strapi.service('admin::role');
|
|
113
204
|
actionProvider.hooks.appliesPropertyToSubject.register(shouldApplyLocalesPropertyToSubject);
|
|
114
205
|
hooks.willResetSuperAdminPermissions.register(addAllLocalesToPermissions);
|
|
206
|
+
hooks.willValidateUpdatePermissions.register(normalizeRolePermissionsLocales);
|
|
115
207
|
};
|
|
116
208
|
const updateActionsProperties = ()=>{
|
|
117
209
|
const { actionProvider } = strapi.service('admin::permission');
|
|
@@ -127,7 +219,9 @@ var i18nActionsService = {
|
|
|
127
219
|
registerI18nActions,
|
|
128
220
|
registerI18nActionsHooks,
|
|
129
221
|
updateActionsProperties,
|
|
130
|
-
syncSuperAdminPermissionsWithLocales
|
|
222
|
+
syncSuperAdminPermissionsWithLocales,
|
|
223
|
+
repairPermissionsForNewlyLocalizedTypes,
|
|
224
|
+
normalizeRolePermissionsLocales
|
|
131
225
|
};
|
|
132
226
|
|
|
133
227
|
export { i18nActionsService as default };
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"actions.mjs","sources":["../../../../server/src/services/permissions/actions.ts"],"sourcesContent":["import { isArray, getOr, prop } from 'lodash/fp';\nimport { getService } from '../../utils';\n\nconst actions = [\n {\n section: 'settings',\n category: 'Internationalization',\n subCategory: 'Locales',\n pluginName: 'i18n',\n displayName: 'Create',\n uid: 'locale.create',\n },\n {\n section: 'settings',\n category: 'Internationalization',\n subCategory: 'Locales',\n pluginName: 'i18n',\n displayName: 'Read',\n uid: 'locale.read',\n aliases: [\n { actionId: 'plugin::content-manager.explorer.read', subjects: ['plugin::i18n.locale'] },\n ],\n },\n {\n section: 'settings',\n category: 'Internationalization',\n subCategory: 'Locales',\n pluginName: 'i18n',\n displayName: 'Update',\n uid: 'locale.update',\n },\n {\n section: 'settings',\n category: 'Internationalization',\n subCategory: 'Locales',\n pluginName: 'i18n',\n displayName: 'Delete',\n uid: 'locale.delete',\n },\n];\n\nconst addLocalesPropertyIfNeeded = ({ value: action }: any) => {\n const {\n section,\n options: { applyToProperties },\n } = action;\n\n // Only add the locales property to contentTypes' actions\n if (section !== 'contentTypes') {\n return;\n }\n\n // If the 'locales' property is already declared within the applyToProperties array, then ignore the next steps\n if (isArray(applyToProperties) && applyToProperties.includes('locales')) {\n return;\n }\n\n // Add the 'locales' property to the applyToProperties array (create it if necessary)\n action.options.applyToProperties = isArray(applyToProperties)\n ? applyToProperties.concat('locales')\n : ['locales'];\n};\n\nconst shouldApplyLocalesPropertyToSubject = ({ property, subject }: any) => {\n if (property === 'locales') {\n const model = strapi.getModel(subject);\n\n return getService('content-types').isLocalizedContentType(model);\n }\n\n return true;\n};\n\nconst addAllLocalesToPermissions = async (permissions: any) => {\n const { actionProvider } = strapi.service('admin::permission');\n const { find: findAllLocales } = getService('locales');\n\n const allLocales = await findAllLocales();\n const allLocalesCode = allLocales.map(prop('code'));\n\n return Promise.all(\n permissions.map(async (permission: any) => {\n const { action, subject } = permission;\n\n const appliesToLocalesProperty = await actionProvider.appliesToProperty(\n 'locales',\n action,\n subject\n );\n\n if (!appliesToLocalesProperty) {\n return permission;\n }\n\n const oldPermissionProperties = getOr({}, 'properties', permission);\n\n return { ...permission, properties: { ...oldPermissionProperties, locales: allLocalesCode } };\n })\n );\n};\n\nconst syncSuperAdminPermissionsWithLocales = async () => {\n const roleService = strapi.service('admin::role');\n const permissionService = strapi.service('admin::permission');\n\n const superAdminRole = await roleService.getSuperAdmin();\n\n if (!superAdminRole) {\n return;\n }\n\n const superAdminPermissions = await permissionService.findMany({\n where: {\n role: {\n id: superAdminRole.id,\n },\n },\n });\n\n const newSuperAdminPermissions = await addAllLocalesToPermissions(superAdminPermissions);\n\n await roleService.assignPermissions(superAdminRole.id, newSuperAdminPermissions);\n};\n\nconst registerI18nActions = async () => {\n const { actionProvider } = strapi.service('admin::permission');\n\n await actionProvider.registerMany(actions);\n};\n\nconst registerI18nActionsHooks = () => {\n const { actionProvider } = strapi.service('admin::permission');\n const { hooks } = strapi.service('admin::role');\n\n actionProvider.hooks.appliesPropertyToSubject.register(shouldApplyLocalesPropertyToSubject);\n hooks.willResetSuperAdminPermissions.register(addAllLocalesToPermissions);\n};\n\nconst updateActionsProperties = () => {\n const { actionProvider } = strapi.service('admin::permission');\n\n // Register the transformation for every new action\n actionProvider.hooks.willRegister.register(addLocalesPropertyIfNeeded);\n\n // Handle already registered actions\n actionProvider.values().forEach((action: any) => addLocalesPropertyIfNeeded({ value: action }));\n};\n\nexport default {\n actions,\n registerI18nActions,\n registerI18nActionsHooks,\n updateActionsProperties,\n syncSuperAdminPermissionsWithLocales,\n};\n"],"names":["actions","section","category","subCategory","pluginName","displayName","uid","aliases","actionId","subjects","addLocalesPropertyIfNeeded","value","action","options","applyToProperties","isArray","includes","concat","shouldApplyLocalesPropertyToSubject","property","subject","model","strapi","getModel","getService","isLocalizedContentType","addAllLocalesToPermissions","permissions","actionProvider","service","find","findAllLocales","allLocales","allLocalesCode","map","prop","Promise","all","permission","appliesToLocalesProperty","appliesToProperty","oldPermissionProperties","getOr","properties","locales","syncSuperAdminPermissionsWithLocales","roleService","permissionService","superAdminRole","getSuperAdmin","superAdminPermissions","findMany","where","role","id","newSuperAdminPermissions","assignPermissions","registerI18nActions","registerMany","registerI18nActionsHooks","hooks","appliesPropertyToSubject","register","willResetSuperAdminPermissions","updateActionsProperties","willRegister","values","forEach"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"actions.mjs","sources":["../../../../server/src/services/permissions/actions.ts"],"sourcesContent":["import { isArray, getOr, prop } from 'lodash/fp';\nimport { getService } from '../../utils';\n\nconst actions = [\n {\n section: 'settings',\n category: 'Internationalization',\n subCategory: 'Locales',\n pluginName: 'i18n',\n displayName: 'Create',\n uid: 'locale.create',\n },\n {\n section: 'settings',\n category: 'Internationalization',\n subCategory: 'Locales',\n pluginName: 'i18n',\n displayName: 'Read',\n uid: 'locale.read',\n aliases: [\n { actionId: 'plugin::content-manager.explorer.read', subjects: ['plugin::i18n.locale'] },\n ],\n },\n {\n section: 'settings',\n category: 'Internationalization',\n subCategory: 'Locales',\n pluginName: 'i18n',\n displayName: 'Update',\n uid: 'locale.update',\n },\n {\n section: 'settings',\n category: 'Internationalization',\n subCategory: 'Locales',\n pluginName: 'i18n',\n displayName: 'Delete',\n uid: 'locale.delete',\n },\n];\n\nconst addLocalesPropertyIfNeeded = ({ value: action }: any) => {\n const {\n section,\n options: { applyToProperties },\n } = action;\n\n // Only add the locales property to contentTypes' actions\n if (section !== 'contentTypes') {\n return;\n }\n\n // If the 'locales' property is already declared within the applyToProperties array, then ignore the next steps\n if (isArray(applyToProperties) && applyToProperties.includes('locales')) {\n return;\n }\n\n // Add the 'locales' property to the applyToProperties array (create it if necessary)\n action.options.applyToProperties = isArray(applyToProperties)\n ? applyToProperties.concat('locales')\n : ['locales'];\n};\n\nconst shouldApplyLocalesPropertyToSubject = ({ property, subject }: any) => {\n if (property === 'locales') {\n const model = strapi.getModel(subject);\n\n return getService('content-types').isLocalizedContentType(model);\n }\n\n return true;\n};\n\nconst addAllLocalesToPermissions = async (permissions: any) => {\n const { actionProvider } = strapi.service('admin::permission');\n const { find: findAllLocales } = getService('locales');\n\n const allLocales = await findAllLocales();\n const allLocalesCode = allLocales.map(prop('code'));\n\n return Promise.all(\n permissions.map(async (permission: any) => {\n const { action, subject } = permission;\n\n const appliesToLocalesProperty = await actionProvider.appliesToProperty(\n 'locales',\n action,\n subject\n );\n\n if (!appliesToLocalesProperty) {\n return permission;\n }\n\n const oldPermissionProperties = getOr({}, 'properties', permission);\n\n return { ...permission, properties: { ...oldPermissionProperties, locales: allLocalesCode } };\n })\n );\n};\n\n/**\n * `properties.locales === null` means access to all locales (see engine handler) — do not patch.\n */\nconst needsLocalesPatch = (properties: Record<string, unknown> = {}) => {\n if (!('locales' in properties)) {\n return true;\n }\n\n const { locales } = properties;\n\n if (locales === null) {\n return false;\n }\n\n return Array.isArray(locales) && locales.length === 0;\n};\n\nconst normalizeRolePermissionsLocales = async (permissions: any[]): Promise<any[]> => {\n const { isLocalizedContentType } = getService('content-types');\n const { actionProvider } = strapi.service('admin::permission');\n const defaultLocale = await getService('locales').getDefaultLocale();\n\n return Promise.all(\n permissions.map(async (permission) => {\n const { subject, action, properties = {} } = permission;\n\n if (!subject) {\n return permission;\n }\n\n const model = strapi.getModel(subject);\n\n if (!model || !isLocalizedContentType(model)) {\n return permission;\n }\n\n const appliesToLocales = await actionProvider.appliesToProperty('locales', action, subject);\n\n if (!appliesToLocales) {\n return permission;\n }\n\n // null means access to all locales — same semantics as the permission engine handler\n if (properties.locales === null) {\n return permission;\n }\n\n if (needsLocalesPatch(properties) && defaultLocale) {\n return { ...permission, properties: { ...properties, locales: [defaultLocale] } };\n }\n\n return permission;\n })\n );\n};\n\n/**\n * Repairs role permissions on content types that just had i18n enabled in this sync.\n * Only patches permissions where `properties.locales` is missing or `[]`; leaves `null` alone.\n * Safe to run at `afterSync` time because it does not depend on the actionProvider.\n */\nconst repairPermissionsForNewlyLocalizedTypes = async ({\n oldContentTypes,\n contentTypes,\n}: {\n oldContentTypes: Record<string, any> | null | undefined;\n contentTypes: Record<string, any>;\n}) => {\n if (!oldContentTypes) {\n return;\n }\n\n const { isLocalizedContentType } = getService('content-types');\n\n const newlyLocalizedUids = Object.keys(contentTypes).filter(\n (uid) =>\n oldContentTypes[uid] &&\n !isLocalizedContentType(oldContentTypes[uid]) &&\n isLocalizedContentType(contentTypes[uid])\n );\n\n if (newlyLocalizedUids.length === 0) {\n return;\n }\n\n try {\n const defaultLocaleCode = await getService('locales').getDefaultLocale();\n if (!defaultLocaleCode) {\n return;\n }\n\n const permissionService = strapi.service('admin::permission');\n const allPermissions = await permissionService.findMany({\n where: { subject: { $in: newlyLocalizedUids } },\n });\n\n const results = await Promise.allSettled(\n allPermissions\n .filter((permission: any) => needsLocalesPatch(permission.properties))\n .map((permission: any) =>\n strapi.db.query('admin::permission').update({\n where: { id: permission.id },\n data: {\n properties: { ...permission.properties, locales: [defaultLocaleCode] },\n },\n })\n )\n );\n\n results\n .filter((r): r is PromiseRejectedResult => r.status === 'rejected')\n .forEach((r) =>\n strapi.log.error(\n 'Failed to patch i18n permission during newly-localized type repair.',\n r.reason\n )\n );\n } catch (error) {\n strapi.log.error('Failed to repair i18n permissions for newly localized content types.', error);\n }\n};\n\nconst syncSuperAdminPermissionsWithLocales = async () => {\n const roleService = strapi.service('admin::role');\n const permissionService = strapi.service('admin::permission');\n\n const superAdminRole = await roleService.getSuperAdmin();\n\n if (!superAdminRole) {\n return;\n }\n\n const superAdminPermissions = await permissionService.findMany({\n where: {\n role: {\n id: superAdminRole.id,\n },\n },\n });\n\n const newSuperAdminPermissions = await addAllLocalesToPermissions(superAdminPermissions);\n\n await roleService.assignPermissions(superAdminRole.id, newSuperAdminPermissions);\n};\n\nconst registerI18nActions = async () => {\n const { actionProvider } = strapi.service('admin::permission');\n\n await actionProvider.registerMany(actions);\n};\n\nconst registerI18nActionsHooks = () => {\n const { actionProvider } = strapi.service('admin::permission');\n const { hooks } = strapi.service('admin::role');\n\n actionProvider.hooks.appliesPropertyToSubject.register(shouldApplyLocalesPropertyToSubject);\n hooks.willResetSuperAdminPermissions.register(addAllLocalesToPermissions);\n hooks.willValidateUpdatePermissions.register(normalizeRolePermissionsLocales);\n};\n\nconst updateActionsProperties = () => {\n const { actionProvider } = strapi.service('admin::permission');\n\n // Register the transformation for every new action\n actionProvider.hooks.willRegister.register(addLocalesPropertyIfNeeded);\n\n // Handle already registered actions\n actionProvider.values().forEach((action: any) => addLocalesPropertyIfNeeded({ value: action }));\n};\n\nexport default {\n actions,\n registerI18nActions,\n registerI18nActionsHooks,\n updateActionsProperties,\n syncSuperAdminPermissionsWithLocales,\n repairPermissionsForNewlyLocalizedTypes,\n normalizeRolePermissionsLocales,\n};\n"],"names":["actions","section","category","subCategory","pluginName","displayName","uid","aliases","actionId","subjects","addLocalesPropertyIfNeeded","value","action","options","applyToProperties","isArray","includes","concat","shouldApplyLocalesPropertyToSubject","property","subject","model","strapi","getModel","getService","isLocalizedContentType","addAllLocalesToPermissions","permissions","actionProvider","service","find","findAllLocales","allLocales","allLocalesCode","map","prop","Promise","all","permission","appliesToLocalesProperty","appliesToProperty","oldPermissionProperties","getOr","properties","locales","needsLocalesPatch","Array","length","normalizeRolePermissionsLocales","defaultLocale","getDefaultLocale","appliesToLocales","repairPermissionsForNewlyLocalizedTypes","oldContentTypes","contentTypes","newlyLocalizedUids","Object","keys","filter","defaultLocaleCode","permissionService","allPermissions","findMany","where","$in","results","allSettled","db","query","update","id","data","r","status","forEach","log","error","reason","syncSuperAdminPermissionsWithLocales","roleService","superAdminRole","getSuperAdmin","superAdminPermissions","role","newSuperAdminPermissions","assignPermissions","registerI18nActions","registerMany","registerI18nActionsHooks","hooks","appliesPropertyToSubject","register","willResetSuperAdminPermissions","willValidateUpdatePermissions","updateActionsProperties","willRegister","values"],"mappings":"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"}
|
|
@@ -11,21 +11,23 @@ var index = require('../../utils/index.js');
|
|
|
11
11
|
* @return {Promise<void>}
|
|
12
12
|
*/ const localesPropertyHandler = async ({ action, section })=>{
|
|
13
13
|
const { actionProvider } = strapi.service('admin::permission');
|
|
14
|
-
const
|
|
14
|
+
const localesService = index.getService('locales');
|
|
15
|
+
const locales = await localesService.setIsDefault(await localesService.find());
|
|
15
16
|
// Do not add the locales property if there is none registered
|
|
16
17
|
if (fp.isEmpty(locales)) {
|
|
17
18
|
return;
|
|
18
19
|
}
|
|
19
20
|
for (const subject of section.subjects){
|
|
20
21
|
const applies = await actionProvider.appliesToProperty('locales', action.actionId, subject.uid);
|
|
21
|
-
const hasLocalesProperty = subject.properties.
|
|
22
|
+
const hasLocalesProperty = subject.properties.some((property)=>property.value === 'locales');
|
|
22
23
|
if (applies && !hasLocalesProperty) {
|
|
23
24
|
subject.properties.push({
|
|
24
25
|
label: 'Locales',
|
|
25
26
|
value: 'locales',
|
|
26
|
-
children: locales.map(({ name, code })=>({
|
|
27
|
+
children: locales.map(({ name, code, isDefault })=>({
|
|
27
28
|
label: name || code,
|
|
28
|
-
value: code
|
|
29
|
+
value: code,
|
|
30
|
+
isDefault
|
|
29
31
|
}))
|
|
30
32
|
});
|
|
31
33
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"sections-builder.js","sources":["../../../../server/src/services/permissions/sections-builder.ts"],"sourcesContent":["import { isEmpty } from 'lodash/fp';\n\nimport { getService } from '../../utils';\n\n/**\n * Handler for the permissions layout (sections builder)\n * Adds the locales property to the subjects\n * @param {Action} action\n * @param {ContentTypesSection} section\n * @return {Promise<void>}\n */\nconst localesPropertyHandler = async ({ action, section }: any) => {\n const { actionProvider } = strapi.service('admin::permission');\n\n const
|
|
1
|
+
{"version":3,"file":"sections-builder.js","sources":["../../../../server/src/services/permissions/sections-builder.ts"],"sourcesContent":["import { isEmpty } from 'lodash/fp';\n\nimport { getService } from '../../utils';\n\n/**\n * Handler for the permissions layout (sections builder)\n * Adds the locales property to the subjects\n * @param {Action} action\n * @param {ContentTypesSection} section\n * @return {Promise<void>}\n */\nconst localesPropertyHandler = async ({ action, section }: any) => {\n const { actionProvider } = strapi.service('admin::permission');\n\n const localesService = getService('locales');\n const locales = await localesService.setIsDefault(await localesService.find());\n\n // Do not add the locales property if there is none registered\n if (isEmpty(locales)) {\n return;\n }\n\n for (const subject of section.subjects) {\n const applies = await actionProvider.appliesToProperty('locales', action.actionId, subject.uid);\n const hasLocalesProperty = subject.properties.some(\n (property: any) => property.value === 'locales'\n );\n\n if (applies && !hasLocalesProperty) {\n subject.properties.push({\n label: 'Locales',\n value: 'locales',\n children: locales.map(({ name, code, isDefault }: any) => ({\n label: name || code,\n value: code,\n isDefault,\n })),\n });\n }\n }\n};\n\nconst registerLocalesPropertyHandler = () => {\n const { sectionsBuilder } = strapi.service('admin::permission');\n\n sectionsBuilder.addHandler('singleTypes', localesPropertyHandler);\n sectionsBuilder.addHandler('collectionTypes', localesPropertyHandler);\n};\n\nexport default {\n localesPropertyHandler,\n registerLocalesPropertyHandler,\n};\n"],"names":["localesPropertyHandler","action","section","actionProvider","strapi","service","localesService","getService","locales","setIsDefault","find","isEmpty","subject","subjects","applies","appliesToProperty","actionId","uid","hasLocalesProperty","properties","some","property","value","push","label","children","map","name","code","isDefault","registerLocalesPropertyHandler","sectionsBuilder","addHandler"],"mappings":";;;;;AAIA;;;;;;AAMC,IACD,MAAMA,sBAAAA,GAAyB,OAAO,EAAEC,MAAM,EAAEC,OAAO,EAAO,GAAA;AAC5D,IAAA,MAAM,EAAEC,cAAc,EAAE,GAAGC,MAAAA,CAAOC,OAAO,CAAC,mBAAA,CAAA;AAE1C,IAAA,MAAMC,iBAAiBC,gBAAAA,CAAW,SAAA,CAAA;AAClC,IAAA,MAAMC,UAAU,MAAMF,cAAAA,CAAeG,YAAY,CAAC,MAAMH,eAAeI,IAAI,EAAA,CAAA;;AAG3E,IAAA,IAAIC,WAAQH,OAAAA,CAAAA,EAAU;AACpB,QAAA;AACF,IAAA;AAEA,IAAA,KAAK,MAAMI,OAAAA,IAAWV,OAAAA,CAAQW,QAAQ,CAAE;QACtC,MAAMC,OAAAA,GAAU,MAAMX,cAAAA,CAAeY,iBAAiB,CAAC,WAAWd,MAAAA,CAAOe,QAAQ,EAAEJ,OAAAA,CAAQK,GAAG,CAAA;QAC9F,MAAMC,kBAAAA,GAAqBN,OAAAA,CAAQO,UAAU,CAACC,IAAI,CAChD,CAACC,QAAAA,GAAkBA,QAAAA,CAASC,KAAK,KAAK,SAAA,CAAA;QAGxC,IAAIR,OAAAA,IAAW,CAACI,kBAAAA,EAAoB;YAClCN,OAAAA,CAAQO,UAAU,CAACI,IAAI,CAAC;gBACtBC,KAAAA,EAAO,SAAA;gBACPF,KAAAA,EAAO,SAAA;AACPG,gBAAAA,QAAAA,EAAUjB,OAAAA,CAAQkB,GAAG,CAAC,CAAC,EAAEC,IAAI,EAAEC,IAAI,EAAEC,SAAS,EAAO,IAAM;AACzDL,wBAAAA,KAAAA,EAAOG,IAAAA,IAAQC,IAAAA;wBACfN,KAAAA,EAAOM,IAAAA;AACPC,wBAAAA;qBACF,CAAA;AACF,aAAA,CAAA;AACF,QAAA;AACF,IAAA;AACF,CAAA;AAEA,MAAMC,8BAAAA,GAAiC,IAAA;AACrC,IAAA,MAAM,EAAEC,eAAe,EAAE,GAAG3B,MAAAA,CAAOC,OAAO,CAAC,mBAAA,CAAA;IAE3C0B,eAAAA,CAAgBC,UAAU,CAAC,aAAA,EAAehC,sBAAAA,CAAAA;IAC1C+B,eAAAA,CAAgBC,UAAU,CAAC,iBAAA,EAAmBhC,sBAAAA,CAAAA;AAChD,CAAA;AAEA,6BAAe;AACbA,IAAAA,sBAAAA;AACA8B,IAAAA;AACF,CAAA;;;;"}
|
|
@@ -9,21 +9,23 @@ import { getService } from '../../utils/index.mjs';
|
|
|
9
9
|
* @return {Promise<void>}
|
|
10
10
|
*/ const localesPropertyHandler = async ({ action, section })=>{
|
|
11
11
|
const { actionProvider } = strapi.service('admin::permission');
|
|
12
|
-
const
|
|
12
|
+
const localesService = getService('locales');
|
|
13
|
+
const locales = await localesService.setIsDefault(await localesService.find());
|
|
13
14
|
// Do not add the locales property if there is none registered
|
|
14
15
|
if (isEmpty(locales)) {
|
|
15
16
|
return;
|
|
16
17
|
}
|
|
17
18
|
for (const subject of section.subjects){
|
|
18
19
|
const applies = await actionProvider.appliesToProperty('locales', action.actionId, subject.uid);
|
|
19
|
-
const hasLocalesProperty = subject.properties.
|
|
20
|
+
const hasLocalesProperty = subject.properties.some((property)=>property.value === 'locales');
|
|
20
21
|
if (applies && !hasLocalesProperty) {
|
|
21
22
|
subject.properties.push({
|
|
22
23
|
label: 'Locales',
|
|
23
24
|
value: 'locales',
|
|
24
|
-
children: locales.map(({ name, code })=>({
|
|
25
|
+
children: locales.map(({ name, code, isDefault })=>({
|
|
25
26
|
label: name || code,
|
|
26
|
-
value: code
|
|
27
|
+
value: code,
|
|
28
|
+
isDefault
|
|
27
29
|
}))
|
|
28
30
|
});
|
|
29
31
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"sections-builder.mjs","sources":["../../../../server/src/services/permissions/sections-builder.ts"],"sourcesContent":["import { isEmpty } from 'lodash/fp';\n\nimport { getService } from '../../utils';\n\n/**\n * Handler for the permissions layout (sections builder)\n * Adds the locales property to the subjects\n * @param {Action} action\n * @param {ContentTypesSection} section\n * @return {Promise<void>}\n */\nconst localesPropertyHandler = async ({ action, section }: any) => {\n const { actionProvider } = strapi.service('admin::permission');\n\n const
|
|
1
|
+
{"version":3,"file":"sections-builder.mjs","sources":["../../../../server/src/services/permissions/sections-builder.ts"],"sourcesContent":["import { isEmpty } from 'lodash/fp';\n\nimport { getService } from '../../utils';\n\n/**\n * Handler for the permissions layout (sections builder)\n * Adds the locales property to the subjects\n * @param {Action} action\n * @param {ContentTypesSection} section\n * @return {Promise<void>}\n */\nconst localesPropertyHandler = async ({ action, section }: any) => {\n const { actionProvider } = strapi.service('admin::permission');\n\n const localesService = getService('locales');\n const locales = await localesService.setIsDefault(await localesService.find());\n\n // Do not add the locales property if there is none registered\n if (isEmpty(locales)) {\n return;\n }\n\n for (const subject of section.subjects) {\n const applies = await actionProvider.appliesToProperty('locales', action.actionId, subject.uid);\n const hasLocalesProperty = subject.properties.some(\n (property: any) => property.value === 'locales'\n );\n\n if (applies && !hasLocalesProperty) {\n subject.properties.push({\n label: 'Locales',\n value: 'locales',\n children: locales.map(({ name, code, isDefault }: any) => ({\n label: name || code,\n value: code,\n isDefault,\n })),\n });\n }\n }\n};\n\nconst registerLocalesPropertyHandler = () => {\n const { sectionsBuilder } = strapi.service('admin::permission');\n\n sectionsBuilder.addHandler('singleTypes', localesPropertyHandler);\n sectionsBuilder.addHandler('collectionTypes', localesPropertyHandler);\n};\n\nexport default {\n localesPropertyHandler,\n registerLocalesPropertyHandler,\n};\n"],"names":["localesPropertyHandler","action","section","actionProvider","strapi","service","localesService","getService","locales","setIsDefault","find","isEmpty","subject","subjects","applies","appliesToProperty","actionId","uid","hasLocalesProperty","properties","some","property","value","push","label","children","map","name","code","isDefault","registerLocalesPropertyHandler","sectionsBuilder","addHandler"],"mappings":";;;AAIA;;;;;;AAMC,IACD,MAAMA,sBAAAA,GAAyB,OAAO,EAAEC,MAAM,EAAEC,OAAO,EAAO,GAAA;AAC5D,IAAA,MAAM,EAAEC,cAAc,EAAE,GAAGC,MAAAA,CAAOC,OAAO,CAAC,mBAAA,CAAA;AAE1C,IAAA,MAAMC,iBAAiBC,UAAAA,CAAW,SAAA,CAAA;AAClC,IAAA,MAAMC,UAAU,MAAMF,cAAAA,CAAeG,YAAY,CAAC,MAAMH,eAAeI,IAAI,EAAA,CAAA;;AAG3E,IAAA,IAAIC,QAAQH,OAAAA,CAAAA,EAAU;AACpB,QAAA;AACF,IAAA;AAEA,IAAA,KAAK,MAAMI,OAAAA,IAAWV,OAAAA,CAAQW,QAAQ,CAAE;QACtC,MAAMC,OAAAA,GAAU,MAAMX,cAAAA,CAAeY,iBAAiB,CAAC,WAAWd,MAAAA,CAAOe,QAAQ,EAAEJ,OAAAA,CAAQK,GAAG,CAAA;QAC9F,MAAMC,kBAAAA,GAAqBN,OAAAA,CAAQO,UAAU,CAACC,IAAI,CAChD,CAACC,QAAAA,GAAkBA,QAAAA,CAASC,KAAK,KAAK,SAAA,CAAA;QAGxC,IAAIR,OAAAA,IAAW,CAACI,kBAAAA,EAAoB;YAClCN,OAAAA,CAAQO,UAAU,CAACI,IAAI,CAAC;gBACtBC,KAAAA,EAAO,SAAA;gBACPF,KAAAA,EAAO,SAAA;AACPG,gBAAAA,QAAAA,EAAUjB,OAAAA,CAAQkB,GAAG,CAAC,CAAC,EAAEC,IAAI,EAAEC,IAAI,EAAEC,SAAS,EAAO,IAAM;AACzDL,wBAAAA,KAAAA,EAAOG,IAAAA,IAAQC,IAAAA;wBACfN,KAAAA,EAAOM,IAAAA;AACPC,wBAAAA;qBACF,CAAA;AACF,aAAA,CAAA;AACF,QAAA;AACF,IAAA;AACF,CAAA;AAEA,MAAMC,8BAAAA,GAAiC,IAAA;AACrC,IAAA,MAAM,EAAEC,eAAe,EAAE,GAAG3B,MAAAA,CAAOC,OAAO,CAAC,mBAAA,CAAA;IAE3C0B,eAAAA,CAAgBC,UAAU,CAAC,aAAA,EAAehC,sBAAAA,CAAAA;IAC1C+B,eAAAA,CAAgBC,UAAU,CAAC,iBAAA,EAAmBhC,sBAAAA,CAAAA;AAChD,CAAA;AAEA,6BAAe;AACbA,IAAAA,sBAAAA;AACA8B,IAAAA;AACF,CAAA;;;;"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"ai-localization-jobs.d.ts","sourceRoot":"","sources":["../../../../server/src/controllers/ai-localization-jobs.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,IAAI,EAAE,MAAM,eAAe,CAAC;AAE1C,QAAA,MAAM,kCAAkC,
|
|
1
|
+
{"version":3,"file":"ai-localization-jobs.d.ts","sourceRoot":"","sources":["../../../../server/src/controllers/ai-localization-jobs.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,IAAI,EAAE,MAAM,eAAe,CAAC;AAE1C,QAAA,MAAM,kCAAkC,GAAI,YAAY;IAAE,MAAM,EAAE,IAAI,CAAC,MAAM,CAAA;CAAE;IAK3E;;;OAGG;6BAC4B,GAAG;IAuBlC;;;OAGG;iCACgC,GAAG;CAwBzC,CAAC;AAEF,eAAe,kCAAkC,CAAC"}
|
|
@@ -1,7 +1,6 @@
|
|
|
1
|
-
/// <reference types="koa" />
|
|
2
1
|
declare const controller: {
|
|
3
|
-
getNonLocalizedAttributes(ctx: import("koa").Context): Promise<
|
|
4
|
-
getFillFromLocaleData(ctx: import("koa").Context): Promise<
|
|
2
|
+
getNonLocalizedAttributes(ctx: import("koa").Context): Promise<any>;
|
|
3
|
+
getFillFromLocaleData(ctx: import("koa").Context): Promise<any>;
|
|
5
4
|
};
|
|
6
5
|
export default controller;
|
|
7
6
|
//# sourceMappingURL=content-types.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"content-types.d.ts","sourceRoot":"","sources":["../../../../server/src/controllers/content-types.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"content-types.d.ts","sourceRoot":"","sources":["../../../../server/src/controllers/content-types.ts"],"names":[],"mappings":"AAmBA,QAAA,MAAM,UAAU;;;CAyIW,CAAC;AAE5B,eAAe,UAAU,CAAC"}
|
|
@@ -1,10 +1,9 @@
|
|
|
1
|
-
/// <reference types="koa" />
|
|
2
1
|
declare const _default: {
|
|
3
2
|
locales: import("@strapi/types/dist/core").Controller;
|
|
4
3
|
'iso-locales': import("@strapi/types/dist/core").Controller;
|
|
5
4
|
'content-types': {
|
|
6
|
-
getNonLocalizedAttributes(ctx: import("koa").Context): Promise<
|
|
7
|
-
getFillFromLocaleData(ctx: import("koa").Context): Promise<
|
|
5
|
+
getNonLocalizedAttributes(ctx: import("koa").Context): Promise<any>;
|
|
6
|
+
getFillFromLocaleData(ctx: import("koa").Context): Promise<any>;
|
|
8
7
|
};
|
|
9
8
|
settings: {
|
|
10
9
|
updateSettings(ctx: import("koa").Context): Promise<void>;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../../server/src/controllers/index.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../../server/src/controllers/index.ts"],"names":[],"mappings":";;;;;;;;;;;;;;;;;;AAMA,wBAME"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"locale.d.ts","sourceRoot":"","sources":["../../../../server/src/domain/locale.ts"],"names":[],"mappings":"AAAA,QAAA,MAAM,YAAY,
|
|
1
|
+
{"version":3,"file":"locale.d.ts","sourceRoot":"","sources":["../../../../server/src/domain/locale.ts"],"names":[],"mappings":"AAAA,QAAA,MAAM,YAAY,GAAI,QAAQ;IAAE,IAAI,EAAE,MAAM,CAAC;IAAC,IAAI,EAAE,MAAM,CAAC;IAAC,SAAS,EAAE,OAAO,CAAA;CAAE;;UAA5B,MAAM;eAAa,OAAO;CAK7E,CAAC;AAEF,OAAO,EAAE,YAAY,EAAE,CAAC"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"graphql.d.ts","sourceRoot":"","sources":["../../../server/src/graphql.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,IAAI,EAAE,MAAM,eAAe,CAAC;
|
|
1
|
+
{"version":3,"file":"graphql.d.ts","sourceRoot":"","sources":["../../../server/src/graphql.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,IAAI,EAAE,MAAM,eAAe,CAAC;yBAO1B,YAAY;IAAE,MAAM,EAAE,IAAI,CAAC,MAAM,CAAA;CAAE;;;AAAnD,wBAqCG"}
|
|
@@ -1,5 +1,3 @@
|
|
|
1
|
-
/// <reference types="koa" />
|
|
2
|
-
/// <reference types="lodash" />
|
|
3
1
|
declare const _default: () => {
|
|
4
2
|
register: ({ strapi }: {
|
|
5
3
|
strapi: import("@strapi/types/dist/core").Strapi;
|
|
@@ -31,8 +29,8 @@ declare const _default: () => {
|
|
|
31
29
|
locales: import("@strapi/types/dist/core").Controller;
|
|
32
30
|
'iso-locales': import("@strapi/types/dist/core").Controller;
|
|
33
31
|
'content-types': {
|
|
34
|
-
getNonLocalizedAttributes(ctx: import("koa").Context): Promise<
|
|
35
|
-
getFillFromLocaleData(ctx: import("koa").Context): Promise<
|
|
32
|
+
getNonLocalizedAttributes(ctx: import("koa").Context): Promise<any>;
|
|
33
|
+
getFillFromLocaleData(ctx: import("koa").Context): Promise<any>;
|
|
36
34
|
};
|
|
37
35
|
settings: {
|
|
38
36
|
updateSettings(ctx: import("koa").Context): Promise<void>;
|
|
@@ -107,6 +105,11 @@ declare const _default: () => {
|
|
|
107
105
|
registerI18nActionsHooks: () => void;
|
|
108
106
|
updateActionsProperties: () => void;
|
|
109
107
|
syncSuperAdminPermissionsWithLocales: () => Promise<void>;
|
|
108
|
+
repairPermissionsForNewlyLocalizedTypes: ({ oldContentTypes, contentTypes, }: {
|
|
109
|
+
oldContentTypes: Record<string, any> | null | undefined;
|
|
110
|
+
contentTypes: Record<string, any>;
|
|
111
|
+
}) => Promise<void>;
|
|
112
|
+
normalizeRolePermissionsLocales: (permissions: any[]) => Promise<any[]>;
|
|
110
113
|
};
|
|
111
114
|
sectionsBuilder: {
|
|
112
115
|
localesPropertyHandler: ({ action, section }: any) => Promise<void>;
|
|
@@ -122,7 +125,7 @@ declare const _default: () => {
|
|
|
122
125
|
sendDidUpdateI18nLocalesEvent: () => Promise<void>;
|
|
123
126
|
};
|
|
124
127
|
localizations: () => {
|
|
125
|
-
syncNonLocalizedAttributes: (sourceEntry: any, model: import("@strapi/types/dist/
|
|
128
|
+
syncNonLocalizedAttributes: (sourceEntry: any, model: import("@strapi/types/dist/schema").ContentType) => Promise<void>;
|
|
126
129
|
};
|
|
127
130
|
locales: () => {
|
|
128
131
|
find: (params?: any) => Promise<any[]>;
|
|
@@ -175,7 +178,7 @@ declare const _default: () => {
|
|
|
175
178
|
contentType: string;
|
|
176
179
|
sourceLocale: string;
|
|
177
180
|
targetLocales: string[];
|
|
178
|
-
status?: "
|
|
181
|
+
status?: import("../../shared/contracts/ai-localization-jobs").AILocalizationJobs["status"];
|
|
179
182
|
}): Promise<any>;
|
|
180
183
|
getJobByDocument(contentType: string, documentId: string): Promise<any>;
|
|
181
184
|
getJobByContentType(contentType: string): Promise<any>;
|
|
@@ -186,14 +189,12 @@ declare const _default: () => {
|
|
|
186
189
|
getSettings: () => Promise<import("yup/lib/object").AssertsShape<{
|
|
187
190
|
aiLocalizations: import("yup").BooleanSchema<boolean, Record<string, any>, boolean>;
|
|
188
191
|
}> | null>;
|
|
189
|
-
setSettings: (value: import("
|
|
190
|
-
aiLocalizations: import("yup").BooleanSchema<boolean, Record<string, any>, boolean>;
|
|
191
|
-
}>) => Promise<void>;
|
|
192
|
+
setSettings: (value: import("./validation/settings").Settings) => Promise<void>;
|
|
192
193
|
};
|
|
193
194
|
'fill-from-locale': ({ strapi }: {
|
|
194
195
|
strapi: import("@strapi/types/dist/core").Strapi;
|
|
195
196
|
}) => {
|
|
196
|
-
fetchRawDocument(model: import("@strapi/types/dist/uid").ContentType, sourceLocale: string, documentId?: string
|
|
197
|
+
fetchRawDocument(model: import("@strapi/types/dist/uid").ContentType, sourceLocale: string, documentId?: string): Promise<import("@strapi/types/dist/modules/documents").AnyDocument | null>;
|
|
197
198
|
transformDocument(document: Record<string, unknown>, model: import("@strapi/types/dist/uid").ContentType, targetLocale: string, userAbility: any): Promise<Record<string, unknown>>;
|
|
198
199
|
};
|
|
199
200
|
};
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../server/src/index.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../server/src/index.ts"],"names":[],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;sBAemW,CAAC;;;;;;;;;;;;;;;;;;;;;AARpW,wBAOG"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"register.d.ts","sourceRoot":"","sources":["../../../server/src/register.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,IAAI,EAAE,MAAM,eAAe,CAAC;
|
|
1
|
+
{"version":3,"file":"register.d.ts","sourceRoot":"","sources":["../../../server/src/register.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,IAAI,EAAE,MAAM,eAAe,CAAC;yBAOpB,YAAY;IAAE,MAAM,EAAE,IAAI,CAAC,MAAM,CAAA;CAAE;AAAzD,wBAcE"}
|
|
@@ -12,7 +12,7 @@ export declare const createAILocalizationJobsService: ({ strapi }: {
|
|
|
12
12
|
contentType: string;
|
|
13
13
|
sourceLocale: string;
|
|
14
14
|
targetLocales: string[];
|
|
15
|
-
status?: AILocalizationJobs[
|
|
15
|
+
status?: AILocalizationJobs["status"];
|
|
16
16
|
}): Promise<any>;
|
|
17
17
|
/**
|
|
18
18
|
* Get job by document ID
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"ai-localization-jobs.d.ts","sourceRoot":"","sources":["../../../../server/src/services/ai-localization-jobs.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,IAAI,EAAE,MAAM,eAAe,CAAC;AAE1C,OAAO,KAAK,EAAE,kBAAkB,EAAE,MAAM,gDAAgD,CAAC;AAEzF,eAAO,MAAM,+BAA+B,
|
|
1
|
+
{"version":3,"file":"ai-localization-jobs.d.ts","sourceRoot":"","sources":["../../../../server/src/services/ai-localization-jobs.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,IAAI,EAAE,MAAM,eAAe,CAAC;AAE1C,OAAO,KAAK,EAAE,kBAAkB,EAAE,MAAM,gDAAgD,CAAC;AAEzF,eAAO,MAAM,+BAA+B,GAAI,YAAY;IAAE,MAAM,EAAE,IAAI,CAAC,MAAM,CAAA;CAAE;IACjF;;;OAGG;4FAOA;QACD,UAAU,EAAE,MAAM,CAAC;QACnB,WAAW,EAAE,MAAM,CAAC;QACpB,YAAY,EAAE,MAAM,CAAC;QACrB,aAAa,EAAE,MAAM,EAAE,CAAC;QACxB,MAAM,CAAC,EAAE,kBAAkB,CAAC,QAAQ,CAAC,CAAC;KACvC;IAsCD;;OAEG;kCACiC,MAAM,cAAc,MAAM;IAS9D;;OAEG;qCACoC,MAAM;CAO7C,CAAC"}
|