@intlayer/backend 5.1.3 → 5.1.5
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/cjs/controllers/dictionary.controller.cjs +7 -11
- package/dist/cjs/controllers/dictionary.controller.cjs.map +1 -1
- package/dist/cjs/emails/InviteUserEmail.cjs +3 -3
- package/dist/cjs/emails/InviteUserEmail.cjs.map +1 -1
- package/dist/cjs/emails/PasswordChangeConfirmation.cjs +3 -3
- package/dist/cjs/emails/PasswordChangeConfirmation.cjs.map +1 -1
- package/dist/cjs/emails/ResetUserPassword.cjs +3 -3
- package/dist/cjs/emails/ResetUserPassword.cjs.map +1 -1
- package/dist/cjs/emails/SubscriptionPaymentCancellation.cjs +3 -3
- package/dist/cjs/emails/SubscriptionPaymentCancellation.cjs.map +1 -1
- package/dist/cjs/emails/SubscriptionPaymentError.cjs +3 -3
- package/dist/cjs/emails/SubscriptionPaymentError.cjs.map +1 -1
- package/dist/cjs/emails/SubscriptionPaymentSuccess.cjs +3 -3
- package/dist/cjs/emails/SubscriptionPaymentSuccess.cjs.map +1 -1
- package/dist/cjs/emails/ValidateUserEmail.cjs +3 -3
- package/dist/cjs/emails/ValidateUserEmail.cjs.map +1 -1
- package/dist/cjs/emails/Welcome.cjs +3 -3
- package/dist/cjs/emails/Welcome.cjs.map +1 -1
- package/dist/cjs/schemas/dictionary.schema.cjs +0 -4
- package/dist/cjs/schemas/dictionary.schema.cjs.map +1 -1
- package/dist/cjs/services/dictionary.service.cjs +6 -0
- package/dist/cjs/services/dictionary.service.cjs.map +1 -1
- package/dist/cjs/types/dictionary.types.cjs.map +1 -1
- package/dist/cjs/utils/auditDictionary/index.cjs +1 -1
- package/dist/cjs/utils/auditDictionary/index.cjs.map +1 -1
- package/dist/cjs/utils/auditDictionaryField/PROMPT.md +17 -7
- package/dist/cjs/utils/auditDictionaryField/index.cjs +1 -1
- package/dist/cjs/utils/auditDictionaryField/index.cjs.map +1 -1
- package/dist/cjs/utils/auditDictionaryMetadata/index.cjs +1 -1
- package/dist/cjs/utils/auditDictionaryMetadata/index.cjs.map +1 -1
- package/dist/cjs/utils/auditTag/index.cjs +1 -1
- package/dist/cjs/utils/auditTag/index.cjs.map +1 -1
- package/dist/esm/controllers/dictionary.controller.mjs +7 -11
- package/dist/esm/controllers/dictionary.controller.mjs.map +1 -1
- package/dist/esm/emails/InviteUserEmail.mjs +3 -3
- package/dist/esm/emails/InviteUserEmail.mjs.map +1 -1
- package/dist/esm/emails/PasswordChangeConfirmation.mjs +3 -3
- package/dist/esm/emails/PasswordChangeConfirmation.mjs.map +1 -1
- package/dist/esm/emails/ResetUserPassword.mjs +3 -3
- package/dist/esm/emails/ResetUserPassword.mjs.map +1 -1
- package/dist/esm/emails/SubscriptionPaymentCancellation.mjs +3 -3
- package/dist/esm/emails/SubscriptionPaymentCancellation.mjs.map +1 -1
- package/dist/esm/emails/SubscriptionPaymentError.mjs +3 -3
- package/dist/esm/emails/SubscriptionPaymentError.mjs.map +1 -1
- package/dist/esm/emails/SubscriptionPaymentSuccess.mjs +3 -3
- package/dist/esm/emails/SubscriptionPaymentSuccess.mjs.map +1 -1
- package/dist/esm/emails/ValidateUserEmail.mjs +3 -3
- package/dist/esm/emails/ValidateUserEmail.mjs.map +1 -1
- package/dist/esm/emails/Welcome.mjs +3 -3
- package/dist/esm/emails/Welcome.mjs.map +1 -1
- package/dist/esm/schemas/dictionary.schema.mjs +0 -4
- package/dist/esm/schemas/dictionary.schema.mjs.map +1 -1
- package/dist/esm/services/dictionary.service.mjs +6 -0
- package/dist/esm/services/dictionary.service.mjs.map +1 -1
- package/dist/esm/utils/auditDictionary/index.mjs +1 -1
- package/dist/esm/utils/auditDictionary/index.mjs.map +1 -1
- package/dist/esm/utils/auditDictionaryField/PROMPT.md +17 -7
- package/dist/esm/utils/auditDictionaryField/index.mjs +1 -1
- package/dist/esm/utils/auditDictionaryField/index.mjs.map +1 -1
- package/dist/esm/utils/auditDictionaryMetadata/index.mjs +1 -1
- package/dist/esm/utils/auditDictionaryMetadata/index.mjs.map +1 -1
- package/dist/esm/utils/auditTag/index.mjs +1 -1
- package/dist/esm/utils/auditTag/index.mjs.map +1 -1
- package/dist/types/controllers/dictionary.controller.d.ts.map +1 -1
- package/dist/types/schemas/dictionary.schema.d.ts.map +1 -1
- package/dist/types/services/dictionary.service.d.ts.map +1 -1
- package/dist/types/types/dictionary.types.d.ts +0 -1
- package/dist/types/types/dictionary.types.d.ts.map +1 -1
- package/package.json +9 -9
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../../src/emails/SubscriptionPaymentError.tsx"],"sourcesContent":["import {\n Html,\n Head,\n Preview,\n Tailwind,\n Body,\n Section,\n Img,\n Heading,\n Container,\n Button,\n Text,\n} from '@react-email/components';\n\nexport type SubscriptionPaymentErrorProps = {\n username: string; // The name of the user receiving the email\n email: string; // The email address of the user\n planName: string; // The name of the subscription plan\n errorDate: string; // The date the payment error occurred\n retryPaymentLink: string; // A link for the user to retry their payment\n};\n\n// Payment Error Email - English (EN)\nexport const SubscriptionPaymentErrorEN = ({\n username,\n planName,\n errorDate,\n retryPaymentLink,\n}: SubscriptionPaymentErrorProps) => {\n const previewText = `There was an issue with your ${planName} subscription payment`;\n\n return (\n <Html>\n <Head />\n <Preview>{previewText}</Preview>\n <Tailwind>\n <Body className=\"m-auto px-2 font-sans\">\n <Container className=\"mx-auto my-[40px] max-w-[465px] rounded-xl border border-solid border-[#eaeaea] bg-white p-[20px]\">\n <Section className=\"mt-[32px]\">\n <Img\n src={`https://intlayer.org/
|
|
1
|
+
{"version":3,"sources":["../../../src/emails/SubscriptionPaymentError.tsx"],"sourcesContent":["import {\n Html,\n Head,\n Preview,\n Tailwind,\n Body,\n Section,\n Img,\n Heading,\n Container,\n Button,\n Text,\n} from '@react-email/components';\n\nexport type SubscriptionPaymentErrorProps = {\n username: string; // The name of the user receiving the email\n email: string; // The email address of the user\n planName: string; // The name of the subscription plan\n errorDate: string; // The date the payment error occurred\n retryPaymentLink: string; // A link for the user to retry their payment\n};\n\n// Payment Error Email - English (EN)\nexport const SubscriptionPaymentErrorEN = ({\n username,\n planName,\n errorDate,\n retryPaymentLink,\n}: SubscriptionPaymentErrorProps) => {\n const previewText = `There was an issue with your ${planName} subscription payment`;\n\n return (\n <Html>\n <Head />\n <Preview>{previewText}</Preview>\n <Tailwind>\n <Body className=\"m-auto px-2 font-sans\">\n <Container className=\"mx-auto my-[40px] max-w-[465px] rounded-xl border border-solid border-[#eaeaea] bg-white p-[20px]\">\n <Section className=\"mt-[32px]\">\n <Img\n src={`https://intlayer.org/favicon-32x32.png`}\n width=\"40\"\n height=\"37\"\n alt=\"Intlayer\"\n className=\"mx-auto my-0\"\n />\n </Section>\n <Heading className=\"mx-0 my-[30px] p-0 text-center text-[24px] font-normal text-black\">\n Payment Issue Detected\n </Heading>\n <Text className=\"text-[14px] leading-[24px] text-black\">\n Hello {username},\n </Text>\n <Text className=\"text-[14px] leading-[24px] text-black\">\n We encountered an issue processing your payment for the{' '}\n <strong>{planName}</strong> plan on <strong>{errorDate}</strong>.\n Please update your payment information to ensure continued access\n to your subscription.\n </Text>\n <Section className=\"my-[32px] text-center\">\n <Button\n className=\"rounded-md bg-[#000000] px-5 py-3 text-center text-[12px] font-semibold text-white no-underline\"\n href={retryPaymentLink}\n >\n Retry Payment\n </Button>\n </Section>\n </Container>\n </Body>\n </Tailwind>\n </Html>\n );\n};\n\n// Payment Error Email - French (FR)\nexport const SubscriptionPaymentErrorFR = ({\n username,\n planName,\n errorDate,\n retryPaymentLink,\n}: SubscriptionPaymentErrorProps) => {\n const previewText = `Un problème est survenu avec votre paiement pour l'abonnement ${planName}`;\n\n return (\n <Html>\n <Head />\n <Preview>{previewText}</Preview>\n <Tailwind>\n <Body className=\"m-auto px-2 font-sans\">\n <Container className=\"mx-auto my-[40px] max-w-[465px] rounded-xl border border-solid border-[#eaeaea] bg-white p-[20px]\">\n <Section className=\"mt-[32px]\">\n <Img\n src={`https://intlayer.org/favicon-32x32.png`}\n width=\"40\"\n height=\"37\"\n alt=\"Intlayer\"\n className=\"mx-auto my-0\"\n />\n </Section>\n <Heading className=\"mx-0 my-[30px] p-0 text-center text-[24px] font-normal text-black\">\n Problème de Paiement\n </Heading>\n <Text className=\"text-[14px] leading-[24px] text-black\">\n Bonjour {username},\n </Text>\n <Text className=\"text-[14px] leading-[24px] text-black\">\n Nous avons rencontré un problème lors du traitement de votre\n paiement pour le plan <strong>{planName}</strong> le{' '}\n <strong>{errorDate}</strong>. Veuillez mettre à jour vos\n informations de paiement pour garantir un accès continu à votre\n abonnement.\n </Text>\n <Section className=\"my-[32px] text-center\">\n <Button\n className=\"rounded-md bg-[#000000] px-5 py-3 text-center text-[12px] font-semibold text-white no-underline\"\n href={retryPaymentLink}\n >\n Réessayer le Paiement\n </Button>\n </Section>\n </Container>\n </Body>\n </Tailwind>\n </Html>\n );\n};\n\n// Payment Error Email - Spanish (ES)\nexport const SubscriptionPaymentErrorES = ({\n username,\n planName,\n errorDate,\n retryPaymentLink,\n}: SubscriptionPaymentErrorProps) => {\n const previewText = `Hubo un problema con el pago de tu suscripción ${planName}`;\n\n return (\n <Html>\n <Head />\n <Preview>{previewText}</Preview>\n <Tailwind>\n <Body className=\"m-auto px-2 font-sans\">\n <Container className=\"mx-auto my-[40px] max-w-[465px] rounded-xl border border-solid border-[#eaeaea] bg-white p-[20px]\">\n <Section className=\"mt-[32px]\">\n <Img\n src={`https://intlayer.org/favicon-32x32.png`}\n width=\"40\"\n height=\"37\"\n alt=\"Intlayer\"\n className=\"mx-auto my-0\"\n />\n </Section>\n <Heading className=\"mx-0 my-[30px] p-0 text-center text-[24px] font-normal text-black\">\n Problema de Pago\n </Heading>\n <Text className=\"text-[14px] leading-[24px] text-black\">\n Hola {username},\n </Text>\n <Text className=\"text-[14px] leading-[24px] text-black\">\n Hubo un problema al procesar tu pago para el plan{' '}\n <strong>{planName}</strong> el <strong>{errorDate}</strong>. Por\n favor, actualiza tu información de pago para garantizar el acceso\n continuo a tu suscripción.\n </Text>\n <Section className=\"my-[32px] text-center\">\n <Button\n className=\"rounded-md bg-[#000000] px-5 py-3 text-center text-[12px] font-semibold text-white no-underline\"\n href={retryPaymentLink}\n >\n Reintentar el Pago\n </Button>\n </Section>\n </Container>\n </Body>\n </Tailwind>\n </Html>\n );\n};\n\n// Preview Props Example\nconst PreviewProps: SubscriptionPaymentErrorProps = {\n username: 'John Doe',\n email: 'john.doe@example.com',\n planName: 'Pro Plan',\n errorDate: 'November 18, 2024',\n retryPaymentLink: 'https://intlayer.org/retry-payment',\n};\n\nSubscriptionPaymentErrorEN.PreviewProps = PreviewProps;\nSubscriptionPaymentErrorFR.PreviewProps = PreviewProps;\nSubscriptionPaymentErrorES.PreviewProps = PreviewProps;\n"],"mappings":"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","names":[]}
|
|
@@ -39,7 +39,7 @@ const SubscriptionPaymentSuccessEN = ({
|
|
|
39
39
|
/* @__PURE__ */ (0, import_jsx_runtime.jsx)(import_components.Section, { className: "mt-[32px]", children: /* @__PURE__ */ (0, import_jsx_runtime.jsx)(
|
|
40
40
|
import_components.Img,
|
|
41
41
|
{
|
|
42
|
-
src: `https://intlayer.org/
|
|
42
|
+
src: `https://intlayer.org/favicon-32x32.png`,
|
|
43
43
|
width: "40",
|
|
44
44
|
height: "37",
|
|
45
45
|
alt: "Intlayer",
|
|
@@ -87,7 +87,7 @@ const SubscriptionPaymentSuccessFR = ({
|
|
|
87
87
|
/* @__PURE__ */ (0, import_jsx_runtime.jsx)(import_components.Section, { className: "mt-[32px]", children: /* @__PURE__ */ (0, import_jsx_runtime.jsx)(
|
|
88
88
|
import_components.Img,
|
|
89
89
|
{
|
|
90
|
-
src: `https://intlayer.org/
|
|
90
|
+
src: `https://intlayer.org/favicon-32x32.png`,
|
|
91
91
|
width: "40",
|
|
92
92
|
height: "37",
|
|
93
93
|
alt: "Intlayer",
|
|
@@ -135,7 +135,7 @@ const SubscriptionPaymentSuccessES = ({
|
|
|
135
135
|
/* @__PURE__ */ (0, import_jsx_runtime.jsx)(import_components.Section, { className: "mt-[32px]", children: /* @__PURE__ */ (0, import_jsx_runtime.jsx)(
|
|
136
136
|
import_components.Img,
|
|
137
137
|
{
|
|
138
|
-
src: `https://intlayer.org/
|
|
138
|
+
src: `https://intlayer.org/favicon-32x32.png`,
|
|
139
139
|
width: "40",
|
|
140
140
|
height: "37",
|
|
141
141
|
alt: "Intlayer",
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../../src/emails/SubscriptionPaymentSuccess.tsx"],"sourcesContent":["import {\n Html,\n Head,\n Preview,\n Tailwind,\n Body,\n Section,\n Img,\n Heading,\n Container,\n Button,\n Text,\n} from '@react-email/components';\n\nexport type SubscriptionPaymentSuccessProps = {\n username: string; // The name of the user receiving the email\n email: string; // The email address of the user\n planName: string; // The name of the subscription plan\n subscriptionStartDate: string; // The start date of the subscription\n manageSubscriptionLink: string; // A link for the user to manage their subscription\n};\n\nexport const SubscriptionPaymentSuccessEN = ({\n username,\n planName,\n subscriptionStartDate,\n manageSubscriptionLink,\n}: SubscriptionPaymentSuccessProps) => {\n const previewText = `Your payment for ${planName} subscription is confirmed`;\n\n return (\n <Html>\n <Head />\n <Preview>{previewText}</Preview>\n <Tailwind>\n <Body className=\"m-auto px-2 font-sans\">\n <Container className=\"mx-auto my-[40px] max-w-[465px] rounded-xl border border-solid border-[#eaeaea] bg-white p-[20px]\">\n <Section className=\"mt-[32px]\">\n <Img\n src={`https://intlayer.org/
|
|
1
|
+
{"version":3,"sources":["../../../src/emails/SubscriptionPaymentSuccess.tsx"],"sourcesContent":["import {\n Html,\n Head,\n Preview,\n Tailwind,\n Body,\n Section,\n Img,\n Heading,\n Container,\n Button,\n Text,\n} from '@react-email/components';\n\nexport type SubscriptionPaymentSuccessProps = {\n username: string; // The name of the user receiving the email\n email: string; // The email address of the user\n planName: string; // The name of the subscription plan\n subscriptionStartDate: string; // The start date of the subscription\n manageSubscriptionLink: string; // A link for the user to manage their subscription\n};\n\nexport const SubscriptionPaymentSuccessEN = ({\n username,\n planName,\n subscriptionStartDate,\n manageSubscriptionLink,\n}: SubscriptionPaymentSuccessProps) => {\n const previewText = `Your payment for ${planName} subscription is confirmed`;\n\n return (\n <Html>\n <Head />\n <Preview>{previewText}</Preview>\n <Tailwind>\n <Body className=\"m-auto px-2 font-sans\">\n <Container className=\"mx-auto my-[40px] max-w-[465px] rounded-xl border border-solid border-[#eaeaea] bg-white p-[20px]\">\n <Section className=\"mt-[32px]\">\n <Img\n src={`https://intlayer.org/favicon-32x32.png`}\n width=\"40\"\n height=\"37\"\n alt=\"Intlayer\"\n className=\"mx-auto my-0\"\n />\n </Section>\n <Heading className=\"mx-0 my-[30px] p-0 text-center text-[24px] font-normal text-black\">\n Payment Confirmed\n </Heading>\n <Text className=\"text-[14px] leading-[24px] text-black\">\n Hello {username},\n </Text>\n <Text className=\"text-[14px] leading-[24px] text-black\">\n Thank you for your payment! Your subscription to the{' '}\n <strong>{planName}</strong> plan is now active.\n </Text>\n <Text className=\"text-[14px] leading-[24px] text-black\">\n Start Date: <strong>{subscriptionStartDate}</strong>\n </Text>\n <Section className=\"my-[32px] text-center\">\n <Button\n className=\"rounded-md bg-[#000000] px-5 py-3 text-center text-[12px] font-semibold text-white no-underline\"\n href={manageSubscriptionLink}\n >\n Manage Your Subscription\n </Button>\n </Section>\n </Container>\n </Body>\n </Tailwind>\n </Html>\n );\n};\n\nexport const SubscriptionPaymentSuccessFR = ({\n username,\n planName,\n subscriptionStartDate,\n manageSubscriptionLink,\n}: SubscriptionPaymentSuccessProps) => {\n const previewText = `Votre paiement pour l'abonnement ${planName} est confirmé`;\n\n return (\n <Html>\n <Head />\n <Preview>{previewText}</Preview>\n <Tailwind>\n <Body className=\"m-auto px-2 font-sans\">\n <Container className=\"mx-auto my-[40px] max-w-[465px] rounded-xl border border-solid border-[#eaeaea] bg-white p-[20px]\">\n <Section className=\"mt-[32px]\">\n <Img\n src={`https://intlayer.org/favicon-32x32.png`}\n width=\"40\"\n height=\"37\"\n alt=\"Intlayer\"\n className=\"mx-auto my-0\"\n />\n </Section>\n <Heading className=\"mx-0 my-[30px] p-0 text-center text-[24px] font-normal text-black\">\n Paiement Confirmé\n </Heading>\n <Text className=\"text-[14px] leading-[24px] text-black\">\n Bonjour {username},\n </Text>\n <Text className=\"text-[14px] leading-[24px] text-black\">\n Merci pour votre paiement ! Votre abonnement au plan{' '}\n <strong>{planName}</strong> est maintenant actif.\n </Text>\n <Text className=\"text-[14px] leading-[24px] text-black\">\n Date de début : <strong>{subscriptionStartDate}</strong>\n </Text>\n <Section className=\"my-[32px] text-center\">\n <Button\n className=\"rounded-md bg-[#000000] px-5 py-3 text-center text-[12px] font-semibold text-white no-underline\"\n href={manageSubscriptionLink}\n >\n Gérer votre abonnement\n </Button>\n </Section>\n </Container>\n </Body>\n </Tailwind>\n </Html>\n );\n};\n\nexport const SubscriptionPaymentSuccessES = ({\n username,\n planName,\n subscriptionStartDate,\n manageSubscriptionLink,\n}: SubscriptionPaymentSuccessProps) => {\n const previewText = `Tu pago por la suscripción ${planName} ha sido confirmado`;\n\n return (\n <Html>\n <Head />\n <Preview>{previewText}</Preview>\n <Tailwind>\n <Body className=\"m-auto px-2 font-sans\">\n <Container className=\"mx-auto my-[40px] max-w-[465px] rounded-xl border border-solid border-[#eaeaea] bg-white p-[20px]\">\n <Section className=\"mt-[32px]\">\n <Img\n src={`https://intlayer.org/favicon-32x32.png`}\n width=\"40\"\n height=\"37\"\n alt=\"Intlayer\"\n className=\"mx-auto my-0\"\n />\n </Section>\n <Heading className=\"mx-0 my-[30px] p-0 text-center text-[24px] font-normal text-black\">\n Pago Confirmado\n </Heading>\n <Text className=\"text-[14px] leading-[24px] text-black\">\n Hola {username},\n </Text>\n <Text className=\"text-[14px] leading-[24px] text-black\">\n ¡Gracias por tu pago! Tu suscripción al plan{' '}\n <strong>{planName}</strong> ya está activa.\n </Text>\n <Text className=\"text-[14px] leading-[24px] text-black\">\n Fecha de inicio: <strong>{subscriptionStartDate}</strong>\n </Text>\n <Section className=\"my-[32px] text-center\">\n <Button\n className=\"rounded-md bg-[#000000] px-5 py-3 text-center text-[12px] font-semibold text-white no-underline\"\n href={manageSubscriptionLink}\n >\n Gestionar tu suscripción\n </Button>\n </Section>\n </Container>\n </Body>\n </Tailwind>\n </Html>\n );\n};\n\nconst PreviewProps: SubscriptionPaymentSuccessProps = {\n username: 'John Doe',\n email: 'john.doe@example.com',\n planName: 'Pro Plan',\n subscriptionStartDate: 'November 20, 2024',\n manageSubscriptionLink: 'https://intlayer.org/manage-subscription',\n};\n\nSubscriptionPaymentSuccessEN.PreviewProps = PreviewProps;\nSubscriptionPaymentSuccessFR.PreviewProps = PreviewProps;\nSubscriptionPaymentSuccessES.PreviewProps = PreviewProps;\n"],"mappings":"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","names":[]}
|
|
@@ -37,7 +37,7 @@ const ValidateUserEmailEN = ({
|
|
|
37
37
|
/* @__PURE__ */ (0, import_jsx_runtime.jsx)(import_components.Section, { className: "mt-[32px]", children: /* @__PURE__ */ (0, import_jsx_runtime.jsx)(
|
|
38
38
|
import_components.Img,
|
|
39
39
|
{
|
|
40
|
-
src: `https://intlayer.org/
|
|
40
|
+
src: `https://intlayer.org/favicon-32x32.png`,
|
|
41
41
|
width: "40",
|
|
42
42
|
height: "37",
|
|
43
43
|
alt: "Intlayer",
|
|
@@ -100,7 +100,7 @@ const ValidateUserEmailFR = ({
|
|
|
100
100
|
/* @__PURE__ */ (0, import_jsx_runtime.jsx)(import_components.Section, { className: "mt-[32px]", children: /* @__PURE__ */ (0, import_jsx_runtime.jsx)(
|
|
101
101
|
import_components.Img,
|
|
102
102
|
{
|
|
103
|
-
src: `https://intlayer.org/
|
|
103
|
+
src: `https://intlayer.org/favicon-32x32.png`,
|
|
104
104
|
width: "40",
|
|
105
105
|
height: "37",
|
|
106
106
|
alt: "Intlayer",
|
|
@@ -163,7 +163,7 @@ const ValidateUserEmailES = ({
|
|
|
163
163
|
/* @__PURE__ */ (0, import_jsx_runtime.jsx)(import_components.Section, { className: "mt-[32px]", children: /* @__PURE__ */ (0, import_jsx_runtime.jsx)(
|
|
164
164
|
import_components.Img,
|
|
165
165
|
{
|
|
166
|
-
src: `https://intlayer.org/
|
|
166
|
+
src: `https://intlayer.org/favicon-32x32.png`,
|
|
167
167
|
width: "40",
|
|
168
168
|
height: "37",
|
|
169
169
|
alt: "Intlayer",
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../../src/emails/ValidateUserEmail.tsx"],"sourcesContent":["import {\n Body,\n Button,\n Container,\n Head,\n Heading,\n Hr,\n Html,\n Img,\n Link,\n Preview,\n Section,\n Text,\n Tailwind,\n} from '@react-email/components';\n\nexport type ValidateUserEmailProps = {\n username: string;\n validationLink: string;\n};\n\nexport const ValidateUserEmailEN = ({\n username,\n validationLink,\n}: ValidateUserEmailProps) => {\n const previewText = `Validate your email for Intlayer`;\n\n return (\n <Html>\n <Head />\n <Preview>{previewText}</Preview>\n <Tailwind>\n <Body className=\"m-auto px-2 font-sans\">\n <Container className=\"mx-auto my-[40px] max-w-[465px] rounded-xl border border-solid border-[#eaeaea] bg-white p-[20px]\">\n <Section className=\"mt-[32px]\">\n <Img\n src={`https://intlayer.org/assets/favicon-32x32.png`}\n width=\"40\"\n height=\"37\"\n alt=\"Intlayer\"\n className=\"mx-auto my-0\"\n />\n </Section>\n <Heading className=\"mx-0 my-[30px] p-0 text-center text-[24px] font-normal text-black\">\n Validate your email for <strong>Intlayer</strong>\n </Heading>\n <Text className=\"text-[14px] leading-[24px] text-black\">\n Hello {username},\n </Text>\n <Text className=\"text-[14px] leading-[24px] text-black\">\n Please validate your email address to complete your registration\n on <strong>Intlayer</strong>.\n </Text>\n\n <Section className=\"my-[32px] text-center\">\n <Button\n className=\"rounded-md bg-[#000000] px-5 py-3 text-center text-[12px] font-semibold text-white no-underline\"\n href={validationLink}\n >\n Validate Email\n </Button>\n </Section>\n <Text className=\"text-[14px] leading-[24px] text-black\">\n or copy and paste this URL into your browser:{' '}\n <Link\n href={validationLink}\n className=\"text-[#E879BA] no-underline\"\n >\n {validationLink}\n </Link>\n </Text>\n <Hr className=\"mx-0 my-[26px] w-full border border-solid border-[#eaeaea]\" />\n <Text className=\"text-[12px] leading-[24px] text-[#666666]\">\n This email was intended for{' '}\n <span className=\"text-black\">{username}</span>. If you were not\n expecting this email, you can ignore it. If you are concerned\n about your account's safety, please reply to this email to get in\n touch with us.\n </Text>\n </Container>\n </Body>\n </Tailwind>\n </Html>\n );\n};\n\nexport const ValidateUserEmailFR = ({\n username,\n validationLink,\n}: ValidateUserEmailProps) => {\n const previewText = `Validez votre e-mail pour Intlayer`;\n\n return (\n <Html>\n <Head />\n <Preview>{previewText}</Preview>\n <Tailwind>\n <Body className=\"m-auto px-2 font-sans\">\n <Container className=\"mx-auto my-[40px] max-w-[465px] rounded-xl border border-solid border-[#eaeaea] bg-white p-[20px]\">\n <Section className=\"mt-[32px]\">\n <Img\n src={`https://intlayer.org/assets/favicon-32x32.png`}\n width=\"40\"\n height=\"37\"\n alt=\"Intlayer\"\n className=\"mx-auto my-0\"\n />\n </Section>\n <Heading className=\"mx-0 my-[30px] p-0 text-center text-[24px] font-normal text-black\">\n Validez votre e-mail pour <strong>Intlayer</strong>\n </Heading>\n <Text className=\"text-[14px] leading-[24px] text-black\">\n Bonjour {username},\n </Text>\n <Text className=\"text-[14px] leading-[24px] text-black\">\n Veuillez valider votre adresse e-mail pour compléter votre\n inscription sur <strong>Intlayer</strong>.\n </Text>\n <Section className=\"my-[32px] text-center\">\n <Button\n className=\"rounded-md bg-[#000000] px-5 py-3 text-center text-[12px] font-semibold text-white no-underline\"\n href={validationLink}\n >\n Valider l'e-mail\n </Button>\n </Section>\n <Text className=\"text-[14px] leading-[24px] text-black\">\n ou copiez et collez cette URL dans votre navigateur :{' '}\n <Link\n href={validationLink}\n className=\"text-[#E879BA] no-underline\"\n >\n {validationLink}\n </Link>\n </Text>\n <Hr className=\"mx-0 my-[26px] w-full border border-solid border-[#eaeaea]\" />\n <Text className=\"text-[12px] leading-[24px] text-[#666666]\">\n Cet e-mail était destiné à{' '}\n <span className=\"text-black\">{username}</span>. Si vous\n n'attendiez pas cet e-mail, vous pouvez l'ignorer. Si vous êtes\n préoccupé par la sécurité de votre compte, veuillez répondre à cet\n e-mail pour nous contacter.\n </Text>\n </Container>\n </Body>\n </Tailwind>\n </Html>\n );\n};\n\nexport const ValidateUserEmailES = ({\n username,\n validationLink,\n}: ValidateUserEmailProps) => {\n const previewText = `Valida tu correo electrónico para Intlayer`;\n\n return (\n <Html>\n <Head />\n <Preview>{previewText}</Preview>\n <Tailwind>\n <Body className=\"m-auto px-2 font-sans\">\n <Container className=\"mx-auto my-[40px] max-w-[465px] rounded-xl border border-solid border-[#eaeaea] bg-white p-[20px]\">\n <Section className=\"mt-[32px]\">\n <Img\n src={`https://intlayer.org/assets/favicon-32x32.png`}\n width=\"40\"\n height=\"37\"\n alt=\"Intlayer\"\n className=\"mx-auto my-0\"\n />\n </Section>\n <Heading className=\"mx-0 my-[30px] p-0 text-center text-[24px] font-normal text-black\">\n Valida tu correo electrónico para <strong>Intlayer</strong>\n </Heading>\n <Text className=\"text-[14px] leading-[24px] text-black\">\n Hola {username},\n </Text>\n <Text className=\"text-[14px] leading-[24px] text-black\">\n Por favor valida tu dirección de correo electrónico para completar\n tu registro en <strong>Intlayer</strong>.\n </Text>\n <Section className=\"my-[32px] text-center\">\n <Button\n className=\"rounded-md bg-[#000000] px-5 py-3 text-center text-[12px] font-semibold text-white no-underline\"\n href={validationLink}\n >\n Validar Email\n </Button>\n </Section>\n <Text className=\"text-[14px] leading-[24px] text-black\">\n o copia y pega esta URL en tu navegador:{' '}\n <Link\n href={validationLink}\n className=\"text-[#E879BA] no-underline\"\n >\n {validationLink}\n </Link>\n </Text>\n <Hr className=\"mx-0 my-[26px] w-full border border-solid border-[#eaeaea]\" />\n <Text className=\"text-[12px] leading-[24px] text-[#666666]\">\n Este correo fue enviado a{' '}\n <span className=\"text-black\">{username}</span>. Si no esperabas\n este correo, puedes ignorarlo. Si estás preocupado por la\n seguridad de tu cuenta, por favor responde a este correo para\n contactarte con nosotros.\n </Text>\n </Container>\n </Body>\n </Tailwind>\n </Html>\n );\n};\n\nconst previewProps: ValidateUserEmailProps = {\n username: 'alanturing',\n validationLink: 'https://intlayer.org/validate/foo',\n};\n\nValidateUserEmailEN.PreviewProps = previewProps;\nValidateUserEmailFR.PreviewProps = previewProps;\nValidateUserEmailES.PreviewProps = previewProps;\n"],"mappings":"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","names":[]}
|
|
1
|
+
{"version":3,"sources":["../../../src/emails/ValidateUserEmail.tsx"],"sourcesContent":["import {\n Body,\n Button,\n Container,\n Head,\n Heading,\n Hr,\n Html,\n Img,\n Link,\n Preview,\n Section,\n Text,\n Tailwind,\n} from '@react-email/components';\n\nexport type ValidateUserEmailProps = {\n username: string;\n validationLink: string;\n};\n\nexport const ValidateUserEmailEN = ({\n username,\n validationLink,\n}: ValidateUserEmailProps) => {\n const previewText = `Validate your email for Intlayer`;\n\n return (\n <Html>\n <Head />\n <Preview>{previewText}</Preview>\n <Tailwind>\n <Body className=\"m-auto px-2 font-sans\">\n <Container className=\"mx-auto my-[40px] max-w-[465px] rounded-xl border border-solid border-[#eaeaea] bg-white p-[20px]\">\n <Section className=\"mt-[32px]\">\n <Img\n src={`https://intlayer.org/favicon-32x32.png`}\n width=\"40\"\n height=\"37\"\n alt=\"Intlayer\"\n className=\"mx-auto my-0\"\n />\n </Section>\n <Heading className=\"mx-0 my-[30px] p-0 text-center text-[24px] font-normal text-black\">\n Validate your email for <strong>Intlayer</strong>\n </Heading>\n <Text className=\"text-[14px] leading-[24px] text-black\">\n Hello {username},\n </Text>\n <Text className=\"text-[14px] leading-[24px] text-black\">\n Please validate your email address to complete your registration\n on <strong>Intlayer</strong>.\n </Text>\n\n <Section className=\"my-[32px] text-center\">\n <Button\n className=\"rounded-md bg-[#000000] px-5 py-3 text-center text-[12px] font-semibold text-white no-underline\"\n href={validationLink}\n >\n Validate Email\n </Button>\n </Section>\n <Text className=\"text-[14px] leading-[24px] text-black\">\n or copy and paste this URL into your browser:{' '}\n <Link\n href={validationLink}\n className=\"text-[#E879BA] no-underline\"\n >\n {validationLink}\n </Link>\n </Text>\n <Hr className=\"mx-0 my-[26px] w-full border border-solid border-[#eaeaea]\" />\n <Text className=\"text-[12px] leading-[24px] text-[#666666]\">\n This email was intended for{' '}\n <span className=\"text-black\">{username}</span>. If you were not\n expecting this email, you can ignore it. If you are concerned\n about your account's safety, please reply to this email to get in\n touch with us.\n </Text>\n </Container>\n </Body>\n </Tailwind>\n </Html>\n );\n};\n\nexport const ValidateUserEmailFR = ({\n username,\n validationLink,\n}: ValidateUserEmailProps) => {\n const previewText = `Validez votre e-mail pour Intlayer`;\n\n return (\n <Html>\n <Head />\n <Preview>{previewText}</Preview>\n <Tailwind>\n <Body className=\"m-auto px-2 font-sans\">\n <Container className=\"mx-auto my-[40px] max-w-[465px] rounded-xl border border-solid border-[#eaeaea] bg-white p-[20px]\">\n <Section className=\"mt-[32px]\">\n <Img\n src={`https://intlayer.org/favicon-32x32.png`}\n width=\"40\"\n height=\"37\"\n alt=\"Intlayer\"\n className=\"mx-auto my-0\"\n />\n </Section>\n <Heading className=\"mx-0 my-[30px] p-0 text-center text-[24px] font-normal text-black\">\n Validez votre e-mail pour <strong>Intlayer</strong>\n </Heading>\n <Text className=\"text-[14px] leading-[24px] text-black\">\n Bonjour {username},\n </Text>\n <Text className=\"text-[14px] leading-[24px] text-black\">\n Veuillez valider votre adresse e-mail pour compléter votre\n inscription sur <strong>Intlayer</strong>.\n </Text>\n <Section className=\"my-[32px] text-center\">\n <Button\n className=\"rounded-md bg-[#000000] px-5 py-3 text-center text-[12px] font-semibold text-white no-underline\"\n href={validationLink}\n >\n Valider l'e-mail\n </Button>\n </Section>\n <Text className=\"text-[14px] leading-[24px] text-black\">\n ou copiez et collez cette URL dans votre navigateur :{' '}\n <Link\n href={validationLink}\n className=\"text-[#E879BA] no-underline\"\n >\n {validationLink}\n </Link>\n </Text>\n <Hr className=\"mx-0 my-[26px] w-full border border-solid border-[#eaeaea]\" />\n <Text className=\"text-[12px] leading-[24px] text-[#666666]\">\n Cet e-mail était destiné à{' '}\n <span className=\"text-black\">{username}</span>. Si vous\n n'attendiez pas cet e-mail, vous pouvez l'ignorer. Si vous êtes\n préoccupé par la sécurité de votre compte, veuillez répondre à cet\n e-mail pour nous contacter.\n </Text>\n </Container>\n </Body>\n </Tailwind>\n </Html>\n );\n};\n\nexport const ValidateUserEmailES = ({\n username,\n validationLink,\n}: ValidateUserEmailProps) => {\n const previewText = `Valida tu correo electrónico para Intlayer`;\n\n return (\n <Html>\n <Head />\n <Preview>{previewText}</Preview>\n <Tailwind>\n <Body className=\"m-auto px-2 font-sans\">\n <Container className=\"mx-auto my-[40px] max-w-[465px] rounded-xl border border-solid border-[#eaeaea] bg-white p-[20px]\">\n <Section className=\"mt-[32px]\">\n <Img\n src={`https://intlayer.org/favicon-32x32.png`}\n width=\"40\"\n height=\"37\"\n alt=\"Intlayer\"\n className=\"mx-auto my-0\"\n />\n </Section>\n <Heading className=\"mx-0 my-[30px] p-0 text-center text-[24px] font-normal text-black\">\n Valida tu correo electrónico para <strong>Intlayer</strong>\n </Heading>\n <Text className=\"text-[14px] leading-[24px] text-black\">\n Hola {username},\n </Text>\n <Text className=\"text-[14px] leading-[24px] text-black\">\n Por favor valida tu dirección de correo electrónico para completar\n tu registro en <strong>Intlayer</strong>.\n </Text>\n <Section className=\"my-[32px] text-center\">\n <Button\n className=\"rounded-md bg-[#000000] px-5 py-3 text-center text-[12px] font-semibold text-white no-underline\"\n href={validationLink}\n >\n Validar Email\n </Button>\n </Section>\n <Text className=\"text-[14px] leading-[24px] text-black\">\n o copia y pega esta URL en tu navegador:{' '}\n <Link\n href={validationLink}\n className=\"text-[#E879BA] no-underline\"\n >\n {validationLink}\n </Link>\n </Text>\n <Hr className=\"mx-0 my-[26px] w-full border border-solid border-[#eaeaea]\" />\n <Text className=\"text-[12px] leading-[24px] text-[#666666]\">\n Este correo fue enviado a{' '}\n <span className=\"text-black\">{username}</span>. Si no esperabas\n este correo, puedes ignorarlo. Si estás preocupado por la\n seguridad de tu cuenta, por favor responde a este correo para\n contactarte con nosotros.\n </Text>\n </Container>\n </Body>\n </Tailwind>\n </Html>\n );\n};\n\nconst previewProps: ValidateUserEmailProps = {\n username: 'alanturing',\n validationLink: 'https://intlayer.org/validate/foo',\n};\n\nValidateUserEmailEN.PreviewProps = previewProps;\nValidateUserEmailFR.PreviewProps = previewProps;\nValidateUserEmailES.PreviewProps = previewProps;\n"],"mappings":"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","names":[]}
|
|
@@ -34,7 +34,7 @@ const WelcomeEmailEN = ({ username, loginLink }) => {
|
|
|
34
34
|
/* @__PURE__ */ (0, import_jsx_runtime.jsx)(import_components.Section, { className: "mt-[32px]", children: /* @__PURE__ */ (0, import_jsx_runtime.jsx)(
|
|
35
35
|
import_components.Img,
|
|
36
36
|
{
|
|
37
|
-
src: `https://intlayer.org/
|
|
37
|
+
src: `https://intlayer.org/favicon-32x32.png`,
|
|
38
38
|
width: "40",
|
|
39
39
|
height: "37",
|
|
40
40
|
alt: "Intlayer",
|
|
@@ -82,7 +82,7 @@ const WelcomeEmailFR = ({ username, loginLink }) => {
|
|
|
82
82
|
/* @__PURE__ */ (0, import_jsx_runtime.jsx)(import_components.Section, { className: "mt-[32px]", children: /* @__PURE__ */ (0, import_jsx_runtime.jsx)(
|
|
83
83
|
import_components.Img,
|
|
84
84
|
{
|
|
85
|
-
src: `https://intlayer.org/
|
|
85
|
+
src: `https://intlayer.org/favicon-32x32.png`,
|
|
86
86
|
width: "40",
|
|
87
87
|
height: "37",
|
|
88
88
|
alt: "Intlayer",
|
|
@@ -130,7 +130,7 @@ const WelcomeEmailES = ({ username, loginLink }) => {
|
|
|
130
130
|
/* @__PURE__ */ (0, import_jsx_runtime.jsx)(import_components.Section, { className: "mt-[32px]", children: /* @__PURE__ */ (0, import_jsx_runtime.jsx)(
|
|
131
131
|
import_components.Img,
|
|
132
132
|
{
|
|
133
|
-
src: `https://intlayer.org/
|
|
133
|
+
src: `https://intlayer.org/favicon-32x32.png`,
|
|
134
134
|
width: "40",
|
|
135
135
|
height: "37",
|
|
136
136
|
alt: "Intlayer",
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../../src/emails/Welcome.tsx"],"sourcesContent":["import {\n Body,\n Button,\n Container,\n Head,\n Heading,\n Hr,\n Html,\n Img,\n Preview,\n Section,\n Text,\n Tailwind,\n Link,\n} from '@react-email/components';\n\nexport type WelcomeEmailProps = {\n username: string;\n loginLink: string;\n};\n\nexport const WelcomeEmailEN = ({ username, loginLink }: WelcomeEmailProps) => {\n const previewText = `Welcome to Intlayer!`;\n\n return (\n <Html>\n <Head />\n <Preview>{previewText}</Preview>\n <Tailwind>\n <Body className=\"m-auto px-2 font-sans\">\n <Container className=\"mx-auto my-[40px] max-w-[465px] rounded-xl border border-solid border-[#eaeaea] bg-white p-[20px]\">\n <Section className=\"mt-[32px]\">\n <Img\n src={`https://intlayer.org/assets/favicon-32x32.png`}\n width=\"40\"\n height=\"37\"\n alt=\"Intlayer\"\n className=\"mx-auto my-0\"\n />\n </Section>\n <Heading className=\"mx-0 my-[30px] p-0 text-center text-[24px] font-normal text-black\">\n Welcome to <strong>Intlayer</strong>\n </Heading>\n <Text className=\"text-[14px] leading-[24px] text-black\">\n Hello {username},\n </Text>\n <Text className=\"text-[14px] leading-[24px] text-black\">\n We're excited to have you on board! Get started by logging in to\n your <strong>Intlayer</strong> account.\n </Text>\n\n <Section className=\"my-[32px] text-center\">\n <Button\n className=\"rounded-md bg-[#000000] px-5 py-3 text-center text-[12px] font-semibold text-white no-underline\"\n href={loginLink}\n >\n Log In to Your Account\n </Button>\n </Section>\n <Text className=\"text-[14px] leading-[24px] text-black\">\n or copy and paste this URL into your browser:{' '}\n <Link href={loginLink} className=\"text-[#E879BA] no-underline\">\n {loginLink}\n </Link>\n </Text>\n <Hr className=\"mx-0 my-[26px] w-full border border-solid border-[#eaeaea]\" />\n <Text className=\"text-[12px] leading-[24px] text-[#666666]\">\n If you have any questions or need help getting started, feel free\n to reply to this email. We're here to help!\n </Text>\n </Container>\n </Body>\n </Tailwind>\n </Html>\n );\n};\n\nexport const WelcomeEmailFR = ({ username, loginLink }: WelcomeEmailProps) => {\n const previewText = `Bienvenue chez Intlayer !`;\n\n return (\n <Html>\n <Head />\n <Preview>{previewText}</Preview>\n <Tailwind>\n <Body className=\"m-auto px-2 font-sans\">\n <Container className=\"mx-auto my-[40px] max-w-[465px] rounded-xl border border-solid border-[#eaeaea] bg-white p-[20px]\">\n <Section className=\"mt-[32px]\">\n <Img\n src={`https://intlayer.org/assets/favicon-32x32.png`}\n width=\"40\"\n height=\"37\"\n alt=\"Intlayer\"\n className=\"mx-auto my-0\"\n />\n </Section>\n <Heading className=\"mx-0 my-[30px] p-0 text-center text-[24px] font-normal text-black\">\n Bienvenue chez <strong>Intlayer</strong>\n </Heading>\n <Text className=\"text-[14px] leading-[24px] text-black\">\n Bonjour {username},\n </Text>\n <Text className=\"text-[14px] leading-[24px] text-black\">\n Nous sommes ravis de vous avoir parmi nous ! Commencez par vous\n connecter à votre compte <strong>Intlayer</strong>.\n </Text>\n <Section className=\"my-[32px] text-center\">\n <Button\n className=\"rounded-md bg-[#000000] px-5 py-3 text-center text-[12px] font-semibold text-white no-underline\"\n href={loginLink}\n >\n Connectez-vous à votre compte\n </Button>\n </Section>\n <Text className=\"text-[14px] leading-[24px] text-black\">\n ou copiez et collez cette URL dans votre navigateur :{' '}\n <Link href={loginLink} className=\"text-[#E879BA] no-underline\">\n {loginLink}\n </Link>\n </Text>\n <Hr className=\"mx-0 my-[26px] w-full border border-solid border-[#eaeaea]\" />\n <Text className=\"text-[12px] leading-[24px] text-[#666666]\">\n Si vous avez des questions ou besoin d'aide pour commencer,\n n'hésitez pas à répondre à cet e-mail. Nous sommes là pour vous\n aider !\n </Text>\n </Container>\n </Body>\n </Tailwind>\n </Html>\n );\n};\n\nexport const WelcomeEmailES = ({ username, loginLink }: WelcomeEmailProps) => {\n const previewText = `¡Bienvenido a Intlayer!`;\n\n return (\n <Html>\n <Head />\n <Preview>{previewText}</Preview>\n <Tailwind>\n <Body className=\"m-auto px-2 font-sans\">\n <Container className=\"mx-auto my-[40px] max-w-[465px] rounded-xl border border-solid border-[#eaeaea] bg-white p-[20px]\">\n <Section className=\"mt-[32px]\">\n <Img\n src={`https://intlayer.org/assets/favicon-32x32.png`}\n width=\"40\"\n height=\"37\"\n alt=\"Intlayer\"\n className=\"mx-auto my-0\"\n />\n </Section>\n <Heading className=\"mx-0 my-[30px] p-0 text-center text-[24px] font-normal text-black\">\n Bienvenido a <strong>Intlayer</strong>\n </Heading>\n <Text className=\"text-[14px] leading-[24px] text-black\">\n Hola {username},\n </Text>\n <Text className=\"text-[14px] leading-[24px] text-black\">\n ¡Estamos emocionados de tenerte a bordo! Comienza iniciando sesión\n en tu cuenta de <strong>Intlayer</strong>.\n </Text>\n <Section className=\"my-[32px] text-center\">\n <Button\n className=\"rounded-md bg-[#000000] px-5 py-3 text-center text-[12px] font-semibold text-white no-underline\"\n href={loginLink}\n >\n Inicia sesión en tu cuenta\n </Button>\n </Section>\n <Text className=\"text-[14px] leading-[24px] text-black\">\n o copia y pega esta URL en tu navegador:{' '}\n <Link href={loginLink} className=\"text-[#E879BA] no-underline\">\n {loginLink}\n </Link>\n </Text>\n <Hr className=\"mx-0 my-[26px] w-full border border-solid border-[#eaeaea]\" />\n <Text className=\"text-[12px] leading-[24px] text-[#666666]\">\n Si tienes preguntas o necesitas ayuda para comenzar, no dudes en\n responder a este correo electrónico. ¡Estamos aquí para ayudarte!\n </Text>\n </Container>\n </Body>\n </Tailwind>\n </Html>\n );\n};\n\nconst PreviewProps: WelcomeEmailProps = {\n username: 'alanturing',\n loginLink: 'https://intlayer.org/login',\n};\n\nWelcomeEmailEN.PreviewProps = PreviewProps;\nWelcomeEmailFR.PreviewProps = PreviewProps;\nWelcomeEmailES.PreviewProps = PreviewProps;\n"],"mappings":"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","names":[]}
|
|
1
|
+
{"version":3,"sources":["../../../src/emails/Welcome.tsx"],"sourcesContent":["import {\n Body,\n Button,\n Container,\n Head,\n Heading,\n Hr,\n Html,\n Img,\n Preview,\n Section,\n Text,\n Tailwind,\n Link,\n} from '@react-email/components';\n\nexport type WelcomeEmailProps = {\n username: string;\n loginLink: string;\n};\n\nexport const WelcomeEmailEN = ({ username, loginLink }: WelcomeEmailProps) => {\n const previewText = `Welcome to Intlayer!`;\n\n return (\n <Html>\n <Head />\n <Preview>{previewText}</Preview>\n <Tailwind>\n <Body className=\"m-auto px-2 font-sans\">\n <Container className=\"mx-auto my-[40px] max-w-[465px] rounded-xl border border-solid border-[#eaeaea] bg-white p-[20px]\">\n <Section className=\"mt-[32px]\">\n <Img\n src={`https://intlayer.org/favicon-32x32.png`}\n width=\"40\"\n height=\"37\"\n alt=\"Intlayer\"\n className=\"mx-auto my-0\"\n />\n </Section>\n <Heading className=\"mx-0 my-[30px] p-0 text-center text-[24px] font-normal text-black\">\n Welcome to <strong>Intlayer</strong>\n </Heading>\n <Text className=\"text-[14px] leading-[24px] text-black\">\n Hello {username},\n </Text>\n <Text className=\"text-[14px] leading-[24px] text-black\">\n We're excited to have you on board! Get started by logging in to\n your <strong>Intlayer</strong> account.\n </Text>\n\n <Section className=\"my-[32px] text-center\">\n <Button\n className=\"rounded-md bg-[#000000] px-5 py-3 text-center text-[12px] font-semibold text-white no-underline\"\n href={loginLink}\n >\n Log In to Your Account\n </Button>\n </Section>\n <Text className=\"text-[14px] leading-[24px] text-black\">\n or copy and paste this URL into your browser:{' '}\n <Link href={loginLink} className=\"text-[#E879BA] no-underline\">\n {loginLink}\n </Link>\n </Text>\n <Hr className=\"mx-0 my-[26px] w-full border border-solid border-[#eaeaea]\" />\n <Text className=\"text-[12px] leading-[24px] text-[#666666]\">\n If you have any questions or need help getting started, feel free\n to reply to this email. We're here to help!\n </Text>\n </Container>\n </Body>\n </Tailwind>\n </Html>\n );\n};\n\nexport const WelcomeEmailFR = ({ username, loginLink }: WelcomeEmailProps) => {\n const previewText = `Bienvenue chez Intlayer !`;\n\n return (\n <Html>\n <Head />\n <Preview>{previewText}</Preview>\n <Tailwind>\n <Body className=\"m-auto px-2 font-sans\">\n <Container className=\"mx-auto my-[40px] max-w-[465px] rounded-xl border border-solid border-[#eaeaea] bg-white p-[20px]\">\n <Section className=\"mt-[32px]\">\n <Img\n src={`https://intlayer.org/favicon-32x32.png`}\n width=\"40\"\n height=\"37\"\n alt=\"Intlayer\"\n className=\"mx-auto my-0\"\n />\n </Section>\n <Heading className=\"mx-0 my-[30px] p-0 text-center text-[24px] font-normal text-black\">\n Bienvenue chez <strong>Intlayer</strong>\n </Heading>\n <Text className=\"text-[14px] leading-[24px] text-black\">\n Bonjour {username},\n </Text>\n <Text className=\"text-[14px] leading-[24px] text-black\">\n Nous sommes ravis de vous avoir parmi nous ! Commencez par vous\n connecter à votre compte <strong>Intlayer</strong>.\n </Text>\n <Section className=\"my-[32px] text-center\">\n <Button\n className=\"rounded-md bg-[#000000] px-5 py-3 text-center text-[12px] font-semibold text-white no-underline\"\n href={loginLink}\n >\n Connectez-vous à votre compte\n </Button>\n </Section>\n <Text className=\"text-[14px] leading-[24px] text-black\">\n ou copiez et collez cette URL dans votre navigateur :{' '}\n <Link href={loginLink} className=\"text-[#E879BA] no-underline\">\n {loginLink}\n </Link>\n </Text>\n <Hr className=\"mx-0 my-[26px] w-full border border-solid border-[#eaeaea]\" />\n <Text className=\"text-[12px] leading-[24px] text-[#666666]\">\n Si vous avez des questions ou besoin d'aide pour commencer,\n n'hésitez pas à répondre à cet e-mail. Nous sommes là pour vous\n aider !\n </Text>\n </Container>\n </Body>\n </Tailwind>\n </Html>\n );\n};\n\nexport const WelcomeEmailES = ({ username, loginLink }: WelcomeEmailProps) => {\n const previewText = `¡Bienvenido a Intlayer!`;\n\n return (\n <Html>\n <Head />\n <Preview>{previewText}</Preview>\n <Tailwind>\n <Body className=\"m-auto px-2 font-sans\">\n <Container className=\"mx-auto my-[40px] max-w-[465px] rounded-xl border border-solid border-[#eaeaea] bg-white p-[20px]\">\n <Section className=\"mt-[32px]\">\n <Img\n src={`https://intlayer.org/favicon-32x32.png`}\n width=\"40\"\n height=\"37\"\n alt=\"Intlayer\"\n className=\"mx-auto my-0\"\n />\n </Section>\n <Heading className=\"mx-0 my-[30px] p-0 text-center text-[24px] font-normal text-black\">\n Bienvenido a <strong>Intlayer</strong>\n </Heading>\n <Text className=\"text-[14px] leading-[24px] text-black\">\n Hola {username},\n </Text>\n <Text className=\"text-[14px] leading-[24px] text-black\">\n ¡Estamos emocionados de tenerte a bordo! Comienza iniciando sesión\n en tu cuenta de <strong>Intlayer</strong>.\n </Text>\n <Section className=\"my-[32px] text-center\">\n <Button\n className=\"rounded-md bg-[#000000] px-5 py-3 text-center text-[12px] font-semibold text-white no-underline\"\n href={loginLink}\n >\n Inicia sesión en tu cuenta\n </Button>\n </Section>\n <Text className=\"text-[14px] leading-[24px] text-black\">\n o copia y pega esta URL en tu navegador:{' '}\n <Link href={loginLink} className=\"text-[#E879BA] no-underline\">\n {loginLink}\n </Link>\n </Text>\n <Hr className=\"mx-0 my-[26px] w-full border border-solid border-[#eaeaea]\" />\n <Text className=\"text-[12px] leading-[24px] text-[#666666]\">\n Si tienes preguntas o necesitas ayuda para comenzar, no dudes en\n responder a este correo electrónico. ¡Estamos aquí para ayudarte!\n </Text>\n </Container>\n </Body>\n </Tailwind>\n </Html>\n );\n};\n\nconst PreviewProps: WelcomeEmailProps = {\n username: 'alanturing',\n loginLink: 'https://intlayer.org/login',\n};\n\nWelcomeEmailEN.PreviewProps = PreviewProps;\nWelcomeEmailFR.PreviewProps = PreviewProps;\nWelcomeEmailES.PreviewProps = PreviewProps;\n"],"mappings":"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","names":[]}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../../src/schemas/dictionary.schema.ts"],"sourcesContent":["import { Schema } from 'mongoose';\nimport type { Dictionary, VersionedContentEl } from '@/types/dictionary.types';\n\nconst versionedContentElSchema = new Schema<VersionedContentEl>(\n {\n name: {\n type: String,\n },\n description: {\n type: String,\n },\n content: {\n type: Schema.Types.Mixed,\n required: true,\n },\n },\n {\n timestamps: true,\n }\n);\n\nexport const dictionarySchema = new Schema<Dictionary>(\n {\n projectIds: {\n type: [Schema.Types.ObjectId],\n ref: 'Project',\n required: true,\n },\n key: {\n type: String,\n required: true,\n },\n title: {\n type: String,\n default: '',\n },\n description: {\n type: String,\n default: '',\n },\n tags: {\n type: [String],\n default: [],\n },\n content: {\n type: Map,\n of: versionedContentElSchema,\n required: true,\n default: null,\n },\n creatorId: {\n type: Schema.Types.ObjectId,\n ref: 'User',\n required: true,\n },\n filePath: {\n type: Map,\n of: String,\n default: null,\n },\n
|
|
1
|
+
{"version":3,"sources":["../../../src/schemas/dictionary.schema.ts"],"sourcesContent":["import { Schema } from 'mongoose';\nimport type { Dictionary, VersionedContentEl } from '@/types/dictionary.types';\n\nconst versionedContentElSchema = new Schema<VersionedContentEl>(\n {\n name: {\n type: String,\n },\n description: {\n type: String,\n },\n content: {\n type: Schema.Types.Mixed,\n required: true,\n },\n },\n {\n timestamps: true,\n }\n);\n\nexport const dictionarySchema = new Schema<Dictionary>(\n {\n projectIds: {\n type: [Schema.Types.ObjectId],\n ref: 'Project',\n required: true,\n },\n key: {\n type: String,\n required: true,\n },\n title: {\n type: String,\n default: '',\n },\n description: {\n type: String,\n default: '',\n },\n tags: {\n type: [String],\n default: [],\n },\n content: {\n type: Map,\n of: versionedContentElSchema,\n required: true,\n default: null,\n },\n creatorId: {\n type: Schema.Types.ObjectId,\n ref: 'User',\n required: true,\n },\n filePath: {\n type: Map,\n of: String,\n default: null,\n },\n },\n {\n timestamps: true,\n }\n);\n"],"mappings":";;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,sBAAuB;AAGvB,MAAM,2BAA2B,IAAI;AAAA,EACnC;AAAA,IACE,MAAM;AAAA,MACJ,MAAM;AAAA,IACR;AAAA,IACA,aAAa;AAAA,MACX,MAAM;AAAA,IACR;AAAA,IACA,SAAS;AAAA,MACP,MAAM,uBAAO,MAAM;AAAA,MACnB,UAAU;AAAA,IACZ;AAAA,EACF;AAAA,EACA;AAAA,IACE,YAAY;AAAA,EACd;AACF;AAEO,MAAM,mBAAmB,IAAI;AAAA,EAClC;AAAA,IACE,YAAY;AAAA,MACV,MAAM,CAAC,uBAAO,MAAM,QAAQ;AAAA,MAC5B,KAAK;AAAA,MACL,UAAU;AAAA,IACZ;AAAA,IACA,KAAK;AAAA,MACH,MAAM;AAAA,MACN,UAAU;AAAA,IACZ;AAAA,IACA,OAAO;AAAA,MACL,MAAM;AAAA,MACN,SAAS;AAAA,IACX;AAAA,IACA,aAAa;AAAA,MACX,MAAM;AAAA,MACN,SAAS;AAAA,IACX;AAAA,IACA,MAAM;AAAA,MACJ,MAAM,CAAC,MAAM;AAAA,MACb,SAAS,CAAC;AAAA,IACZ;AAAA,IACA,SAAS;AAAA,MACP,MAAM;AAAA,MACN,IAAI;AAAA,MACJ,UAAU;AAAA,MACV,SAAS;AAAA,IACX;AAAA,IACA,WAAW;AAAA,MACT,MAAM,uBAAO,MAAM;AAAA,MACnB,KAAK;AAAA,MACL,UAAU;AAAA,IACZ;AAAA,IACA,UAAU;AAAA,MACR,MAAM;AAAA,MACN,IAAI;AAAA,MACJ,SAAS;AAAA,IACX;AAAA,EACF;AAAA,EACA;AAAA,IACE,YAAY;AAAA,EACd;AACF;","names":[]}
|
|
@@ -231,10 +231,16 @@ const updateDictionaryByKey = async (dictionaryKey, dictionary, projectId) => {
|
|
|
231
231
|
errors
|
|
232
232
|
});
|
|
233
233
|
}
|
|
234
|
+
const dd = dictionaryToUpdate;
|
|
235
|
+
if (dd.content instanceof Map) {
|
|
236
|
+
dd.content = Object.fromEntries(dd.content);
|
|
237
|
+
}
|
|
238
|
+
console.log("dictionaryToUpdate 2", dictionaryToUpdate);
|
|
234
239
|
const result = await import_dictionary.DictionaryModel.updateOne(
|
|
235
240
|
{ key: dictionaryKey, projectIds: projectId },
|
|
236
241
|
dictionaryToUpdate
|
|
237
242
|
);
|
|
243
|
+
console.log("result", result);
|
|
238
244
|
if (result.matchedCount === 0) {
|
|
239
245
|
throw new import_errors.GenericError("DICTIONARY_UPDATE_FAILED", { dictionaryKey });
|
|
240
246
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../../src/services/dictionary.service.ts"],"sourcesContent":["import { DictionaryModel } from '@models/dictionary.model';\nimport { ensureMongoDocumentToObject } from '@utils/ensureMongoDocumentToObject';\nimport { GenericError } from '@utils/errors';\nimport type { DictionaryFilters } from '@utils/filtersAndPagination/getDictionaryFiltersAndPagination';\nimport { removeObjectKeys } from '@utils/removeObjectKeys';\nimport {\n type DictionaryFields,\n validateDictionary,\n} from '@utils/validation/validateDictionary';\nimport type { ObjectId } from 'mongoose';\nimport type {\n Dictionary,\n DictionaryData,\n DictionaryDocument,\n} from '@/types/dictionary.types';\nimport type { Project } from '@/types/project.types';\n\n/**\n * Finds dictionaries based on filters and pagination options.\n * @param filters - MongoDB filter query.\n * @param skip - Number of documents to skip.\n * @param limit - Number of documents to limit.\n * @returns List of dictionaries matching the filters.\n */\nexport const findDictionaries = async (\n filters: DictionaryFilters,\n skip = 0,\n limit = 100\n): Promise<DictionaryDocument[]> => {\n try {\n const dictionaries = await DictionaryModel.aggregate<DictionaryDocument>([\n // Stage 1: Match the filters\n { $match: filters },\n\n // Stage 2: Skip for pagination\n { $skip: skip },\n\n // Stage 3: Limit the number of documents\n { $limit: limit },\n\n // Stage 4: Add the 'availableVersions' field\n {\n $addFields: {\n availableVersions: {\n $map: {\n input: { $objectToArray: '$content' },\n as: 'version',\n in: '$$version.k',\n },\n },\n },\n },\n\n // (Optional) Stage 5: Project the fields you want to include/exclude\n // For example, to exclude the entire 'content' field and keep only 'availableVersions'\n // {\n // $project: {\n // content: 0 // Exclude the 'content' field\n // }\n // }\n ]);\n\n const formattedResults = dictionaries.map(\n (result) => new DictionaryModel(result)\n );\n\n return formattedResults;\n } catch (error) {\n console.error('Error fetching dictionaries:', error);\n throw error;\n }\n};\n\n/**\n * Finds a dictionary by its ID.\n * @param dictionaryId - The ID of the dictionary to find.\n * @returns The dictionary matching the ID.\n */\n/**\n * Finds a dictionary by its ID and includes the 'availableVersions' field.\n * @param dictionaryId - The ID of the dictionary to find.\n * @returns The dictionary matching the ID with available versions.\n */\nexport const getDictionaryById = async (\n dictionaryId: string | ObjectId\n): Promise<DictionaryDocument> => {\n const dictionaries = await DictionaryModel.aggregate<DictionaryDocument>([\n // Stage 1: Match the document by ID\n { $match: { _id: dictionaryId } },\n\n // Stage 2: Add the 'availableVersions' field\n {\n $addFields: {\n availableVersions: {\n $map: {\n input: { $objectToArray: '$content' },\n as: 'version',\n in: '$$version.k',\n },\n },\n },\n },\n ]);\n\n if (!dictionaries.length) {\n throw new GenericError('DICTIONARY_NOT_FOUND', { dictionaryId });\n }\n\n return new DictionaryModel(dictionaries[0]);\n};\n\n/**\n * Finds a dictionary by its ID.\n * @param dictionaryKey - The ID of the dictionary to find.\n * @returns The dictionary matching the ID.\n */\nexport const getDictionaryByKey = async (\n dictionaryKey: string,\n projectId: string | ObjectId\n): Promise<DictionaryDocument> => {\n const dictionaries = await getDictionariesByKeys([dictionaryKey], projectId);\n\n return dictionaries[0];\n};\n\nexport const getDictionariesByKeys = async (\n dictionaryKeys: string[],\n projectId: string | ObjectId\n): Promise<DictionaryDocument[]> => {\n const dictionaries = await DictionaryModel.aggregate<DictionaryDocument>([\n // Stage 1: Match the document by key\n { $match: { key: { $in: dictionaryKeys }, projectIds: projectId } },\n\n // Stage 2: Add the 'availableVersions' field\n {\n $addFields: {\n availableVersions: {\n $map: {\n input: { $objectToArray: '$content' },\n as: 'version',\n in: '$$version.k',\n },\n },\n },\n },\n ]);\n\n if (!dictionaries) {\n throw new GenericError('DICTIONARY_NOT_FOUND', {\n dictionaryKeys,\n projectId,\n });\n }\n\n const formattedResults = dictionaries.map(\n (result) => new DictionaryModel(result)\n );\n\n return formattedResults;\n};\n\nexport const getDictionariesKeys = async (\n projectId: string | ObjectId\n): Promise<string[]> => {\n const dictionaries = await DictionaryModel.find({\n projectIds: projectId,\n }).select('key');\n\n return dictionaries.map((dictionary) => dictionary.key);\n};\n\nexport const getDictionariesByTags = async (\n tags: string[],\n projectId: string | Project['_id']\n): Promise<DictionaryDocument[]> => {\n const dictionaries = await DictionaryModel.aggregate<DictionaryDocument>([\n // Stage 1: Match the document by tags\n {\n $match: {\n tags: { $in: tags },\n projectIds: projectId,\n },\n },\n\n // Stage 2: Add the 'availableVersions' field\n {\n $addFields: {\n availableVersions: {\n $map: {\n input: { $objectToArray: '$content' },\n as: 'version',\n in: '$$version.k',\n },\n },\n },\n },\n ]);\n\n const formattedResults = dictionaries.map(\n (result) => new DictionaryModel(result)\n );\n\n return formattedResults;\n};\n\n/**\n * Counts the total number of dictionaries that match the filters.\n * @param filters - MongoDB filter query.\n * @returns Total number of dictionaries.\n */\nexport const countDictionaries = async (\n filters: DictionaryFilters\n): Promise<number> => {\n const result = await DictionaryModel.countDocuments(filters);\n\n if (typeof result === 'undefined') {\n throw new GenericError('DICTIONARY_COUNT_FAILED', { filters });\n }\n\n return result;\n};\n\n/**\n * Creates a new dictionary in the database.\n * @param dictionary - The dictionary data to create.\n * @returns The created dictionary.\n */\nexport const createDictionary = async (\n dictionary: DictionaryData\n): Promise<DictionaryDocument> => {\n const errors = await validateDictionary(dictionary);\n\n if (Object.keys(errors).length > 0) {\n throw new GenericError('DICTIONARY_INVALID_FIELDS', {\n errors,\n });\n }\n\n return await DictionaryModel.create(dictionary);\n};\n\ntype GetExistingDictionaryResult = {\n existingDictionariesKey: string[];\n newDictionariesKey: string[];\n};\n\n/**\n * Gets the existing dictionaries from the provided list of keys.\n * @param dictionariesKeys - List of dictionary keys to check.\n * @param projectId - The ID of the project to check the dictionaries against.\n * @returns The existing dictionaries and the new dictionaries.\n */\nexport const getExistingDictionaryKey = async (\n dictionariesKeys: string[],\n projectId: string | ObjectId\n): Promise<GetExistingDictionaryResult> => {\n // Fetch dictionaries from the database where the key is in the provided list\n const existingDictionaries = await DictionaryModel.find({\n key: { $in: dictionariesKeys },\n projectIds: projectId,\n });\n\n // Map existing dictionaries to a LocalDictionary object\n const existingDictionariesKey: string[] = [];\n const newDictionariesKey: string[] = [];\n\n for (const key of dictionariesKeys) {\n const isDictionaryExist = existingDictionaries.some(\n (dictionary) => dictionary.key === key\n );\n\n if (isDictionaryExist) {\n existingDictionariesKey.push(key);\n } else {\n newDictionariesKey.push(key);\n }\n }\n\n return { existingDictionariesKey, newDictionariesKey };\n};\n\n/**\n * Updates an existing dictionary in the database by its ID.\n * @param dictionaryId - The ID of the dictionary to update.\n * @param dictionary - The updated dictionary data.\n * @returns The updated dictionary.\n */\nexport const updateDictionaryById = async (\n dictionaryId: string | ObjectId,\n dictionary: Partial<Dictionary>\n): Promise<DictionaryDocument> => {\n const dictionaryObject = ensureMongoDocumentToObject(dictionary);\n const dictionaryToUpdate = removeObjectKeys(dictionaryObject, ['_id']);\n\n const updatedKeys = Object.keys(dictionaryToUpdate) as DictionaryFields;\n const errors = await validateDictionary(dictionaryToUpdate, updatedKeys);\n\n if (Object.keys(errors).length > 0) {\n throw new GenericError('DICTIONARY_INVALID_FIELDS', {\n dictionaryId,\n errors,\n });\n }\n\n const result = await DictionaryModel.updateOne(\n { _id: dictionaryId },\n dictionaryToUpdate\n );\n\n if (result.matchedCount === 0) {\n throw new GenericError('DICTIONARY_UPDATE_FAILED', { dictionaryId });\n }\n\n const updatedDictionary = await getDictionaryById(dictionaryId);\n\n return updatedDictionary;\n};\n\n/**\n * Updates an existing dictionary in the database by its key.\n * @param dictionaryKey - The ID of the dictionary to update.\n * @param dictionary - The updated dictionary data.\n * @returns The updated dictionary.\n */\nexport const updateDictionaryByKey = async (\n dictionaryKey: string,\n dictionary: Partial<Dictionary>,\n projectId: string | ObjectId\n): Promise<DictionaryDocument> => {\n const dictionaryObject = ensureMongoDocumentToObject(dictionary);\n\n const dictionaryToUpdate = removeObjectKeys(dictionaryObject, ['_id']);\n\n const updatedKeys = Object.keys(dictionaryToUpdate) as DictionaryFields;\n const errors = await validateDictionary(dictionaryToUpdate, updatedKeys);\n\n if (Object.keys(errors).length > 0) {\n throw new GenericError('DICTIONARY_INVALID_FIELDS', {\n dictionaryKey,\n projectId,\n errors,\n });\n }\n\n const result = await DictionaryModel.updateOne(\n { key: dictionaryKey, projectIds: projectId },\n dictionaryToUpdate\n );\n\n if (result.matchedCount === 0) {\n throw new GenericError('DICTIONARY_UPDATE_FAILED', { dictionaryKey });\n }\n\n const updatedDictionary = await getDictionaryByKey(dictionaryKey, projectId);\n\n return updatedDictionary;\n};\n\n/**\n * Deletes a dictionary from the database by its ID.\n * @param dictionaryId - The ID of the dictionary to delete.\n * @returns The result of the deletion operation.\n */\nexport const deleteDictionaryById = async (\n dictionaryId: string\n): Promise<DictionaryDocument> => {\n const dictionary = await DictionaryModel.findByIdAndDelete(dictionaryId);\n\n if (!dictionary) {\n throw new GenericError('DICTIONARY_NOT_FOUND', { dictionaryId });\n }\n\n return dictionary;\n};\n\nexport const incrementVersion = (dictionary: Dictionary): string => {\n const VERSION_PREFIX = 'v';\n const availableVersions = dictionary.availableVersions ?? [];\n\n // Get the current version from the version list, default to 'v1' if not present\n const currentVersion =\n availableVersions.length > 0\n ? availableVersions[availableVersions.length - 1]\n : 'v1';\n\n // Function to extract the numeric part of the version\n const getVersionNumber = (version: string): number => {\n const match = version.match(/^v(\\d+)$/);\n if (!match) {\n throw new Error(`Invalid version format: ${version}`);\n }\n return parseInt(match[1], 10);\n };\n\n // Start with the next version number\n let newNumber = getVersionNumber(currentVersion) + 1;\n let newVersion = `${VERSION_PREFIX}${newNumber}`;\n\n // Loop until a unique version is found\n while (availableVersions.includes(newVersion)) {\n newNumber += 1;\n newVersion = `${VERSION_PREFIX}${newNumber}`;\n }\n\n return newVersion;\n};\n"],"mappings":"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","names":[]}
|
|
1
|
+
{"version":3,"sources":["../../../src/services/dictionary.service.ts"],"sourcesContent":["import { DictionaryModel } from '@models/dictionary.model';\nimport { ensureMongoDocumentToObject } from '@utils/ensureMongoDocumentToObject';\nimport { GenericError } from '@utils/errors';\nimport type { DictionaryFilters } from '@utils/filtersAndPagination/getDictionaryFiltersAndPagination';\nimport { removeObjectKeys } from '@utils/removeObjectKeys';\nimport {\n type DictionaryFields,\n validateDictionary,\n} from '@utils/validation/validateDictionary';\nimport type { ObjectId } from 'mongoose';\nimport type {\n Dictionary,\n DictionaryData,\n DictionaryDocument,\n} from '@/types/dictionary.types';\nimport type { Project } from '@/types/project.types';\n\n/**\n * Finds dictionaries based on filters and pagination options.\n * @param filters - MongoDB filter query.\n * @param skip - Number of documents to skip.\n * @param limit - Number of documents to limit.\n * @returns List of dictionaries matching the filters.\n */\nexport const findDictionaries = async (\n filters: DictionaryFilters,\n skip = 0,\n limit = 100\n): Promise<DictionaryDocument[]> => {\n try {\n const dictionaries = await DictionaryModel.aggregate<DictionaryDocument>([\n // Stage 1: Match the filters\n { $match: filters },\n\n // Stage 2: Skip for pagination\n { $skip: skip },\n\n // Stage 3: Limit the number of documents\n { $limit: limit },\n\n // Stage 4: Add the 'availableVersions' field\n {\n $addFields: {\n availableVersions: {\n $map: {\n input: { $objectToArray: '$content' },\n as: 'version',\n in: '$$version.k',\n },\n },\n },\n },\n\n // (Optional) Stage 5: Project the fields you want to include/exclude\n // For example, to exclude the entire 'content' field and keep only 'availableVersions'\n // {\n // $project: {\n // content: 0 // Exclude the 'content' field\n // }\n // }\n ]);\n\n const formattedResults = dictionaries.map(\n (result) => new DictionaryModel(result)\n );\n\n return formattedResults;\n } catch (error) {\n console.error('Error fetching dictionaries:', error);\n throw error;\n }\n};\n\n/**\n * Finds a dictionary by its ID.\n * @param dictionaryId - The ID of the dictionary to find.\n * @returns The dictionary matching the ID.\n */\n/**\n * Finds a dictionary by its ID and includes the 'availableVersions' field.\n * @param dictionaryId - The ID of the dictionary to find.\n * @returns The dictionary matching the ID with available versions.\n */\nexport const getDictionaryById = async (\n dictionaryId: string | ObjectId\n): Promise<DictionaryDocument> => {\n const dictionaries = await DictionaryModel.aggregate<DictionaryDocument>([\n // Stage 1: Match the document by ID\n { $match: { _id: dictionaryId } },\n\n // Stage 2: Add the 'availableVersions' field\n {\n $addFields: {\n availableVersions: {\n $map: {\n input: { $objectToArray: '$content' },\n as: 'version',\n in: '$$version.k',\n },\n },\n },\n },\n ]);\n\n if (!dictionaries.length) {\n throw new GenericError('DICTIONARY_NOT_FOUND', { dictionaryId });\n }\n\n return new DictionaryModel(dictionaries[0]);\n};\n\n/**\n * Finds a dictionary by its ID.\n * @param dictionaryKey - The ID of the dictionary to find.\n * @returns The dictionary matching the ID.\n */\nexport const getDictionaryByKey = async (\n dictionaryKey: string,\n projectId: string | ObjectId\n): Promise<DictionaryDocument> => {\n const dictionaries = await getDictionariesByKeys([dictionaryKey], projectId);\n\n return dictionaries[0];\n};\n\nexport const getDictionariesByKeys = async (\n dictionaryKeys: string[],\n projectId: string | ObjectId\n): Promise<DictionaryDocument[]> => {\n const dictionaries = await DictionaryModel.aggregate<DictionaryDocument>([\n // Stage 1: Match the document by key\n { $match: { key: { $in: dictionaryKeys }, projectIds: projectId } },\n\n // Stage 2: Add the 'availableVersions' field\n {\n $addFields: {\n availableVersions: {\n $map: {\n input: { $objectToArray: '$content' },\n as: 'version',\n in: '$$version.k',\n },\n },\n },\n },\n ]);\n\n if (!dictionaries) {\n throw new GenericError('DICTIONARY_NOT_FOUND', {\n dictionaryKeys,\n projectId,\n });\n }\n\n const formattedResults = dictionaries.map(\n (result) => new DictionaryModel(result)\n );\n\n return formattedResults;\n};\n\nexport const getDictionariesKeys = async (\n projectId: string | ObjectId\n): Promise<string[]> => {\n const dictionaries = await DictionaryModel.find({\n projectIds: projectId,\n }).select('key');\n\n return dictionaries.map((dictionary) => dictionary.key);\n};\n\nexport const getDictionariesByTags = async (\n tags: string[],\n projectId: string | Project['_id']\n): Promise<DictionaryDocument[]> => {\n const dictionaries = await DictionaryModel.aggregate<DictionaryDocument>([\n // Stage 1: Match the document by tags\n {\n $match: {\n tags: { $in: tags },\n projectIds: projectId,\n },\n },\n\n // Stage 2: Add the 'availableVersions' field\n {\n $addFields: {\n availableVersions: {\n $map: {\n input: { $objectToArray: '$content' },\n as: 'version',\n in: '$$version.k',\n },\n },\n },\n },\n ]);\n\n const formattedResults = dictionaries.map(\n (result) => new DictionaryModel(result)\n );\n\n return formattedResults;\n};\n\n/**\n * Counts the total number of dictionaries that match the filters.\n * @param filters - MongoDB filter query.\n * @returns Total number of dictionaries.\n */\nexport const countDictionaries = async (\n filters: DictionaryFilters\n): Promise<number> => {\n const result = await DictionaryModel.countDocuments(filters);\n\n if (typeof result === 'undefined') {\n throw new GenericError('DICTIONARY_COUNT_FAILED', { filters });\n }\n\n return result;\n};\n\n/**\n * Creates a new dictionary in the database.\n * @param dictionary - The dictionary data to create.\n * @returns The created dictionary.\n */\nexport const createDictionary = async (\n dictionary: DictionaryData\n): Promise<DictionaryDocument> => {\n const errors = await validateDictionary(dictionary);\n\n if (Object.keys(errors).length > 0) {\n throw new GenericError('DICTIONARY_INVALID_FIELDS', {\n errors,\n });\n }\n\n return await DictionaryModel.create(dictionary);\n};\n\ntype GetExistingDictionaryResult = {\n existingDictionariesKey: string[];\n newDictionariesKey: string[];\n};\n\n/**\n * Gets the existing dictionaries from the provided list of keys.\n * @param dictionariesKeys - List of dictionary keys to check.\n * @param projectId - The ID of the project to check the dictionaries against.\n * @returns The existing dictionaries and the new dictionaries.\n */\nexport const getExistingDictionaryKey = async (\n dictionariesKeys: string[],\n projectId: string | ObjectId\n): Promise<GetExistingDictionaryResult> => {\n // Fetch dictionaries from the database where the key is in the provided list\n const existingDictionaries = await DictionaryModel.find({\n key: { $in: dictionariesKeys },\n projectIds: projectId,\n });\n\n // Map existing dictionaries to a LocalDictionary object\n const existingDictionariesKey: string[] = [];\n const newDictionariesKey: string[] = [];\n\n for (const key of dictionariesKeys) {\n const isDictionaryExist = existingDictionaries.some(\n (dictionary) => dictionary.key === key\n );\n\n if (isDictionaryExist) {\n existingDictionariesKey.push(key);\n } else {\n newDictionariesKey.push(key);\n }\n }\n\n return { existingDictionariesKey, newDictionariesKey };\n};\n\n/**\n * Updates an existing dictionary in the database by its ID.\n * @param dictionaryId - The ID of the dictionary to update.\n * @param dictionary - The updated dictionary data.\n * @returns The updated dictionary.\n */\nexport const updateDictionaryById = async (\n dictionaryId: string | ObjectId,\n dictionary: Partial<Dictionary>\n): Promise<DictionaryDocument> => {\n const dictionaryObject = ensureMongoDocumentToObject(dictionary);\n const dictionaryToUpdate = removeObjectKeys(dictionaryObject, ['_id']);\n\n const updatedKeys = Object.keys(dictionaryToUpdate) as DictionaryFields;\n const errors = await validateDictionary(dictionaryToUpdate, updatedKeys);\n\n if (Object.keys(errors).length > 0) {\n throw new GenericError('DICTIONARY_INVALID_FIELDS', {\n dictionaryId,\n errors,\n });\n }\n\n const result = await DictionaryModel.updateOne(\n { _id: dictionaryId },\n dictionaryToUpdate\n );\n\n if (result.matchedCount === 0) {\n throw new GenericError('DICTIONARY_UPDATE_FAILED', { dictionaryId });\n }\n\n const updatedDictionary = await getDictionaryById(dictionaryId);\n\n return updatedDictionary;\n};\n\n/**\n * Updates an existing dictionary in the database by its key.\n * @param dictionaryKey - The ID of the dictionary to update.\n * @param dictionary - The updated dictionary data.\n * @returns The updated dictionary.\n */\nexport const updateDictionaryByKey = async (\n dictionaryKey: string,\n dictionary: Partial<Dictionary>,\n projectId: string | ObjectId\n): Promise<DictionaryDocument> => {\n const dictionaryObject = ensureMongoDocumentToObject(dictionary);\n const dictionaryToUpdate = removeObjectKeys(dictionaryObject, ['_id']);\n\n const updatedKeys = Object.keys(dictionaryToUpdate) as DictionaryFields;\n const errors = await validateDictionary(dictionaryToUpdate, updatedKeys);\n\n if (Object.keys(errors).length > 0) {\n throw new GenericError('DICTIONARY_INVALID_FIELDS', {\n dictionaryKey,\n projectId,\n errors,\n });\n }\n\n const dd = dictionaryToUpdate;\n\n // Convert Map fields to plain objects\n if (dd.content instanceof Map) {\n dd.content = Object.fromEntries(dd.content) as any;\n }\n\n console.log('dictionaryToUpdate 2', dictionaryToUpdate);\n\n const result = await DictionaryModel.updateOne(\n { key: dictionaryKey, projectIds: projectId },\n dictionaryToUpdate\n );\n\n console.log('result', result);\n\n if (result.matchedCount === 0) {\n throw new GenericError('DICTIONARY_UPDATE_FAILED', { dictionaryKey });\n }\n\n const updatedDictionary = await getDictionaryByKey(dictionaryKey, projectId);\n\n return updatedDictionary;\n};\n\n/**\n * Deletes a dictionary from the database by its ID.\n * @param dictionaryId - The ID of the dictionary to delete.\n * @returns The result of the deletion operation.\n */\nexport const deleteDictionaryById = async (\n dictionaryId: string\n): Promise<DictionaryDocument> => {\n const dictionary = await DictionaryModel.findByIdAndDelete(dictionaryId);\n\n if (!dictionary) {\n throw new GenericError('DICTIONARY_NOT_FOUND', { dictionaryId });\n }\n\n return dictionary;\n};\n\nexport const incrementVersion = (dictionary: Dictionary): string => {\n const VERSION_PREFIX = 'v';\n const availableVersions = dictionary.availableVersions ?? [];\n\n // Get the current version from the version list, default to 'v1' if not present\n const currentVersion =\n availableVersions.length > 0\n ? availableVersions[availableVersions.length - 1]\n : 'v1';\n\n // Function to extract the numeric part of the version\n const getVersionNumber = (version: string): number => {\n const match = version.match(/^v(\\d+)$/);\n if (!match) {\n throw new Error(`Invalid version format: ${version}`);\n }\n return parseInt(match[1], 10);\n };\n\n // Start with the next version number\n let newNumber = getVersionNumber(currentVersion) + 1;\n let newVersion = `${VERSION_PREFIX}${newNumber}`;\n\n // Loop until a unique version is found\n while (availableVersions.includes(newVersion)) {\n newNumber += 1;\n newVersion = `${VERSION_PREFIX}${newNumber}`;\n }\n\n return newVersion;\n};\n"],"mappings":"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","names":[]}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../../src/types/dictionary.types.ts"],"sourcesContent":["import {\n type ContentNode,\n type Dictionary as DictionaryCore,\n} from '@intlayer/core';\nimport type { Model, ObjectId, Document } from 'mongoose';\nimport type { Project } from './project.types';\nimport type { User } from './user.types';\n\nexport type DictionaryCreationData = {\n projectIds: (Project['_id'] | string)[];\n key: string;\n content?: ContentNode;\n title?: string;\n description?: string;\n tags?: string[];\n filePath?: string;\n};\n\nexport type VersionedContentEl = {\n name?: string;\n description?: string;\n content: ContentNode;\n};\n\nexport type ContentVersion = string;\nexport type VersionedContent = Map<string, VersionedContentEl>;\n\nexport type DictionaryData = {\n key: string;\n content: VersionedContent;\n projectIds: (Project['_id'] | string)[];\n creatorId: User['_id'];\n title?: string;\n description?: string;\n tags?: string[];\n filePath?: Record<string, string>;\n
|
|
1
|
+
{"version":3,"sources":["../../../src/types/dictionary.types.ts"],"sourcesContent":["import {\n type ContentNode,\n type Dictionary as DictionaryCore,\n} from '@intlayer/core';\nimport type { Model, ObjectId, Document } from 'mongoose';\nimport type { Project } from './project.types';\nimport type { User } from './user.types';\n\nexport type DictionaryCreationData = {\n projectIds: (Project['_id'] | string)[];\n key: string;\n content?: ContentNode;\n title?: string;\n description?: string;\n tags?: string[];\n filePath?: string;\n};\n\nexport type VersionedContentEl = {\n name?: string;\n description?: string;\n content: ContentNode;\n};\n\nexport type ContentVersion = string;\nexport type VersionedContent = Map<string, VersionedContentEl>;\n\nexport type DictionaryData = {\n key: string;\n content: VersionedContent;\n projectIds: (Project['_id'] | string)[];\n creatorId: User['_id'];\n title?: string;\n description?: string;\n tags?: string[];\n filePath?: Record<string, string>;\n};\n\nexport type Dictionary = DictionaryData & {\n _id: ObjectId;\n createdAt: number;\n updatedAt: number;\n availableVersions?: string[];\n};\n\nexport type DictionaryAPI = DictionaryCore & {\n projectIds: (Project['_id'] | string)[];\n};\n\nexport type DictionaryDocument = Document<unknown, {}, Dictionary> & Dictionary;\nexport type DictionaryModelType = Model<Dictionary>;\n"],"mappings":";;;;;;;;;;;;;;AAAA;AAAA;","names":[]}
|
|
@@ -76,7 +76,7 @@ const auditDictionary = async ({
|
|
|
76
76
|
FILE_TEMPLATE[fileExtension]
|
|
77
77
|
).replace("{{fileContent}}", fileContent).replace("{{tagsInstructions}}", formatTagInstructions(tags));
|
|
78
78
|
const chatCompletion = await openai.chat.completions.create({
|
|
79
|
-
model: model ?? "gpt-4o-
|
|
79
|
+
model: model ?? "gpt-4o-2024-11-20",
|
|
80
80
|
messages: [{ role: "system", content: prompt }]
|
|
81
81
|
});
|
|
82
82
|
const newContent = chatCompletion.choices[0].message?.content;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../../../src/utils/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 AuditOptions = {\n locales: Locales[];\n defaultLocale: Locales;\n fileContent: string;\n filePath?: string;\n model?: string;\n openAiApiKey: string;\n customPrompt?: string;\n tags?: Tag[];\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\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 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,\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: model ?? 'gpt-4o-
|
|
1
|
+
{"version":3,"sources":["../../../../src/utils/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 AuditOptions = {\n locales: Locales[];\n defaultLocale: Locales;\n fileContent: string;\n filePath?: string;\n model?: string;\n openAiApiKey: string;\n customPrompt?: string;\n tags?: Tag[];\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\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 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,\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: 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,kBAA8B;AAC9B,oBAAuB;AAEvB,oBAAuB;AANvB;AASA,MAAM,gBAAY,yBAAQ,0BAAc,YAAY,GAAG,CAAC;AAqBxD,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;AACF,MAA8D;AAC5D,MAAI;AAIF,UAAM,SAAS,IAAI,qBAAO;AAAA,MACxB,QAAQ;AAAA,IACV,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,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,12 +1,12 @@
|
|
|
1
|
-
You are an expert in internationalization, copy writing and content management. Your task is to audit the given
|
|
1
|
+
You are an expert in internationalization, copy writing and content management. Your task is to audit the given dictionary. If the element is not declared, review it. If this element is missing, write it by considering the given context of the dictionary, and by following instructions.
|
|
2
2
|
|
|
3
3
|
**Instructions:**
|
|
4
4
|
|
|
5
5
|
1. **Terminology:**
|
|
6
6
|
|
|
7
|
-
- **Dictionary:** A
|
|
8
|
-
- **Tag:** A tag is attached to a
|
|
9
|
-
- **KeyPath** The KeyPath correspond to to the path to retrieve the targeted element from the `content` key of the
|
|
7
|
+
- **Dictionary:** A dictionary is a is a file (.ts, .js or .json) that contains the multilingual declaration related to a specific content. A dictionary file is usually related to a specific component, or page or section of a website.
|
|
8
|
+
- **Tag:** A tag is attached to a dictionary and is used to group dictionary and harmonize them.
|
|
9
|
+
- **KeyPath** The KeyPath correspond to to the path to retrieve the targeted element from the `content` key of the dictionary file.
|
|
10
10
|
|
|
11
11
|
2. **Locales:**
|
|
12
12
|
|
|
@@ -15,6 +15,7 @@ You are an expert in internationalization, copy writing and content management.
|
|
|
15
15
|
3. **Audit Requirements:**
|
|
16
16
|
|
|
17
17
|
- **Consistency:** Ensure that all keys have translations for all specified locales.
|
|
18
|
+
- **Incoherence:** Ensure that all content is coherent and not misspelled.
|
|
18
19
|
- **Missing Content:** Identify any missing translations and specify the expected content.
|
|
19
20
|
- **Misplaced Content:** Detect if any translations are placed under incorrect keys.
|
|
20
21
|
- **Type Compliance:** Verify that the content types match the declarations (e.g., strings, string arrays).
|
|
@@ -23,7 +24,8 @@ You are an expert in internationalization, copy writing and content management.
|
|
|
23
24
|
|
|
24
25
|
- **Return Only the Targeted Content:** Provide the updated targeted content as plain text without any markdown, additional comments or explanations.
|
|
25
26
|
- **Consider the locale context:** If the targeted field correspond to a specific language, contains similar languages, as `zh` or `en-GB`, consider return the content in this specified language.
|
|
26
|
-
- **
|
|
27
|
+
- **Fix Incoherent Content:** If the content is inconsistent, misspelled, understandable, or contains errors, fix it by providing a more accurate content.
|
|
28
|
+
- **Escape Special Characters:** If the content contain special characters, escape them using the appropriate escape sequence.
|
|
27
29
|
- **Respect the tags instructions:** If the tags instructions are provided, ensure that the audited file adheres to them.
|
|
28
30
|
|
|
29
31
|
5. **Example Scenario:**
|
|
@@ -75,7 +77,7 @@ You are an expert in internationalization, copy writing and content management.
|
|
|
75
77
|
audienceType: {
|
|
76
78
|
object1: enu({
|
|
77
79
|
"1": t({
|
|
78
|
-
en: "
|
|
80
|
+
en: "Developes, _lln_ Managers",
|
|
79
81
|
es: "Desarrolladores, Gestores de Contenido",
|
|
80
82
|
fr: "Développeurs, Responsables de contenu",
|
|
81
83
|
}),
|
|
@@ -92,7 +94,15 @@ You are an expert in internationalization, copy writing and content management.
|
|
|
92
94
|
|
|
93
95
|
- **Input target:**
|
|
94
96
|
|
|
95
|
-
`[{type: "object", key: "audienceType"},{type: "enumeration", key: ">2"},{type: "
|
|
97
|
+
`[{type: "object", key: "audienceType"},{type: "enumeration", key: ">2"},{type: "translation", key: "es"}]`
|
|
98
|
+
|
|
99
|
+
- **Expected Output:**
|
|
100
|
+
|
|
101
|
+
Desarrolladores, Gestores de Contenido
|
|
102
|
+
|
|
103
|
+
- **Input target:**
|
|
104
|
+
|
|
105
|
+
`[{type: "object", key: "audienceType"},{type: "enumeration", key: "1"},{type: "translation", key: "fr"}]`
|
|
96
106
|
|
|
97
107
|
- **Expected Output:**
|
|
98
108
|
|
|
@@ -58,7 +58,7 @@ const auditDictionaryField = async ({
|
|
|
58
58
|
`{${locales.map(formatLocaleWithName).join(", ")}}`
|
|
59
59
|
).replace("{{keyPath}}", JSON.stringify(keyPath)).replace("{{fileContent}}", fileContent).replace("{{tagsInstructions}}", formatTagInstructions(tags));
|
|
60
60
|
const chatCompletion = await openai.chat.completions.create({
|
|
61
|
-
model: model ?? "gpt-4o-
|
|
61
|
+
model: model ?? "gpt-4o-2024-11-20",
|
|
62
62
|
messages: [{ role: "system", content: prompt }]
|
|
63
63
|
});
|
|
64
64
|
const newContent = chatCompletion.choices[0].message?.content;
|