@justanarthur/payload-plugin-translator 1.3.6

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 (124) hide show
  1. package/README.md +215 -0
  2. package/dist/client/api/index.d.ts +8 -0
  3. package/dist/client/api/index.d.ts.map +1 -0
  4. package/dist/client/components/CustomButton/CustomButtonWithTranslator.d.ts +5 -0
  5. package/dist/client/components/CustomButton/CustomButtonWithTranslator.d.ts.map +1 -0
  6. package/dist/client/components/CustomButton/index.d.ts +3 -0
  7. package/dist/client/components/CustomButton/index.d.ts.map +1 -0
  8. package/dist/client/components/CustomButton/styles.scss +5 -0
  9. package/dist/client/components/LocaleLabel/LocaleLabel.d.ts +5 -0
  10. package/dist/client/components/LocaleLabel/LocaleLabel.d.ts.map +1 -0
  11. package/dist/client/components/LocaleLabel/index.d.ts +2 -0
  12. package/dist/client/components/LocaleLabel/index.d.ts.map +1 -0
  13. package/dist/client/components/ResolverButton/ResolverButton.d.ts +5 -0
  14. package/dist/client/components/ResolverButton/ResolverButton.d.ts.map +1 -0
  15. package/dist/client/components/ResolverButton/index.d.ts +2 -0
  16. package/dist/client/components/ResolverButton/index.d.ts.map +1 -0
  17. package/dist/client/components/TranslatorModal/Content.d.ts +2 -0
  18. package/dist/client/components/TranslatorModal/Content.d.ts.map +1 -0
  19. package/dist/client/components/TranslatorModal/TranslatorModal.d.ts +3 -0
  20. package/dist/client/components/TranslatorModal/TranslatorModal.d.ts.map +1 -0
  21. package/dist/client/components/TranslatorModal/index.d.ts +2 -0
  22. package/dist/client/components/TranslatorModal/index.d.ts.map +1 -0
  23. package/dist/client/components/TranslatorModal/styles.scss +76 -0
  24. package/dist/client/providers/Translator/TranslatorProvider.d.ts +5 -0
  25. package/dist/client/providers/Translator/TranslatorProvider.d.ts.map +1 -0
  26. package/dist/client/providers/Translator/context.d.ts +21 -0
  27. package/dist/client/providers/Translator/context.d.ts.map +1 -0
  28. package/dist/exports/client.d.ts +2 -0
  29. package/dist/exports/client.d.ts.map +1 -0
  30. package/dist/i18n-translations.d.ts +87 -0
  31. package/dist/i18n-translations.d.ts.map +1 -0
  32. package/dist/index.d.ts +11 -0
  33. package/dist/index.d.ts.map +1 -0
  34. package/dist/resolvers/copy.d.ts +3 -0
  35. package/dist/resolvers/copy.d.ts.map +1 -0
  36. package/dist/resolvers/google.d.ts +11 -0
  37. package/dist/resolvers/google.d.ts.map +1 -0
  38. package/dist/resolvers/libreTranslate.d.ts +16 -0
  39. package/dist/resolvers/libreTranslate.d.ts.map +1 -0
  40. package/dist/resolvers/openAI.d.ts +22 -0
  41. package/dist/resolvers/openAI.d.ts.map +1 -0
  42. package/dist/resolvers/types.d.ts +20 -0
  43. package/dist/resolvers/types.d.ts.map +1 -0
  44. package/dist/src/client/api/index.js +28 -0
  45. package/dist/src/client/api/index.js.map +1 -0
  46. package/dist/src/client/components/CustomButton/CustomButtonWithTranslator.js +28 -0
  47. package/dist/src/client/components/CustomButton/CustomButtonWithTranslator.js.map +1 -0
  48. package/dist/src/client/components/CustomButton/index.js +10 -0
  49. package/dist/src/client/components/CustomButton/index.js.map +1 -0
  50. package/dist/src/client/components/LocaleLabel/LocaleLabel.js +28 -0
  51. package/dist/src/client/components/LocaleLabel/LocaleLabel.js.map +1 -0
  52. package/dist/src/client/components/LocaleLabel/index.js +3 -0
  53. package/dist/src/client/components/LocaleLabel/index.js.map +1 -0
  54. package/dist/src/client/components/ResolverButton/ResolverButton.js +16 -0
  55. package/dist/src/client/components/ResolverButton/ResolverButton.js.map +1 -0
  56. package/dist/src/client/components/ResolverButton/index.js +3 -0
  57. package/dist/src/client/components/ResolverButton/index.js.map +1 -0
  58. package/dist/src/client/components/TranslatorModal/Content.js +60 -0
  59. package/dist/src/client/components/TranslatorModal/Content.js.map +1 -0
  60. package/dist/src/client/components/TranslatorModal/TranslatorModal.js +26 -0
  61. package/dist/src/client/components/TranslatorModal/TranslatorModal.js.map +1 -0
  62. package/dist/src/client/components/TranslatorModal/index.js +3 -0
  63. package/dist/src/client/components/TranslatorModal/index.js.map +1 -0
  64. package/dist/src/client/providers/Translator/TranslatorProvider.js +109 -0
  65. package/dist/src/client/providers/Translator/TranslatorProvider.js.map +1 -0
  66. package/dist/src/client/providers/Translator/context.js +9 -0
  67. package/dist/src/client/providers/Translator/context.js.map +1 -0
  68. package/dist/src/exports/client.js +3 -0
  69. package/dist/src/exports/client.js.map +1 -0
  70. package/dist/src/i18n-translations.js +88 -0
  71. package/dist/src/i18n-translations.js.map +1 -0
  72. package/dist/src/index.js +87 -0
  73. package/dist/src/index.js.map +1 -0
  74. package/dist/src/resolvers/copy.js +14 -0
  75. package/dist/src/resolvers/copy.js.map +1 -0
  76. package/dist/src/resolvers/google.js +47 -0
  77. package/dist/src/resolvers/google.js.map +1 -0
  78. package/dist/src/resolvers/libreTranslate.js +48 -0
  79. package/dist/src/resolvers/libreTranslate.js.map +1 -0
  80. package/dist/src/resolvers/openAI.js +100 -0
  81. package/dist/src/resolvers/openAI.js.map +1 -0
  82. package/dist/src/resolvers/types.js +3 -0
  83. package/dist/src/resolvers/types.js.map +1 -0
  84. package/dist/src/translate/endpoint.js +23 -0
  85. package/dist/src/translate/endpoint.js.map +1 -0
  86. package/dist/src/translate/findEntityWithConfig.js +34 -0
  87. package/dist/src/translate/findEntityWithConfig.js.map +1 -0
  88. package/dist/src/translate/operation.js +76 -0
  89. package/dist/src/translate/operation.js.map +1 -0
  90. package/dist/src/translate/traverseFields.js +190 -0
  91. package/dist/src/translate/traverseFields.js.map +1 -0
  92. package/dist/src/translate/traverseRichText.js +17 -0
  93. package/dist/src/translate/traverseRichText.js.map +1 -0
  94. package/dist/src/translate/types.js +3 -0
  95. package/dist/src/translate/types.js.map +1 -0
  96. package/dist/src/translate/updateEntity.js +26 -0
  97. package/dist/src/translate/updateEntity.js.map +1 -0
  98. package/dist/src/types.js +3 -0
  99. package/dist/src/types.js.map +1 -0
  100. package/dist/src/utils/chunkArray.js +7 -0
  101. package/dist/src/utils/chunkArray.js.map +1 -0
  102. package/dist/src/utils/isEmpty.js +8 -0
  103. package/dist/src/utils/isEmpty.js.map +1 -0
  104. package/dist/translate/endpoint.d.ts +3 -0
  105. package/dist/translate/endpoint.d.ts.map +1 -0
  106. package/dist/translate/findEntityWithConfig.d.ts +15 -0
  107. package/dist/translate/findEntityWithConfig.d.ts.map +1 -0
  108. package/dist/translate/operation.d.ts +9 -0
  109. package/dist/translate/operation.d.ts.map +1 -0
  110. package/dist/translate/traverseFields.d.ts +13 -0
  111. package/dist/translate/traverseFields.d.ts.map +1 -0
  112. package/dist/translate/traverseRichText.d.ts +6 -0
  113. package/dist/translate/traverseRichText.d.ts.map +1 -0
  114. package/dist/translate/types.d.ts +25 -0
  115. package/dist/translate/types.d.ts.map +1 -0
  116. package/dist/translate/updateEntity.d.ts +14 -0
  117. package/dist/translate/updateEntity.d.ts.map +1 -0
  118. package/dist/types.d.ts +21 -0
  119. package/dist/types.d.ts.map +1 -0
  120. package/dist/utils/chunkArray.d.ts +2 -0
  121. package/dist/utils/chunkArray.d.ts.map +1 -0
  122. package/dist/utils/isEmpty.d.ts +2 -0
  123. package/dist/utils/isEmpty.d.ts.map +1 -0
  124. package/package.json +89 -0
@@ -0,0 +1,87 @@
1
+ import { deepMerge } from 'payload/shared';
2
+ import { CustomButton } from './client/components/CustomButton';
3
+ import { translations } from './i18n-translations';
4
+ import { translateEndpoint } from './translate/endpoint';
5
+ import { translateOperation } from './translate/operation';
6
+ export { copyResolver } from './resolvers/copy';
7
+ export { googleResolver } from './resolvers/google';
8
+ export { libreResolver } from './resolvers/libreTranslate';
9
+ export { openAIResolver } from './resolvers/openAI';
10
+ export * from './resolvers/types';
11
+ export { translateOperation };
12
+ export const translator = (pluginConfig)=>{
13
+ return (config)=>{
14
+ if (pluginConfig.disabled || !config.localization || config.localization.locales.length < 2) return config;
15
+ const updatedConfig = {
16
+ ...config,
17
+ admin: {
18
+ ...config.admin ?? {},
19
+ custom: {
20
+ ...config.admin?.custom ?? {},
21
+ translator: {
22
+ resolvers: pluginConfig.resolvers.map(({ key })=>({
23
+ key
24
+ }))
25
+ }
26
+ }
27
+ },
28
+ collections: config.collections?.map((collection)=>{
29
+ if (!pluginConfig.collections.includes(collection.slug)) return collection;
30
+ return {
31
+ ...collection,
32
+ admin: {
33
+ ...collection.admin ?? {},
34
+ components: {
35
+ ...collection.admin?.components ?? {},
36
+ edit: {
37
+ ...collection.admin?.components?.edit ?? {},
38
+ PublishButton: CustomButton('publish'),
39
+ SaveButton: CustomButton('save')
40
+ }
41
+ }
42
+ }
43
+ };
44
+ }) ?? [],
45
+ custom: {
46
+ ...config.custom ?? {},
47
+ translator: {
48
+ resolvers: pluginConfig.resolvers
49
+ }
50
+ },
51
+ endpoints: [
52
+ ...config.endpoints ?? [],
53
+ {
54
+ handler: translateEndpoint,
55
+ method: 'post',
56
+ path: '/translator/translate'
57
+ }
58
+ ],
59
+ globals: config.globals?.map((global)=>{
60
+ if (!pluginConfig.globals.includes(global.slug)) return global;
61
+ return {
62
+ ...global,
63
+ admin: {
64
+ ...global.admin ?? {},
65
+ components: {
66
+ ...global.admin?.components ?? {},
67
+ elements: {
68
+ ...global.admin?.components?.elements ?? {},
69
+ PublishButton: CustomButton('publish'),
70
+ SaveButton: CustomButton('save')
71
+ }
72
+ }
73
+ }
74
+ };
75
+ }) ?? [],
76
+ i18n: {
77
+ ...config.i18n,
78
+ translations: {
79
+ ...deepMerge(config.i18n?.translations ?? {}, translations)
80
+ }
81
+ }
82
+ };
83
+ return updatedConfig;
84
+ };
85
+ };
86
+
87
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../../src/index.ts"],"sourcesContent":["import type { CollectionSlug, Config, GlobalSlug, Plugin } from 'payload'\nimport { deepMerge } from 'payload/shared'\n\nimport { CustomButton } from './client/components/CustomButton'\nimport { translations } from './i18n-translations'\nimport { translateEndpoint } from './translate/endpoint'\nimport { translateOperation } from './translate/operation'\nimport type { TranslatorConfig } from './types'\n\nexport { copyResolver } from './resolvers/copy'\n\nexport { googleResolver } from './resolvers/google'\n\nexport { libreResolver } from './resolvers/libreTranslate'\n\nexport { openAIResolver } from './resolvers/openAI'\nexport * from './resolvers/types'\n\nexport { translateOperation }\n\nexport const translator: (pluginConfig: TranslatorConfig) => Plugin = (pluginConfig) => {\n return (config) => {\n if (pluginConfig.disabled || !config.localization || config.localization.locales.length < 2)\n return config\n\n const updatedConfig: Config = {\n ...config,\n admin: {\n ...(config.admin ?? {}),\n custom: {\n ...(config.admin?.custom ?? {}),\n translator: {\n resolvers: pluginConfig.resolvers.map(({ key }) => ({ key })),\n },\n },\n },\n collections:\n config.collections?.map((collection) => {\n if (!pluginConfig.collections.includes(collection.slug as CollectionSlug))\n return collection\n\n return {\n ...collection,\n admin: {\n ...(collection.admin ?? {}),\n components: {\n ...(collection.admin?.components ?? {}),\n edit: {\n ...(collection.admin?.components?.edit ?? {}),\n PublishButton: CustomButton('publish'),\n SaveButton: CustomButton('save'),\n },\n },\n },\n }\n }) ?? [],\n custom: {\n ...(config.custom ?? {}),\n translator: {\n resolvers: pluginConfig.resolvers,\n },\n },\n endpoints: [\n ...(config.endpoints ?? []),\n {\n handler: translateEndpoint,\n method: 'post',\n path: '/translator/translate',\n },\n ],\n globals:\n config.globals?.map((global) => {\n if (!pluginConfig.globals.includes(global.slug as GlobalSlug)) return global\n\n return {\n ...global,\n admin: {\n ...(global.admin ?? {}),\n components: {\n ...(global.admin?.components ?? {}),\n elements: {\n ...(global.admin?.components?.elements ?? {}),\n PublishButton: CustomButton('publish'),\n SaveButton: CustomButton('save'),\n },\n },\n },\n }\n }) ?? [],\n i18n: {\n ...config.i18n,\n translations: {\n ...deepMerge(config.i18n?.translations ?? {}, translations),\n },\n },\n }\n\n return updatedConfig\n }\n}\n"],"names":["deepMerge","CustomButton","translations","translateEndpoint","translateOperation","copyResolver","googleResolver","libreResolver","openAIResolver","translator","pluginConfig","config","disabled","localization","locales","length","updatedConfig","admin","custom","resolvers","map","key","collections","collection","includes","slug","components","edit","PublishButton","SaveButton","endpoints","handler","method","path","globals","global","elements","i18n"],"mappings":"AACA,SAASA,SAAS,QAAQ,iBAAgB;AAE1C,SAASC,YAAY,QAAQ,mCAAkC;AAC/D,SAASC,YAAY,QAAQ,sBAAqB;AAClD,SAASC,iBAAiB,QAAQ,uBAAsB;AACxD,SAASC,kBAAkB,QAAQ,wBAAuB;AAG1D,SAASC,YAAY,QAAQ,mBAAkB;AAE/C,SAASC,cAAc,QAAQ,qBAAoB;AAEnD,SAASC,aAAa,QAAQ,6BAA4B;AAE1D,SAASC,cAAc,QAAQ,qBAAoB;AACnD,cAAc,oBAAmB;AAEjC,SAASJ,kBAAkB,GAAE;AAE7B,OAAO,MAAMK,aAAyD,CAACC;IACrE,OAAO,CAACC;QACN,IAAID,aAAaE,QAAQ,IAAI,CAACD,OAAOE,YAAY,IAAIF,OAAOE,YAAY,CAACC,OAAO,CAACC,MAAM,GAAG,GACxF,OAAOJ;QAET,MAAMK,gBAAwB;YAC5B,GAAGL,MAAM;YACTM,OAAO;gBACL,GAAIN,OAAOM,KAAK,IAAI,CAAC,CAAC;gBACtBC,QAAQ;oBACN,GAAIP,OAAOM,KAAK,EAAEC,UAAU,CAAC,CAAC;oBAC9BT,YAAY;wBACVU,WAAWT,aAAaS,SAAS,CAACC,GAAG,CAAC,CAAC,EAAEC,GAAG,EAAE,GAAM,CAAA;gCAAEA;4BAAI,CAAA;oBAC5D;gBACF;YACF;YACAC,aACEX,OAAOW,WAAW,EAAEF,IAAI,CAACG;gBACvB,IAAI,CAACb,aAAaY,WAAW,CAACE,QAAQ,CAACD,WAAWE,IAAI,GACpD,OAAOF;gBAET,OAAO;oBACL,GAAGA,UAAU;oBACbN,OAAO;wBACL,GAAIM,WAAWN,KAAK,IAAI,CAAC,CAAC;wBAC1BS,YAAY;4BACV,GAAIH,WAAWN,KAAK,EAAES,cAAc,CAAC,CAAC;4BACtCC,MAAM;gCACJ,GAAIJ,WAAWN,KAAK,EAAES,YAAYC,QAAQ,CAAC,CAAC;gCAC5CC,eAAe3B,aAAa;gCAC5B4B,YAAY5B,aAAa;4BAC3B;wBACF;oBACF;gBACF;YACF,MAAM,EAAE;YACViB,QAAQ;gBACN,GAAIP,OAAOO,MAAM,IAAI,CAAC,CAAC;gBACvBT,YAAY;oBACVU,WAAWT,aAAaS,SAAS;gBACnC;YACF;YACAW,WAAW;mBACLnB,OAAOmB,SAAS,IAAI,EAAE;gBAC1B;oBACEC,SAAS5B;oBACT6B,QAAQ;oBACRC,MAAM;gBACR;aACD;YACDC,SACEvB,OAAOuB,OAAO,EAAEd,IAAI,CAACe;gBACnB,IAAI,CAACzB,aAAawB,OAAO,CAACV,QAAQ,CAACW,OAAOV,IAAI,GAAiB,OAAOU;gBAEtE,OAAO;oBACL,GAAGA,MAAM;oBACTlB,OAAO;wBACL,GAAIkB,OAAOlB,KAAK,IAAI,CAAC,CAAC;wBACtBS,YAAY;4BACV,GAAIS,OAAOlB,KAAK,EAAES,cAAc,CAAC,CAAC;4BAClCU,UAAU;gCACR,GAAID,OAAOlB,KAAK,EAAES,YAAYU,YAAY,CAAC,CAAC;gCAC5CR,eAAe3B,aAAa;gCAC5B4B,YAAY5B,aAAa;4BAC3B;wBACF;oBACF;gBACF;YACF,MAAM,EAAE;YACVoC,MAAM;gBACJ,GAAG1B,OAAO0B,IAAI;gBACdnC,cAAc;oBACZ,GAAGF,UAAUW,OAAO0B,IAAI,EAAEnC,gBAAgB,CAAC,GAAGA,aAAa;gBAC7D;YACF;QACF;QAEA,OAAOc;IACT;AACF,EAAC"}
@@ -0,0 +1,14 @@
1
+ export const copyResolver = ()=>{
2
+ return {
3
+ key: 'copy',
4
+ resolve: (args)=>{
5
+ const { texts } = args;
6
+ return {
7
+ success: true,
8
+ translatedTexts: texts
9
+ };
10
+ }
11
+ };
12
+ };
13
+
14
+ //# sourceMappingURL=copy.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../../../src/resolvers/copy.ts"],"sourcesContent":["import type { TranslateResolver } from './types'\n\nexport const copyResolver = (): TranslateResolver => {\n return {\n key: 'copy',\n resolve: (args) => {\n const { texts } = args\n\n return {\n success: true,\n translatedTexts: texts,\n }\n },\n }\n}\n"],"names":["copyResolver","key","resolve","args","texts","success","translatedTexts"],"mappings":"AAEA,OAAO,MAAMA,eAAe;IAC1B,OAAO;QACLC,KAAK;QACLC,SAAS,CAACC;YACR,MAAM,EAAEC,KAAK,EAAE,GAAGD;YAElB,OAAO;gBACLE,SAAS;gBACTC,iBAAiBF;YACnB;QACF;IACF;AACF,EAAC"}
@@ -0,0 +1,47 @@
1
+ import { chunkArray } from '../utils/chunkArray';
2
+ const localeToCountryCodeMapper = {
3
+ ua: 'uk'
4
+ };
5
+ const mapLocale = (incoming)=>incoming in localeToCountryCodeMapper ? localeToCountryCodeMapper[incoming] : incoming;
6
+ export const googleResolver = ({ apiKey, chunkLength = 100 })=>{
7
+ return {
8
+ key: 'google',
9
+ resolve: async (args)=>{
10
+ const { localeFrom, localeTo, req, texts } = args;
11
+ const apiUrl = `https://translation.googleapis.com/language/translate/v2?key=${apiKey}`;
12
+ const responses = await Promise.all(chunkArray(texts, chunkLength).map((q)=>fetch(apiUrl, {
13
+ body: JSON.stringify({
14
+ q,
15
+ source: mapLocale(localeFrom),
16
+ target: mapLocale(localeTo)
17
+ }),
18
+ headers: {
19
+ 'Content-Type': 'application/json'
20
+ },
21
+ method: 'POST'
22
+ }).then(async (res)=>{
23
+ const data = await res.json();
24
+ if (!res.ok) req.payload.logger.info({
25
+ googleResponse: data,
26
+ message: 'An error occurred when trying to translate the data using Google API'
27
+ });
28
+ return {
29
+ data,
30
+ success: res.ok
31
+ };
32
+ })));
33
+ if (responses.some((res)=>!res.success)) {
34
+ return {
35
+ success: false
36
+ };
37
+ }
38
+ const translatedTexts = responses.flatMap((chunk)=>chunk.data.data.translations).map((translation)=>translation.translatedText);
39
+ return {
40
+ success: true,
41
+ translatedTexts
42
+ };
43
+ }
44
+ };
45
+ };
46
+
47
+ //# sourceMappingURL=google.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../../../src/resolvers/google.ts"],"sourcesContent":["import { chunkArray } from '../utils/chunkArray'\nimport type { TranslateResolver } from './types'\n\ntype GoogleResponse = {\n data: {\n data: {\n translations: {\n detectedSourceLanguage: string\n model: string\n translatedText: string\n }[]\n }\n }\n success: boolean\n}\n\nconst localeToCountryCodeMapper = {\n ua: 'uk',\n}\n\nconst mapLocale = (incoming: string) =>\n incoming in localeToCountryCodeMapper\n ? localeToCountryCodeMapper[incoming as keyof typeof localeToCountryCodeMapper]\n : incoming\n\nexport type GoogleResolverConfig = {\n apiKey: string\n /**\n * How many texts to include into 1 request\n * @default 100\n */\n chunkLength?: number\n}\n\nexport const googleResolver = ({\n apiKey,\n chunkLength = 100,\n}: GoogleResolverConfig): TranslateResolver => {\n return {\n key: 'google',\n resolve: async (args) => {\n const { localeFrom, localeTo, req, texts } = args\n\n const apiUrl = `https://translation.googleapis.com/language/translate/v2?key=${apiKey}`\n\n const responses: GoogleResponse[] = await Promise.all(\n chunkArray(texts, chunkLength).map((q) =>\n fetch(apiUrl, {\n body: JSON.stringify({\n q,\n source: mapLocale(localeFrom),\n target: mapLocale(localeTo),\n }),\n headers: {\n 'Content-Type': 'application/json',\n },\n method: 'POST',\n }).then(async (res) => {\n const data = await res.json()\n\n if (!res.ok)\n req.payload.logger.info({\n googleResponse: data,\n message: 'An error occurred when trying to translate the data using Google API',\n })\n\n return {\n data,\n success: res.ok,\n }\n }),\n ),\n )\n\n if (responses.some((res) => !res.success)) {\n return {\n success: false,\n }\n }\n\n const translatedTexts = responses\n .flatMap((chunk) => chunk.data.data.translations)\n .map((translation) => translation.translatedText)\n\n return {\n success: true,\n translatedTexts,\n }\n },\n }\n}\n"],"names":["chunkArray","localeToCountryCodeMapper","ua","mapLocale","incoming","googleResolver","apiKey","chunkLength","key","resolve","args","localeFrom","localeTo","req","texts","apiUrl","responses","Promise","all","map","q","fetch","body","JSON","stringify","source","target","headers","method","then","res","data","json","ok","payload","logger","info","googleResponse","message","success","some","translatedTexts","flatMap","chunk","translations","translation","translatedText"],"mappings":"AAAA,SAASA,UAAU,QAAQ,sBAAqB;AAgBhD,MAAMC,4BAA4B;IAChCC,IAAI;AACN;AAEA,MAAMC,YAAY,CAACC,WACjBA,YAAYH,4BACRA,yBAAyB,CAACG,SAAmD,GAC7EA;AAWN,OAAO,MAAMC,iBAAiB,CAAC,EAC7BC,MAAM,EACNC,cAAc,GAAG,EACI;IACrB,OAAO;QACLC,KAAK;QACLC,SAAS,OAAOC;YACd,MAAM,EAAEC,UAAU,EAAEC,QAAQ,EAAEC,GAAG,EAAEC,KAAK,EAAE,GAAGJ;YAE7C,MAAMK,SAAS,CAAC,6DAA6D,EAAET,QAAQ;YAEvF,MAAMU,YAA8B,MAAMC,QAAQC,GAAG,CACnDlB,WAAWc,OAAOP,aAAaY,GAAG,CAAC,CAACC,IAClCC,MAAMN,QAAQ;oBACZO,MAAMC,KAAKC,SAAS,CAAC;wBACnBJ;wBACAK,QAAQtB,UAAUQ;wBAClBe,QAAQvB,UAAUS;oBACpB;oBACAe,SAAS;wBACP,gBAAgB;oBAClB;oBACAC,QAAQ;gBACV,GAAGC,IAAI,CAAC,OAAOC;oBACb,MAAMC,OAAO,MAAMD,IAAIE,IAAI;oBAE3B,IAAI,CAACF,IAAIG,EAAE,EACTpB,IAAIqB,OAAO,CAACC,MAAM,CAACC,IAAI,CAAC;wBACtBC,gBAAgBN;wBAChBO,SAAS;oBACX;oBAEF,OAAO;wBACLP;wBACAQ,SAAST,IAAIG,EAAE;oBACjB;gBACF;YAIJ,IAAIjB,UAAUwB,IAAI,CAAC,CAACV,MAAQ,CAACA,IAAIS,OAAO,GAAG;gBACzC,OAAO;oBACLA,SAAS;gBACX;YACF;YAEA,MAAME,kBAAkBzB,UACrB0B,OAAO,CAAC,CAACC,QAAUA,MAAMZ,IAAI,CAACA,IAAI,CAACa,YAAY,EAC/CzB,GAAG,CAAC,CAAC0B,cAAgBA,YAAYC,cAAc;YAElD,OAAO;gBACLP,SAAS;gBACTE;YACF;QACF;IACF;AACF,EAAC"}
@@ -0,0 +1,48 @@
1
+ import { chunkArray } from '../utils/chunkArray';
2
+ const localeToCountryCodeMapper = {
3
+ ua: 'uk'
4
+ };
5
+ const mapLocale = (incoming)=>incoming in localeToCountryCodeMapper ? localeToCountryCodeMapper[incoming] : incoming;
6
+ export const libreResolver = ({ apiKey, chunkLength = 100, url = 'https://libretranslate.com/translate' })=>{
7
+ return {
8
+ key: 'libre',
9
+ resolve: async (args)=>{
10
+ const { localeFrom, localeTo, req, texts } = args;
11
+ const apiUrl = url;
12
+ const responses = await Promise.all(chunkArray(texts, chunkLength).map((q)=>fetch(apiUrl, {
13
+ body: JSON.stringify({
14
+ api_key: apiKey,
15
+ q,
16
+ source: mapLocale(localeFrom),
17
+ target: mapLocale(localeTo)
18
+ }),
19
+ headers: {
20
+ 'Content-Type': 'application/json'
21
+ },
22
+ method: 'POST'
23
+ }).then(async (res)=>{
24
+ const data = await res.json();
25
+ if (!res.ok) req.payload.logger.info({
26
+ libreResponse: data,
27
+ message: 'An error occurred when trying to translate the data using LibreTranslate API'
28
+ });
29
+ return {
30
+ data,
31
+ success: res.ok
32
+ };
33
+ })));
34
+ if (responses.some((res)=>!res.success)) {
35
+ return {
36
+ success: false
37
+ };
38
+ }
39
+ const translatedTexts = responses.flatMap((chunk)=>chunk.data.translatedText);
40
+ return {
41
+ success: true,
42
+ translatedTexts
43
+ };
44
+ }
45
+ };
46
+ };
47
+
48
+ //# sourceMappingURL=libreTranslate.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../../../src/resolvers/libreTranslate.ts"],"sourcesContent":["import { chunkArray } from '../utils/chunkArray'\nimport type { TranslateResolver } from './types'\n\ntype LibreResponse = {\n data: {\n translatedText: string[]\n }\n success: boolean\n}\n\nconst localeToCountryCodeMapper = {\n ua: 'uk',\n}\n\nconst mapLocale = (incoming: string) =>\n incoming in localeToCountryCodeMapper\n ? localeToCountryCodeMapper[incoming as keyof typeof localeToCountryCodeMapper]\n : incoming\n\nexport type LibreResolverConfig = {\n apiKey: string\n /**\n * How many texts to include into 1 request\n * @default 100\n */\n chunkLength?: number\n /**\n * Custom url for the libre translate instance\n * @default \"https://libretranslate.com/translate\"\n */\n url?: string\n}\n\nexport const libreResolver = ({\n apiKey,\n chunkLength = 100,\n url = 'https://libretranslate.com/translate',\n}: LibreResolverConfig): TranslateResolver => {\n return {\n key: 'libre',\n resolve: async (args) => {\n const { localeFrom, localeTo, req, texts } = args\n\n const apiUrl = url\n\n const responses: LibreResponse[] = await Promise.all(\n chunkArray(texts, chunkLength).map((q) =>\n fetch(apiUrl, {\n body: JSON.stringify({\n api_key: apiKey,\n q,\n source: mapLocale(localeFrom),\n target: mapLocale(localeTo),\n }),\n headers: {\n 'Content-Type': 'application/json',\n },\n method: 'POST',\n }).then(async (res) => {\n const data = await res.json()\n\n if (!res.ok)\n req.payload.logger.info({\n libreResponse: data,\n message:\n 'An error occurred when trying to translate the data using LibreTranslate API',\n })\n\n return {\n data,\n success: res.ok,\n }\n }),\n ),\n )\n\n if (responses.some((res) => !res.success)) {\n return {\n success: false,\n }\n }\n\n const translatedTexts = responses.flatMap((chunk) => chunk.data.translatedText)\n\n return {\n success: true,\n translatedTexts,\n }\n },\n }\n}\n"],"names":["chunkArray","localeToCountryCodeMapper","ua","mapLocale","incoming","libreResolver","apiKey","chunkLength","url","key","resolve","args","localeFrom","localeTo","req","texts","apiUrl","responses","Promise","all","map","q","fetch","body","JSON","stringify","api_key","source","target","headers","method","then","res","data","json","ok","payload","logger","info","libreResponse","message","success","some","translatedTexts","flatMap","chunk","translatedText"],"mappings":"AAAA,SAASA,UAAU,QAAQ,sBAAqB;AAUhD,MAAMC,4BAA4B;IAChCC,IAAI;AACN;AAEA,MAAMC,YAAY,CAACC,WACjBA,YAAYH,4BACRA,yBAAyB,CAACG,SAAmD,GAC7EA;AAgBN,OAAO,MAAMC,gBAAgB,CAAC,EAC5BC,MAAM,EACNC,cAAc,GAAG,EACjBC,MAAM,sCAAsC,EACxB;IACpB,OAAO;QACLC,KAAK;QACLC,SAAS,OAAOC;YACd,MAAM,EAAEC,UAAU,EAAEC,QAAQ,EAAEC,GAAG,EAAEC,KAAK,EAAE,GAAGJ;YAE7C,MAAMK,SAASR;YAEf,MAAMS,YAA6B,MAAMC,QAAQC,GAAG,CAClDnB,WAAWe,OAAOR,aAAaa,GAAG,CAAC,CAACC,IAClCC,MAAMN,QAAQ;oBACZO,MAAMC,KAAKC,SAAS,CAAC;wBACnBC,SAASpB;wBACTe;wBACAM,QAAQxB,UAAUS;wBAClBgB,QAAQzB,UAAUU;oBACpB;oBACAgB,SAAS;wBACP,gBAAgB;oBAClB;oBACAC,QAAQ;gBACV,GAAGC,IAAI,CAAC,OAAOC;oBACb,MAAMC,OAAO,MAAMD,IAAIE,IAAI;oBAE3B,IAAI,CAACF,IAAIG,EAAE,EACTrB,IAAIsB,OAAO,CAACC,MAAM,CAACC,IAAI,CAAC;wBACtBC,eAAeN;wBACfO,SACE;oBACJ;oBAEF,OAAO;wBACLP;wBACAQ,SAAST,IAAIG,EAAE;oBACjB;gBACF;YAIJ,IAAIlB,UAAUyB,IAAI,CAAC,CAACV,MAAQ,CAACA,IAAIS,OAAO,GAAG;gBACzC,OAAO;oBACLA,SAAS;gBACX;YACF;YAEA,MAAME,kBAAkB1B,UAAU2B,OAAO,CAAC,CAACC,QAAUA,MAAMZ,IAAI,CAACa,cAAc;YAE9E,OAAO;gBACLL,SAAS;gBACTE;YACF;QACF;IACF;AACF,EAAC"}
@@ -0,0 +1,100 @@
1
+ import { chunkArray } from '../utils/chunkArray';
2
+ const defaultPrompt = ({ localeFrom, localeTo, texts })=>{
3
+ return `Translate me the following array: ${JSON.stringify(texts)} in locale=${localeFrom} to locale ${localeTo}, respond me with the same array structure`;
4
+ };
5
+ export const openAIResolver = ({ apiKey, baseUrl, chunkLength = 100, model = 'gpt-3.5-turbo', prompt = defaultPrompt })=>{
6
+ return {
7
+ key: 'openai',
8
+ resolve: async ({ localeFrom, localeTo, req, texts })=>{
9
+ const apiUrl = `${baseUrl || 'https://api.openai.com'}/v1/chat/completions`;
10
+ try {
11
+ const response = await Promise.all(chunkArray(texts, chunkLength).map((texts)=>{
12
+ return fetch(apiUrl, {
13
+ body: JSON.stringify({
14
+ messages: [
15
+ {
16
+ content: prompt({
17
+ localeFrom,
18
+ localeTo,
19
+ texts
20
+ }),
21
+ role: 'user'
22
+ }
23
+ ],
24
+ model
25
+ }),
26
+ headers: {
27
+ Authorization: `Bearer ${apiKey}`,
28
+ 'Content-Type': 'application/json'
29
+ },
30
+ method: 'post'
31
+ }).then(async (res)=>{
32
+ const data = await res.json();
33
+ if (!res.ok) req.payload.logger.info({
34
+ message: 'An error occurred when trying to translate the data using OpenAI API',
35
+ openAIresponse: data
36
+ });
37
+ return {
38
+ data,
39
+ success: res.ok
40
+ };
41
+ });
42
+ }));
43
+ const translated = [];
44
+ for (const { data, success } of response){
45
+ if (!success) return {
46
+ success: false
47
+ };
48
+ const content = data?.choices?.[0]?.message?.content;
49
+ if (!content) {
50
+ req.payload.logger.error('An error occurred when trying to translate the data using OpenAI API - missing content in the response');
51
+ return {
52
+ success: false
53
+ };
54
+ }
55
+ const translatedChunk = JSON.parse(content);
56
+ if (!Array.isArray(translatedChunk)) {
57
+ req.payload.logger.error({
58
+ data: translatedChunk,
59
+ fullContent: content,
60
+ message: 'An error occurred when trying to translate the data using OpenAI API - parsed content is not an array'
61
+ });
62
+ return {
63
+ success: false
64
+ };
65
+ }
66
+ for (const text of translatedChunk){
67
+ if (text && typeof text !== 'string') {
68
+ req.payload.logger.error({
69
+ chunkData: translatedChunk,
70
+ data: text,
71
+ fullContent: content,
72
+ message: 'An error occurred when trying to translate the data using OpenAI API - parsed content is not a string'
73
+ });
74
+ return {
75
+ success: false
76
+ };
77
+ }
78
+ translated.push(text);
79
+ }
80
+ }
81
+ return {
82
+ success: true,
83
+ translatedTexts: translated
84
+ };
85
+ } catch (e) {
86
+ if (e instanceof Error) {
87
+ req.payload.logger.info({
88
+ message: 'An error occurred when trying to translate the data using OpenAI API',
89
+ originalErr: e.message
90
+ });
91
+ }
92
+ return {
93
+ success: false
94
+ };
95
+ }
96
+ }
97
+ };
98
+ };
99
+
100
+ //# sourceMappingURL=openAI.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../../../src/resolvers/openAI.ts"],"sourcesContent":["import { chunkArray } from '../utils/chunkArray'\nimport type { TranslateResolver } from './types'\n\nexport type OpenAIPrompt = (args: {\n localeFrom: string\n localeTo: string\n texts: string[]\n}) => string\n\nexport type OpenAIResolverConfig = {\n apiKey: string\n baseUrl?: string\n /**\n * How many texts to include into 1 request\n * @default 100\n */\n chunkLength?: number\n /**\n * @default \"gpt-3.5-turbo\"\n */\n model?: string\n prompt?: OpenAIPrompt\n}\n\ntype OpenAIResponse = {\n choices: {\n message: {\n content: string\n }\n }[]\n}\n\nconst defaultPrompt: OpenAIPrompt = ({ localeFrom, localeTo, texts }) => {\n return `Translate me the following array: ${JSON.stringify(texts)} in locale=${localeFrom} to locale ${localeTo}, respond me with the same array structure`\n}\n\nexport const openAIResolver = ({\n apiKey,\n baseUrl,\n chunkLength = 100,\n model = 'gpt-3.5-turbo',\n prompt = defaultPrompt,\n}: OpenAIResolverConfig): TranslateResolver => {\n return {\n key: 'openai',\n resolve: async ({ localeFrom, localeTo, req, texts }) => {\n const apiUrl = `${baseUrl || 'https://api.openai.com'}/v1/chat/completions`\n\n try {\n const response: {\n data: OpenAIResponse\n success: boolean\n }[] = await Promise.all(\n chunkArray(texts, chunkLength).map((texts) => {\n return fetch(apiUrl, {\n body: JSON.stringify({\n messages: [\n {\n content: prompt({ localeFrom, localeTo, texts }),\n role: 'user',\n },\n ],\n model,\n }),\n headers: {\n Authorization: `Bearer ${apiKey}`,\n 'Content-Type': 'application/json',\n },\n method: 'post',\n }).then(async (res) => {\n const data = await res.json()\n\n if (!res.ok)\n req.payload.logger.info({\n message: 'An error occurred when trying to translate the data using OpenAI API',\n openAIresponse: data,\n })\n\n return {\n data,\n success: res.ok,\n }\n })\n }),\n )\n\n const translated: string[] = []\n\n for (const { data, success } of response) {\n if (!success)\n return {\n success: false as const,\n }\n\n const content = data?.choices?.[0]?.message?.content\n\n if (!content) {\n req.payload.logger.error(\n 'An error occurred when trying to translate the data using OpenAI API - missing content in the response',\n )\n\n return {\n success: false as const,\n }\n }\n\n const translatedChunk: string[] = JSON.parse(content)\n\n if (!Array.isArray(translatedChunk)) {\n req.payload.logger.error({\n data: translatedChunk,\n fullContent: content,\n message:\n 'An error occurred when trying to translate the data using OpenAI API - parsed content is not an array',\n })\n\n return {\n success: false as const,\n }\n }\n\n for (const text of translatedChunk) {\n if (text && typeof text !== 'string') {\n req.payload.logger.error({\n chunkData: translatedChunk,\n data: text,\n fullContent: content,\n message:\n 'An error occurred when trying to translate the data using OpenAI API - parsed content is not a string',\n })\n\n return {\n success: false as const,\n }\n }\n\n translated.push(text)\n }\n }\n\n return {\n success: true as const,\n translatedTexts: translated,\n }\n } catch (e) {\n if (e instanceof Error) {\n req.payload.logger.info({\n message: 'An error occurred when trying to translate the data using OpenAI API',\n originalErr: e.message,\n })\n }\n\n return { success: false as const }\n }\n },\n }\n}\n"],"names":["chunkArray","defaultPrompt","localeFrom","localeTo","texts","JSON","stringify","openAIResolver","apiKey","baseUrl","chunkLength","model","prompt","key","resolve","req","apiUrl","response","Promise","all","map","fetch","body","messages","content","role","headers","Authorization","method","then","res","data","json","ok","payload","logger","info","message","openAIresponse","success","translated","choices","error","translatedChunk","parse","Array","isArray","fullContent","text","chunkData","push","translatedTexts","e","Error","originalErr"],"mappings":"AAAA,SAASA,UAAU,QAAQ,sBAAqB;AAgChD,MAAMC,gBAA8B,CAAC,EAAEC,UAAU,EAAEC,QAAQ,EAAEC,KAAK,EAAE;IAClE,OAAO,CAAC,kCAAkC,EAAEC,KAAKC,SAAS,CAACF,OAAO,WAAW,EAAEF,WAAW,WAAW,EAAEC,SAAS,0CAA0C,CAAC;AAC7J;AAEA,OAAO,MAAMI,iBAAiB,CAAC,EAC7BC,MAAM,EACNC,OAAO,EACPC,cAAc,GAAG,EACjBC,QAAQ,eAAe,EACvBC,SAASX,aAAa,EACD;IACrB,OAAO;QACLY,KAAK;QACLC,SAAS,OAAO,EAAEZ,UAAU,EAAEC,QAAQ,EAAEY,GAAG,EAAEX,KAAK,EAAE;YAClD,MAAMY,SAAS,GAAGP,WAAW,yBAAyB,oBAAoB,CAAC;YAE3E,IAAI;gBACF,MAAMQ,WAGA,MAAMC,QAAQC,GAAG,CACrBnB,WAAWI,OAAOM,aAAaU,GAAG,CAAC,CAAChB;oBAClC,OAAOiB,MAAML,QAAQ;wBACnBM,MAAMjB,KAAKC,SAAS,CAAC;4BACnBiB,UAAU;gCACR;oCACEC,SAASZ,OAAO;wCAAEV;wCAAYC;wCAAUC;oCAAM;oCAC9CqB,MAAM;gCACR;6BACD;4BACDd;wBACF;wBACAe,SAAS;4BACPC,eAAe,CAAC,OAAO,EAAEnB,QAAQ;4BACjC,gBAAgB;wBAClB;wBACAoB,QAAQ;oBACV,GAAGC,IAAI,CAAC,OAAOC;wBACb,MAAMC,OAAO,MAAMD,IAAIE,IAAI;wBAE3B,IAAI,CAACF,IAAIG,EAAE,EACTlB,IAAImB,OAAO,CAACC,MAAM,CAACC,IAAI,CAAC;4BACtBC,SAAS;4BACTC,gBAAgBP;wBAClB;wBAEF,OAAO;4BACLA;4BACAQ,SAAST,IAAIG,EAAE;wBACjB;oBACF;gBACF;gBAGF,MAAMO,aAAuB,EAAE;gBAE/B,KAAK,MAAM,EAAET,IAAI,EAAEQ,OAAO,EAAE,IAAItB,SAAU;oBACxC,IAAI,CAACsB,SACH,OAAO;wBACLA,SAAS;oBACX;oBAEF,MAAMf,UAAUO,MAAMU,SAAS,CAAC,EAAE,EAAEJ,SAASb;oBAE7C,IAAI,CAACA,SAAS;wBACZT,IAAImB,OAAO,CAACC,MAAM,CAACO,KAAK,CACtB;wBAGF,OAAO;4BACLH,SAAS;wBACX;oBACF;oBAEA,MAAMI,kBAA4BtC,KAAKuC,KAAK,CAACpB;oBAE7C,IAAI,CAACqB,MAAMC,OAAO,CAACH,kBAAkB;wBACnC5B,IAAImB,OAAO,CAACC,MAAM,CAACO,KAAK,CAAC;4BACvBX,MAAMY;4BACNI,aAAavB;4BACba,SACE;wBACJ;wBAEA,OAAO;4BACLE,SAAS;wBACX;oBACF;oBAEA,KAAK,MAAMS,QAAQL,gBAAiB;wBAClC,IAAIK,QAAQ,OAAOA,SAAS,UAAU;4BACpCjC,IAAImB,OAAO,CAACC,MAAM,CAACO,KAAK,CAAC;gCACvBO,WAAWN;gCACXZ,MAAMiB;gCACND,aAAavB;gCACba,SACE;4BACJ;4BAEA,OAAO;gCACLE,SAAS;4BACX;wBACF;wBAEAC,WAAWU,IAAI,CAACF;oBAClB;gBACF;gBAEA,OAAO;oBACLT,SAAS;oBACTY,iBAAiBX;gBACnB;YACF,EAAE,OAAOY,GAAG;gBACV,IAAIA,aAAaC,OAAO;oBACtBtC,IAAImB,OAAO,CAACC,MAAM,CAACC,IAAI,CAAC;wBACtBC,SAAS;wBACTiB,aAAaF,EAAEf,OAAO;oBACxB;gBACF;gBAEA,OAAO;oBAAEE,SAAS;gBAAe;YACnC;QACF;IACF;AACF,EAAC"}
@@ -0,0 +1,3 @@
1
+ export { };
2
+
3
+ //# sourceMappingURL=types.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../../../src/resolvers/types.ts"],"sourcesContent":["import type { PayloadRequest } from 'payload'\n\nexport type TranslateResolverArgs = {\n /** Locale to translate from */\n localeFrom: string\n /** Locale to translate to */\n localeTo: string\n req: PayloadRequest\n texts: string[]\n}\n\nexport type TranslateResolverResponse =\n | {\n success: false\n }\n | {\n success: true\n translatedTexts: string[]\n }\n\nexport type TranslateResolver = {\n key: string\n resolve: (\n args: TranslateResolverArgs,\n ) => Promise<TranslateResolverResponse> | TranslateResolverResponse\n}\n"],"names":[],"mappings":"AAoBA,WAKC"}
@@ -0,0 +1,23 @@
1
+ import { APIError } from 'payload';
2
+ import { translateOperation } from './operation';
3
+ export const translateEndpoint = async (req)=>{
4
+ if (!req.json) throw new APIError('Content-Type should be json');
5
+ const args = await req.json();
6
+ const { collectionSlug, data, emptyOnly, globalSlug, id, locale, localeFrom, resolver } = args;
7
+ const result = await translateOperation({
8
+ collectionSlug,
9
+ data,
10
+ emptyOnly,
11
+ globalSlug,
12
+ id,
13
+ locale,
14
+ localeFrom,
15
+ overrideAccess: false,
16
+ req,
17
+ resolver,
18
+ update: false
19
+ });
20
+ return Response.json(result);
21
+ };
22
+
23
+ //# sourceMappingURL=endpoint.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../../../src/translate/endpoint.ts"],"sourcesContent":["import type { PayloadHandler } from 'payload'\nimport { APIError } from 'payload'\n\nimport { translateOperation } from './operation'\nimport type { TranslateEndpointArgs } from './types'\n\nexport const translateEndpoint: PayloadHandler = async (req) => {\n if (!req.json) throw new APIError('Content-Type should be json')\n\n const args: TranslateEndpointArgs = await req.json()\n\n const { collectionSlug, data, emptyOnly, globalSlug, id, locale, localeFrom, resolver } = args\n\n const result = await translateOperation({\n collectionSlug,\n data,\n emptyOnly,\n globalSlug,\n id,\n locale,\n localeFrom,\n overrideAccess: false,\n req,\n resolver,\n update: false,\n })\n\n return Response.json(result)\n}\n"],"names":["APIError","translateOperation","translateEndpoint","req","json","args","collectionSlug","data","emptyOnly","globalSlug","id","locale","localeFrom","resolver","result","overrideAccess","update","Response"],"mappings":"AACA,SAASA,QAAQ,QAAQ,UAAS;AAElC,SAASC,kBAAkB,QAAQ,cAAa;AAGhD,OAAO,MAAMC,oBAAoC,OAAOC;IACtD,IAAI,CAACA,IAAIC,IAAI,EAAE,MAAM,IAAIJ,SAAS;IAElC,MAAMK,OAA8B,MAAMF,IAAIC,IAAI;IAElD,MAAM,EAAEE,cAAc,EAAEC,IAAI,EAAEC,SAAS,EAAEC,UAAU,EAAEC,EAAE,EAAEC,MAAM,EAAEC,UAAU,EAAEC,QAAQ,EAAE,GAAGR;IAE1F,MAAMS,SAAS,MAAMb,mBAAmB;QACtCK;QACAC;QACAC;QACAC;QACAC;QACAC;QACAC;QACAG,gBAAgB;QAChBZ;QACAU;QACAG,QAAQ;IACV;IAEA,OAAOC,SAASb,IAAI,CAACU;AACvB,EAAC"}
@@ -0,0 +1,34 @@
1
+ import { APIError } from 'payload';
2
+ const findConfigBySlug = (slug, enities)=>enities.find((entity)=>entity.slug === slug);
3
+ export const findEntityWithConfig = async (args)=>{
4
+ const { collectionSlug, globalSlug, id, locale, overrideAccess, req } = args;
5
+ if (!collectionSlug && !globalSlug) throw new APIError('Bad Request', 400);
6
+ const { payload } = req;
7
+ const { config } = payload;
8
+ const isGlobal = !!globalSlug;
9
+ if (!isGlobal && !id) throw new APIError('Bad Request', 400);
10
+ const entityConfig = isGlobal ? findConfigBySlug(globalSlug, config.globals) : findConfigBySlug(collectionSlug, config.collections);
11
+ if (!entityConfig) throw new APIError('Bad Request', 400);
12
+ const docPromise = isGlobal ? payload.findGlobal({
13
+ depth: 0,
14
+ fallbackLocale: undefined,
15
+ locale: locale,
16
+ overrideAccess,
17
+ req,
18
+ slug: args.globalSlug
19
+ }) : payload.findByID({
20
+ collection: collectionSlug,
21
+ depth: 0,
22
+ fallbackLocale: undefined,
23
+ id: id,
24
+ locale: locale,
25
+ overrideAccess,
26
+ req
27
+ });
28
+ return {
29
+ config: entityConfig,
30
+ doc: await docPromise
31
+ };
32
+ };
33
+
34
+ //# sourceMappingURL=findEntityWithConfig.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../../../src/translate/findEntityWithConfig.ts"],"sourcesContent":["import type {\n CollectionSlug,\n GlobalSlug,\n PayloadRequest,\n SanitizedCollectionConfig,\n SanitizedGlobalConfig,\n TypeWithID,\n} from 'payload'\nimport { APIError } from 'payload'\n\ntype Args = {\n collectionSlug?: string\n globalSlug?: string\n id?: number | string\n locale: string\n overrideAccess?: boolean\n req: PayloadRequest\n}\n\nconst findConfigBySlug = (\n slug: string,\n enities: SanitizedCollectionConfig[] | SanitizedGlobalConfig[],\n) => enities.find((entity) => entity.slug === slug)\n\nexport const findEntityWithConfig = async (\n args: Args,\n): Promise<{\n config: SanitizedCollectionConfig | SanitizedGlobalConfig\n doc: Record<string, unknown> & TypeWithID\n}> => {\n const { collectionSlug, globalSlug, id, locale, overrideAccess, req } = args\n\n if (!collectionSlug && !globalSlug) throw new APIError('Bad Request', 400)\n\n const { payload } = req\n\n const { config } = payload\n\n const isGlobal = !!globalSlug\n\n if (!isGlobal && !id) throw new APIError('Bad Request', 400)\n\n const entityConfig = isGlobal\n ? findConfigBySlug(globalSlug, config.globals)\n : findConfigBySlug(collectionSlug as string, config.collections)\n\n if (!entityConfig) throw new APIError('Bad Request', 400)\n\n const docPromise = isGlobal\n ? payload.findGlobal({\n depth: 0,\n fallbackLocale: undefined,\n locale: locale as any,\n overrideAccess,\n req,\n slug: args.globalSlug as GlobalSlug,\n })\n : payload.findByID({\n collection: collectionSlug as CollectionSlug,\n depth: 0,\n fallbackLocale: undefined,\n id: id as number | string,\n locale: locale as any,\n overrideAccess,\n req,\n })\n\n return {\n config: entityConfig,\n doc: (await docPromise) as any,\n }\n}\n"],"names":["APIError","findConfigBySlug","slug","enities","find","entity","findEntityWithConfig","args","collectionSlug","globalSlug","id","locale","overrideAccess","req","payload","config","isGlobal","entityConfig","globals","collections","docPromise","findGlobal","depth","fallbackLocale","undefined","findByID","collection","doc"],"mappings":"AAQA,SAASA,QAAQ,QAAQ,UAAS;AAWlC,MAAMC,mBAAmB,CACvBC,MACAC,UACGA,QAAQC,IAAI,CAAC,CAACC,SAAWA,OAAOH,IAAI,KAAKA;AAE9C,OAAO,MAAMI,uBAAuB,OAClCC;IAKA,MAAM,EAAEC,cAAc,EAAEC,UAAU,EAAEC,EAAE,EAAEC,MAAM,EAAEC,cAAc,EAAEC,GAAG,EAAE,GAAGN;IAExE,IAAI,CAACC,kBAAkB,CAACC,YAAY,MAAM,IAAIT,SAAS,eAAe;IAEtE,MAAM,EAAEc,OAAO,EAAE,GAAGD;IAEpB,MAAM,EAAEE,MAAM,EAAE,GAAGD;IAEnB,MAAME,WAAW,CAAC,CAACP;IAEnB,IAAI,CAACO,YAAY,CAACN,IAAI,MAAM,IAAIV,SAAS,eAAe;IAExD,MAAMiB,eAAeD,WACjBf,iBAAiBQ,YAAYM,OAAOG,OAAO,IAC3CjB,iBAAiBO,gBAA0BO,OAAOI,WAAW;IAEjE,IAAI,CAACF,cAAc,MAAM,IAAIjB,SAAS,eAAe;IAErD,MAAMoB,aAAaJ,WACfF,QAAQO,UAAU,CAAC;QACjBC,OAAO;QACPC,gBAAgBC;QAChBb,QAAQA;QACRC;QACAC;QACAX,MAAMK,KAAKE,UAAU;IACvB,KACAK,QAAQW,QAAQ,CAAC;QACfC,YAAYlB;QACZc,OAAO;QACPC,gBAAgBC;QAChBd,IAAIA;QACJC,QAAQA;QACRC;QACAC;IACF;IAEJ,OAAO;QACLE,QAAQE;QACRU,KAAM,MAAMP;IACd;AACF,EAAC"}
@@ -0,0 +1,76 @@
1
+ import he from 'he';
2
+ import { APIError } from 'payload';
3
+ import { findEntityWithConfig } from './findEntityWithConfig';
4
+ import { traverseFields } from './traverseFields';
5
+ import { updateEntity } from './updateEntity';
6
+ export const translateOperation = async (args)=>{
7
+ const req = 'req' in args ? args.req : {
8
+ payload: args.payload
9
+ };
10
+ const { collectionSlug, globalSlug, id, locale, localeFrom, overrideAccess } = args;
11
+ const { config, doc: dataFrom } = await findEntityWithConfig({
12
+ collectionSlug,
13
+ globalSlug,
14
+ id,
15
+ locale: localeFrom,
16
+ req
17
+ });
18
+ const resolver = (req.payload.config.custom?.translator?.resolvers ?? []).find((each)=>each.key === args.resolver);
19
+ if (!resolver) throw new APIError(`Resolver with the key ${args.resolver} was not found`);
20
+ const valuesToTranslate = [];
21
+ let translatedData = args.data;
22
+ if (!translatedData) {
23
+ const { doc } = await findEntityWithConfig({
24
+ collectionSlug,
25
+ globalSlug,
26
+ id,
27
+ locale,
28
+ overrideAccess,
29
+ req
30
+ });
31
+ translatedData = doc;
32
+ }
33
+ traverseFields({
34
+ dataFrom,
35
+ emptyOnly: args.emptyOnly,
36
+ fields: config.fields,
37
+ translatedData,
38
+ valuesToTranslate
39
+ });
40
+ const resolveResult = await resolver.resolve({
41
+ localeFrom: args.localeFrom,
42
+ localeTo: args.locale,
43
+ req,
44
+ texts: valuesToTranslate.map((each)=>each.value)
45
+ });
46
+ let result;
47
+ if (!resolveResult.success) {
48
+ result = {
49
+ success: false
50
+ };
51
+ } else {
52
+ resolveResult.translatedTexts.forEach((translated, index)=>{
53
+ const formattedValue = he.decode(translated);
54
+ valuesToTranslate[index].onTranslate(formattedValue);
55
+ });
56
+ if (args.update) {
57
+ await updateEntity({
58
+ collectionSlug,
59
+ data: translatedData,
60
+ depth: 0,
61
+ globalSlug,
62
+ id,
63
+ locale,
64
+ overrideAccess,
65
+ req
66
+ });
67
+ }
68
+ result = {
69
+ success: true,
70
+ translatedData
71
+ };
72
+ }
73
+ return result;
74
+ };
75
+
76
+ //# sourceMappingURL=operation.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../../../src/translate/operation.ts"],"sourcesContent":["import he from 'he'\nimport { APIError, type Payload, type PayloadRequest } from 'payload'\n\nimport type { TranslateResolver } from '../resolvers/types'\nimport { findEntityWithConfig } from './findEntityWithConfig'\nimport { traverseFields } from './traverseFields'\nimport type { TranslateArgs, TranslateResult, ValueToTranslate } from './types'\nimport { updateEntity } from './updateEntity'\n\nexport type TranslateOperationArgs = (\n | {\n payload: Payload\n }\n | {\n req: PayloadRequest\n }\n) &\n TranslateArgs\n\nexport const translateOperation = async (args: TranslateOperationArgs) => {\n const req: PayloadRequest =\n 'req' in args\n ? args.req\n : ({\n payload: args.payload,\n } as PayloadRequest)\n\n const { collectionSlug, globalSlug, id, locale, localeFrom, overrideAccess } = args\n\n const { config, doc: dataFrom } = await findEntityWithConfig({\n collectionSlug,\n globalSlug,\n id,\n locale: localeFrom,\n req,\n })\n\n const resolver = (\n (req.payload.config.custom?.translator?.resolvers as TranslateResolver[]) ?? []\n ).find((each) => each.key === args.resolver)\n\n if (!resolver) throw new APIError(`Resolver with the key ${args.resolver} was not found`)\n\n const valuesToTranslate: ValueToTranslate[] = []\n\n let translatedData = args.data\n\n if (!translatedData) {\n const { doc } = await findEntityWithConfig({\n collectionSlug,\n globalSlug,\n id,\n locale,\n overrideAccess,\n req,\n })\n\n translatedData = doc\n }\n\n traverseFields({\n dataFrom,\n emptyOnly: args.emptyOnly,\n fields: config.fields,\n translatedData,\n valuesToTranslate,\n })\n\n const resolveResult = await resolver.resolve({\n localeFrom: args.localeFrom,\n localeTo: args.locale,\n req,\n texts: valuesToTranslate.map((each) => each.value),\n })\n\n let result: TranslateResult\n\n if (!resolveResult.success) {\n result = {\n success: false,\n }\n } else {\n resolveResult.translatedTexts.forEach((translated, index) => {\n const formattedValue = he.decode(translated)\n\n valuesToTranslate[index].onTranslate(formattedValue)\n })\n\n if (args.update) {\n await updateEntity({\n collectionSlug,\n data: translatedData,\n depth: 0,\n globalSlug,\n id,\n locale,\n overrideAccess,\n req,\n })\n }\n\n result = {\n success: true,\n translatedData,\n }\n }\n\n return result\n}\n"],"names":["he","APIError","findEntityWithConfig","traverseFields","updateEntity","translateOperation","args","req","payload","collectionSlug","globalSlug","id","locale","localeFrom","overrideAccess","config","doc","dataFrom","resolver","custom","translator","resolvers","find","each","key","valuesToTranslate","translatedData","data","emptyOnly","fields","resolveResult","resolve","localeTo","texts","map","value","result","success","translatedTexts","forEach","translated","index","formattedValue","decode","onTranslate","update","depth"],"mappings":"AAAA,OAAOA,QAAQ,KAAI;AACnB,SAASC,QAAQ,QAA2C,UAAS;AAGrE,SAASC,oBAAoB,QAAQ,yBAAwB;AAC7D,SAASC,cAAc,QAAQ,mBAAkB;AAEjD,SAASC,YAAY,QAAQ,iBAAgB;AAY7C,OAAO,MAAMC,qBAAqB,OAAOC;IACvC,MAAMC,MACJ,SAASD,OACLA,KAAKC,GAAG,GACP;QACCC,SAASF,KAAKE,OAAO;IACvB;IAEN,MAAM,EAAEC,cAAc,EAAEC,UAAU,EAAEC,EAAE,EAAEC,MAAM,EAAEC,UAAU,EAAEC,cAAc,EAAE,GAAGR;IAE/E,MAAM,EAAES,MAAM,EAAEC,KAAKC,QAAQ,EAAE,GAAG,MAAMf,qBAAqB;QAC3DO;QACAC;QACAC;QACAC,QAAQC;QACRN;IACF;IAEA,MAAMW,WAAW,AACf,CAAA,AAACX,IAAIC,OAAO,CAACO,MAAM,CAACI,MAAM,EAAEC,YAAYC,aAAqC,EAAE,AAAD,EAC9EC,IAAI,CAAC,CAACC,OAASA,KAAKC,GAAG,KAAKlB,KAAKY,QAAQ;IAE3C,IAAI,CAACA,UAAU,MAAM,IAAIjB,SAAS,CAAC,sBAAsB,EAAEK,KAAKY,QAAQ,CAAC,cAAc,CAAC;IAExF,MAAMO,oBAAwC,EAAE;IAEhD,IAAIC,iBAAiBpB,KAAKqB,IAAI;IAE9B,IAAI,CAACD,gBAAgB;QACnB,MAAM,EAAEV,GAAG,EAAE,GAAG,MAAMd,qBAAqB;YACzCO;YACAC;YACAC;YACAC;YACAE;YACAP;QACF;QAEAmB,iBAAiBV;IACnB;IAEAb,eAAe;QACbc;QACAW,WAAWtB,KAAKsB,SAAS;QACzBC,QAAQd,OAAOc,MAAM;QACrBH;QACAD;IACF;IAEA,MAAMK,gBAAgB,MAAMZ,SAASa,OAAO,CAAC;QAC3ClB,YAAYP,KAAKO,UAAU;QAC3BmB,UAAU1B,KAAKM,MAAM;QACrBL;QACA0B,OAAOR,kBAAkBS,GAAG,CAAC,CAACX,OAASA,KAAKY,KAAK;IACnD;IAEA,IAAIC;IAEJ,IAAI,CAACN,cAAcO,OAAO,EAAE;QAC1BD,SAAS;YACPC,SAAS;QACX;IACF,OAAO;QACLP,cAAcQ,eAAe,CAACC,OAAO,CAAC,CAACC,YAAYC;YACjD,MAAMC,iBAAiB1C,GAAG2C,MAAM,CAACH;YAEjCf,iBAAiB,CAACgB,MAAM,CAACG,WAAW,CAACF;QACvC;QAEA,IAAIpC,KAAKuC,MAAM,EAAE;YACf,MAAMzC,aAAa;gBACjBK;gBACAkB,MAAMD;gBACNoB,OAAO;gBACPpC;gBACAC;gBACAC;gBACAE;gBACAP;YACF;QACF;QAEA6B,SAAS;YACPC,SAAS;YACTX;QACF;IACF;IAEA,OAAOU;AACT,EAAC"}