@strapi/admin 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.
Files changed (181) hide show
  1. package/dist/admin/admin/src/StrapiApp.js +1 -0
  2. package/dist/admin/admin/src/StrapiApp.js.map +1 -1
  3. package/dist/admin/admin/src/StrapiApp.mjs +1 -0
  4. package/dist/admin/admin/src/StrapiApp.mjs.map +1 -1
  5. package/dist/admin/admin/src/components/Form.js +11 -10
  6. package/dist/admin/admin/src/components/Form.js.map +1 -1
  7. package/dist/admin/admin/src/components/Form.mjs +11 -10
  8. package/dist/admin/admin/src/components/Form.mjs.map +1 -1
  9. package/dist/admin/admin/src/components/FormInputs/Date.js +2 -2
  10. package/dist/admin/admin/src/components/FormInputs/Date.js.map +1 -1
  11. package/dist/admin/admin/src/components/FormInputs/Date.mjs +2 -2
  12. package/dist/admin/admin/src/components/FormInputs/Date.mjs.map +1 -1
  13. package/dist/admin/admin/src/components/FormInputs/Time.js +6 -1
  14. package/dist/admin/admin/src/components/FormInputs/Time.js.map +1 -1
  15. package/dist/admin/admin/src/components/FormInputs/Time.mjs +6 -1
  16. package/dist/admin/admin/src/components/FormInputs/Time.mjs.map +1 -1
  17. package/dist/admin/admin/src/components/GuidedTour/Context.js +3 -2
  18. package/dist/admin/admin/src/components/GuidedTour/Context.js.map +1 -1
  19. package/dist/admin/admin/src/components/GuidedTour/Context.mjs +3 -2
  20. package/dist/admin/admin/src/components/GuidedTour/Context.mjs.map +1 -1
  21. package/dist/admin/admin/src/components/PageHelpers.js +1 -1
  22. package/dist/admin/admin/src/components/PageHelpers.js.map +1 -1
  23. package/dist/admin/admin/src/components/PageHelpers.mjs +1 -1
  24. package/dist/admin/admin/src/components/PageHelpers.mjs.map +1 -1
  25. package/dist/admin/admin/src/components/Table.js +28 -15
  26. package/dist/admin/admin/src/components/Table.js.map +1 -1
  27. package/dist/admin/admin/src/components/Table.mjs +29 -16
  28. package/dist/admin/admin/src/components/Table.mjs.map +1 -1
  29. package/dist/admin/admin/src/core/store/configure.js +3 -1
  30. package/dist/admin/admin/src/core/store/configure.js.map +1 -1
  31. package/dist/admin/admin/src/core/store/configure.mjs +3 -1
  32. package/dist/admin/admin/src/core/store/configure.mjs.map +1 -1
  33. package/dist/admin/admin/src/features/Widgets.js +1 -1
  34. package/dist/admin/admin/src/features/Widgets.js.map +1 -1
  35. package/dist/admin/admin/src/features/Widgets.mjs +1 -1
  36. package/dist/admin/admin/src/features/Widgets.mjs.map +1 -1
  37. package/dist/admin/admin/src/hooks/usePersistentState.js +9 -4
  38. package/dist/admin/admin/src/hooks/usePersistentState.js.map +1 -1
  39. package/dist/admin/admin/src/hooks/usePersistentState.mjs +10 -6
  40. package/dist/admin/admin/src/hooks/usePersistentState.mjs.map +1 -1
  41. package/dist/admin/admin/src/pages/ProfilePage.js +2 -2
  42. package/dist/admin/admin/src/pages/ProfilePage.js.map +1 -1
  43. package/dist/admin/admin/src/pages/ProfilePage.mjs +2 -2
  44. package/dist/admin/admin/src/pages/ProfilePage.mjs.map +1 -1
  45. package/dist/admin/admin/src/pages/Settings/pages/ApplicationInfo/components/LogoInput.js +4 -1
  46. package/dist/admin/admin/src/pages/Settings/pages/ApplicationInfo/components/LogoInput.js.map +1 -1
  47. package/dist/admin/admin/src/pages/Settings/pages/ApplicationInfo/components/LogoInput.mjs +4 -1
  48. package/dist/admin/admin/src/pages/Settings/pages/ApplicationInfo/components/LogoInput.mjs.map +1 -1
  49. package/dist/admin/admin/src/pages/Settings/pages/Roles/utils/forms.js +1 -1
  50. package/dist/admin/admin/src/pages/Settings/pages/Roles/utils/forms.js.map +1 -1
  51. package/dist/admin/admin/src/pages/Settings/pages/Roles/utils/forms.mjs +1 -1
  52. package/dist/admin/admin/src/pages/Settings/pages/Roles/utils/forms.mjs.map +1 -1
  53. package/dist/admin/admin/src/pages/Settings/pages/TransferTokens/ListView.js +1 -1
  54. package/dist/admin/admin/src/pages/Settings/pages/TransferTokens/ListView.js.map +1 -1
  55. package/dist/admin/admin/src/pages/Settings/pages/TransferTokens/ListView.mjs +1 -1
  56. package/dist/admin/admin/src/pages/Settings/pages/TransferTokens/ListView.mjs.map +1 -1
  57. package/dist/admin/admin/src/render.js +2 -0
  58. package/dist/admin/admin/src/render.js.map +1 -1
  59. package/dist/admin/admin/src/render.mjs +2 -0
  60. package/dist/admin/admin/src/render.mjs.map +1 -1
  61. package/dist/admin/admin/src/services/api.js +2 -2
  62. package/dist/admin/admin/src/services/api.js.map +1 -1
  63. package/dist/admin/admin/src/services/api.mjs +2 -2
  64. package/dist/admin/admin/src/services/api.mjs.map +1 -1
  65. package/dist/admin/admin/src/translations/fi.json.js +890 -0
  66. package/dist/admin/admin/src/translations/fi.json.js.map +1 -0
  67. package/dist/admin/admin/src/translations/fi.json.mjs +868 -0
  68. package/dist/admin/admin/src/translations/fi.json.mjs.map +1 -0
  69. package/dist/admin/admin/src/translations/languageNativeNames.js +2 -1
  70. package/dist/admin/admin/src/translations/languageNativeNames.js.map +1 -1
  71. package/dist/admin/admin/src/translations/languageNativeNames.mjs +2 -1
  72. package/dist/admin/admin/src/translations/languageNativeNames.mjs.map +1 -1
  73. package/dist/admin/admin/src/translations/nl.json.js +394 -89
  74. package/dist/admin/admin/src/translations/nl.json.js.map +1 -1
  75. package/dist/admin/admin/src/translations/nl.json.mjs +393 -90
  76. package/dist/admin/admin/src/translations/nl.json.mjs.map +1 -1
  77. package/dist/admin/admin/src/translations/pl.json.js +411 -37
  78. package/dist/admin/admin/src/translations/pl.json.js.map +1 -1
  79. package/dist/admin/admin/src/translations/pl.json.mjs +408 -38
  80. package/dist/admin/admin/src/translations/pl.json.mjs.map +1 -1
  81. package/dist/admin/ee/admin/src/hooks/useAIUsageWarning.js +1 -1
  82. package/dist/admin/ee/admin/src/hooks/useAIUsageWarning.js.map +1 -1
  83. package/dist/admin/ee/admin/src/hooks/useAIUsageWarning.mjs +2 -2
  84. package/dist/admin/ee/admin/src/hooks/useAIUsageWarning.mjs.map +1 -1
  85. package/dist/admin/ee/admin/src/pages/SettingsPage/pages/ApplicationInfoPage/components/AIUsage.js +1 -1
  86. package/dist/admin/ee/admin/src/pages/SettingsPage/pages/ApplicationInfoPage/components/AIUsage.js.map +1 -1
  87. package/dist/admin/ee/admin/src/pages/SettingsPage/pages/ApplicationInfoPage/components/AIUsage.mjs +2 -2
  88. package/dist/admin/ee/admin/src/pages/SettingsPage/pages/ApplicationInfoPage/components/AIUsage.mjs.map +1 -1
  89. package/dist/admin/ee/admin/src/services/ai.js +7 -7
  90. package/dist/admin/ee/admin/src/services/ai.js.map +1 -1
  91. package/dist/admin/ee/admin/src/services/ai.mjs +6 -6
  92. package/dist/admin/ee/admin/src/services/ai.mjs.map +1 -1
  93. package/dist/admin/ee.js +2 -2
  94. package/dist/admin/ee.mjs +1 -1
  95. package/dist/admin/index.js +1 -0
  96. package/dist/admin/index.js.map +1 -1
  97. package/dist/admin/index.mjs +1 -1
  98. package/dist/admin/src/core/store/configure.d.ts +2 -2
  99. package/dist/admin/src/core/store/hooks.d.ts +2 -2
  100. package/dist/admin/src/ee.d.ts +1 -1
  101. package/dist/admin/src/hooks/useAdminRoles.d.ts +1 -1
  102. package/dist/admin/src/hooks/usePersistentState.d.ts +2 -1
  103. package/dist/admin/src/index.d.ts +1 -1
  104. package/dist/admin/src/pages/Settings/pages/Roles/utils/forms.d.ts +1 -1
  105. package/dist/admin/src/pages/Settings/pages/Webhooks/hooks/useWebhooks.d.ts +4 -4
  106. package/dist/admin/src/selectors.d.ts +2 -2
  107. package/dist/admin/src/services/admin.d.ts +6 -6
  108. package/dist/admin/src/services/api.d.ts +1 -1
  109. package/dist/admin/src/services/apiTokens.d.ts +1 -1
  110. package/dist/admin/src/services/auth.d.ts +11 -11
  111. package/dist/admin/src/services/contentApi.d.ts +1 -1
  112. package/dist/admin/src/services/contentManager.d.ts +1 -1
  113. package/dist/admin/src/services/homepage.d.ts +3 -3
  114. package/dist/admin/src/services/transferTokens.d.ts +1 -1
  115. package/dist/admin/src/services/users.d.ts +8 -8
  116. package/dist/admin/src/services/webhooks.d.ts +2 -2
  117. package/dist/admin/src/translations/languageNativeNames.d.ts +1 -0
  118. package/dist/admin/tests/utils.d.ts +1 -1
  119. package/dist/ee/admin/src/services/ai.d.ts +6 -6
  120. package/dist/ee/admin/src/services/auditLogs.d.ts +1 -1
  121. package/dist/ee/server/src/audit-logs/services/lifecycles.d.ts +1 -1
  122. package/dist/ee/server/src/index.d.ts +0 -16
  123. package/dist/ee/server/src/index.d.ts.map +1 -1
  124. package/dist/server/ee/server/src/audit-logs/services/lifecycles.js +1 -1
  125. package/dist/server/ee/server/src/audit-logs/services/lifecycles.js.map +1 -1
  126. package/dist/server/ee/server/src/audit-logs/services/lifecycles.mjs +1 -1
  127. package/dist/server/ee/server/src/audit-logs/services/lifecycles.mjs.map +1 -1
  128. package/dist/server/ee/server/src/index.js +1 -17
  129. package/dist/server/ee/server/src/index.js.map +1 -1
  130. package/dist/server/ee/server/src/index.mjs +1 -17
  131. package/dist/server/ee/server/src/index.mjs.map +1 -1
  132. package/dist/server/server/src/ai/controllers/ai.js +52 -0
  133. package/dist/server/server/src/ai/controllers/ai.js.map +1 -0
  134. package/dist/server/server/src/ai/controllers/ai.mjs +50 -0
  135. package/dist/server/server/src/ai/controllers/ai.mjs.map +1 -0
  136. package/dist/server/{ee/server → server}/src/ai/routes/ai.js +1 -2
  137. package/dist/server/server/src/ai/routes/ai.js.map +1 -0
  138. package/dist/server/{ee/server → server}/src/ai/routes/ai.mjs +1 -2
  139. package/dist/server/server/src/ai/routes/ai.mjs.map +1 -0
  140. package/dist/server/{ee/server/src/ai/containers → server/src/ai/services}/ai.js +107 -32
  141. package/dist/server/server/src/ai/services/ai.js.map +1 -0
  142. package/dist/server/{ee/server/src/ai/containers → server/src/ai/services}/ai.mjs +107 -32
  143. package/dist/server/server/src/ai/services/ai.mjs.map +1 -0
  144. package/dist/server/server/src/controllers/index.js +3 -1
  145. package/dist/server/server/src/controllers/index.js.map +1 -1
  146. package/dist/server/server/src/controllers/index.mjs +3 -1
  147. package/dist/server/server/src/controllers/index.mjs.map +1 -1
  148. package/dist/server/server/src/register.js +4 -0
  149. package/dist/server/server/src/register.js.map +1 -1
  150. package/dist/server/server/src/register.mjs +4 -0
  151. package/dist/server/server/src/register.mjs.map +1 -1
  152. package/dist/server/server/src/routes/index.js +3 -1
  153. package/dist/server/server/src/routes/index.js.map +1 -1
  154. package/dist/server/server/src/routes/index.mjs +3 -1
  155. package/dist/server/server/src/routes/index.mjs.map +1 -1
  156. package/dist/{ee/server → server}/src/ai/controllers/ai.d.ts +1 -1
  157. package/dist/server/src/ai/controllers/ai.d.ts.map +1 -0
  158. package/dist/server/src/ai/routes/ai.d.ts.map +1 -0
  159. package/dist/server/src/ai/services/ai.d.ts +30 -0
  160. package/dist/server/src/ai/services/ai.d.ts.map +1 -0
  161. package/dist/server/src/controllers/index.d.ts +5 -0
  162. package/dist/server/src/controllers/index.d.ts.map +1 -1
  163. package/dist/server/src/index.d.ts +5 -0
  164. package/dist/server/src/index.d.ts.map +1 -1
  165. package/dist/server/src/register.d.ts.map +1 -1
  166. package/dist/server/src/routes/index.d.ts.map +1 -1
  167. package/dist/shared/contracts/ai.d.ts +3 -3
  168. package/package.json +9 -9
  169. package/dist/ee/server/src/ai/containers/ai.d.ts +0 -15
  170. package/dist/ee/server/src/ai/containers/ai.d.ts.map +0 -1
  171. package/dist/ee/server/src/ai/controllers/ai.d.ts.map +0 -1
  172. package/dist/ee/server/src/ai/routes/ai.d.ts.map +0 -1
  173. package/dist/server/ee/server/src/ai/containers/ai.js.map +0 -1
  174. package/dist/server/ee/server/src/ai/containers/ai.mjs.map +0 -1
  175. package/dist/server/ee/server/src/ai/controllers/ai.js +0 -121
  176. package/dist/server/ee/server/src/ai/controllers/ai.js.map +0 -1
  177. package/dist/server/ee/server/src/ai/controllers/ai.mjs +0 -119
  178. package/dist/server/ee/server/src/ai/controllers/ai.mjs.map +0 -1
  179. package/dist/server/ee/server/src/ai/routes/ai.js.map +0 -1
  180. package/dist/server/ee/server/src/ai/routes/ai.mjs.map +0 -1
  181. /package/dist/{ee/server → server}/src/ai/routes/ai.d.ts +0 -0
@@ -1 +0,0 @@
1
- {"version":3,"file":"ai.js","sources":["../../../../../../../ee/server/src/ai/containers/ai.ts"],"sourcesContent":["import type { Core } from '@strapi/types';\nimport crypto from 'crypto';\nimport fs from 'fs';\nimport path from 'path';\nimport { AdminUser } from '../../../../../shared/contracts/shared';\n\n/**\n * In-memory cache for AI tokens\n * Key format: `${projectId}:${userId}`\n */\nconst aiTokenCache = new Map<\n string,\n {\n token: string;\n expiresAt?: string;\n expiresAtMs?: number;\n }\n>();\n\nconst createAIContainer = ({ strapi }: { strapi: Core.Strapi }) => {\n const getAIFeatureConfig = async () => {\n const i18nSettings = await strapi.plugin('i18n').service('settings').getSettings();\n const uploadSettings = await strapi.plugin('upload').service('upload').getSettings();\n\n return {\n isAIi18nConfigured: Boolean(i18nSettings?.aiLocalizations),\n isAIMediaLibraryConfigured: Boolean(uploadSettings?.aiMetadata),\n };\n };\n\n const getAiToken = async () => {\n const ERROR_PREFIX = 'AI token request failed:';\n\n // Check if EE features are enabled first\n if (!strapi.ee?.isEE) {\n strapi.log.error(`${ERROR_PREFIX} Enterprise Edition features are not enabled`);\n throw new Error('AI token request failed. Check server logs for details.');\n }\n\n // Get the EE license\n // First try environment variable, then try reading from file\n let eeLicense = process.env.STRAPI_LICENSE;\n\n if (!eeLicense) {\n try {\n const licensePath = path.join(strapi.dirs.app.root, 'license.txt');\n eeLicense = fs.readFileSync(licensePath).toString();\n } catch (error) {\n // License file doesn't exist or can't be read\n }\n }\n\n if (!eeLicense) {\n strapi.log.error(\n `${ERROR_PREFIX} No EE license found. Please ensure STRAPI_LICENSE environment variable is set or license.txt file exists.`\n );\n\n throw new Error('AI token request failed. Check server logs for details.');\n }\n\n const aiServerUrl = process.env.STRAPI_AI_URL || 'https://strapi-ai.apps.strapi.io';\n\n if (!aiServerUrl) {\n strapi.log.error(\n `${ERROR_PREFIX} AI server URL not configured. Please set STRAPI_AI_URL environment variable.`\n );\n throw new Error('AI token request failed. Check server logs for details.');\n }\n\n // Get the current user\n const user = strapi.requestContext.get()?.state?.user as AdminUser | undefined;\n if (!user) {\n strapi.log.error(`${ERROR_PREFIX} No authenticated user in request context`);\n throw new Error('AI token request failed. Check server logs for details.');\n }\n\n // Create a secure user identifier using only user ID\n const userIdentifier = user.id.toString();\n\n // Get project ID\n const projectId = strapi.config.get('uuid');\n if (!projectId) {\n strapi.log.error(`${ERROR_PREFIX} Project ID not configured`);\n throw new Error('AI token request failed. Check server logs for details.');\n }\n\n // Check cache for existing valid token\n const cacheKey = `${projectId}:${userIdentifier}`;\n const cachedToken = aiTokenCache.get(cacheKey);\n\n if (cachedToken) {\n const now = Date.now();\n // Check if token is still valid (with buffer so it has time to to be used)\n const bufferMs = 2 * 60 * 1000; // 2 minutes\n\n if (cachedToken.expiresAtMs && cachedToken.expiresAtMs - bufferMs > now) {\n strapi.log.info('Using cached AI token');\n\n return {\n token: cachedToken.token,\n expiresAt: cachedToken.expiresAt,\n };\n }\n\n // Token expired or will expire soon, remove from cache\n aiTokenCache.delete(cacheKey);\n }\n\n strapi.log.http('Contacting AI Server for token generation');\n\n try {\n // Call the AI server's getAiJWT endpoint\n const response = await fetch(`${aiServerUrl}/auth/getAiJWT`, {\n method: 'POST',\n headers: {\n 'Content-Type': 'application/json',\n // No authorization header needed for public endpoint\n // Add request ID for tracing\n 'X-Request-Id': crypto.randomUUID(),\n },\n body: JSON.stringify({\n eeLicense,\n userIdentifier,\n projectId,\n }),\n });\n\n if (!response.ok) {\n let errorData;\n let errorText;\n try {\n errorText = await response.text();\n errorData = JSON.parse(errorText);\n } catch {\n errorData = { error: errorText || 'Failed to parse error response' };\n }\n\n strapi.log.error(`${ERROR_PREFIX} ${errorData?.error || 'Unknown error'}`, {\n status: response.status,\n statusText: response.statusText,\n error: errorData,\n errorText,\n projectId,\n });\n\n throw new Error('AI token request failed. Check server logs for details.');\n }\n\n let data;\n try {\n data = (await response.json()) as {\n jwt: string;\n expiresAt?: string;\n };\n } catch (parseError) {\n strapi.log.error(`${ERROR_PREFIX} Failed to parse AI server response`, parseError);\n throw new Error('AI token request failed. Check server logs for details.');\n }\n\n if (!data.jwt) {\n strapi.log.error(`${ERROR_PREFIX} Invalid response: missing JWT token`);\n throw new Error('AI token request failed. Check server logs for details.');\n }\n\n strapi.log.info('AI token generated successfully', {\n userId: user.id,\n expiresAt: data.expiresAt,\n });\n\n // Cache the token if it has an expiration time\n if (data.expiresAt) {\n const expiresAtMs = new Date(data.expiresAt).getTime();\n aiTokenCache.set(cacheKey, {\n token: data.jwt,\n expiresAt: data.expiresAt,\n expiresAtMs,\n });\n }\n\n // Return the AI JWT with metadata\n // Note: Token expires in 1 hour, client should handle refresh\n return {\n token: data.jwt,\n expiresAt: data.expiresAt, // 1 hour from generation\n };\n } catch (fetchError) {\n if (fetchError instanceof Error && fetchError.name === 'AbortError') {\n strapi.log.error(`${ERROR_PREFIX} Request to AI server timed out`);\n throw new Error('AI token request failed. Check server logs for details.');\n }\n\n throw fetchError;\n }\n };\n\n return {\n getAIFeatureConfig,\n getAiToken,\n };\n};\n\nexport { createAIContainer };\n"],"names":["aiTokenCache","Map","createAIContainer","strapi","getAIFeatureConfig","i18nSettings","plugin","service","getSettings","uploadSettings","isAIi18nConfigured","Boolean","aiLocalizations","isAIMediaLibraryConfigured","aiMetadata","getAiToken","ERROR_PREFIX","ee","isEE","log","error","Error","eeLicense","process","env","STRAPI_LICENSE","licensePath","path","join","dirs","app","root","fs","readFileSync","toString","aiServerUrl","STRAPI_AI_URL","user","requestContext","get","state","userIdentifier","id","projectId","config","cacheKey","cachedToken","now","Date","bufferMs","expiresAtMs","info","token","expiresAt","delete","http","response","fetch","method","headers","crypto","randomUUID","body","JSON","stringify","ok","errorData","errorText","text","parse","status","statusText","data","json","parseError","jwt","userId","getTime","set","fetchError","name"],"mappings":"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"}
@@ -1 +0,0 @@
1
- {"version":3,"file":"ai.mjs","sources":["../../../../../../../ee/server/src/ai/containers/ai.ts"],"sourcesContent":["import type { Core } from '@strapi/types';\nimport crypto from 'crypto';\nimport fs from 'fs';\nimport path from 'path';\nimport { AdminUser } from '../../../../../shared/contracts/shared';\n\n/**\n * In-memory cache for AI tokens\n * Key format: `${projectId}:${userId}`\n */\nconst aiTokenCache = new Map<\n string,\n {\n token: string;\n expiresAt?: string;\n expiresAtMs?: number;\n }\n>();\n\nconst createAIContainer = ({ strapi }: { strapi: Core.Strapi }) => {\n const getAIFeatureConfig = async () => {\n const i18nSettings = await strapi.plugin('i18n').service('settings').getSettings();\n const uploadSettings = await strapi.plugin('upload').service('upload').getSettings();\n\n return {\n isAIi18nConfigured: Boolean(i18nSettings?.aiLocalizations),\n isAIMediaLibraryConfigured: Boolean(uploadSettings?.aiMetadata),\n };\n };\n\n const getAiToken = async () => {\n const ERROR_PREFIX = 'AI token request failed:';\n\n // Check if EE features are enabled first\n if (!strapi.ee?.isEE) {\n strapi.log.error(`${ERROR_PREFIX} Enterprise Edition features are not enabled`);\n throw new Error('AI token request failed. Check server logs for details.');\n }\n\n // Get the EE license\n // First try environment variable, then try reading from file\n let eeLicense = process.env.STRAPI_LICENSE;\n\n if (!eeLicense) {\n try {\n const licensePath = path.join(strapi.dirs.app.root, 'license.txt');\n eeLicense = fs.readFileSync(licensePath).toString();\n } catch (error) {\n // License file doesn't exist or can't be read\n }\n }\n\n if (!eeLicense) {\n strapi.log.error(\n `${ERROR_PREFIX} No EE license found. Please ensure STRAPI_LICENSE environment variable is set or license.txt file exists.`\n );\n\n throw new Error('AI token request failed. Check server logs for details.');\n }\n\n const aiServerUrl = process.env.STRAPI_AI_URL || 'https://strapi-ai.apps.strapi.io';\n\n if (!aiServerUrl) {\n strapi.log.error(\n `${ERROR_PREFIX} AI server URL not configured. Please set STRAPI_AI_URL environment variable.`\n );\n throw new Error('AI token request failed. Check server logs for details.');\n }\n\n // Get the current user\n const user = strapi.requestContext.get()?.state?.user as AdminUser | undefined;\n if (!user) {\n strapi.log.error(`${ERROR_PREFIX} No authenticated user in request context`);\n throw new Error('AI token request failed. Check server logs for details.');\n }\n\n // Create a secure user identifier using only user ID\n const userIdentifier = user.id.toString();\n\n // Get project ID\n const projectId = strapi.config.get('uuid');\n if (!projectId) {\n strapi.log.error(`${ERROR_PREFIX} Project ID not configured`);\n throw new Error('AI token request failed. Check server logs for details.');\n }\n\n // Check cache for existing valid token\n const cacheKey = `${projectId}:${userIdentifier}`;\n const cachedToken = aiTokenCache.get(cacheKey);\n\n if (cachedToken) {\n const now = Date.now();\n // Check if token is still valid (with buffer so it has time to to be used)\n const bufferMs = 2 * 60 * 1000; // 2 minutes\n\n if (cachedToken.expiresAtMs && cachedToken.expiresAtMs - bufferMs > now) {\n strapi.log.info('Using cached AI token');\n\n return {\n token: cachedToken.token,\n expiresAt: cachedToken.expiresAt,\n };\n }\n\n // Token expired or will expire soon, remove from cache\n aiTokenCache.delete(cacheKey);\n }\n\n strapi.log.http('Contacting AI Server for token generation');\n\n try {\n // Call the AI server's getAiJWT endpoint\n const response = await fetch(`${aiServerUrl}/auth/getAiJWT`, {\n method: 'POST',\n headers: {\n 'Content-Type': 'application/json',\n // No authorization header needed for public endpoint\n // Add request ID for tracing\n 'X-Request-Id': crypto.randomUUID(),\n },\n body: JSON.stringify({\n eeLicense,\n userIdentifier,\n projectId,\n }),\n });\n\n if (!response.ok) {\n let errorData;\n let errorText;\n try {\n errorText = await response.text();\n errorData = JSON.parse(errorText);\n } catch {\n errorData = { error: errorText || 'Failed to parse error response' };\n }\n\n strapi.log.error(`${ERROR_PREFIX} ${errorData?.error || 'Unknown error'}`, {\n status: response.status,\n statusText: response.statusText,\n error: errorData,\n errorText,\n projectId,\n });\n\n throw new Error('AI token request failed. Check server logs for details.');\n }\n\n let data;\n try {\n data = (await response.json()) as {\n jwt: string;\n expiresAt?: string;\n };\n } catch (parseError) {\n strapi.log.error(`${ERROR_PREFIX} Failed to parse AI server response`, parseError);\n throw new Error('AI token request failed. Check server logs for details.');\n }\n\n if (!data.jwt) {\n strapi.log.error(`${ERROR_PREFIX} Invalid response: missing JWT token`);\n throw new Error('AI token request failed. Check server logs for details.');\n }\n\n strapi.log.info('AI token generated successfully', {\n userId: user.id,\n expiresAt: data.expiresAt,\n });\n\n // Cache the token if it has an expiration time\n if (data.expiresAt) {\n const expiresAtMs = new Date(data.expiresAt).getTime();\n aiTokenCache.set(cacheKey, {\n token: data.jwt,\n expiresAt: data.expiresAt,\n expiresAtMs,\n });\n }\n\n // Return the AI JWT with metadata\n // Note: Token expires in 1 hour, client should handle refresh\n return {\n token: data.jwt,\n expiresAt: data.expiresAt, // 1 hour from generation\n };\n } catch (fetchError) {\n if (fetchError instanceof Error && fetchError.name === 'AbortError') {\n strapi.log.error(`${ERROR_PREFIX} Request to AI server timed out`);\n throw new Error('AI token request failed. Check server logs for details.');\n }\n\n throw fetchError;\n }\n };\n\n return {\n getAIFeatureConfig,\n getAiToken,\n };\n};\n\nexport { createAIContainer };\n"],"names":["aiTokenCache","Map","createAIContainer","strapi","getAIFeatureConfig","i18nSettings","plugin","service","getSettings","uploadSettings","isAIi18nConfigured","Boolean","aiLocalizations","isAIMediaLibraryConfigured","aiMetadata","getAiToken","ERROR_PREFIX","ee","isEE","log","error","Error","eeLicense","process","env","STRAPI_LICENSE","licensePath","path","join","dirs","app","root","fs","readFileSync","toString","aiServerUrl","STRAPI_AI_URL","user","requestContext","get","state","userIdentifier","id","projectId","config","cacheKey","cachedToken","now","Date","bufferMs","expiresAtMs","info","token","expiresAt","delete","http","response","fetch","method","headers","crypto","randomUUID","body","JSON","stringify","ok","errorData","errorText","text","parse","status","statusText","data","json","parseError","jwt","userId","getTime","set","fetchError","name"],"mappings":"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"}
@@ -1,121 +0,0 @@
1
- 'use strict';
2
-
3
- var path = require('path');
4
- var fs = require('fs');
5
- var crypto = require('crypto');
6
-
7
- var aiController = {
8
- async getAiToken (ctx) {
9
- try {
10
- // TODO: auth check is not necessary? Already protected by route middleware?
11
- // Security check: Ensure user is authenticated and has proper permissions
12
- if (!ctx.state.user) {
13
- return ctx.unauthorized('Authentication required');
14
- }
15
- const aiToken = await strapi.get('ai').getAiToken();
16
- ctx.body = {
17
- data: aiToken
18
- };
19
- } catch (error) {
20
- const errorMessage = 'AI token request failed. Check server logs for details.';
21
- return ctx.internalServerError(errorMessage);
22
- }
23
- },
24
- async getAiUsage (ctx) {
25
- const ERROR_PREFIX = 'AI usage data request failed:';
26
- const USER_ERROR_MESSAGE = 'AI usage data request failed. Check server logs for details.';
27
- // Security check: Ensure user is authenticated and has proper permissions
28
- if (!ctx.state.user) {
29
- return ctx.unauthorized('Authentication required');
30
- }
31
- // Check if EE features are enabled first
32
- if (!strapi.ee?.isEE) {
33
- strapi.log.error(`${ERROR_PREFIX} Enterprise Edition features are not enabled`);
34
- return ctx.internalServerError(USER_ERROR_MESSAGE);
35
- }
36
- // Get the EE license
37
- // First try environment variable, then try reading from file
38
- let eeLicense = process.env.STRAPI_LICENSE;
39
- if (!eeLicense) {
40
- try {
41
- const licensePath = path.join(strapi.dirs.app.root, 'license.txt');
42
- eeLicense = fs.readFileSync(licensePath).toString();
43
- } catch (error) {
44
- // License file doesn't exist or can't be read
45
- }
46
- }
47
- if (!eeLicense) {
48
- strapi.log.error(`${ERROR_PREFIX} No EE license found. Please ensure STRAPI_LICENSE environment variable is set or license.txt file exists.`);
49
- return ctx.internalServerError(USER_ERROR_MESSAGE);
50
- }
51
- const aiServerUrl = process.env.STRAPI_AI_URL || 'https://strapi-ai.apps.strapi.io';
52
- // Get project ID
53
- const projectId = strapi.config.get('uuid');
54
- if (!projectId) {
55
- strapi.log.error(`${ERROR_PREFIX} Project ID not configured`);
56
- return ctx.internalServerError(USER_ERROR_MESSAGE);
57
- }
58
- try {
59
- // Call the AI server's getAiJWT endpoint
60
- const response = await fetch(`${aiServerUrl}/cms/ai-data`, {
61
- method: 'POST',
62
- headers: {
63
- 'Content-Type': 'application/json',
64
- // No authorization header needed for public endpoint
65
- // Add request ID for tracing
66
- 'X-Request-Id': crypto.randomUUID()
67
- },
68
- body: JSON.stringify({
69
- eeKey: eeLicense,
70
- projectId
71
- })
72
- });
73
- if (!response.ok) {
74
- let errorData;
75
- let errorText;
76
- try {
77
- errorText = await response.text();
78
- errorData = JSON.parse(errorText);
79
- } catch {
80
- errorData = {
81
- error: errorText || 'Failed to parse error response'
82
- };
83
- }
84
- strapi.log.error(`${ERROR_PREFIX} ${errorData?.error || 'Unknown error'}`, {
85
- status: response.status,
86
- statusText: response.statusText,
87
- error: errorData,
88
- errorText,
89
- projectId
90
- });
91
- return ctx.internalServerError(USER_ERROR_MESSAGE);
92
- }
93
- let data;
94
- try {
95
- data = await response.json();
96
- } catch (parseError) {
97
- strapi.log.error(`${ERROR_PREFIX} Failed to parse AI server response`, parseError);
98
- return ctx.internalServerError(USER_ERROR_MESSAGE);
99
- }
100
- ctx.body = {
101
- ...data.data,
102
- subscription: data.subscription
103
- };
104
- } catch (fetchError) {
105
- if (fetchError instanceof Error && fetchError.name === 'AbortError') {
106
- strapi.log.error(`${ERROR_PREFIX} Request to AI server timed out`);
107
- return ctx.internalServerError(USER_ERROR_MESSAGE);
108
- }
109
- throw fetchError;
110
- }
111
- },
112
- async getAIFeatureConfig (ctx) {
113
- const aiFeatureConfig = await strapi.get('ai').getAIFeatureConfig();
114
- ctx.body = {
115
- data: aiFeatureConfig
116
- };
117
- }
118
- };
119
-
120
- module.exports = aiController;
121
- //# sourceMappingURL=ai.js.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"ai.js","sources":["../../../../../../../ee/server/src/ai/controllers/ai.ts"],"sourcesContent":["import type { Context } from 'koa';\nimport path from 'path';\nimport fs from 'fs';\nimport crypto from 'crypto';\nimport { GetAiToken } from '../../../../../shared/contracts/ai';\n\nexport default {\n async getAiToken(ctx: Context) {\n try {\n // TODO: auth check is not necessary? Already protected by route middleware?\n // Security check: Ensure user is authenticated and has proper permissions\n if (!ctx.state.user) {\n return ctx.unauthorized('Authentication required');\n }\n\n const aiToken = await strapi.get('ai').getAiToken();\n\n ctx.body = {\n data: aiToken,\n } satisfies GetAiToken.Response;\n } catch (error) {\n const errorMessage = 'AI token request failed. Check server logs for details.';\n return ctx.internalServerError(errorMessage);\n }\n },\n\n async getAiUsage(ctx: Context) {\n const ERROR_PREFIX = 'AI usage data request failed:';\n const USER_ERROR_MESSAGE = 'AI usage data request failed. Check server logs for details.';\n // Security check: Ensure user is authenticated and has proper permissions\n if (!ctx.state.user) {\n return ctx.unauthorized('Authentication required');\n }\n\n // Check if EE features are enabled first\n if (!strapi.ee?.isEE) {\n strapi.log.error(`${ERROR_PREFIX} Enterprise Edition features are not enabled`);\n return ctx.internalServerError(USER_ERROR_MESSAGE);\n }\n\n // Get the EE license\n // First try environment variable, then try reading from file\n let eeLicense = process.env.STRAPI_LICENSE;\n\n if (!eeLicense) {\n try {\n const licensePath = path.join(strapi.dirs.app.root, 'license.txt');\n eeLicense = fs.readFileSync(licensePath).toString();\n } catch (error) {\n // License file doesn't exist or can't be read\n }\n }\n\n if (!eeLicense) {\n strapi.log.error(\n `${ERROR_PREFIX} No EE license found. Please ensure STRAPI_LICENSE environment variable is set or license.txt file exists.`\n );\n\n return ctx.internalServerError(USER_ERROR_MESSAGE);\n }\n\n const aiServerUrl = process.env.STRAPI_AI_URL || 'https://strapi-ai.apps.strapi.io';\n\n if (!aiServerUrl) {\n strapi.log.error(\n `${ERROR_PREFIX} AI server URL not configured. Please set STRAPI_AI_URL or STRAPI_AI_URL environment variable.`\n );\n return ctx.internalServerError(USER_ERROR_MESSAGE);\n }\n\n // Get project ID\n const projectId = strapi.config.get('uuid');\n if (!projectId) {\n strapi.log.error(`${ERROR_PREFIX} Project ID not configured`);\n return ctx.internalServerError(USER_ERROR_MESSAGE);\n }\n\n try {\n // Call the AI server's getAiJWT endpoint\n const response = await fetch(`${aiServerUrl}/cms/ai-data`, {\n method: 'POST',\n headers: {\n 'Content-Type': 'application/json',\n // No authorization header needed for public endpoint\n // Add request ID for tracing\n 'X-Request-Id': crypto.randomUUID(),\n },\n body: JSON.stringify({\n eeKey: eeLicense,\n projectId,\n }),\n });\n\n if (!response.ok) {\n let errorData;\n let errorText;\n try {\n errorText = await response.text();\n errorData = JSON.parse(errorText);\n } catch {\n errorData = { error: errorText || 'Failed to parse error response' };\n }\n\n strapi.log.error(`${ERROR_PREFIX} ${errorData?.error || 'Unknown error'}`, {\n status: response.status,\n statusText: response.statusText,\n error: errorData,\n errorText,\n projectId,\n });\n\n return ctx.internalServerError(USER_ERROR_MESSAGE);\n }\n\n let data;\n try {\n data = (await response.json()) as {\n data: {\n cmsAiCreditsUsed: number;\n };\n subscription: {\n subscriptionId: string;\n planPriceId: string;\n subscriptionStatus: string;\n isActiveSubscription: boolean;\n cmsAiEnabled: boolean;\n cmsAiCreditsBase: number;\n cmsAiCreditsMaxUsage: number;\n currentTermStart: string;\n currentTermEnd: string;\n };\n };\n } catch (parseError) {\n strapi.log.error(`${ERROR_PREFIX} Failed to parse AI server response`, parseError);\n return ctx.internalServerError(USER_ERROR_MESSAGE);\n }\n\n ctx.body = {\n ...data.data,\n subscription: data.subscription,\n };\n } catch (fetchError) {\n if (fetchError instanceof Error && fetchError.name === 'AbortError') {\n strapi.log.error(`${ERROR_PREFIX} Request to AI server timed out`);\n return ctx.internalServerError(USER_ERROR_MESSAGE);\n }\n\n throw fetchError;\n }\n },\n async getAIFeatureConfig(ctx: Context) {\n const aiFeatureConfig = await strapi.get('ai').getAIFeatureConfig();\n\n ctx.body = {\n data: aiFeatureConfig,\n };\n },\n};\n"],"names":["getAiToken","ctx","state","user","unauthorized","aiToken","strapi","get","body","data","error","errorMessage","internalServerError","getAiUsage","ERROR_PREFIX","USER_ERROR_MESSAGE","ee","isEE","log","eeLicense","process","env","STRAPI_LICENSE","licensePath","path","join","dirs","app","root","fs","readFileSync","toString","aiServerUrl","STRAPI_AI_URL","projectId","config","response","fetch","method","headers","crypto","randomUUID","JSON","stringify","eeKey","ok","errorData","errorText","text","parse","status","statusText","json","parseError","subscription","fetchError","Error","name","getAIFeatureConfig","aiFeatureConfig"],"mappings":"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"}
@@ -1,119 +0,0 @@
1
- import path from 'path';
2
- import fs from 'fs';
3
- import crypto from 'crypto';
4
-
5
- var aiController = {
6
- async getAiToken (ctx) {
7
- try {
8
- // TODO: auth check is not necessary? Already protected by route middleware?
9
- // Security check: Ensure user is authenticated and has proper permissions
10
- if (!ctx.state.user) {
11
- return ctx.unauthorized('Authentication required');
12
- }
13
- const aiToken = await strapi.get('ai').getAiToken();
14
- ctx.body = {
15
- data: aiToken
16
- };
17
- } catch (error) {
18
- const errorMessage = 'AI token request failed. Check server logs for details.';
19
- return ctx.internalServerError(errorMessage);
20
- }
21
- },
22
- async getAiUsage (ctx) {
23
- const ERROR_PREFIX = 'AI usage data request failed:';
24
- const USER_ERROR_MESSAGE = 'AI usage data request failed. Check server logs for details.';
25
- // Security check: Ensure user is authenticated and has proper permissions
26
- if (!ctx.state.user) {
27
- return ctx.unauthorized('Authentication required');
28
- }
29
- // Check if EE features are enabled first
30
- if (!strapi.ee?.isEE) {
31
- strapi.log.error(`${ERROR_PREFIX} Enterprise Edition features are not enabled`);
32
- return ctx.internalServerError(USER_ERROR_MESSAGE);
33
- }
34
- // Get the EE license
35
- // First try environment variable, then try reading from file
36
- let eeLicense = process.env.STRAPI_LICENSE;
37
- if (!eeLicense) {
38
- try {
39
- const licensePath = path.join(strapi.dirs.app.root, 'license.txt');
40
- eeLicense = fs.readFileSync(licensePath).toString();
41
- } catch (error) {
42
- // License file doesn't exist or can't be read
43
- }
44
- }
45
- if (!eeLicense) {
46
- strapi.log.error(`${ERROR_PREFIX} No EE license found. Please ensure STRAPI_LICENSE environment variable is set or license.txt file exists.`);
47
- return ctx.internalServerError(USER_ERROR_MESSAGE);
48
- }
49
- const aiServerUrl = process.env.STRAPI_AI_URL || 'https://strapi-ai.apps.strapi.io';
50
- // Get project ID
51
- const projectId = strapi.config.get('uuid');
52
- if (!projectId) {
53
- strapi.log.error(`${ERROR_PREFIX} Project ID not configured`);
54
- return ctx.internalServerError(USER_ERROR_MESSAGE);
55
- }
56
- try {
57
- // Call the AI server's getAiJWT endpoint
58
- const response = await fetch(`${aiServerUrl}/cms/ai-data`, {
59
- method: 'POST',
60
- headers: {
61
- 'Content-Type': 'application/json',
62
- // No authorization header needed for public endpoint
63
- // Add request ID for tracing
64
- 'X-Request-Id': crypto.randomUUID()
65
- },
66
- body: JSON.stringify({
67
- eeKey: eeLicense,
68
- projectId
69
- })
70
- });
71
- if (!response.ok) {
72
- let errorData;
73
- let errorText;
74
- try {
75
- errorText = await response.text();
76
- errorData = JSON.parse(errorText);
77
- } catch {
78
- errorData = {
79
- error: errorText || 'Failed to parse error response'
80
- };
81
- }
82
- strapi.log.error(`${ERROR_PREFIX} ${errorData?.error || 'Unknown error'}`, {
83
- status: response.status,
84
- statusText: response.statusText,
85
- error: errorData,
86
- errorText,
87
- projectId
88
- });
89
- return ctx.internalServerError(USER_ERROR_MESSAGE);
90
- }
91
- let data;
92
- try {
93
- data = await response.json();
94
- } catch (parseError) {
95
- strapi.log.error(`${ERROR_PREFIX} Failed to parse AI server response`, parseError);
96
- return ctx.internalServerError(USER_ERROR_MESSAGE);
97
- }
98
- ctx.body = {
99
- ...data.data,
100
- subscription: data.subscription
101
- };
102
- } catch (fetchError) {
103
- if (fetchError instanceof Error && fetchError.name === 'AbortError') {
104
- strapi.log.error(`${ERROR_PREFIX} Request to AI server timed out`);
105
- return ctx.internalServerError(USER_ERROR_MESSAGE);
106
- }
107
- throw fetchError;
108
- }
109
- },
110
- async getAIFeatureConfig (ctx) {
111
- const aiFeatureConfig = await strapi.get('ai').getAIFeatureConfig();
112
- ctx.body = {
113
- data: aiFeatureConfig
114
- };
115
- }
116
- };
117
-
118
- export { aiController as default };
119
- //# sourceMappingURL=ai.mjs.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"ai.mjs","sources":["../../../../../../../ee/server/src/ai/controllers/ai.ts"],"sourcesContent":["import type { Context } from 'koa';\nimport path from 'path';\nimport fs from 'fs';\nimport crypto from 'crypto';\nimport { GetAiToken } from '../../../../../shared/contracts/ai';\n\nexport default {\n async getAiToken(ctx: Context) {\n try {\n // TODO: auth check is not necessary? Already protected by route middleware?\n // Security check: Ensure user is authenticated and has proper permissions\n if (!ctx.state.user) {\n return ctx.unauthorized('Authentication required');\n }\n\n const aiToken = await strapi.get('ai').getAiToken();\n\n ctx.body = {\n data: aiToken,\n } satisfies GetAiToken.Response;\n } catch (error) {\n const errorMessage = 'AI token request failed. Check server logs for details.';\n return ctx.internalServerError(errorMessage);\n }\n },\n\n async getAiUsage(ctx: Context) {\n const ERROR_PREFIX = 'AI usage data request failed:';\n const USER_ERROR_MESSAGE = 'AI usage data request failed. Check server logs for details.';\n // Security check: Ensure user is authenticated and has proper permissions\n if (!ctx.state.user) {\n return ctx.unauthorized('Authentication required');\n }\n\n // Check if EE features are enabled first\n if (!strapi.ee?.isEE) {\n strapi.log.error(`${ERROR_PREFIX} Enterprise Edition features are not enabled`);\n return ctx.internalServerError(USER_ERROR_MESSAGE);\n }\n\n // Get the EE license\n // First try environment variable, then try reading from file\n let eeLicense = process.env.STRAPI_LICENSE;\n\n if (!eeLicense) {\n try {\n const licensePath = path.join(strapi.dirs.app.root, 'license.txt');\n eeLicense = fs.readFileSync(licensePath).toString();\n } catch (error) {\n // License file doesn't exist or can't be read\n }\n }\n\n if (!eeLicense) {\n strapi.log.error(\n `${ERROR_PREFIX} No EE license found. Please ensure STRAPI_LICENSE environment variable is set or license.txt file exists.`\n );\n\n return ctx.internalServerError(USER_ERROR_MESSAGE);\n }\n\n const aiServerUrl = process.env.STRAPI_AI_URL || 'https://strapi-ai.apps.strapi.io';\n\n if (!aiServerUrl) {\n strapi.log.error(\n `${ERROR_PREFIX} AI server URL not configured. Please set STRAPI_AI_URL or STRAPI_AI_URL environment variable.`\n );\n return ctx.internalServerError(USER_ERROR_MESSAGE);\n }\n\n // Get project ID\n const projectId = strapi.config.get('uuid');\n if (!projectId) {\n strapi.log.error(`${ERROR_PREFIX} Project ID not configured`);\n return ctx.internalServerError(USER_ERROR_MESSAGE);\n }\n\n try {\n // Call the AI server's getAiJWT endpoint\n const response = await fetch(`${aiServerUrl}/cms/ai-data`, {\n method: 'POST',\n headers: {\n 'Content-Type': 'application/json',\n // No authorization header needed for public endpoint\n // Add request ID for tracing\n 'X-Request-Id': crypto.randomUUID(),\n },\n body: JSON.stringify({\n eeKey: eeLicense,\n projectId,\n }),\n });\n\n if (!response.ok) {\n let errorData;\n let errorText;\n try {\n errorText = await response.text();\n errorData = JSON.parse(errorText);\n } catch {\n errorData = { error: errorText || 'Failed to parse error response' };\n }\n\n strapi.log.error(`${ERROR_PREFIX} ${errorData?.error || 'Unknown error'}`, {\n status: response.status,\n statusText: response.statusText,\n error: errorData,\n errorText,\n projectId,\n });\n\n return ctx.internalServerError(USER_ERROR_MESSAGE);\n }\n\n let data;\n try {\n data = (await response.json()) as {\n data: {\n cmsAiCreditsUsed: number;\n };\n subscription: {\n subscriptionId: string;\n planPriceId: string;\n subscriptionStatus: string;\n isActiveSubscription: boolean;\n cmsAiEnabled: boolean;\n cmsAiCreditsBase: number;\n cmsAiCreditsMaxUsage: number;\n currentTermStart: string;\n currentTermEnd: string;\n };\n };\n } catch (parseError) {\n strapi.log.error(`${ERROR_PREFIX} Failed to parse AI server response`, parseError);\n return ctx.internalServerError(USER_ERROR_MESSAGE);\n }\n\n ctx.body = {\n ...data.data,\n subscription: data.subscription,\n };\n } catch (fetchError) {\n if (fetchError instanceof Error && fetchError.name === 'AbortError') {\n strapi.log.error(`${ERROR_PREFIX} Request to AI server timed out`);\n return ctx.internalServerError(USER_ERROR_MESSAGE);\n }\n\n throw fetchError;\n }\n },\n async getAIFeatureConfig(ctx: Context) {\n const aiFeatureConfig = await strapi.get('ai').getAIFeatureConfig();\n\n ctx.body = {\n data: aiFeatureConfig,\n };\n },\n};\n"],"names":["getAiToken","ctx","state","user","unauthorized","aiToken","strapi","get","body","data","error","errorMessage","internalServerError","getAiUsage","ERROR_PREFIX","USER_ERROR_MESSAGE","ee","isEE","log","eeLicense","process","env","STRAPI_LICENSE","licensePath","path","join","dirs","app","root","fs","readFileSync","toString","aiServerUrl","STRAPI_AI_URL","projectId","config","response","fetch","method","headers","crypto","randomUUID","JSON","stringify","eeKey","ok","errorData","errorText","text","parse","status","statusText","json","parseError","subscription","fetchError","Error","name","getAIFeatureConfig","aiFeatureConfig"],"mappings":";;;;AAMA,mBAAe;AACb,IAAA,MAAMA,YAAWC,GAAY,EAAA;QAC3B,IAAI;;;AAGF,YAAA,IAAI,CAACA,GAAAA,CAAIC,KAAK,CAACC,IAAI,EAAE;gBACnB,OAAOF,GAAAA,CAAIG,YAAY,CAAC,yBAAA,CAAA;AAC1B,YAAA;AAEA,YAAA,MAAMC,UAAU,MAAMC,MAAAA,CAAOC,GAAG,CAAC,MAAMP,UAAU,EAAA;AAEjDC,YAAAA,GAAAA,CAAIO,IAAI,GAAG;gBACTC,IAAAA,EAAMJ;AACR,aAAA;AACF,QAAA,CAAA,CAAE,OAAOK,KAAAA,EAAO;AACd,YAAA,MAAMC,YAAAA,GAAe,yDAAA;YACrB,OAAOV,GAAAA,CAAIW,mBAAmB,CAACD,YAAAA,CAAAA;AACjC,QAAA;AACF,IAAA,CAAA;AAEA,IAAA,MAAME,YAAWZ,GAAY,EAAA;AAC3B,QAAA,MAAMa,YAAAA,GAAe,+BAAA;AACrB,QAAA,MAAMC,kBAAAA,GAAqB,8DAAA;;AAE3B,QAAA,IAAI,CAACd,GAAAA,CAAIC,KAAK,CAACC,IAAI,EAAE;YACnB,OAAOF,GAAAA,CAAIG,YAAY,CAAC,yBAAA,CAAA;AAC1B,QAAA;;AAGA,QAAA,IAAI,CAACE,MAAAA,CAAOU,EAAE,EAAEC,IAAAA,EAAM;AACpBX,YAAAA,MAAAA,CAAOY,GAAG,CAACR,KAAK,CAAC,CAAA,EAAGI,YAAAA,CAAa,4CAA4C,CAAC,CAAA;YAC9E,OAAOb,GAAAA,CAAIW,mBAAmB,CAACG,kBAAAA,CAAAA;AACjC,QAAA;;;AAIA,QAAA,IAAII,SAAAA,GAAYC,OAAAA,CAAQC,GAAG,CAACC,cAAc;AAE1C,QAAA,IAAI,CAACH,SAAAA,EAAW;YACd,IAAI;gBACF,MAAMI,WAAAA,GAAcC,IAAAA,CAAKC,IAAI,CAACnB,MAAAA,CAAOoB,IAAI,CAACC,GAAG,CAACC,IAAI,EAAE,aAAA,CAAA;AACpDT,gBAAAA,SAAAA,GAAYU,EAAAA,CAAGC,YAAY,CAACP,WAAAA,CAAAA,CAAaQ,QAAQ,EAAA;AACnD,YAAA,CAAA,CAAE,OAAOrB,KAAAA,EAAO;;AAEhB,YAAA;AACF,QAAA;AAEA,QAAA,IAAI,CAACS,SAAAA,EAAW;AACdb,YAAAA,MAAAA,CAAOY,GAAG,CAACR,KAAK,CACd,CAAA,EAAGI,YAAAA,CAAa,0GAA0G,CAAC,CAAA;YAG7H,OAAOb,GAAAA,CAAIW,mBAAmB,CAACG,kBAAAA,CAAAA;AACjC,QAAA;AAEA,QAAA,MAAMiB,WAAAA,GAAcZ,OAAAA,CAAQC,GAAG,CAACY,aAAa,IAAI,kCAAA;;AAUjD,QAAA,MAAMC,SAAAA,GAAY5B,MAAAA,CAAO6B,MAAM,CAAC5B,GAAG,CAAC,MAAA,CAAA;AACpC,QAAA,IAAI,CAAC2B,SAAAA,EAAW;AACd5B,YAAAA,MAAAA,CAAOY,GAAG,CAACR,KAAK,CAAC,CAAA,EAAGI,YAAAA,CAAa,0BAA0B,CAAC,CAAA;YAC5D,OAAOb,GAAAA,CAAIW,mBAAmB,CAACG,kBAAAA,CAAAA;AACjC,QAAA;QAEA,IAAI;;AAEF,YAAA,MAAMqB,WAAW,MAAMC,KAAAA,CAAM,GAAGL,WAAAA,CAAY,YAAY,CAAC,EAAE;gBACzDM,MAAAA,EAAQ,MAAA;gBACRC,OAAAA,EAAS;oBACP,cAAA,EAAgB,kBAAA;;;AAGhB,oBAAA,cAAA,EAAgBC,OAAOC,UAAU;AACnC,iBAAA;gBACAjC,IAAAA,EAAMkC,IAAAA,CAAKC,SAAS,CAAC;oBACnBC,KAAAA,EAAOzB,SAAAA;AACPe,oBAAAA;AACF,iBAAA;AACF,aAAA,CAAA;YAEA,IAAI,CAACE,QAAAA,CAASS,EAAE,EAAE;gBAChB,IAAIC,SAAAA;gBACJ,IAAIC,SAAAA;gBACJ,IAAI;oBACFA,SAAAA,GAAY,MAAMX,SAASY,IAAI,EAAA;oBAC/BF,SAAAA,GAAYJ,IAAAA,CAAKO,KAAK,CAACF,SAAAA,CAAAA;AACzB,gBAAA,CAAA,CAAE,OAAM;oBACND,SAAAA,GAAY;AAAEpC,wBAAAA,KAAAA,EAAOqC,SAAAA,IAAa;AAAiC,qBAAA;AACrE,gBAAA;gBAEAzC,MAAAA,CAAOY,GAAG,CAACR,KAAK,CAAC,CAAA,EAAGI,YAAAA,CAAa,CAAC,EAAEgC,SAAAA,EAAWpC,KAAAA,IAAS,eAAA,CAAA,CAAiB,EAAE;AACzEwC,oBAAAA,MAAAA,EAAQd,SAASc,MAAM;AACvBC,oBAAAA,UAAAA,EAAYf,SAASe,UAAU;oBAC/BzC,KAAAA,EAAOoC,SAAAA;AACPC,oBAAAA,SAAAA;AACAb,oBAAAA;AACF,iBAAA,CAAA;gBAEA,OAAOjC,GAAAA,CAAIW,mBAAmB,CAACG,kBAAAA,CAAAA;AACjC,YAAA;YAEA,IAAIN,IAAAA;YACJ,IAAI;gBACFA,IAAAA,GAAQ,MAAM2B,SAASgB,IAAI,EAAA;AAgB7B,YAAA,CAAA,CAAE,OAAOC,UAAAA,EAAY;gBACnB/C,MAAAA,CAAOY,GAAG,CAACR,KAAK,CAAC,GAAGI,YAAAA,CAAa,mCAAmC,CAAC,EAAEuC,UAAAA,CAAAA;gBACvE,OAAOpD,GAAAA,CAAIW,mBAAmB,CAACG,kBAAAA,CAAAA;AACjC,YAAA;AAEAd,YAAAA,GAAAA,CAAIO,IAAI,GAAG;AACT,gBAAA,GAAGC,KAAKA,IAAI;AACZ6C,gBAAAA,YAAAA,EAAc7C,KAAK6C;AACrB,aAAA;AACF,QAAA,CAAA,CAAE,OAAOC,UAAAA,EAAY;AACnB,YAAA,IAAIA,UAAAA,YAAsBC,KAAAA,IAASD,UAAAA,CAAWE,IAAI,KAAK,YAAA,EAAc;AACnEnD,gBAAAA,MAAAA,CAAOY,GAAG,CAACR,KAAK,CAAC,CAAA,EAAGI,YAAAA,CAAa,+BAA+B,CAAC,CAAA;gBACjE,OAAOb,GAAAA,CAAIW,mBAAmB,CAACG,kBAAAA,CAAAA;AACjC,YAAA;YAEA,MAAMwC,UAAAA;AACR,QAAA;AACF,IAAA,CAAA;AACA,IAAA,MAAMG,oBAAmBzD,GAAY,EAAA;AACnC,QAAA,MAAM0D,kBAAkB,MAAMrD,MAAAA,CAAOC,GAAG,CAAC,MAAMmD,kBAAkB,EAAA;AAEjEzD,QAAAA,GAAAA,CAAIO,IAAI,GAAG;YACTC,IAAAA,EAAMkD;AACR,SAAA;AACF,IAAA;AACF,CAAA;;;;"}
@@ -1 +0,0 @@
1
- {"version":3,"file":"ai.js","sources":["../../../../../../../ee/server/src/ai/routes/ai.ts"],"sourcesContent":["export default {\n type: 'admin',\n routes: [\n {\n method: 'GET',\n path: '/ai-usage',\n handler: 'ai.getAiUsage',\n config: {\n policies: ['admin::isAuthenticatedAdmin'],\n },\n },\n {\n method: 'GET',\n path: '/ai-token',\n handler: 'ai.getAiToken',\n config: {\n policies: ['admin::isAuthenticatedAdmin'],\n },\n },\n {\n method: 'GET',\n path: '/ai-feature-config',\n handler: 'ai.getAIFeatureConfig',\n config: {\n policies: ['admin::isAuthenticatedAdmin'],\n },\n },\n ],\n};\n"],"names":["type","routes","method","path","handler","config","policies"],"mappings":";;AAAA,eAAe;IACbA,IAAAA,EAAM,OAAA;IACNC,MAAAA,EAAQ;AACN,QAAA;YACEC,MAAAA,EAAQ,KAAA;YACRC,IAAAA,EAAM,WAAA;YACNC,OAAAA,EAAS,eAAA;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,eAAA;YACTC,MAAAA,EAAQ;gBACNC,QAAAA,EAAU;AAAC,oBAAA;AAA8B;AAC3C;AACF,SAAA;AACA,QAAA;YACEJ,MAAAA,EAAQ,KAAA;YACRC,IAAAA,EAAM,oBAAA;YACNC,OAAAA,EAAS,uBAAA;YACTC,MAAAA,EAAQ;gBACNC,QAAAA,EAAU;AAAC,oBAAA;AAA8B;AAC3C;AACF;AACD;AACH,CAAA;;;;"}
@@ -1 +0,0 @@
1
- {"version":3,"file":"ai.mjs","sources":["../../../../../../../ee/server/src/ai/routes/ai.ts"],"sourcesContent":["export default {\n type: 'admin',\n routes: [\n {\n method: 'GET',\n path: '/ai-usage',\n handler: 'ai.getAiUsage',\n config: {\n policies: ['admin::isAuthenticatedAdmin'],\n },\n },\n {\n method: 'GET',\n path: '/ai-token',\n handler: 'ai.getAiToken',\n config: {\n policies: ['admin::isAuthenticatedAdmin'],\n },\n },\n {\n method: 'GET',\n path: '/ai-feature-config',\n handler: 'ai.getAIFeatureConfig',\n config: {\n policies: ['admin::isAuthenticatedAdmin'],\n },\n },\n ],\n};\n"],"names":["type","routes","method","path","handler","config","policies"],"mappings":"AAAA,eAAe;IACbA,IAAAA,EAAM,OAAA;IACNC,MAAAA,EAAQ;AACN,QAAA;YACEC,MAAAA,EAAQ,KAAA;YACRC,IAAAA,EAAM,WAAA;YACNC,OAAAA,EAAS,eAAA;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,eAAA;YACTC,MAAAA,EAAQ;gBACNC,QAAAA,EAAU;AAAC,oBAAA;AAA8B;AAC3C;AACF,SAAA;AACA,QAAA;YACEJ,MAAAA,EAAQ,KAAA;YACRC,IAAAA,EAAM,oBAAA;YACNC,OAAAA,EAAS,uBAAA;YACTC,MAAAA,EAAQ;gBACNC,QAAAA,EAAU;AAAC,oBAAA;AAA8B;AAC3C;AACF;AACD;AACH,CAAA;;;;"}