@intlayer/backend 5.1.5 → 5.1.7

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 (245) hide show
  1. package/dist/cjs/controllers/ai.controller.cjs +61 -43
  2. package/dist/cjs/controllers/ai.controller.cjs.map +1 -1
  3. package/dist/cjs/controllers/dictionary.controller.cjs +1 -1
  4. package/dist/cjs/controllers/dictionary.controller.cjs.map +1 -1
  5. package/dist/cjs/controllers/organization.controller.cjs +17 -1
  6. package/dist/cjs/controllers/organization.controller.cjs.map +1 -1
  7. package/dist/cjs/controllers/project.controller.cjs +1 -0
  8. package/dist/cjs/controllers/project.controller.cjs.map +1 -1
  9. package/dist/cjs/controllers/sessionAuth.controller.cjs +6 -12
  10. package/dist/cjs/controllers/sessionAuth.controller.cjs.map +1 -1
  11. package/dist/cjs/controllers/stripe.controller.cjs +31 -10
  12. package/dist/cjs/controllers/stripe.controller.cjs.map +1 -1
  13. package/dist/cjs/controllers/tag.controller.cjs +0 -7
  14. package/dist/cjs/controllers/tag.controller.cjs.map +1 -1
  15. package/dist/cjs/controllers/user.controller.cjs +1 -1
  16. package/dist/cjs/controllers/user.controller.cjs.map +1 -1
  17. package/dist/cjs/emails/InviteUserEmail.cjs +3 -3
  18. package/dist/cjs/emails/InviteUserEmail.cjs.map +1 -1
  19. package/dist/cjs/emails/PasswordChangeConfirmation.cjs +3 -3
  20. package/dist/cjs/emails/PasswordChangeConfirmation.cjs.map +1 -1
  21. package/dist/cjs/emails/ResetUserPassword.cjs +3 -3
  22. package/dist/cjs/emails/ResetUserPassword.cjs.map +1 -1
  23. package/dist/cjs/emails/SubscriptionPaymentCancellation.cjs +19 -3
  24. package/dist/cjs/emails/SubscriptionPaymentCancellation.cjs.map +1 -1
  25. package/dist/cjs/emails/SubscriptionPaymentError.cjs +19 -3
  26. package/dist/cjs/emails/SubscriptionPaymentError.cjs.map +1 -1
  27. package/dist/cjs/emails/SubscriptionPaymentSuccess.cjs +19 -3
  28. package/dist/cjs/emails/SubscriptionPaymentSuccess.cjs.map +1 -1
  29. package/dist/cjs/emails/ValidateUserEmail.cjs +3 -3
  30. package/dist/cjs/emails/ValidateUserEmail.cjs.map +1 -1
  31. package/dist/cjs/emails/Welcome.cjs +3 -3
  32. package/dist/cjs/emails/Welcome.cjs.map +1 -1
  33. package/dist/cjs/export.cjs +10 -10
  34. package/dist/cjs/export.cjs.map +1 -1
  35. package/dist/cjs/routes/ai.routes.cjs +21 -15
  36. package/dist/cjs/routes/ai.routes.cjs.map +1 -1
  37. package/dist/cjs/routes/dictionary.routes.cjs +15 -12
  38. package/dist/cjs/routes/dictionary.routes.cjs.map +1 -1
  39. package/dist/cjs/routes/event-listener.routes.cjs +4 -4
  40. package/dist/cjs/routes/event-listener.routes.cjs.map +1 -1
  41. package/dist/cjs/routes/organization.routes.cjs +15 -15
  42. package/dist/cjs/routes/organization.routes.cjs.map +1 -1
  43. package/dist/cjs/routes/project.routes.cjs +30 -18
  44. package/dist/cjs/routes/project.routes.cjs.map +1 -1
  45. package/dist/cjs/routes/sessionAuth.routes.cjs +38 -35
  46. package/dist/cjs/routes/sessionAuth.routes.cjs.map +1 -1
  47. package/dist/cjs/routes/stripe.routes.cjs +23 -11
  48. package/dist/cjs/routes/stripe.routes.cjs.map +1 -1
  49. package/dist/cjs/routes/tags.routes.cjs +11 -11
  50. package/dist/cjs/routes/tags.routes.cjs.map +1 -1
  51. package/dist/cjs/routes/user.routes.cjs +13 -13
  52. package/dist/cjs/routes/user.routes.cjs.map +1 -1
  53. package/dist/cjs/schemas/project.schema.cjs +2 -2
  54. package/dist/cjs/schemas/project.schema.cjs.map +1 -1
  55. package/dist/cjs/services/dictionary.service.cjs +0 -6
  56. package/dist/cjs/services/dictionary.service.cjs.map +1 -1
  57. package/dist/cjs/services/email.service.cjs +1 -1
  58. package/dist/cjs/services/email.service.cjs.map +1 -1
  59. package/dist/cjs/services/subscription.service.cjs +81 -2
  60. package/dist/cjs/services/subscription.service.cjs.map +1 -1
  61. package/dist/cjs/utils/AI/{askDocQuestion.cjs → askDocQuestion/askDocQuestion.cjs} +1 -1
  62. package/dist/cjs/utils/AI/askDocQuestion/askDocQuestion.cjs.map +1 -0
  63. package/dist/{esm/utils/AI → cjs/utils/AI/askDocQuestion}/embeddings.json +4288 -4288
  64. package/dist/cjs/utils/{auditDictionary → AI/auditDictionary}/index.cjs +5 -3
  65. package/dist/cjs/utils/AI/auditDictionary/index.cjs.map +1 -0
  66. package/dist/cjs/utils/{auditDictionaryField → AI/auditDictionaryField}/index.cjs +5 -3
  67. package/dist/cjs/utils/AI/auditDictionaryField/index.cjs.map +1 -0
  68. package/dist/cjs/utils/{auditDictionaryMetadata → AI/auditDictionaryMetadata}/index.cjs +5 -3
  69. package/dist/cjs/utils/AI/auditDictionaryMetadata/index.cjs.map +1 -0
  70. package/dist/cjs/utils/AI/autocomplete/PROMPT.md +13 -0
  71. package/dist/cjs/utils/AI/autocomplete/index.cjs +73 -0
  72. package/dist/cjs/utils/AI/autocomplete/index.cjs.map +1 -0
  73. package/dist/cjs/utils/auditTag/index.cjs +4 -2
  74. package/dist/cjs/utils/auditTag/index.cjs.map +1 -1
  75. package/dist/cjs/utils/errors/errorCodes.cjs +26 -0
  76. package/dist/cjs/utils/errors/errorCodes.cjs.map +1 -1
  77. package/dist/cjs/utils/mongoDB/connectDB.cjs +10 -0
  78. package/dist/cjs/utils/mongoDB/connectDB.cjs.map +1 -1
  79. package/dist/cjs/webhooks/stripe.webhook.cjs +42 -0
  80. package/dist/cjs/webhooks/stripe.webhook.cjs.map +1 -1
  81. package/dist/esm/controllers/ai.controller.mjs +59 -42
  82. package/dist/esm/controllers/ai.controller.mjs.map +1 -1
  83. package/dist/esm/controllers/dictionary.controller.mjs +1 -1
  84. package/dist/esm/controllers/dictionary.controller.mjs.map +1 -1
  85. package/dist/esm/controllers/organization.controller.mjs +18 -2
  86. package/dist/esm/controllers/organization.controller.mjs.map +1 -1
  87. package/dist/esm/controllers/project.controller.mjs +1 -0
  88. package/dist/esm/controllers/project.controller.mjs.map +1 -1
  89. package/dist/esm/controllers/sessionAuth.controller.mjs +6 -12
  90. package/dist/esm/controllers/sessionAuth.controller.mjs.map +1 -1
  91. package/dist/esm/controllers/stripe.controller.mjs +30 -10
  92. package/dist/esm/controllers/stripe.controller.mjs.map +1 -1
  93. package/dist/esm/controllers/tag.controller.mjs +0 -7
  94. package/dist/esm/controllers/tag.controller.mjs.map +1 -1
  95. package/dist/esm/controllers/user.controller.mjs +2 -2
  96. package/dist/esm/controllers/user.controller.mjs.map +1 -1
  97. package/dist/esm/emails/InviteUserEmail.mjs +3 -3
  98. package/dist/esm/emails/InviteUserEmail.mjs.map +1 -1
  99. package/dist/esm/emails/PasswordChangeConfirmation.mjs +3 -3
  100. package/dist/esm/emails/PasswordChangeConfirmation.mjs.map +1 -1
  101. package/dist/esm/emails/ResetUserPassword.mjs +3 -3
  102. package/dist/esm/emails/ResetUserPassword.mjs.map +1 -1
  103. package/dist/esm/emails/SubscriptionPaymentCancellation.mjs +19 -3
  104. package/dist/esm/emails/SubscriptionPaymentCancellation.mjs.map +1 -1
  105. package/dist/esm/emails/SubscriptionPaymentError.mjs +19 -3
  106. package/dist/esm/emails/SubscriptionPaymentError.mjs.map +1 -1
  107. package/dist/esm/emails/SubscriptionPaymentSuccess.mjs +19 -3
  108. package/dist/esm/emails/SubscriptionPaymentSuccess.mjs.map +1 -1
  109. package/dist/esm/emails/ValidateUserEmail.mjs +3 -3
  110. package/dist/esm/emails/ValidateUserEmail.mjs.map +1 -1
  111. package/dist/esm/emails/Welcome.mjs +3 -3
  112. package/dist/esm/emails/Welcome.mjs.map +1 -1
  113. package/dist/esm/export.mjs +10 -10
  114. package/dist/esm/export.mjs.map +1 -1
  115. package/dist/esm/routes/ai.routes.mjs +22 -15
  116. package/dist/esm/routes/ai.routes.mjs.map +1 -1
  117. package/dist/esm/routes/dictionary.routes.mjs +14 -11
  118. package/dist/esm/routes/dictionary.routes.mjs.map +1 -1
  119. package/dist/esm/routes/event-listener.routes.mjs +4 -4
  120. package/dist/esm/routes/event-listener.routes.mjs.map +1 -1
  121. package/dist/esm/routes/organization.routes.mjs +13 -13
  122. package/dist/esm/routes/organization.routes.mjs.map +1 -1
  123. package/dist/esm/routes/project.routes.mjs +28 -16
  124. package/dist/esm/routes/project.routes.mjs.map +1 -1
  125. package/dist/esm/routes/sessionAuth.routes.mjs +37 -34
  126. package/dist/esm/routes/sessionAuth.routes.mjs.map +1 -1
  127. package/dist/esm/routes/stripe.routes.mjs +22 -9
  128. package/dist/esm/routes/stripe.routes.mjs.map +1 -1
  129. package/dist/esm/routes/tags.routes.mjs +9 -9
  130. package/dist/esm/routes/tags.routes.mjs.map +1 -1
  131. package/dist/esm/routes/user.routes.mjs +11 -11
  132. package/dist/esm/routes/user.routes.mjs.map +1 -1
  133. package/dist/esm/schemas/project.schema.mjs +2 -2
  134. package/dist/esm/schemas/project.schema.mjs.map +1 -1
  135. package/dist/esm/services/dictionary.service.mjs +0 -6
  136. package/dist/esm/services/dictionary.service.mjs.map +1 -1
  137. package/dist/esm/services/email.service.mjs +1 -1
  138. package/dist/esm/services/email.service.mjs.map +1 -1
  139. package/dist/esm/services/subscription.service.mjs +78 -1
  140. package/dist/esm/services/subscription.service.mjs.map +1 -1
  141. package/dist/esm/utils/AI/{askDocQuestion.mjs → askDocQuestion/askDocQuestion.mjs} +1 -1
  142. package/dist/esm/utils/AI/askDocQuestion/askDocQuestion.mjs.map +1 -0
  143. package/dist/{cjs/utils/AI → esm/utils/AI/askDocQuestion}/embeddings.json +4288 -4288
  144. package/dist/esm/utils/{auditDictionary → AI/auditDictionary}/index.mjs +5 -3
  145. package/dist/esm/utils/AI/auditDictionary/index.mjs.map +1 -0
  146. package/dist/esm/utils/{auditDictionaryField → AI/auditDictionaryField}/index.mjs +5 -3
  147. package/dist/esm/utils/AI/auditDictionaryField/index.mjs.map +1 -0
  148. package/dist/esm/utils/{auditDictionaryMetadata → AI/auditDictionaryMetadata}/index.mjs +5 -3
  149. package/dist/esm/utils/AI/auditDictionaryMetadata/index.mjs.map +1 -0
  150. package/dist/esm/utils/AI/autocomplete/PROMPT.md +13 -0
  151. package/dist/esm/utils/AI/autocomplete/index.mjs +48 -0
  152. package/dist/esm/utils/AI/autocomplete/index.mjs.map +1 -0
  153. package/dist/esm/utils/auditTag/index.mjs +4 -2
  154. package/dist/esm/utils/auditTag/index.mjs.map +1 -1
  155. package/dist/esm/utils/errors/errorCodes.mjs +26 -0
  156. package/dist/esm/utils/errors/errorCodes.mjs.map +1 -1
  157. package/dist/esm/utils/mongoDB/connectDB.mjs +10 -0
  158. package/dist/esm/utils/mongoDB/connectDB.mjs.map +1 -1
  159. package/dist/esm/webhooks/stripe.webhook.mjs +32 -0
  160. package/dist/esm/webhooks/stripe.webhook.mjs.map +1 -1
  161. package/dist/types/controllers/ai.controller.d.ts +17 -2
  162. package/dist/types/controllers/ai.controller.d.ts.map +1 -1
  163. package/dist/types/controllers/organization.controller.d.ts.map +1 -1
  164. package/dist/types/controllers/project.controller.d.ts.map +1 -1
  165. package/dist/types/controllers/sessionAuth.controller.d.ts +4 -3
  166. package/dist/types/controllers/sessionAuth.controller.d.ts.map +1 -1
  167. package/dist/types/controllers/stripe.controller.d.ts +15 -7
  168. package/dist/types/controllers/stripe.controller.d.ts.map +1 -1
  169. package/dist/types/controllers/tag.controller.d.ts.map +1 -1
  170. package/dist/types/emails/SubscriptionPaymentCancellation.d.ts +4 -3
  171. package/dist/types/emails/SubscriptionPaymentCancellation.d.ts.map +1 -1
  172. package/dist/types/emails/SubscriptionPaymentError.d.ts +4 -3
  173. package/dist/types/emails/SubscriptionPaymentError.d.ts.map +1 -1
  174. package/dist/types/emails/SubscriptionPaymentSuccess.d.ts +4 -3
  175. package/dist/types/emails/SubscriptionPaymentSuccess.d.ts.map +1 -1
  176. package/dist/types/export.d.ts +5 -5
  177. package/dist/types/export.d.ts.map +1 -1
  178. package/dist/types/routes/ai.routes.d.ts +6 -1
  179. package/dist/types/routes/ai.routes.d.ts.map +1 -1
  180. package/dist/types/routes/dictionary.routes.d.ts +4 -4
  181. package/dist/types/routes/dictionary.routes.d.ts.map +1 -1
  182. package/dist/types/routes/event-listener.routes.d.ts +1 -1
  183. package/dist/types/routes/event-listener.routes.d.ts.map +1 -1
  184. package/dist/types/routes/organization.routes.d.ts +5 -5
  185. package/dist/types/routes/organization.routes.d.ts.map +1 -1
  186. package/dist/types/routes/project.routes.d.ts +5 -5
  187. package/dist/types/routes/project.routes.d.ts.map +1 -1
  188. package/dist/types/routes/sessionAuth.routes.d.ts +4 -7
  189. package/dist/types/routes/sessionAuth.routes.d.ts.map +1 -1
  190. package/dist/types/routes/stripe.routes.d.ts +6 -1
  191. package/dist/types/routes/stripe.routes.d.ts.map +1 -1
  192. package/dist/types/routes/tags.routes.d.ts +3 -3
  193. package/dist/types/routes/tags.routes.d.ts.map +1 -1
  194. package/dist/types/routes/user.routes.d.ts +4 -4
  195. package/dist/types/routes/user.routes.d.ts.map +1 -1
  196. package/dist/types/services/dictionary.service.d.ts.map +1 -1
  197. package/dist/types/services/subscription.service.d.ts +9 -0
  198. package/dist/types/services/subscription.service.d.ts.map +1 -1
  199. package/dist/types/utils/AI/askDocQuestion/askDocQuestion.d.ts.map +1 -0
  200. package/dist/types/utils/{auditDictionary → AI/auditDictionary}/index.d.ts +8 -5
  201. package/dist/types/utils/AI/auditDictionary/index.d.ts.map +1 -0
  202. package/dist/types/utils/{auditDictionaryField → AI/auditDictionaryField}/index.d.ts +8 -5
  203. package/dist/types/utils/AI/auditDictionaryField/index.d.ts.map +1 -0
  204. package/dist/types/utils/{auditDictionaryMetadata → AI/auditDictionaryMetadata}/index.d.ts +8 -5
  205. package/dist/types/utils/AI/auditDictionaryMetadata/index.d.ts.map +1 -0
  206. package/dist/types/utils/AI/autocomplete/index.d.ts +22 -0
  207. package/dist/types/utils/AI/autocomplete/index.d.ts.map +1 -0
  208. package/dist/types/utils/auditTag/index.d.ts +7 -4
  209. package/dist/types/utils/auditTag/index.d.ts.map +1 -1
  210. package/dist/types/utils/errors/errorCodes.d.ts +26 -0
  211. package/dist/types/utils/errors/errorCodes.d.ts.map +1 -1
  212. package/dist/types/utils/mongoDB/connectDB.d.ts.map +1 -1
  213. package/dist/types/webhooks/stripe.webhook.d.ts.map +1 -1
  214. package/package.json +10 -9
  215. package/dist/cjs/utils/AI/askDocQuestion.cjs.map +0 -1
  216. package/dist/cjs/utils/auditDictionary/index.cjs.map +0 -1
  217. package/dist/cjs/utils/auditDictionaryField/index.cjs.map +0 -1
  218. package/dist/cjs/utils/auditDictionaryMetadata/index.cjs.map +0 -1
  219. package/dist/esm/utils/AI/askDocQuestion.mjs.map +0 -1
  220. package/dist/esm/utils/auditDictionary/index.mjs.map +0 -1
  221. package/dist/esm/utils/auditDictionaryField/index.mjs.map +0 -1
  222. package/dist/esm/utils/auditDictionaryMetadata/index.mjs.map +0 -1
  223. package/dist/types/utils/AI/askDocQuestion.d.ts.map +0 -1
  224. package/dist/types/utils/auditDictionary/index.d.ts.map +0 -1
  225. package/dist/types/utils/auditDictionaryField/index.d.ts.map +0 -1
  226. package/dist/types/utils/auditDictionaryMetadata/index.d.ts.map +0 -1
  227. /package/dist/cjs/utils/{auditDictionary → AI/auditDictionary}/CJS_FORMAT.md +0 -0
  228. /package/dist/cjs/utils/{auditDictionary → AI/auditDictionary}/JSON_FORMAT.md +0 -0
  229. /package/dist/cjs/utils/{auditDictionary → AI/auditDictionary}/JSX_FORMAT.md +0 -0
  230. /package/dist/cjs/utils/{auditDictionary → AI/auditDictionary}/MJS_FORMAT.md +0 -0
  231. /package/dist/cjs/utils/{auditDictionary → AI/auditDictionary}/PROMPT.md +0 -0
  232. /package/dist/cjs/utils/{auditDictionary → AI/auditDictionary}/TSX_FORMAT.md +0 -0
  233. /package/dist/cjs/utils/{auditDictionary → AI/auditDictionary}/TS_FORMAT.md +0 -0
  234. /package/dist/cjs/utils/{auditDictionaryField → AI/auditDictionaryField}/PROMPT.md +0 -0
  235. /package/dist/cjs/utils/{auditDictionaryMetadata → AI/auditDictionaryMetadata}/PROMPT.md +0 -0
  236. /package/dist/esm/utils/{auditDictionary → AI/auditDictionary}/CJS_FORMAT.md +0 -0
  237. /package/dist/esm/utils/{auditDictionary → AI/auditDictionary}/JSON_FORMAT.md +0 -0
  238. /package/dist/esm/utils/{auditDictionary → AI/auditDictionary}/JSX_FORMAT.md +0 -0
  239. /package/dist/esm/utils/{auditDictionary → AI/auditDictionary}/MJS_FORMAT.md +0 -0
  240. /package/dist/esm/utils/{auditDictionary → AI/auditDictionary}/PROMPT.md +0 -0
  241. /package/dist/esm/utils/{auditDictionary → AI/auditDictionary}/TSX_FORMAT.md +0 -0
  242. /package/dist/esm/utils/{auditDictionary → AI/auditDictionary}/TS_FORMAT.md +0 -0
  243. /package/dist/esm/utils/{auditDictionaryField → AI/auditDictionaryField}/PROMPT.md +0 -0
  244. /package/dist/esm/utils/{auditDictionaryMetadata → AI/auditDictionaryMetadata}/PROMPT.md +0 -0
  245. /package/dist/types/utils/AI/{askDocQuestion.d.ts → askDocQuestion/askDocQuestion.d.ts} +0 -0
@@ -25,7 +25,7 @@ var import_fs = require("fs");
25
25
  var import_path = require("path");
26
26
  var import_url = require("url");
27
27
  var import_core = require("@intlayer/core");
28
- var import_logger = require('./../../logger/index.cjs');
28
+ var import_logger = require('./../../../logger/index.cjs');
29
29
  var import_openai = require("openai");
30
30
  const import_meta = {};
31
31
  const __dirname = (0, import_path.dirname)((0, import_url.fileURLToPath)(import_meta.url));
@@ -55,13 +55,14 @@ const auditDictionary = async ({
55
55
  model,
56
56
  openAiApiKey,
57
57
  customPrompt,
58
+ temperature,
58
59
  locales,
59
60
  defaultLocale,
60
61
  tags
61
62
  }) => {
62
63
  try {
63
64
  const openai = new import_openai.OpenAI({
64
- apiKey: openAiApiKey
65
+ apiKey: openAiApiKey ?? process.env.OPENAI_API_KEY
65
66
  });
66
67
  const splitted = (filePath ?? ".json").split(".");
67
68
  const fileExtension = splitted[splitted.length - 1];
@@ -76,7 +77,8 @@ const auditDictionary = async ({
76
77
  FILE_TEMPLATE[fileExtension]
77
78
  ).replace("{{fileContent}}", fileContent).replace("{{tagsInstructions}}", formatTagInstructions(tags));
78
79
  const chatCompletion = await openai.chat.completions.create({
79
- model: model ?? "gpt-4o-2024-11-20",
80
+ model: openAiApiKey ? model ?? "gpt-4o-2024-11-20" : "gpt-4o-2024-11-20",
81
+ temperature: openAiApiKey ? temperature ?? 0.1 : 0.1,
80
82
  messages: [{ role: "system", content: prompt }]
81
83
  });
82
84
  const newContent = chatCompletion.choices[0].message?.content;
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../../../../../src/utils/AI/auditDictionary/index.ts"],"sourcesContent":["import { readFileSync } from 'fs';\nimport { dirname, join } from 'path';\nimport { fileURLToPath } from 'url';\nimport { getLocaleName } from '@intlayer/core';\nimport { logger } from '@logger';\nimport type { Locales } from 'intlayer';\nimport { OpenAI } from 'openai';\nimport type { Tag } from '@/types/tag.types';\n\nconst __dirname = dirname(fileURLToPath(import.meta.url));\n\nexport type AIOptions = {\n model?: string;\n temperature?: number;\n openAiApiKey?: string;\n};\n\nexport type AuditOptions = {\n locales: Locales[];\n defaultLocale: Locales;\n fileContent: string;\n filePath?: string;\n customPrompt?: string;\n tags?: Tag[];\n} & AIOptions;\nexport type AuditFileResultData = { fileContent: string; tokenUsed: number };\n\n/**\n * Reads the content of a file synchronously.\n *\n * @function\n * @param relativeFilePath - The relative or absolute path to the target file.\n * @returns The entire contents of the specified file as a UTF-8 encoded string.\n */\nconst getFileContent = (relativeFilePath: string): string => {\n const absolutePath = join(__dirname, relativeFilePath);\n const fileContent = readFileSync(absolutePath, 'utf-8');\n return fileContent;\n};\n\nconst FILE_TEMPLATE: Record<string, string> = {\n ts: getFileContent('./TS_FORMAT.md'),\n tsx: getFileContent('./TSX_FORMAT.md'),\n js: getFileContent('./MJS_FORMAT.md'),\n mjs: getFileContent('./MJS_FORMAT.md'),\n cjs: getFileContent('./CJS_FORMAT.md'),\n jsx: getFileContent('./JSX_FORMAT.md'),\n json: getFileContent('./JSON_FORMAT.md'),\n};\n\n// The prompt template to send to ChatGPT, requesting an audit of content declaration files.\nconst CHAT_GPT_PROMPT = getFileContent('./PROMPT.md');\n\n/**\n * Formats a locale with its full name and returns a string representation.\n *\n * @function\n * @param locale - A locale from the project's configuration (e.g., 'en-US', 'fr-FR').\n * @returns A formatted string combining the locale's name and code. Example: \"English (US): en-US\".\n */\nconst formatLocaleWithName = (locale: Locales): string => {\n // getLocaleName returns a human-readable name for the locale.\n const localeName = getLocaleName(locale);\n\n // Concatenate both the readable name and the locale code.\n return `${locale}: ${localeName}`;\n};\n\n/**\n * Formats an array of tags with their keys and instructions.\n *\n * @function\n * @param tags - An array of tags from the project's configuration.\n * @returns A string representation of the tags, with their keys and instructions.\n */\nconst formatTagInstructions = (tags: Tag[] = []) =>\n tags.map((tag) => `- ${tag.key}: ${tag.instructions}`).join('\\n\\n');\n\n/**\n * Audits a content declaration file by constructing a prompt for ChatGPT.\n * The prompt includes details about the project's locales, file paths of content declarations,\n * and requests for identifying issues or inconsistencies. It prints the prompt for each file,\n * and could be adapted to send requests to the ChatGPT model.\n */\nexport const auditDictionary = async ({\n fileContent,\n filePath,\n model,\n openAiApiKey,\n customPrompt,\n temperature,\n locales,\n defaultLocale,\n tags,\n}: AuditOptions): Promise<AuditFileResultData | undefined> => {\n try {\n // Optionally, you could initialize and configure the OpenAI client here, if you intend to make API calls.\n // Uncomment and configure the following lines if you have `openai` installed and want to call the API:\n\n const openai = new OpenAI({\n apiKey: openAiApiKey ?? process.env.OPENAI_API_KEY,\n });\n\n // Read the file's content.\n const splitted = (filePath ?? '.json').split('.');\n const fileExtension = splitted[splitted.length - 1];\n\n // Prepare the prompt for ChatGPT by replacing placeholders with actual values.\n const prompt =\n customPrompt ??\n CHAT_GPT_PROMPT.replace('{{filePath}}', filePath ?? 'Not provided')\n .replace(\n '{{defaultLocale}}',\n `{${formatLocaleWithName(defaultLocale)}}`\n )\n .replace(\n '{{otherLocales}}',\n `{${locales.map(formatLocaleWithName).join(', ')}}`\n )\n .replace(\n '{{declarationsContentTemplate}}',\n FILE_TEMPLATE[fileExtension]\n )\n .replace('{{fileContent}}', fileContent)\n .replace('{{tagsInstructions}}', formatTagInstructions(tags));\n\n // Example of how you might request a completion from ChatGPT:\n const chatCompletion = await openai.chat.completions.create({\n model: openAiApiKey\n ? (model ?? 'gpt-4o-2024-11-20')\n : 'gpt-4o-2024-11-20',\n temperature: openAiApiKey ? (temperature ?? 0.1) : 0.1,\n messages: [{ role: 'system', content: prompt }],\n });\n\n const newContent = chatCompletion.choices[0].message?.content;\n\n logger.info(\n `${chatCompletion.usage?.total_tokens} tokens used in the request`\n );\n\n return {\n fileContent: newContent ?? '',\n tokenUsed: chatCompletion.usage?.total_tokens ?? 0,\n };\n } catch (error) {\n console.error(error);\n }\n};\n"],"mappings":";;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,gBAA6B;AAC7B,kBAA8B;AAC9B,iBAA8B;AAC9B,kBAA8B;AAC9B,oBAAuB;AAEvB,oBAAuB;AANvB;AASA,MAAM,gBAAY,yBAAQ,0BAAc,YAAY,GAAG,CAAC;AAyBxD,MAAM,iBAAiB,CAAC,qBAAqC;AAC3D,QAAM,mBAAe,kBAAK,WAAW,gBAAgB;AACrD,QAAM,kBAAc,wBAAa,cAAc,OAAO;AACtD,SAAO;AACT;AAEA,MAAM,gBAAwC;AAAA,EAC5C,IAAI,eAAe,gBAAgB;AAAA,EACnC,KAAK,eAAe,iBAAiB;AAAA,EACrC,IAAI,eAAe,iBAAiB;AAAA,EACpC,KAAK,eAAe,iBAAiB;AAAA,EACrC,KAAK,eAAe,iBAAiB;AAAA,EACrC,KAAK,eAAe,iBAAiB;AAAA,EACrC,MAAM,eAAe,kBAAkB;AACzC;AAGA,MAAM,kBAAkB,eAAe,aAAa;AASpD,MAAM,uBAAuB,CAAC,WAA4B;AAExD,QAAM,iBAAa,2BAAc,MAAM;AAGvC,SAAO,GAAG,MAAM,KAAK,UAAU;AACjC;AASA,MAAM,wBAAwB,CAAC,OAAc,CAAC,MAC5C,KAAK,IAAI,CAAC,QAAQ,KAAK,IAAI,GAAG,KAAK,IAAI,YAAY,EAAE,EAAE,KAAK,MAAM;AAQ7D,MAAM,kBAAkB,OAAO;AAAA,EACpC;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AACF,MAA8D;AAC5D,MAAI;AAIF,UAAM,SAAS,IAAI,qBAAO;AAAA,MACxB,QAAQ,gBAAgB,QAAQ,IAAI;AAAA,IACtC,CAAC;AAGD,UAAM,YAAY,YAAY,SAAS,MAAM,GAAG;AAChD,UAAM,gBAAgB,SAAS,SAAS,SAAS,CAAC;AAGlD,UAAM,SACJ,gBACA,gBAAgB,QAAQ,gBAAgB,YAAY,cAAc,EAC/D;AAAA,MACC;AAAA,MACA,IAAI,qBAAqB,aAAa,CAAC;AAAA,IACzC,EACC;AAAA,MACC;AAAA,MACA,IAAI,QAAQ,IAAI,oBAAoB,EAAE,KAAK,IAAI,CAAC;AAAA,IAClD,EACC;AAAA,MACC;AAAA,MACA,cAAc,aAAa;AAAA,IAC7B,EACC,QAAQ,mBAAmB,WAAW,EACtC,QAAQ,wBAAwB,sBAAsB,IAAI,CAAC;AAGhE,UAAM,iBAAiB,MAAM,OAAO,KAAK,YAAY,OAAO;AAAA,MAC1D,OAAO,eACF,SAAS,sBACV;AAAA,MACJ,aAAa,eAAgB,eAAe,MAAO;AAAA,MACnD,UAAU,CAAC,EAAE,MAAM,UAAU,SAAS,OAAO,CAAC;AAAA,IAChD,CAAC;AAED,UAAM,aAAa,eAAe,QAAQ,CAAC,EAAE,SAAS;AAEtD,yBAAO;AAAA,MACL,GAAG,eAAe,OAAO,YAAY;AAAA,IACvC;AAEA,WAAO;AAAA,MACL,aAAa,cAAc;AAAA,MAC3B,WAAW,eAAe,OAAO,gBAAgB;AAAA,IACnD;AAAA,EACF,SAAS,OAAO;AACd,YAAQ,MAAM,KAAK;AAAA,EACrB;AACF;","names":[]}
@@ -25,7 +25,7 @@ var import_fs = require("fs");
25
25
  var import_path = require("path");
26
26
  var import_url = require("url");
27
27
  var import_core = require("@intlayer/core");
28
- var import_logger = require('./../../logger/index.cjs');
28
+ var import_logger = require('./../../../logger/index.cjs');
29
29
  var import_openai = require("openai");
30
30
  const import_meta = {};
31
31
  const __dirname = (0, import_path.dirname)((0, import_url.fileURLToPath)(import_meta.url));
@@ -44,6 +44,7 @@ const auditDictionaryField = async ({
44
44
  fileContent,
45
45
  model,
46
46
  openAiApiKey,
47
+ temperature,
47
48
  customPrompt,
48
49
  locales,
49
50
  keyPath,
@@ -51,14 +52,15 @@ const auditDictionaryField = async ({
51
52
  }) => {
52
53
  try {
53
54
  const openai = new import_openai.OpenAI({
54
- apiKey: openAiApiKey
55
+ apiKey: openAiApiKey ?? process.env.OPENAI_API_KEY
55
56
  });
56
57
  const prompt = customPrompt ?? CHAT_GPT_PROMPT.replace(
57
58
  "{{otherLocales}}",
58
59
  `{${locales.map(formatLocaleWithName).join(", ")}}`
59
60
  ).replace("{{keyPath}}", JSON.stringify(keyPath)).replace("{{fileContent}}", fileContent).replace("{{tagsInstructions}}", formatTagInstructions(tags));
60
61
  const chatCompletion = await openai.chat.completions.create({
61
- model: model ?? "gpt-4o-2024-11-20",
62
+ model: openAiApiKey ? model ?? "gpt-4o-2024-11-20" : "gpt-4o-2024-11-20",
63
+ temperature: openAiApiKey ? temperature ?? 0.1 : 0.1,
62
64
  messages: [{ role: "system", content: prompt }]
63
65
  });
64
66
  const newContent = chatCompletion.choices[0].message?.content;
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../../../../../src/utils/AI/auditDictionaryField/index.ts"],"sourcesContent":["import { readFileSync } from 'fs';\nimport { dirname, join } from 'path';\nimport { fileURLToPath } from 'url';\nimport { getLocaleName, type KeyPath } from '@intlayer/core';\nimport { logger } from '@logger';\nimport type { Locales } from 'intlayer';\nimport { OpenAI } from 'openai';\nimport type { Tag } from '@/types/tag.types';\n\nconst __dirname = dirname(fileURLToPath(import.meta.url));\n\nexport type AIOptions = {\n model?: string;\n temperature?: number;\n openAiApiKey?: string;\n};\n\nexport type AuditDictionaryFieldOptions = {\n locales: Locales[];\n fileContent: string;\n customPrompt?: string;\n keyPath: KeyPath[];\n tags?: Tag[];\n} & AIOptions;\nexport type AuditDictionaryFieldResultData = {\n fileContent: string;\n tokenUsed: number;\n};\n\n/**\n * Reads the content of a file synchronously.\n *\n * @function\n * @param relativeFilePath - The relative or absolute path to the target file.\n * @returns The entire contents of the specified file as a UTF-8 encoded string.\n */\nconst getFileContent = (relativeFilePath: string): string => {\n const absolutePath = join(__dirname, relativeFilePath);\n const fileContent = readFileSync(absolutePath, 'utf-8');\n return fileContent;\n};\n\n// The prompt template to send to ChatGPT, requesting an audit of content declaration files.\nconst CHAT_GPT_PROMPT = getFileContent('./PROMPT.md');\n\n/**\n * Formats a locale with its full name and returns a string representation.\n *\n * @function\n * @param locale - A locale from the project's configuration (e.g., 'en-US', 'fr-FR').\n * @returns A formatted string combining the locale's name and code. Example: \"English (US): en-US\".\n */\nconst formatLocaleWithName = (locale: Locales): string => {\n // getLocaleName returns a human-readable name for the locale.\n const localeName = getLocaleName(locale);\n\n // Concatenate both the readable name and the locale code.\n return `${locale}: ${localeName}`;\n};\n\n/**\n * Formats an array of tags with their keys and instructions.\n *\n * @function\n * @param tags - An array of tags from the project's configuration.\n * @returns A string representation of the tags, with their keys and instructions.\n */\nconst formatTagInstructions = (tags: Tag[] = []) =>\n tags.map((tag) => `- ${tag.key}: ${tag.instructions}`).join('\\n\\n');\n\n/**\n * Audits a content declaration file by constructing a prompt for ChatGPT.\n * The prompt includes details about the project's locales, file paths of content declarations,\n * and requests for identifying issues or inconsistencies. It prints the prompt for each file,\n * and could be adapted to send requests to the ChatGPT model.\n */\nexport const auditDictionaryField = async ({\n fileContent,\n model,\n openAiApiKey,\n temperature,\n customPrompt,\n locales,\n keyPath,\n tags,\n}: AuditDictionaryFieldOptions): Promise<\n AuditDictionaryFieldResultData | undefined\n> => {\n try {\n // Optionally, you could initialize and configure the OpenAI client here, if you intend to make API calls.\n // Uncomment and configure the following lines if you have `openai` installed and want to call the API:\n\n const openai = new OpenAI({\n apiKey: openAiApiKey ?? process.env.OPENAI_API_KEY,\n });\n\n // Prepare the prompt for ChatGPT by replacing placeholders with actual values.\n const prompt =\n customPrompt ??\n CHAT_GPT_PROMPT.replace(\n '{{otherLocales}}',\n `{${locales.map(formatLocaleWithName).join(', ')}}`\n )\n .replace('{{keyPath}}', JSON.stringify(keyPath))\n .replace('{{fileContent}}', fileContent)\n .replace('{{tagsInstructions}}', formatTagInstructions(tags));\n\n // Example of how you might request a completion from ChatGPT:\n const chatCompletion = await openai.chat.completions.create({\n model: openAiApiKey\n ? (model ?? 'gpt-4o-2024-11-20')\n : 'gpt-4o-2024-11-20',\n temperature: openAiApiKey ? (temperature ?? 0.1) : 0.1,\n messages: [{ role: 'system', content: prompt }],\n });\n\n const newContent = chatCompletion.choices[0].message?.content;\n\n logger.info(\n `${chatCompletion.usage?.total_tokens} tokens used in the request`\n );\n\n return {\n fileContent: newContent ?? '',\n tokenUsed: chatCompletion.usage?.total_tokens ?? 0,\n };\n } catch (error) {\n console.error(error);\n }\n};\n"],"mappings":";;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,gBAA6B;AAC7B,kBAA8B;AAC9B,iBAA8B;AAC9B,kBAA4C;AAC5C,oBAAuB;AAEvB,oBAAuB;AANvB;AASA,MAAM,gBAAY,yBAAQ,0BAAc,YAAY,GAAG,CAAC;AA2BxD,MAAM,iBAAiB,CAAC,qBAAqC;AAC3D,QAAM,mBAAe,kBAAK,WAAW,gBAAgB;AACrD,QAAM,kBAAc,wBAAa,cAAc,OAAO;AACtD,SAAO;AACT;AAGA,MAAM,kBAAkB,eAAe,aAAa;AASpD,MAAM,uBAAuB,CAAC,WAA4B;AAExD,QAAM,iBAAa,2BAAc,MAAM;AAGvC,SAAO,GAAG,MAAM,KAAK,UAAU;AACjC;AASA,MAAM,wBAAwB,CAAC,OAAc,CAAC,MAC5C,KAAK,IAAI,CAAC,QAAQ,KAAK,IAAI,GAAG,KAAK,IAAI,YAAY,EAAE,EAAE,KAAK,MAAM;AAQ7D,MAAM,uBAAuB,OAAO;AAAA,EACzC;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AACF,MAEK;AACH,MAAI;AAIF,UAAM,SAAS,IAAI,qBAAO;AAAA,MACxB,QAAQ,gBAAgB,QAAQ,IAAI;AAAA,IACtC,CAAC;AAGD,UAAM,SACJ,gBACA,gBAAgB;AAAA,MACd;AAAA,MACA,IAAI,QAAQ,IAAI,oBAAoB,EAAE,KAAK,IAAI,CAAC;AAAA,IAClD,EACG,QAAQ,eAAe,KAAK,UAAU,OAAO,CAAC,EAC9C,QAAQ,mBAAmB,WAAW,EACtC,QAAQ,wBAAwB,sBAAsB,IAAI,CAAC;AAGhE,UAAM,iBAAiB,MAAM,OAAO,KAAK,YAAY,OAAO;AAAA,MAC1D,OAAO,eACF,SAAS,sBACV;AAAA,MACJ,aAAa,eAAgB,eAAe,MAAO;AAAA,MACnD,UAAU,CAAC,EAAE,MAAM,UAAU,SAAS,OAAO,CAAC;AAAA,IAChD,CAAC;AAED,UAAM,aAAa,eAAe,QAAQ,CAAC,EAAE,SAAS;AAEtD,yBAAO;AAAA,MACL,GAAG,eAAe,OAAO,YAAY;AAAA,IACvC;AAEA,WAAO;AAAA,MACL,aAAa,cAAc;AAAA,MAC3B,WAAW,eAAe,OAAO,gBAAgB;AAAA,IACnD;AAAA,EACF,SAAS,OAAO;AACd,YAAQ,MAAM,KAAK;AAAA,EACrB;AACF;","names":[]}
@@ -24,7 +24,7 @@ module.exports = __toCommonJS(auditDictionaryMetadata_exports);
24
24
  var import_fs = require("fs");
25
25
  var import_path = require("path");
26
26
  var import_url = require("url");
27
- var import_logger = require('./../../logger/index.cjs');
27
+ var import_logger = require('./../../../logger/index.cjs');
28
28
  var import_openai = require("openai");
29
29
  const import_meta = {};
30
30
  const __dirname = (0, import_path.dirname)((0, import_url.fileURLToPath)(import_meta.url));
@@ -37,13 +37,14 @@ const CHAT_GPT_PROMPT = getFileContent("./PROMPT.md");
37
37
  const auditDictionaryMetadata = async ({
38
38
  model,
39
39
  openAiApiKey,
40
+ temperature,
40
41
  customPrompt,
41
42
  tags,
42
43
  fileContent
43
44
  }) => {
44
45
  try {
45
46
  const openai = new import_openai.OpenAI({
46
- apiKey: openAiApiKey
47
+ apiKey: openAiApiKey ?? process.env.OPENAI_API_KEY
47
48
  });
48
49
  const prompt = customPrompt ?? CHAT_GPT_PROMPT.replace(
49
50
  "{{tags}}",
@@ -54,7 +55,8 @@ const auditDictionaryMetadata = async ({
54
55
  )}`
55
56
  ).replace("{{contentDeclaration}}", fileContent);
56
57
  const chatCompletion = await openai.chat.completions.create({
57
- model: model ?? "gpt-4o-2024-11-20",
58
+ model: openAiApiKey ? model ?? "gpt-4o-2024-11-20" : "gpt-4o-2024-11-20",
59
+ temperature: openAiApiKey ? temperature ?? 0.1 : 0.1,
58
60
  messages: [{ role: "system", content: prompt }]
59
61
  });
60
62
  const newContent = chatCompletion.choices[0].message?.content;
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../../../../../src/utils/AI/auditDictionaryMetadata/index.ts"],"sourcesContent":["import { readFileSync } from 'fs';\nimport { dirname, join } from 'path';\nimport { fileURLToPath } from 'url';\nimport { logger } from '@logger';\nimport { OpenAI } from 'openai';\nimport type { Tag } from '@/types/tag.types';\n\nconst __dirname = dirname(fileURLToPath(import.meta.url));\n\nexport type AIOptions = {\n model?: string;\n temperature?: number;\n openAiApiKey?: string;\n};\n\nexport type AuditOptions = {\n tags: Tag[];\n fileContent: string;\n customPrompt?: string;\n} & AIOptions;\nexport type AuditFileResultData = { fileContent: string; tokenUsed: number };\n\n/**\n * Reads the content of a file synchronously.\n *\n * @function\n * @param relativeFilePath - The relative or absolute path to the target file.\n * @returns The entire contents of the specified file as a UTF-8 encoded string.\n */\nconst getFileContent = (relativeFilePath: string): string => {\n const absolutePath = join(__dirname, relativeFilePath);\n const fileContent = readFileSync(absolutePath, 'utf-8');\n return fileContent;\n};\n\n// The prompt template to send to ChatGPT, requesting an audit of content declaration files.\nconst CHAT_GPT_PROMPT = getFileContent('./PROMPT.md');\n\n/**\n * Audits a content declaration file by constructing a prompt for ChatGPT.\n * The prompt includes details about the project's locales, file paths of content declarations,\n * and requests for identifying issues or inconsistencies. It prints the prompt for each file,\n * and could be adapted to send requests to the ChatGPT model.\n *\n */\nexport const auditDictionaryMetadata = async ({\n model,\n openAiApiKey,\n temperature,\n customPrompt,\n tags,\n fileContent,\n}: AuditOptions): Promise<AuditFileResultData | undefined> => {\n try {\n // Optionally, you could initialize and configure the OpenAI client here, if you intend to make API calls.\n // Uncomment and configure the following lines if you have `openai` installed and want to call the API:\n\n const openai = new OpenAI({\n apiKey: openAiApiKey ?? process.env.OPENAI_API_KEY,\n });\n\n // Prepare the prompt for ChatGPT by replacing placeholders with actual values.\n const prompt =\n customPrompt ??\n CHAT_GPT_PROMPT.replace(\n '{{tags}}',\n `${JSON.stringify(\n tags\n .map(({ key, description }) => `- ${key}: ${description}`)\n .join('\\n\\n'),\n null,\n 2\n )}`\n ).replace('{{contentDeclaration}}', fileContent);\n\n // Example of how you might request a completion from ChatGPT:\n const chatCompletion = await openai.chat.completions.create({\n model: openAiApiKey\n ? (model ?? 'gpt-4o-2024-11-20')\n : 'gpt-4o-2024-11-20',\n temperature: openAiApiKey ? (temperature ?? 0.1) : 0.1,\n messages: [{ role: 'system', content: prompt }],\n });\n\n const newContent = chatCompletion.choices[0].message?.content;\n\n logger.info(\n `${chatCompletion.usage?.total_tokens} tokens used in the request`\n );\n\n return {\n fileContent: newContent ?? '',\n tokenUsed: chatCompletion.usage?.total_tokens ?? 0,\n };\n } catch (error) {\n console.error(error);\n }\n};\n"],"mappings":";;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,gBAA6B;AAC7B,kBAA8B;AAC9B,iBAA8B;AAC9B,oBAAuB;AACvB,oBAAuB;AAJvB;AAOA,MAAM,gBAAY,yBAAQ,0BAAc,YAAY,GAAG,CAAC;AAsBxD,MAAM,iBAAiB,CAAC,qBAAqC;AAC3D,QAAM,mBAAe,kBAAK,WAAW,gBAAgB;AACrD,QAAM,kBAAc,wBAAa,cAAc,OAAO;AACtD,SAAO;AACT;AAGA,MAAM,kBAAkB,eAAe,aAAa;AAS7C,MAAM,0BAA0B,OAAO;AAAA,EAC5C;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AACF,MAA8D;AAC5D,MAAI;AAIF,UAAM,SAAS,IAAI,qBAAO;AAAA,MACxB,QAAQ,gBAAgB,QAAQ,IAAI;AAAA,IACtC,CAAC;AAGD,UAAM,SACJ,gBACA,gBAAgB;AAAA,MACd;AAAA,MACA,GAAG,KAAK;AAAA,QACN,KACG,IAAI,CAAC,EAAE,KAAK,YAAY,MAAM,KAAK,GAAG,KAAK,WAAW,EAAE,EACxD,KAAK,MAAM;AAAA,QACd;AAAA,QACA;AAAA,MACF,CAAC;AAAA,IACH,EAAE,QAAQ,0BAA0B,WAAW;AAGjD,UAAM,iBAAiB,MAAM,OAAO,KAAK,YAAY,OAAO;AAAA,MAC1D,OAAO,eACF,SAAS,sBACV;AAAA,MACJ,aAAa,eAAgB,eAAe,MAAO;AAAA,MACnD,UAAU,CAAC,EAAE,MAAM,UAAU,SAAS,OAAO,CAAC;AAAA,IAChD,CAAC;AAED,UAAM,aAAa,eAAe,QAAQ,CAAC,EAAE,SAAS;AAEtD,yBAAO;AAAA,MACL,GAAG,eAAe,OAAO,YAAY;AAAA,IACvC;AAEA,WAAO;AAAA,MACL,aAAa,cAAc;AAAA,MAC3B,WAAW,eAAe,OAAO,gBAAgB;AAAA,IACnD;AAAA,EACF,SAAS,OAAO;AACd,YAAQ,MAAM,KAAK;AAAA,EACrB;AACF;","names":[]}
@@ -0,0 +1,13 @@
1
+ Your role is to autocomplete the user input.
2
+
3
+ Without prior context, you can try to:
4
+
5
+ - complete the user's word,
6
+ - guess the next word(s)
7
+ - complete the sentence
8
+
9
+ Your completion should not exceed one sentence. Minimize the completion length if you're unsure about the user's input.
10
+
11
+ The user input will be provided in the next user message: { role: 'user', content: 'xxx' }
12
+
13
+ You should return your autocompletion without any additional text or formatting.
@@ -0,0 +1,73 @@
1
+ "use strict";
2
+ var __defProp = Object.defineProperty;
3
+ var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
4
+ var __getOwnPropNames = Object.getOwnPropertyNames;
5
+ var __hasOwnProp = Object.prototype.hasOwnProperty;
6
+ var __export = (target, all) => {
7
+ for (var name in all)
8
+ __defProp(target, name, { get: all[name], enumerable: true });
9
+ };
10
+ var __copyProps = (to, from, except, desc) => {
11
+ if (from && typeof from === "object" || typeof from === "function") {
12
+ for (let key of __getOwnPropNames(from))
13
+ if (!__hasOwnProp.call(to, key) && key !== except)
14
+ __defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
15
+ }
16
+ return to;
17
+ };
18
+ var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
19
+ var autocomplete_exports = {};
20
+ __export(autocomplete_exports, {
21
+ autocomplete: () => autocomplete
22
+ });
23
+ module.exports = __toCommonJS(autocomplete_exports);
24
+ var import_fs = require("fs");
25
+ var import_path = require("path");
26
+ var import_url = require("url");
27
+ var import_logger = require('./../../../logger/index.cjs');
28
+ var import_openai = require("openai");
29
+ const import_meta = {};
30
+ const __dirname = (0, import_path.dirname)((0, import_url.fileURLToPath)(import_meta.url));
31
+ const getFileContent = (relativeFilePath) => {
32
+ const absolutePath = (0, import_path.join)(__dirname, relativeFilePath);
33
+ const fileContent = (0, import_fs.readFileSync)(absolutePath, "utf-8");
34
+ return fileContent;
35
+ };
36
+ const CHAT_GPT_PROMPT = getFileContent("./PROMPT.md");
37
+ const autocomplete = async ({
38
+ text,
39
+ model,
40
+ openAiApiKey,
41
+ temperature,
42
+ customPrompt
43
+ }) => {
44
+ try {
45
+ const openai = new import_openai.OpenAI({
46
+ apiKey: openAiApiKey ?? process.env.OPENAI_API_KEY
47
+ });
48
+ const prompt = customPrompt ?? CHAT_GPT_PROMPT;
49
+ const chatCompletion = await openai.chat.completions.create({
50
+ model: openAiApiKey ? model ?? "gpt-4o-mini" : "gpt-4o-mini",
51
+ temperature: openAiApiKey ? temperature ?? 0.1 : 0.1,
52
+ messages: [
53
+ { role: "system", content: prompt },
54
+ { role: "user", content: text }
55
+ ]
56
+ });
57
+ const newContent = chatCompletion.choices[0].message?.content;
58
+ import_logger.logger.info(
59
+ `${chatCompletion.usage?.total_tokens} tokens used in the request`
60
+ );
61
+ return {
62
+ autocompletion: newContent ?? "",
63
+ tokenUsed: chatCompletion.usage?.total_tokens ?? 0
64
+ };
65
+ } catch (error) {
66
+ console.error(error);
67
+ }
68
+ };
69
+ // Annotate the CommonJS export names for ESM import in node:
70
+ 0 && (module.exports = {
71
+ autocomplete
72
+ });
73
+ //# sourceMappingURL=index.cjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../../../../../src/utils/AI/autocomplete/index.ts"],"sourcesContent":["import { readFileSync } from 'fs';\nimport { dirname, join } from 'path';\nimport { fileURLToPath } from 'url';\nimport { logger } from '@logger';\nimport { OpenAI } from 'openai';\n\nconst __dirname = dirname(fileURLToPath(import.meta.url));\n\nexport type AIOptions = {\n model?: string;\n temperature?: number;\n openAiApiKey?: string;\n};\n\nexport type AutocompleteOptions = {\n text: string;\n customPrompt?: string;\n} & AIOptions;\nexport type AutocompleteFileResultData = {\n autocompletion: string;\n tokenUsed: number;\n};\n\n/**\n * Reads the content of a file synchronously.\n *\n * @function\n * @param relativeFilePath - The relative or absolute path to the target file.\n * @returns The entire contents of the specified file as a UTF-8 encoded string.\n */\nconst getFileContent = (relativeFilePath: string): string => {\n const absolutePath = join(__dirname, relativeFilePath);\n const fileContent = readFileSync(absolutePath, 'utf-8');\n return fileContent;\n};\n\n// The prompt template to send to ChatGPT, requesting an audit of content declaration files.\nconst CHAT_GPT_PROMPT = getFileContent('./PROMPT.md');\n\n/**\n * Autocompletes a content declaration file by constructing a prompt for ChatGPT.\n * The prompt includes details about the project's locales, file paths of content declarations,\n * and requests for identifying issues or inconsistencies. It prints the prompt for each file,\n * and could be adapted to send requests to the ChatGPT model.\n *\n */\nexport const autocomplete = async ({\n text,\n model,\n openAiApiKey,\n temperature,\n customPrompt,\n}: AutocompleteOptions): Promise<AutocompleteFileResultData | undefined> => {\n try {\n // Optionally, you could initialize and configure the OpenAI client here, if you intend to make API calls.\n // Uncomment and configure the following lines if you have `openai` installed and want to call the API:\n\n const openai = new OpenAI({\n apiKey: openAiApiKey ?? process.env.OPENAI_API_KEY,\n });\n\n // Prepare the prompt for ChatGPT by replacing placeholders with actual values.\n const prompt = customPrompt ?? CHAT_GPT_PROMPT;\n\n // Example of how you might request a completion from ChatGPT:\n const chatCompletion = await openai.chat.completions.create({\n model: openAiApiKey ? (model ?? 'gpt-4o-mini') : 'gpt-4o-mini',\n temperature: openAiApiKey ? (temperature ?? 0.1) : 0.1,\n messages: [\n { role: 'system', content: prompt },\n { role: 'user', content: text },\n ],\n });\n\n const newContent = chatCompletion.choices[0].message?.content;\n\n logger.info(\n `${chatCompletion.usage?.total_tokens} tokens used in the request`\n );\n\n return {\n autocompletion: newContent ?? '',\n tokenUsed: chatCompletion.usage?.total_tokens ?? 0,\n };\n } catch (error) {\n console.error(error);\n }\n};\n"],"mappings":";;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,gBAA6B;AAC7B,kBAA8B;AAC9B,iBAA8B;AAC9B,oBAAuB;AACvB,oBAAuB;AAJvB;AAMA,MAAM,gBAAY,yBAAQ,0BAAc,YAAY,GAAG,CAAC;AAwBxD,MAAM,iBAAiB,CAAC,qBAAqC;AAC3D,QAAM,mBAAe,kBAAK,WAAW,gBAAgB;AACrD,QAAM,kBAAc,wBAAa,cAAc,OAAO;AACtD,SAAO;AACT;AAGA,MAAM,kBAAkB,eAAe,aAAa;AAS7C,MAAM,eAAe,OAAO;AAAA,EACjC;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AACF,MAA4E;AAC1E,MAAI;AAIF,UAAM,SAAS,IAAI,qBAAO;AAAA,MACxB,QAAQ,gBAAgB,QAAQ,IAAI;AAAA,IACtC,CAAC;AAGD,UAAM,SAAS,gBAAgB;AAG/B,UAAM,iBAAiB,MAAM,OAAO,KAAK,YAAY,OAAO;AAAA,MAC1D,OAAO,eAAgB,SAAS,gBAAiB;AAAA,MACjD,aAAa,eAAgB,eAAe,MAAO;AAAA,MACnD,UAAU;AAAA,QACR,EAAE,MAAM,UAAU,SAAS,OAAO;AAAA,QAClC,EAAE,MAAM,QAAQ,SAAS,KAAK;AAAA,MAChC;AAAA,IACF,CAAC;AAED,UAAM,aAAa,eAAe,QAAQ,CAAC,EAAE,SAAS;AAEtD,yBAAO;AAAA,MACL,GAAG,eAAe,OAAO,YAAY;AAAA,IACvC;AAEA,WAAO;AAAA,MACL,gBAAgB,cAAc;AAAA,MAC9B,WAAW,eAAe,OAAO,gBAAgB;AAAA,IACnD;AAAA,EACF,SAAS,OAAO;AACd,YAAQ,MAAM,KAAK;AAAA,EACrB;AACF;","names":[]}
@@ -38,19 +38,21 @@ const auditTag = async ({
38
38
  model,
39
39
  openAiApiKey,
40
40
  customPrompt,
41
+ temperature,
41
42
  tag,
42
43
  dictionaries
43
44
  }) => {
44
45
  try {
45
46
  const openai = new import_openai.OpenAI({
46
- apiKey: openAiApiKey
47
+ apiKey: openAiApiKey ?? process.env.OPENAI_API_KEY
47
48
  });
48
49
  const prompt = customPrompt ?? CHAT_GPT_PROMPT.replace("{{tag}}", `${JSON.stringify(tag)}`).replace(
49
50
  "{{contentDeclarations}}",
50
51
  dictionaries.map((dictionary) => `- ${JSON.stringify(dictionary)}`).join("\n\n")
51
52
  );
52
53
  const chatCompletion = await openai.chat.completions.create({
53
- model: model ?? "gpt-4o-2024-11-20",
54
+ model: openAiApiKey ? model ?? "gpt-4o-2024-11-20" : "gpt-4o-2024-11-20",
55
+ temperature: openAiApiKey ? temperature ?? 0.1 : 0.1,
54
56
  messages: [{ role: "system", content: prompt }]
55
57
  });
56
58
  const newContent = chatCompletion.choices[0].message?.content;
@@ -1 +1 @@
1
- {"version":3,"sources":["../../../../src/utils/auditTag/index.ts"],"sourcesContent":["import { readFileSync } from 'fs';\nimport { dirname, join } from 'path';\nimport { fileURLToPath } from 'url';\nimport { logger } from '@logger';\nimport { OpenAI } from 'openai';\nimport type { Dictionary } from '@/types/dictionary.types';\nimport type { Tag } from '@/types/tag.types';\n\nconst __dirname = dirname(fileURLToPath(import.meta.url));\n\nexport type AuditOptions = {\n tag: Tag;\n dictionaries: Dictionary[];\n model?: string;\n openAiApiKey: string;\n customPrompt?: string;\n};\nexport type AuditFileResultData = { fileContent: string; tokenUsed: number };\n\n/**\n * Reads the content of a file synchronously.\n *\n * @function\n * @param relativeFilePath - The relative or absolute path to the target file.\n * @returns The entire contents of the specified file as a UTF-8 encoded string.\n */\nconst getFileContent = (relativeFilePath: string): string => {\n const absolutePath = join(__dirname, relativeFilePath);\n const fileContent = readFileSync(absolutePath, 'utf-8');\n return fileContent;\n};\n\n// The prompt template to send to ChatGPT, requesting an audit of content declaration files.\nconst CHAT_GPT_PROMPT = getFileContent('./PROMPT.md');\n\n/**\n * Audits a content declaration file by constructing a prompt for ChatGPT.\n * The prompt includes details about the project's locales, file paths of content declarations,\n * and requests for identifying issues or inconsistencies. It prints the prompt for each file,\n * and could be adapted to send requests to the ChatGPT model.\n *\n * @async\n * @function\n * @param filePath - The relative or absolute path to the target file.\n * @param options - Optional configuration for the audit process.\n * @returns This function returns a Promise that resolves once the audit is complete.\n */\nexport const auditTag = async ({\n model,\n openAiApiKey,\n customPrompt,\n tag,\n dictionaries,\n}: AuditOptions): Promise<AuditFileResultData | undefined> => {\n try {\n // Optionally, you could initialize and configure the OpenAI client here, if you intend to make API calls.\n // Uncomment and configure the following lines if you have `openai` installed and want to call the API:\n\n const openai = new OpenAI({\n apiKey: openAiApiKey,\n });\n\n // Prepare the prompt for ChatGPT by replacing placeholders with actual values.\n const prompt =\n customPrompt ??\n CHAT_GPT_PROMPT.replace('{{tag}}', `${JSON.stringify(tag)}`).replace(\n '{{contentDeclarations}}',\n dictionaries\n .map((dictionary) => `- ${JSON.stringify(dictionary)}`)\n .join('\\n\\n')\n );\n\n // Example of how you might request a completion from ChatGPT:\n const chatCompletion = await openai.chat.completions.create({\n model: model ?? 'gpt-4o-2024-11-20',\n messages: [{ role: 'system', content: prompt }],\n });\n\n const newContent = chatCompletion.choices[0].message?.content;\n\n logger.info(\n `${chatCompletion.usage?.total_tokens} tokens used in the request`\n );\n\n return {\n fileContent: newContent ?? '',\n tokenUsed: chatCompletion.usage?.total_tokens ?? 0,\n };\n } catch (error) {\n console.error(error);\n }\n};\n"],"mappings":";;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,gBAA6B;AAC7B,kBAA8B;AAC9B,iBAA8B;AAC9B,oBAAuB;AACvB,oBAAuB;AAJvB;AAQA,MAAM,gBAAY,yBAAQ,0BAAc,YAAY,GAAG,CAAC;AAkBxD,MAAM,iBAAiB,CAAC,qBAAqC;AAC3D,QAAM,mBAAe,kBAAK,WAAW,gBAAgB;AACrD,QAAM,kBAAc,wBAAa,cAAc,OAAO;AACtD,SAAO;AACT;AAGA,MAAM,kBAAkB,eAAe,aAAa;AAc7C,MAAM,WAAW,OAAO;AAAA,EAC7B;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AACF,MAA8D;AAC5D,MAAI;AAIF,UAAM,SAAS,IAAI,qBAAO;AAAA,MACxB,QAAQ;AAAA,IACV,CAAC;AAGD,UAAM,SACJ,gBACA,gBAAgB,QAAQ,WAAW,GAAG,KAAK,UAAU,GAAG,CAAC,EAAE,EAAE;AAAA,MAC3D;AAAA,MACA,aACG,IAAI,CAAC,eAAe,KAAK,KAAK,UAAU,UAAU,CAAC,EAAE,EACrD,KAAK,MAAM;AAAA,IAChB;AAGF,UAAM,iBAAiB,MAAM,OAAO,KAAK,YAAY,OAAO;AAAA,MAC1D,OAAO,SAAS;AAAA,MAChB,UAAU,CAAC,EAAE,MAAM,UAAU,SAAS,OAAO,CAAC;AAAA,IAChD,CAAC;AAED,UAAM,aAAa,eAAe,QAAQ,CAAC,EAAE,SAAS;AAEtD,yBAAO;AAAA,MACL,GAAG,eAAe,OAAO,YAAY;AAAA,IACvC;AAEA,WAAO;AAAA,MACL,aAAa,cAAc;AAAA,MAC3B,WAAW,eAAe,OAAO,gBAAgB;AAAA,IACnD;AAAA,EACF,SAAS,OAAO;AACd,YAAQ,MAAM,KAAK;AAAA,EACrB;AACF;","names":[]}
1
+ {"version":3,"sources":["../../../../src/utils/auditTag/index.ts"],"sourcesContent":["import { readFileSync } from 'fs';\nimport { dirname, join } from 'path';\nimport { fileURLToPath } from 'url';\nimport { logger } from '@logger';\nimport { OpenAI } from 'openai';\nimport type { Dictionary } from '@/types/dictionary.types';\nimport type { Tag } from '@/types/tag.types';\n\nconst __dirname = dirname(fileURLToPath(import.meta.url));\n\nexport type AIOptions = {\n model?: string;\n temperature?: number;\n openAiApiKey?: string;\n};\n\nexport type AuditOptions = {\n tag: Tag;\n dictionaries: Dictionary[];\n customPrompt?: string;\n} & AIOptions;\nexport type AuditFileResultData = { fileContent: string; tokenUsed: number };\n\n/**\n * Reads the content of a file synchronously.\n *\n * @function\n * @param relativeFilePath - The relative or absolute path to the target file.\n * @returns The entire contents of the specified file as a UTF-8 encoded string.\n */\nconst getFileContent = (relativeFilePath: string): string => {\n const absolutePath = join(__dirname, relativeFilePath);\n const fileContent = readFileSync(absolutePath, 'utf-8');\n return fileContent;\n};\n\n// The prompt template to send to ChatGPT, requesting an audit of content declaration files.\nconst CHAT_GPT_PROMPT = getFileContent('./PROMPT.md');\n\n/**\n * Audits a content declaration file by constructing a prompt for ChatGPT.\n * The prompt includes details about the project's locales, file paths of content declarations,\n * and requests for identifying issues or inconsistencies. It prints the prompt for each file,\n * and could be adapted to send requests to the ChatGPT model.\n *\n * @async\n * @function\n * @param filePath - The relative or absolute path to the target file.\n * @param options - Optional configuration for the audit process.\n * @returns This function returns a Promise that resolves once the audit is complete.\n */\nexport const auditTag = async ({\n model,\n openAiApiKey,\n customPrompt,\n temperature,\n tag,\n dictionaries,\n}: AuditOptions): Promise<AuditFileResultData | undefined> => {\n try {\n // Optionally, you could initialize and configure the OpenAI client here, if you intend to make API calls.\n // Uncomment and configure the following lines if you have `openai` installed and want to call the API:\n\n const openai = new OpenAI({\n apiKey: openAiApiKey ?? process.env.OPENAI_API_KEY,\n });\n\n // Prepare the prompt for ChatGPT by replacing placeholders with actual values.\n const prompt =\n customPrompt ??\n CHAT_GPT_PROMPT.replace('{{tag}}', `${JSON.stringify(tag)}`).replace(\n '{{contentDeclarations}}',\n dictionaries\n .map((dictionary) => `- ${JSON.stringify(dictionary)}`)\n .join('\\n\\n')\n );\n\n // Example of how you might request a completion from ChatGPT:\n const chatCompletion = await openai.chat.completions.create({\n model: openAiApiKey\n ? (model ?? 'gpt-4o-2024-11-20')\n : 'gpt-4o-2024-11-20',\n temperature: openAiApiKey ? (temperature ?? 0.1) : 0.1,\n messages: [{ role: 'system', content: prompt }],\n });\n\n const newContent = chatCompletion.choices[0].message?.content;\n\n logger.info(\n `${chatCompletion.usage?.total_tokens} tokens used in the request`\n );\n\n return {\n fileContent: newContent ?? '',\n tokenUsed: chatCompletion.usage?.total_tokens ?? 0,\n };\n } catch (error) {\n console.error(error);\n }\n};\n"],"mappings":";;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,gBAA6B;AAC7B,kBAA8B;AAC9B,iBAA8B;AAC9B,oBAAuB;AACvB,oBAAuB;AAJvB;AAQA,MAAM,gBAAY,yBAAQ,0BAAc,YAAY,GAAG,CAAC;AAsBxD,MAAM,iBAAiB,CAAC,qBAAqC;AAC3D,QAAM,mBAAe,kBAAK,WAAW,gBAAgB;AACrD,QAAM,kBAAc,wBAAa,cAAc,OAAO;AACtD,SAAO;AACT;AAGA,MAAM,kBAAkB,eAAe,aAAa;AAc7C,MAAM,WAAW,OAAO;AAAA,EAC7B;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AACF,MAA8D;AAC5D,MAAI;AAIF,UAAM,SAAS,IAAI,qBAAO;AAAA,MACxB,QAAQ,gBAAgB,QAAQ,IAAI;AAAA,IACtC,CAAC;AAGD,UAAM,SACJ,gBACA,gBAAgB,QAAQ,WAAW,GAAG,KAAK,UAAU,GAAG,CAAC,EAAE,EAAE;AAAA,MAC3D;AAAA,MACA,aACG,IAAI,CAAC,eAAe,KAAK,KAAK,UAAU,UAAU,CAAC,EAAE,EACrD,KAAK,MAAM;AAAA,IAChB;AAGF,UAAM,iBAAiB,MAAM,OAAO,KAAK,YAAY,OAAO;AAAA,MAC1D,OAAO,eACF,SAAS,sBACV;AAAA,MACJ,aAAa,eAAgB,eAAe,MAAO;AAAA,MACnD,UAAU,CAAC,EAAE,MAAM,UAAU,SAAS,OAAO,CAAC;AAAA,IAChD,CAAC;AAED,UAAM,aAAa,eAAe,QAAQ,CAAC,EAAE,SAAS;AAEtD,yBAAO;AAAA,MACL,GAAG,eAAe,OAAO,YAAY;AAAA,IACvC;AAEA,WAAO;AAAA,MACL,aAAa,cAAc;AAAA,MAC3B,WAAW,eAAe,OAAO,gBAAgB;AAAA,IACnD;AAAA,EACF,SAAS,OAAO;AACd,YAAQ,MAAM,KAAK;AAAA,EACrB;AACF;","names":[]}
@@ -1111,6 +1111,19 @@ const errorData = {
1111
1111
  },
1112
1112
  statusCode: import_httpStatusCodes.HttpStatusCodes.FORBIDDEN_403
1113
1113
  },
1114
+ PROJECTS_EXIST: {
1115
+ title: {
1116
+ en: "Projects Exist",
1117
+ fr: "Des projets existent",
1118
+ es: "Existen proyectos"
1119
+ },
1120
+ message: {
1121
+ en: "Projects exist in this organization. Please delete them before deleting the organization.",
1122
+ fr: "Des projets existent dans cette organisation. Veuillez les supprimer avant de supprimer l'organisation.",
1123
+ es: "Existen proyectos en esta organizaci\xF3n. Por favor, elimine los antes de eliminar la organizaci\xF3n."
1124
+ },
1125
+ statusCode: import_httpStatusCodes.HttpStatusCodes.FORBIDDEN_403
1126
+ },
1114
1127
  PLAN_NOT_FOUND: {
1115
1128
  title: {
1116
1129
  en: "Plan Not Found",
@@ -1370,6 +1383,19 @@ const errorData = {
1370
1383
  es: "La etiqueta especificada no est\xE1 en la organizaci\xF3n."
1371
1384
  },
1372
1385
  statusCode: import_httpStatusCodes.HttpStatusCodes.FORBIDDEN_403
1386
+ },
1387
+ AI_ACCESS_DENIED: {
1388
+ title: {
1389
+ en: "Access denied",
1390
+ fr: "Acc\xE8s refus\xE9",
1391
+ es: "Acceso denegado"
1392
+ },
1393
+ message: {
1394
+ en: "Invalid Access keys. Access keys should be defined to use AI features. See https://intlayer.org/doc/concept/editor. Alternatively, you can add your own openAI API key in the settings.",
1395
+ fr: "Cl\xE9es d'acc\xE8s invalides. Les cl\xE9s d'acc\xE8s doivent \xEAtre d\xE9finies pour utiliser les fonctionnalit\xE9s AI. Voir https://intlayer.org/doc/concept/editor. Alternativement, vous pouvez ajouter votre propre cl\xE9 API openAI dans les param\xE8tres.",
1396
+ es: "Claves de acceso no v\xE1lidas. Las claves de acceso deben definirse para usar funciones AI. Ver https://intlayer.org/doc/concept/editor. Alternativamente, puede agregar su propia clave API openAI en la configuraci\xF3n."
1397
+ },
1398
+ statusCode: import_httpStatusCodes.HttpStatusCodes.FORBIDDEN_403
1373
1399
  }
1374
1400
  };
1375
1401
  // Annotate the CommonJS export names for ESM import in node: