payload-intl 0.0.1 → 0.0.3

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (46) hide show
  1. package/dist/components/MessageController.js +1 -1
  2. package/dist/components/MessagesForm.js +15 -14
  3. package/dist/components/MessagesForm.js.map +1 -1
  4. package/dist/components/actions/JsonImport.js +57 -0
  5. package/dist/components/actions/JsonImport.js.map +1 -0
  6. package/dist/components/inputs/InputWrapper.js +1 -1
  7. package/dist/components/inputs/MessageInput.js +21 -36
  8. package/dist/components/inputs/MessageInput.js.map +1 -1
  9. package/dist/components/inputs/RichTextInput.js +1 -1
  10. package/dist/components/inputs/toolbar/BlockElementSelect.js +1 -1
  11. package/dist/components/inputs/toolbar/LinkEditor.js +1 -1
  12. package/dist/components/inputs/toolbar/RichTextToolbar.js +1 -1
  13. package/dist/components/inputs/variables/VariableChip.js +20 -19
  14. package/dist/components/inputs/variables/VariableChip.js.map +1 -1
  15. package/dist/components/inputs/variables/VariableSuggestion.js +1 -1
  16. package/dist/components/inputs/variables/editors/PluralVariableEditor.js +2 -2
  17. package/dist/components/inputs/variables/editors/SelectVariableEditor.js +1 -1
  18. package/dist/components/inputs/variables/editors/TagVariableEditor.js +1 -1
  19. package/dist/components/inputs/variables/extension.js +3 -3
  20. package/dist/components/inputs/variables/pickers/NumericVariablePicker.js +1 -1
  21. package/dist/components/layout/MessageField.js +5 -5
  22. package/dist/components/layout/MessagesTabs.js +3 -3
  23. package/dist/components/layout/MessagesTree.js +3 -3
  24. package/dist/context/messages-form.js +26 -0
  25. package/dist/context/messages-form.js.map +1 -0
  26. package/dist/endpoints/set-messages.js +1 -1
  27. package/dist/exports/view.js +1 -1
  28. package/dist/requests/fetchMessages.js +1 -1
  29. package/dist/types.d.ts +2 -2
  30. package/dist/utils/cn.js +9 -0
  31. package/dist/utils/cn.js.map +1 -0
  32. package/dist/utils/config.js +8 -9
  33. package/dist/utils/config.js.map +1 -1
  34. package/dist/utils/format.js +15 -0
  35. package/dist/utils/format.js.map +1 -0
  36. package/dist/utils/guards.js +16 -0
  37. package/dist/utils/guards.js.map +1 -0
  38. package/dist/utils/icu-tranform.js +110 -0
  39. package/dist/utils/icu-tranform.js.map +1 -0
  40. package/dist/utils/sanitize.js +19 -0
  41. package/dist/utils/sanitize.js.map +1 -0
  42. package/dist/utils/schema.js +34 -0
  43. package/dist/utils/schema.js.map +1 -0
  44. package/dist/utils/validate.js +57 -0
  45. package/dist/utils/validate.js.map +1 -0
  46. package/package.json +1 -2
@@ -1,5 +1,5 @@
1
1
  import { Controller as l } from "react-hook-form";
2
- import { useMessagesForm as s } from "@/context/messages-form";
2
+ import { useMessagesForm as s } from "../context/messages-form.js";
3
3
  import { MessageInput as p } from "./inputs/MessageInput.js";
4
4
  import { RichTextInput as h } from "./inputs/RichTextInput.js";
5
5
  function B({
@@ -1,15 +1,16 @@
1
1
  "use client";
2
- import { useStepNav as N, Button as R } from "@payloadcms/ui";
2
+ import { useStepNav as v, Button as N } from "@payloadcms/ui";
3
3
  import { isEqual as S } from "lodash-es";
4
4
  import { useEffect as M, useState as x } from "react";
5
5
  import { useForm as y } from "react-hook-form";
6
6
  import { toast as f } from "sonner";
7
- import { MessagesFormProvider as T } from "@/context/messages-form";
8
- import { cn as d } from "@/utils/cn";
9
- import { MessageField as j } from "./layout/MessageField.js";
10
- import { MessagesTabs as F } from "./layout/MessagesTabs.js";
7
+ import { MessagesFormProvider as T } from "../context/messages-form.js";
8
+ import { cn as d } from "../utils/cn.js";
9
+ import { JsonImport as j } from "./actions/JsonImport.js";
10
+ import { MessageField as F } from "./layout/MessageField.js";
11
+ import { MessagesTabs as O } from "./layout/MessagesTabs.js";
11
12
  import { MessagesTree as p } from "./layout/MessagesTree.js";
12
- function J({
13
+ function U({
13
14
  locales: g,
14
15
  schema: a,
15
16
  tabs: r = !1,
@@ -17,7 +18,7 @@ function J({
17
18
  endpointUrl: h,
18
19
  richTextEditorOptions: u
19
20
  }) {
20
- const { setStepNav: n } = N();
21
+ const { setStepNav: n } = v();
21
22
  M(() => {
22
23
  n([{ label: "Intl Messages", url: "/intl" }]);
23
24
  }, [n]);
@@ -25,13 +26,13 @@ function J({
25
26
  defaultValues: c,
26
27
  reValidateMode: "onChange"
27
28
  }), [m, b] = x(Object.keys(a)[0]), E = async (e) => {
28
- const t = f.loading("Saving..."), v = Object.entries(e).reduce((o, [i, l]) => S(l, c[i]) ? o : {
29
+ const t = f.loading("Saving..."), R = Object.entries(e).reduce((o, [i, l]) => S(l, c[i]) ? o : {
29
30
  ...o,
30
31
  [i]: l
31
32
  }, {});
32
33
  await fetch(h, {
33
34
  method: "PUT",
34
- body: JSON.stringify(v)
35
+ body: JSON.stringify(R)
35
36
  }), s.reset(e), f.success("Saved", { id: t });
36
37
  };
37
38
  return /* @__PURE__ */ React.createElement(
@@ -47,8 +48,8 @@ function J({
47
48
  className: "flex h-[calc(100vh-var(--app-header-height))] flex-col",
48
49
  onSubmit: s.handleSubmit(E)
49
50
  },
50
- /* @__PURE__ */ React.createElement("div", { className: "sticky top-0 z-10 bg-background" }, /* @__PURE__ */ React.createElement("header", { className: "mb-6 flex items-center justify-between gap-4" }, /* @__PURE__ */ React.createElement("h1", { className: "text-4xl" }, "Messages"), /* @__PURE__ */ React.createElement("div", { className: "flex items-center gap-2" }, /* @__PURE__ */ React.createElement(
51
- R,
51
+ /* @__PURE__ */ React.createElement("div", { className: "sticky top-0 z-10 bg-background" }, /* @__PURE__ */ React.createElement("header", { className: "mb-6 flex items-center justify-between gap-4" }, /* @__PURE__ */ React.createElement("h1", { className: "text-4xl" }, "Messages"), /* @__PURE__ */ React.createElement("div", { className: "flex items-center gap-2" }, /* @__PURE__ */ React.createElement(j, null), /* @__PURE__ */ React.createElement(
52
+ N,
52
53
  {
53
54
  className: "my-0",
54
55
  type: "submit",
@@ -56,7 +57,7 @@ function J({
56
57
  },
57
58
  "Save"
58
59
  ))), r && /* @__PURE__ */ React.createElement(
59
- F,
60
+ O,
60
61
  {
61
62
  schema: a,
62
63
  activeTab: m,
@@ -64,7 +65,7 @@ function J({
64
65
  }
65
66
  )),
66
67
  /* @__PURE__ */ React.createElement("div", { id: "messages-form-content", className: "overflow-y-auto pt-8 pb-16" }, !r && /* @__PURE__ */ React.createElement(p, { path: "", schema: a, nestingLevel: 0 }), r && Object.entries(a).map(([e, t]) => typeof t == "string" ? /* @__PURE__ */ React.createElement(
67
- j,
68
+ F,
68
69
  {
69
70
  schema: t,
70
71
  key: e,
@@ -86,6 +87,6 @@ function J({
86
87
  );
87
88
  }
88
89
  export {
89
- J as MessagesForm
90
+ U as MessagesForm
90
91
  };
91
92
  //# sourceMappingURL=MessagesForm.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"MessagesForm.js","sources":["../../src/components/MessagesForm.tsx"],"sourcesContent":["\"use client\";\n\nimport type { FormValues } from \"@/context/messages-form\";\nimport type {\n DeepPartial,\n Locales,\n Messages,\n MessagesSchema,\n RichTextEditorOptions,\n Translations,\n} from \"@/types\";\nimport { Button, useStepNav } from \"@payloadcms/ui\";\nimport { isEqual } from \"lodash-es\";\nimport { useEffect, useState } from \"react\";\nimport { useForm } from \"react-hook-form\";\nimport { toast } from \"sonner\";\n\nimport { MessagesFormProvider } from \"@/context/messages-form\";\nimport { cn } from \"@/utils/cn\";\n\nimport { MessageField } from \"./layout/MessageField\";\nimport { MessagesTabs } from \"./layout/MessagesTabs\";\nimport { MessagesTree } from \"./layout/MessagesTree\";\n\ninterface MessagesFormProps {\n locales: Locales;\n schema: MessagesSchema;\n tabs?: boolean;\n values: Translations<DeepPartial<Messages>>;\n endpointUrl: string;\n richTextEditorOptions?: RichTextEditorOptions;\n}\n\nexport function MessagesForm({\n locales,\n schema,\n tabs = false,\n values,\n endpointUrl,\n richTextEditorOptions,\n}: MessagesFormProps): React.ReactNode {\n const { setStepNav } = useStepNav();\n useEffect(() => {\n setStepNav([{ label: \"Intl Messages\", url: \"/intl\" }]);\n }, [setStepNav]);\n\n const form = useForm<FormValues>({\n defaultValues: values,\n reValidateMode: \"onChange\",\n });\n const [activeTab, setActiveTab] = useState(Object.keys(schema)[0]);\n\n const handleSubmit = async (currentValues: FormValues) => {\n const toastId = toast.loading(\"Saving...\");\n const changes = Object.entries(currentValues).reduce<\n Translations<Messages>\n >((acc, [locale, value]) => {\n const hasChanged = !isEqual(value, values[locale]);\n if (!hasChanged) {\n return acc;\n }\n return {\n ...acc,\n [locale]: value,\n };\n }, {});\n\n await fetch(endpointUrl, {\n method: \"PUT\",\n body: JSON.stringify(changes),\n });\n\n form.reset(currentValues);\n toast.success(\"Saved\", { id: toastId });\n };\n\n return (\n <MessagesFormProvider\n form={form}\n locales={locales}\n richTextEditorOptions={richTextEditorOptions}\n >\n <form\n className=\"flex h-[calc(100vh-var(--app-header-height))] flex-col\"\n onSubmit={form.handleSubmit(handleSubmit)}\n >\n <div className=\"sticky top-0 z-10 bg-background\">\n <header className=\"mb-6 flex items-center justify-between gap-4\">\n <h1 className=\"text-4xl\">Messages</h1>\n <div className=\"flex items-center gap-2\">\n <Button\n className=\"my-0\"\n type=\"submit\"\n disabled={!form.formState.isDirty}\n >\n Save\n </Button>\n </div>\n </header>\n {tabs && (\n <MessagesTabs\n schema={schema}\n activeTab={activeTab}\n setActiveTab={setActiveTab}\n />\n )}\n </div>\n\n <div id=\"messages-form-content\" className=\"overflow-y-auto pt-8 pb-16\">\n {!tabs && <MessagesTree path=\"\" schema={schema} nestingLevel={0} />}\n {tabs &&\n Object.entries(schema).map(([key, value]) => {\n if (typeof value === \"string\") {\n return (\n <MessageField\n schema={value}\n key={key}\n className={cn({ hidden: activeTab !== key })}\n messageKey={key}\n path={key}\n />\n );\n }\n return (\n <MessagesTree\n className={cn({ hidden: activeTab !== key })}\n key={key}\n path={key}\n schema={value}\n nestingLevel={0}\n />\n );\n })}\n </div>\n </form>\n </MessagesFormProvider>\n );\n}\n"],"names":["MessagesForm","locales","schema","tabs","values","endpointUrl","richTextEditorOptions","setStepNav","useStepNav","useEffect","form","useForm","activeTab","setActiveTab","useState","handleSubmit","currentValues","toastId","toast","changes","acc","locale","value","isEqual","MessagesFormProvider","Button","MessagesTabs","MessagesTree","key","MessageField","cn"],"mappings":";;;;;;;;;;;AAiCO,SAASA,EAAa;AAAA,EAC3B,SAAAC;AAAA,EACA,QAAAC;AAAA,EACA,MAAAC,IAAO;AAAA,EACP,QAAAC;AAAA,EACA,aAAAC;AAAA,EACA,uBAAAC;AACF,GAAuC;AACrC,QAAM,EAAE,YAAAC,EAAA,IAAeC,EAAA;AACvB,EAAAC,EAAU,MAAM;AACd,IAAAF,EAAW,CAAC,EAAE,OAAO,iBAAiB,KAAK,QAAA,CAAS,CAAC;AAAA,EACvD,GAAG,CAACA,CAAU,CAAC;AAEf,QAAMG,IAAOC,EAAoB;AAAA,IAC/B,eAAeP;AAAA,IACf,gBAAgB;AAAA,EAAA,CACjB,GACK,CAACQ,GAAWC,CAAY,IAAIC,EAAS,OAAO,KAAKZ,CAAM,EAAE,CAAC,CAAC,GAE3Da,IAAe,OAAOC,MAA8B;AACxD,UAAMC,IAAUC,EAAM,QAAQ,WAAW,GACnCC,IAAU,OAAO,QAAQH,CAAa,EAAE,OAE5C,CAACI,GAAK,CAACC,GAAQC,CAAK,MACAC,EAAQD,GAAOlB,EAAOiB,CAAM,CAAC,IAExCD,IAEF;AAAA,MACL,GAAGA;AAAA,MACH,CAACC,CAAM,GAAGC;AAAA,IAAA,GAEX,CAAA,CAAE;AAEL,UAAM,MAAMjB,GAAa;AAAA,MACvB,QAAQ;AAAA,MACR,MAAM,KAAK,UAAUc,CAAO;AAAA,IAAA,CAC7B,GAEDT,EAAK,MAAMM,CAAa,GACxBE,EAAM,QAAQ,SAAS,EAAE,IAAID,GAAS;AAAA,EACxC;AAEA,SACE,sBAAA;AAAA,IAACO;AAAA,IAAA;AAAA,MACC,MAAAd;AAAA,MACA,SAAAT;AAAA,MACA,uBAAAK;AAAA,IAAA;AAAA,IAEA,sBAAA;AAAA,MAAC;AAAA,MAAA;AAAA,QACC,WAAU;AAAA,QACV,UAAUI,EAAK,aAAaK,CAAY;AAAA,MAAA;AAAA,0CAEvC,OAAA,EAAI,WAAU,kCAAA,GACb,sBAAA,cAAC,YAAO,WAAU,+CAAA,GAChB,sBAAA,cAAC,MAAA,EAAG,WAAU,WAAA,GAAW,UAAQ,GACjC,sBAAA,cAAC,OAAA,EAAI,WAAU,0BAAA,GACb,sBAAA;AAAA,QAACU;AAAA,QAAA;AAAA,UACC,WAAU;AAAA,UACV,MAAK;AAAA,UACL,UAAU,CAACf,EAAK,UAAU;AAAA,QAAA;AAAA,QAC3B;AAAA,MAAA,CAGH,CACF,GACCP,KACC,sBAAA;AAAA,QAACuB;AAAA,QAAA;AAAA,UACC,QAAAxB;AAAA,UACA,WAAAU;AAAA,UACA,cAAAC;AAAA,QAAA;AAAA,MAAA,CAGN;AAAA,MAEA,sBAAA,cAAC,OAAA,EAAI,IAAG,yBAAwB,WAAU,6BAAA,GACvC,CAACV,KAAQ,sBAAA,cAACwB,GAAA,EAAa,MAAK,IAAG,QAAAzB,GAAgB,cAAc,EAAA,CAAG,GAChEC,KACC,OAAO,QAAQD,CAAM,EAAE,IAAI,CAAC,CAAC0B,GAAKN,CAAK,MACjC,OAAOA,KAAU,WAEjB,sBAAA;AAAA,QAACO;AAAA,QAAA;AAAA,UACC,QAAQP;AAAA,UACR,KAAAM;AAAA,UACA,WAAWE,EAAG,EAAE,QAAQlB,MAAcgB,GAAK;AAAA,UAC3C,YAAYA;AAAA,UACZ,MAAMA;AAAA,QAAA;AAAA,MAAA,IAKV,sBAAA;AAAA,QAACD;AAAA,QAAA;AAAA,UACC,WAAWG,EAAG,EAAE,QAAQlB,MAAcgB,GAAK;AAAA,UAC3C,KAAAA;AAAA,UACA,MAAMA;AAAA,UACN,QAAQN;AAAA,UACR,cAAc;AAAA,QAAA;AAAA,MAAA,CAGnB,CACL;AAAA,IAAA;AAAA,EACF;AAGN;"}
1
+ {"version":3,"file":"MessagesForm.js","sources":["../../src/components/MessagesForm.tsx"],"sourcesContent":["\"use client\";\n\nimport type { FormValues } from \"@/context/messages-form\";\nimport type {\n DeepPartial,\n Locales,\n Messages,\n MessagesSchema,\n RichTextEditorOptions,\n Translations,\n} from \"@/types\";\nimport { Button, useStepNav } from \"@payloadcms/ui\";\nimport { isEqual } from \"lodash-es\";\nimport { useEffect, useState } from \"react\";\nimport { useForm } from \"react-hook-form\";\nimport { toast } from \"sonner\";\n\nimport { MessagesFormProvider } from \"@/context/messages-form\";\nimport { cn } from \"@/utils/cn\";\n\nimport { JsonImport } from \"./actions/JsonImport\";\nimport { MessageField } from \"./layout/MessageField\";\nimport { MessagesTabs } from \"./layout/MessagesTabs\";\nimport { MessagesTree } from \"./layout/MessagesTree\";\n\ninterface MessagesFormProps {\n locales: Locales;\n schema: MessagesSchema;\n tabs?: boolean;\n values: Translations<DeepPartial<Messages>>;\n endpointUrl: string;\n richTextEditorOptions?: RichTextEditorOptions;\n}\n\nexport function MessagesForm({\n locales,\n schema,\n tabs = false,\n values,\n endpointUrl,\n richTextEditorOptions,\n}: MessagesFormProps): React.ReactNode {\n const { setStepNav } = useStepNav();\n useEffect(() => {\n setStepNav([{ label: \"Intl Messages\", url: \"/intl\" }]);\n }, [setStepNav]);\n\n const form = useForm<FormValues>({\n defaultValues: values,\n reValidateMode: \"onChange\",\n });\n const [activeTab, setActiveTab] = useState(Object.keys(schema)[0]);\n\n const handleSubmit = async (currentValues: FormValues) => {\n const toastId = toast.loading(\"Saving...\");\n const changes = Object.entries(currentValues).reduce<\n Translations<Messages>\n >((acc, [locale, value]) => {\n const hasChanged = !isEqual(value, values[locale]);\n if (!hasChanged) {\n return acc;\n }\n return {\n ...acc,\n [locale]: value,\n };\n }, {});\n\n await fetch(endpointUrl, {\n method: \"PUT\",\n body: JSON.stringify(changes),\n });\n\n form.reset(currentValues);\n toast.success(\"Saved\", { id: toastId });\n };\n\n return (\n <MessagesFormProvider\n form={form}\n locales={locales}\n richTextEditorOptions={richTextEditorOptions}\n >\n <form\n className=\"flex h-[calc(100vh-var(--app-header-height))] flex-col\"\n onSubmit={form.handleSubmit(handleSubmit)}\n >\n <div className=\"sticky top-0 z-10 bg-background\">\n <header className=\"mb-6 flex items-center justify-between gap-4\">\n <h1 className=\"text-4xl\">Messages</h1>\n <div className=\"flex items-center gap-2\">\n <JsonImport />\n <Button\n className=\"my-0\"\n type=\"submit\"\n disabled={!form.formState.isDirty}\n >\n Save\n </Button>\n </div>\n </header>\n {tabs && (\n <MessagesTabs\n schema={schema}\n activeTab={activeTab}\n setActiveTab={setActiveTab}\n />\n )}\n </div>\n\n <div id=\"messages-form-content\" className=\"overflow-y-auto pt-8 pb-16\">\n {!tabs && <MessagesTree path=\"\" schema={schema} nestingLevel={0} />}\n {tabs &&\n Object.entries(schema).map(([key, value]) => {\n if (typeof value === \"string\") {\n return (\n <MessageField\n schema={value}\n key={key}\n className={cn({ hidden: activeTab !== key })}\n messageKey={key}\n path={key}\n />\n );\n }\n return (\n <MessagesTree\n className={cn({ hidden: activeTab !== key })}\n key={key}\n path={key}\n schema={value}\n nestingLevel={0}\n />\n );\n })}\n </div>\n </form>\n </MessagesFormProvider>\n );\n}\n"],"names":["MessagesForm","locales","schema","tabs","values","endpointUrl","richTextEditorOptions","setStepNav","useStepNav","useEffect","form","useForm","activeTab","setActiveTab","useState","handleSubmit","currentValues","toastId","toast","changes","acc","locale","value","isEqual","MessagesFormProvider","JsonImport","Button","MessagesTabs","MessagesTree","key","MessageField","cn"],"mappings":";;;;;;;;;;;;AAkCO,SAASA,EAAa;AAAA,EAC3B,SAAAC;AAAA,EACA,QAAAC;AAAA,EACA,MAAAC,IAAO;AAAA,EACP,QAAAC;AAAA,EACA,aAAAC;AAAA,EACA,uBAAAC;AACF,GAAuC;AACrC,QAAM,EAAE,YAAAC,EAAA,IAAeC,EAAA;AACvB,EAAAC,EAAU,MAAM;AACd,IAAAF,EAAW,CAAC,EAAE,OAAO,iBAAiB,KAAK,QAAA,CAAS,CAAC;AAAA,EACvD,GAAG,CAACA,CAAU,CAAC;AAEf,QAAMG,IAAOC,EAAoB;AAAA,IAC/B,eAAeP;AAAA,IACf,gBAAgB;AAAA,EAAA,CACjB,GACK,CAACQ,GAAWC,CAAY,IAAIC,EAAS,OAAO,KAAKZ,CAAM,EAAE,CAAC,CAAC,GAE3Da,IAAe,OAAOC,MAA8B;AACxD,UAAMC,IAAUC,EAAM,QAAQ,WAAW,GACnCC,IAAU,OAAO,QAAQH,CAAa,EAAE,OAE5C,CAACI,GAAK,CAACC,GAAQC,CAAK,MACAC,EAAQD,GAAOlB,EAAOiB,CAAM,CAAC,IAExCD,IAEF;AAAA,MACL,GAAGA;AAAA,MACH,CAACC,CAAM,GAAGC;AAAA,IAAA,GAEX,CAAA,CAAE;AAEL,UAAM,MAAMjB,GAAa;AAAA,MACvB,QAAQ;AAAA,MACR,MAAM,KAAK,UAAUc,CAAO;AAAA,IAAA,CAC7B,GAEDT,EAAK,MAAMM,CAAa,GACxBE,EAAM,QAAQ,SAAS,EAAE,IAAID,GAAS;AAAA,EACxC;AAEA,SACE,sBAAA;AAAA,IAACO;AAAA,IAAA;AAAA,MACC,MAAAd;AAAA,MACA,SAAAT;AAAA,MACA,uBAAAK;AAAA,IAAA;AAAA,IAEA,sBAAA;AAAA,MAAC;AAAA,MAAA;AAAA,QACC,WAAU;AAAA,QACV,UAAUI,EAAK,aAAaK,CAAY;AAAA,MAAA;AAAA,MAExC,sBAAA,cAAC,SAAI,WAAU,kCAAA,uCACZ,UAAA,EAAO,WAAU,kDAChB,sBAAA,cAAC,MAAA,EAAG,WAAU,WAAA,GAAW,UAAQ,GACjC,sBAAA,cAAC,OAAA,EAAI,WAAU,0BAAA,GACb,sBAAA,cAACU,OAAW,GACZ,sBAAA;AAAA,QAACC;AAAA,QAAA;AAAA,UACC,WAAU;AAAA,UACV,MAAK;AAAA,UACL,UAAU,CAAChB,EAAK,UAAU;AAAA,QAAA;AAAA,QAC3B;AAAA,MAAA,CAGH,CACF,GACCP,KACC,sBAAA;AAAA,QAACwB;AAAA,QAAA;AAAA,UACC,QAAAzB;AAAA,UACA,WAAAU;AAAA,UACA,cAAAC;AAAA,QAAA;AAAA,MAAA,CAGN;AAAA,MAEA,sBAAA,cAAC,OAAA,EAAI,IAAG,yBAAwB,WAAU,6BAAA,GACvC,CAACV,KAAQ,sBAAA,cAACyB,GAAA,EAAa,MAAK,IAAG,QAAA1B,GAAgB,cAAc,EAAA,CAAG,GAChEC,KACC,OAAO,QAAQD,CAAM,EAAE,IAAI,CAAC,CAAC2B,GAAKP,CAAK,MACjC,OAAOA,KAAU,WAEjB,sBAAA;AAAA,QAACQ;AAAA,QAAA;AAAA,UACC,QAAQR;AAAA,UACR,KAAAO;AAAA,UACA,WAAWE,EAAG,EAAE,QAAQnB,MAAciB,GAAK;AAAA,UAC3C,YAAYA;AAAA,UACZ,MAAMA;AAAA,QAAA;AAAA,MAAA,IAKV,sBAAA;AAAA,QAACD;AAAA,QAAA;AAAA,UACC,WAAWG,EAAG,EAAE,QAAQnB,MAAciB,GAAK;AAAA,UAC3C,KAAAA;AAAA,UACA,MAAMA;AAAA,UACN,QAAQP;AAAA,UACR,cAAc;AAAA,QAAA;AAAA,MAAA,CAGnB,CACL;AAAA,IAAA;AAAA,EACF;AAGN;"}
@@ -0,0 +1,57 @@
1
+ import { Button as l } from "@payloadcms/ui";
2
+ import { IconBraces as d } from "@tabler/icons-react";
3
+ import { useRef as f, useState as R } from "react";
4
+ import { useMessagesForm as g } from "../../context/messages-form.js";
5
+ function h() {
6
+ const { locales: s, setValue: c } = g(), a = f(null), [o, n] = R(), u = (t) => {
7
+ const e = t.target.files?.[0];
8
+ if (!o || !e) {
9
+ t.target.value = "";
10
+ return;
11
+ }
12
+ const r = new FileReader();
13
+ r.onload = (i) => {
14
+ const m = i.target?.result, p = JSON.parse(m);
15
+ c(o, p, {
16
+ shouldDirty: !0,
17
+ shouldValidate: !0
18
+ }), n(void 0), t.target.value = "";
19
+ }, r.readAsText(e);
20
+ };
21
+ return /* @__PURE__ */ React.createElement(React.Fragment, null, /* @__PURE__ */ React.createElement(
22
+ "input",
23
+ {
24
+ ref: a,
25
+ accept: ".json",
26
+ hidden: !0,
27
+ onChange: u,
28
+ type: "file"
29
+ }
30
+ ), /* @__PURE__ */ React.createElement(
31
+ l,
32
+ {
33
+ className: "my-0",
34
+ buttonStyle: "subtle",
35
+ iconPosition: "left",
36
+ icon: /* @__PURE__ */ React.createElement(d, { className: "size-5" }),
37
+ SubMenuPopupContent: ({ close: t }) => /* @__PURE__ */ React.createElement("div", { className: "flex flex-col gap-2" }, s.map((e) => /* @__PURE__ */ React.createElement(
38
+ l,
39
+ {
40
+ key: e,
41
+ buttonStyle: "subtle",
42
+ size: "small",
43
+ onClick: () => {
44
+ n(e), a.current?.click(), t();
45
+ }
46
+ },
47
+ e,
48
+ ".json"
49
+ )))
50
+ },
51
+ "Import"
52
+ ));
53
+ }
54
+ export {
55
+ h as JsonImport
56
+ };
57
+ //# sourceMappingURL=JsonImport.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"JsonImport.js","sources":["../../../src/components/actions/JsonImport.tsx"],"sourcesContent":["import { Button } from \"@payloadcms/ui\";\nimport { IconBraces } from \"@tabler/icons-react\";\nimport { useRef, useState } from \"react\";\n\nimport { useMessagesForm } from \"@/context/messages-form\";\n\nexport function JsonImport() {\n const { locales, setValue } = useMessagesForm();\n const inputRef = useRef<HTMLInputElement>(null);\n const [selectedLocale, setSelectedLocale] = useState<string>();\n\n const handleImportJSON = (event: React.ChangeEvent<HTMLInputElement>) => {\n const file = event.target.files?.[0];\n if (!selectedLocale || !file) {\n event.target.value = \"\";\n return;\n }\n\n const reader = new FileReader();\n reader.onload = (readerEvent) => {\n const text = readerEvent.target?.result as string;\n const data = JSON.parse(text);\n // FIMXE this does not cause the form to re-render\n setValue(selectedLocale, data, {\n shouldDirty: true,\n shouldValidate: true,\n });\n setSelectedLocale(undefined);\n // Clear the input value to allow re-selection of the same or different file\n event.target.value = \"\";\n };\n reader.readAsText(file);\n };\n\n return (\n <>\n <input\n ref={inputRef}\n accept=\".json\"\n hidden\n onChange={handleImportJSON}\n type=\"file\"\n />\n <Button\n className=\"my-0\"\n buttonStyle=\"subtle\"\n iconPosition=\"left\"\n icon={<IconBraces className=\"size-5\" />}\n SubMenuPopupContent={({ close }) => (\n <div className=\"flex flex-col gap-2\">\n {locales.map((locale) => (\n <Button\n key={locale}\n buttonStyle=\"subtle\"\n size=\"small\"\n onClick={() => {\n setSelectedLocale(locale);\n inputRef.current?.click();\n close();\n }}\n >\n {locale}.json\n </Button>\n ))}\n </div>\n )}\n >\n Import\n </Button>\n </>\n );\n}\n"],"names":["JsonImport","locales","setValue","useMessagesForm","inputRef","useRef","selectedLocale","setSelectedLocale","useState","handleImportJSON","event","file","reader","readerEvent","text","data","Button","IconBraces","close","locale"],"mappings":";;;;AAMO,SAASA,IAAa;AAC3B,QAAM,EAAE,SAAAC,GAAS,UAAAC,EAAA,IAAaC,EAAA,GACxBC,IAAWC,EAAyB,IAAI,GACxC,CAACC,GAAgBC,CAAiB,IAAIC,EAAA,GAEtCC,IAAmB,CAACC,MAA+C;AACvE,UAAMC,IAAOD,EAAM,OAAO,QAAQ,CAAC;AACnC,QAAI,CAACJ,KAAkB,CAACK,GAAM;AAC5B,MAAAD,EAAM,OAAO,QAAQ;AACrB;AAAA,IACF;AAEA,UAAME,IAAS,IAAI,WAAA;AACnB,IAAAA,EAAO,SAAS,CAACC,MAAgB;AAC/B,YAAMC,IAAOD,EAAY,QAAQ,QAC3BE,IAAO,KAAK,MAAMD,CAAI;AAE5B,MAAAZ,EAASI,GAAgBS,GAAM;AAAA,QAC7B,aAAa;AAAA,QACb,gBAAgB;AAAA,MAAA,CACjB,GACDR,EAAkB,MAAS,GAE3BG,EAAM,OAAO,QAAQ;AAAA,IACvB,GACAE,EAAO,WAAWD,CAAI;AAAA,EACxB;AAEA,SACE,sBAAA,cAAA,MAAA,UAAA,MACE,sBAAA;AAAA,IAAC;AAAA,IAAA;AAAA,MACC,KAAKP;AAAA,MACL,QAAO;AAAA,MACP,QAAM;AAAA,MACN,UAAUK;AAAA,MACV,MAAK;AAAA,IAAA;AAAA,EAAA,GAEP,sBAAA;AAAA,IAACO;AAAA,IAAA;AAAA,MACC,WAAU;AAAA,MACV,aAAY;AAAA,MACZ,cAAa;AAAA,MACb,MAAM,sBAAA,cAACC,GAAA,EAAW,WAAU,UAAS;AAAA,MACrC,qBAAqB,CAAC,EAAE,OAAAC,EAAA,MACtB,sBAAA,cAAC,OAAA,EAAI,WAAU,sBAAA,GACZjB,EAAQ,IAAI,CAACkB,MACZ,sBAAA;AAAA,QAACH;AAAA,QAAA;AAAA,UACC,KAAKG;AAAA,UACL,aAAY;AAAA,UACZ,MAAK;AAAA,UACL,SAAS,MAAM;AACb,YAAAZ,EAAkBY,CAAM,GACxBf,EAAS,SAAS,MAAA,GAClBc,EAAA;AAAA,UACF;AAAA,QAAA;AAAA,QAECC;AAAA,QAAO;AAAA,MAAA,CAEX,CACH;AAAA,IAAA;AAAA,IAEH;AAAA,EAAA,CAGH;AAEJ;"}
@@ -1,5 +1,5 @@
1
1
  import { FieldLabel as l } from "@payloadcms/ui";
2
- import { cn as t } from "@/utils/cn";
2
+ import { cn as t } from "../../utils/cn.js";
3
3
  function o({
4
4
  label: a,
5
5
  error: e,
@@ -1,52 +1,37 @@
1
- import { useEditor as m, EditorContent as c } from "@tiptap/react";
2
- import d from "@tiptap/starter-kit";
3
- import { parseIcuToProseMirrorJSON as p } from "@/utils/icu-tranform";
4
- import { InputWrapper as u } from "./InputWrapper.js";
5
- import { VariableMention as b } from "./variables/extension.js";
6
- function h({
1
+ import c from "@tiptap/extension-document";
2
+ import f from "@tiptap/extension-paragraph";
3
+ import d from "@tiptap/extension-text";
4
+ import { useEditor as u, EditorContent as l } from "@tiptap/react";
5
+ import { parseIcuToProseMirrorJSON as x } from "../../utils/icu-tranform.js";
6
+ import { InputWrapper as E } from "./InputWrapper.js";
7
+ import { VariableMention as g } from "./variables/extension.js";
8
+ function b({
7
9
  label: e,
8
10
  value: t,
9
11
  lang: r,
10
12
  error: o,
11
- variables: a,
12
- onChange: i,
13
- onBlur: l,
14
- className: s
13
+ variables: i,
14
+ onChange: m,
15
+ onBlur: n,
16
+ className: a
15
17
  }) {
16
- const n = m({
18
+ const p = u({
17
19
  immediatelyRender: !1,
18
- content: p(t),
19
- extensions: [
20
- d.configure({
21
- blockquote: !1,
22
- bulletList: !1,
23
- codeBlock: !1,
24
- heading: !1,
25
- horizontalRule: !1,
26
- listItem: !1,
27
- orderedList: !1,
28
- bold: !1,
29
- italic: !1,
30
- link: !1,
31
- underline: !1,
32
- strike: !1,
33
- code: !1
34
- }),
35
- b(a)
36
- ],
37
- onUpdate: ({ editor: f }) => i(f.getText())
20
+ content: x(t),
21
+ extensions: [c, f, d, g(i)],
22
+ onUpdate: ({ editor: s }) => m(s.getText())
38
23
  });
39
- return /* @__PURE__ */ React.createElement(u, { label: e, error: o, className: s }, /* @__PURE__ */ React.createElement(
40
- c,
24
+ return /* @__PURE__ */ React.createElement(E, { label: e, error: o, className: a }, /* @__PURE__ */ React.createElement(
25
+ l,
41
26
  {
42
27
  className: "tiptap-editor min-h-8",
43
- editor: n,
28
+ editor: p,
44
29
  lang: r,
45
- onBlur: l
30
+ onBlur: n
46
31
  }
47
32
  ));
48
33
  }
49
34
  export {
50
- h as MessageInput
35
+ b as MessageInput
51
36
  };
52
37
  //# sourceMappingURL=MessageInput.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"MessageInput.js","sources":["../../../src/components/inputs/MessageInput.tsx"],"sourcesContent":["import type { TemplateVariable } from \"@/types\";\nimport { EditorContent, useEditor } from \"@tiptap/react\";\nimport StarterKit from \"@tiptap/starter-kit\";\n\nimport { parseIcuToProseMirrorJSON } from \"@/utils/icu-tranform\";\n\nimport type { InputWrapperProps } from \"./InputWrapper\";\nimport { InputWrapper } from \"./InputWrapper\";\nimport { VariableMention } from \"./variables/extension\";\n\nexport interface MessageInputProps extends InputWrapperProps {\n value: string;\n lang: string;\n variables: TemplateVariable[];\n onChange: (value: string) => void;\n onBlur: () => void;\n}\n\n// TODO add variable editor (style, options, etc)\n// TODO add tooltip to show all variables\n\nexport function MessageInput({\n label,\n value,\n lang,\n error,\n variables,\n onChange,\n onBlur,\n className,\n}: MessageInputProps) {\n const editor = useEditor({\n immediatelyRender: false,\n content: parseIcuToProseMirrorJSON(value),\n extensions: [\n StarterKit.configure({\n blockquote: false,\n bulletList: false,\n codeBlock: false,\n heading: false,\n horizontalRule: false,\n listItem: false,\n orderedList: false,\n bold: false,\n italic: false,\n link: false,\n underline: false,\n strike: false,\n code: false,\n }),\n VariableMention(variables),\n ],\n onUpdate: ({ editor }) => onChange(editor.getText()),\n });\n\n return (\n <InputWrapper label={label} error={error} className={className}>\n <EditorContent\n className=\"tiptap-editor min-h-8\"\n editor={editor}\n lang={lang}\n onBlur={onBlur}\n />\n </InputWrapper>\n );\n}\n"],"names":["MessageInput","label","value","lang","error","variables","onChange","onBlur","className","editor","useEditor","parseIcuToProseMirrorJSON","StarterKit","VariableMention","InputWrapper","EditorContent"],"mappings":";;;;;AAqBO,SAASA,EAAa;AAAA,EAC3B,OAAAC;AAAA,EACA,OAAAC;AAAA,EACA,MAAAC;AAAA,EACA,OAAAC;AAAA,EACA,WAAAC;AAAA,EACA,UAAAC;AAAA,EACA,QAAAC;AAAA,EACA,WAAAC;AACF,GAAsB;AACpB,QAAMC,IAASC,EAAU;AAAA,IACvB,mBAAmB;AAAA,IACnB,SAASC,EAA0BT,CAAK;AAAA,IACxC,YAAY;AAAA,MACVU,EAAW,UAAU;AAAA,QACnB,YAAY;AAAA,QACZ,YAAY;AAAA,QACZ,WAAW;AAAA,QACX,SAAS;AAAA,QACT,gBAAgB;AAAA,QAChB,UAAU;AAAA,QACV,aAAa;AAAA,QACb,MAAM;AAAA,QACN,QAAQ;AAAA,QACR,MAAM;AAAA,QACN,WAAW;AAAA,QACX,QAAQ;AAAA,QACR,MAAM;AAAA,MAAA,CACP;AAAA,MACDC,EAAgBR,CAAS;AAAA,IAAA;AAAA,IAE3B,UAAU,CAAC,EAAE,QAAAI,QAAaH,EAASG,EAAO,QAAA,CAAS;AAAA,EAAA,CACpD;AAED,SACE,sBAAA,cAACK,GAAA,EAAa,OAAAb,GAAc,OAAAG,GAAc,WAAAI,KACxC,sBAAA;AAAA,IAACO;AAAA,IAAA;AAAA,MACC,WAAU;AAAA,MACV,QAAAN;AAAA,MACA,MAAAN;AAAA,MACA,QAAAI;AAAA,IAAA;AAAA,EAAA,CAEJ;AAEJ;"}
1
+ {"version":3,"file":"MessageInput.js","sources":["../../../src/components/inputs/MessageInput.tsx"],"sourcesContent":["import type { TemplateVariable } from \"@/types\";\nimport Document from \"@tiptap/extension-document\";\nimport Paragraph from \"@tiptap/extension-paragraph\";\nimport Text from \"@tiptap/extension-text\";\nimport { EditorContent, useEditor } from \"@tiptap/react\";\n\nimport { parseIcuToProseMirrorJSON } from \"@/utils/icu-tranform\";\n\nimport type { InputWrapperProps } from \"./InputWrapper\";\nimport { InputWrapper } from \"./InputWrapper\";\nimport { VariableMention } from \"./variables/extension\";\n\nexport interface MessageInputProps extends InputWrapperProps {\n value: string;\n lang: string;\n variables: TemplateVariable[];\n onChange: (value: string) => void;\n onBlur: () => void;\n}\n\n// TODO add variable editor (style, options, etc)\n// TODO add tooltip to show all variables\n\nexport function MessageInput({\n label,\n value,\n lang,\n error,\n variables,\n onChange,\n onBlur,\n className,\n}: MessageInputProps) {\n const editor = useEditor({\n immediatelyRender: false,\n content: parseIcuToProseMirrorJSON(value),\n extensions: [Document, Paragraph, Text, VariableMention(variables)],\n onUpdate: ({ editor }) => onChange(editor.getText()),\n });\n\n return (\n <InputWrapper label={label} error={error} className={className}>\n <EditorContent\n className=\"tiptap-editor min-h-8\"\n editor={editor}\n lang={lang}\n onBlur={onBlur}\n />\n </InputWrapper>\n );\n}\n"],"names":["MessageInput","label","value","lang","error","variables","onChange","onBlur","className","editor","useEditor","parseIcuToProseMirrorJSON","Document","Paragraph","Text","VariableMention","InputWrapper","EditorContent"],"mappings":";;;;;;;AAuBO,SAASA,EAAa;AAAA,EAC3B,OAAAC;AAAA,EACA,OAAAC;AAAA,EACA,MAAAC;AAAA,EACA,OAAAC;AAAA,EACA,WAAAC;AAAA,EACA,UAAAC;AAAA,EACA,QAAAC;AAAA,EACA,WAAAC;AACF,GAAsB;AACpB,QAAMC,IAASC,EAAU;AAAA,IACvB,mBAAmB;AAAA,IACnB,SAASC,EAA0BT,CAAK;AAAA,IACxC,YAAY,CAACU,GAAUC,GAAWC,GAAMC,EAAgBV,CAAS,CAAC;AAAA,IAClE,UAAU,CAAC,EAAE,QAAAI,QAAaH,EAASG,EAAO,QAAA,CAAS;AAAA,EAAA,CACpD;AAED,SACE,sBAAA,cAACO,GAAA,EAAa,OAAAf,GAAc,OAAAG,GAAc,WAAAI,KACxC,sBAAA;AAAA,IAACS;AAAA,IAAA;AAAA,MACC,WAAU;AAAA,MACV,QAAAR;AAAA,MACA,MAAAN;AAAA,MACA,QAAAI;AAAA,IAAA;AAAA,EAAA,CAEJ;AAEJ;"}
@@ -17,7 +17,7 @@ import I from "@tiptap/extension-typography";
17
17
  import N from "@tiptap/extension-underline";
18
18
  import { UndoRedo as O, TrailingNode as U } from "@tiptap/extensions";
19
19
  import { useEditor as q, EditorContent as w } from "@tiptap/react";
20
- import { useMessagesForm as M } from "@/context/messages-form";
20
+ import { useMessagesForm as M } from "../../context/messages-form.js";
21
21
  import { InputWrapper as S } from "./InputWrapper.js";
22
22
  import { RichTextToolbar as z } from "./toolbar/RichTextToolbar.js";
23
23
  function mo({
@@ -2,7 +2,7 @@ import { IconH6 as s, IconH5 as u, IconH4 as d, IconH3 as h, IconH2 as m, IconH1
2
2
  import { useEditorState as H } from "@tiptap/react";
3
3
  import { Select as t, Toolbar as I } from "radix-ui";
4
4
  import { useMemo as L } from "react";
5
- import { cn as c } from "@/utils/cn";
5
+ import { cn as c } from "../../../utils/cn.js";
6
6
  function x({ editor: a }) {
7
7
  const o = L(() => {
8
8
  const e = a?.extensionManager.extensions.find((l) => l.name === "heading")?.options.levels.map(
@@ -2,7 +2,7 @@ import { IconLink as A, IconCornerDownLeft as I, IconExternalLink as N, IconLink
2
2
  import { useEditorState as W } from "@tiptap/react";
3
3
  import { Popover as k, Toolbar as p } from "radix-ui";
4
4
  import { useState as v, useCallback as d, useEffect as h } from "react";
5
- import { cn as B } from "@/utils/cn";
5
+ import { cn as B } from "../../../utils/cn.js";
6
6
  function q({
7
7
  editor: e,
8
8
  hideWhenUnavailable: t = !1,
@@ -1,5 +1,5 @@
1
1
  import { Toolbar as t } from "radix-ui";
2
- import { cn as a } from "@/utils/cn";
2
+ import { cn as a } from "../../../utils/cn.js";
3
3
  import { AlignmentControls as o } from "./AlignmentControls.js";
4
4
  import { BlockElementSelect as n } from "./BlockElementSelect.js";
5
5
  import { LinkEditor as l } from "./LinkEditor.js";
@@ -1,22 +1,23 @@
1
- import { NodeViewWrapper as l } from "@tiptap/react";
1
+ import { NodeViewWrapper as d } from "@tiptap/react";
2
2
  import { Popover as r } from "radix-ui";
3
- import { useMemo as m } from "react";
4
- import { cn as s } from "@/utils/cn";
5
- import { isArgumentElement as c, isTemporalElement as p, isNumericElement as f, isSelectElement as u, isTagElement as E } from "@/utils/guards";
6
- import { parseICUMessage as b } from "@/utils/icu-tranform";
7
- import { SelectVariableEditor as g } from "./editors/SelectVariableEditor.js";
8
- import { TagVariableEditor as h } from "./editors/TagVariableEditor.js";
9
- import { NumericVariablePicker as v } from "./pickers/NumericVariablePicker.js";
3
+ import { useMemo as l } from "react";
4
+ import { cn as s } from "../../../utils/cn.js";
5
+ import { isTemporalElement as c, isNumericElement as p } from "../../../utils/guards.js";
6
+ import { parseICUMessage as f } from "../../../utils/icu-tranform.js";
7
+ import { SelectVariableEditor as u } from "./editors/SelectVariableEditor.js";
8
+ import { TagVariableEditor as E } from "./editors/TagVariableEditor.js";
9
+ import { NumericVariablePicker as b } from "./pickers/NumericVariablePicker.js";
10
+ import { isArgumentElement as g, isSelectElement as h, isTagElement as v } from "@formatjs/icu-messageformat-parser";
10
11
  const i = !1;
11
- function M({
12
+ function P({
12
13
  node: n,
13
- updateAttributes: d
14
+ updateAttributes: m
14
15
  }) {
15
- const a = n.attrs, o = (t) => d({
16
+ const a = n.attrs, o = (t) => m({
16
17
  icu: t
17
- }), e = m(() => {
18
+ }), e = l(() => {
18
19
  try {
19
- const [t] = b(a.icu);
20
+ const [t] = f(a.icu);
20
21
  if (!t) throw new Error("No part found");
21
22
  return t;
22
23
  } catch (t) {
@@ -24,13 +25,13 @@ function M({
24
25
  }
25
26
  }, [a.icu]);
26
27
  return /* @__PURE__ */ React.createElement(r.Root, null, /* @__PURE__ */ React.createElement(r.Trigger, { asChild: !0 }, /* @__PURE__ */ React.createElement(
27
- l,
28
+ d,
28
29
  {
29
30
  as: "span",
30
31
  className: s(
31
32
  "inline-flex cursor-pointer items-center rounded-md bg-elevation-250 px-1 hover:bg-elevation-400",
32
33
  {
33
- "pointer-events-none": c(e) || p(e) && !i
34
+ "pointer-events-none": g(e) || c(e) && !i
34
35
  }
35
36
  ),
36
37
  contentEditable: !1,
@@ -48,13 +49,13 @@ function M({
48
49
  align: "start",
49
50
  className: "z-50 grid origin-(--radix-hover-card-content-transform-origin) overflow-clip rounded-md border border-border bg-elevation-50 shadow-md outline-hidden empty:hidden data-[side=bottom]:slide-in-from-top-2 data-[side=left]:slide-in-from-right-2 data-[side=right]:slide-in-from-left-2 data-[side=top]:slide-in-from-bottom-2 data-[state=closed]:animate-out data-[state=closed]:fade-out-0 data-[state=closed]:zoom-out-95 data-[state=open]:animate-in data-[state=open]:fade-in-0 data-[state=open]:zoom-in-95"
50
51
  },
51
- f(e) && /* @__PURE__ */ React.createElement(v, { element: e, onUpdate: o }),
52
- u(e) && /* @__PURE__ */ React.createElement(g, { element: e, onUpdate: o }),
52
+ p(e) && /* @__PURE__ */ React.createElement(b, { element: e, onUpdate: o }),
53
+ h(e) && /* @__PURE__ */ React.createElement(u, { element: e, onUpdate: o }),
53
54
  i,
54
- E(e) && /* @__PURE__ */ React.createElement(h, { element: e, onUpdate: o })
55
+ v(e) && /* @__PURE__ */ React.createElement(E, { element: e, onUpdate: o })
55
56
  )));
56
57
  }
57
58
  export {
58
- M as VariableChip
59
+ P as VariableChip
59
60
  };
60
61
  //# sourceMappingURL=VariableChip.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"VariableChip.js","sources":["../../../../src/components/inputs/variables/VariableChip.tsx"],"sourcesContent":["import type { VariableMentionNodeAttrs } from \"@/types\";\nimport type { ReactNodeViewProps } from \"@tiptap/react\";\nimport { NodeViewWrapper } from \"@tiptap/react\";\nimport { Popover } from \"radix-ui\";\nimport { useMemo } from \"react\";\n\nimport { cn } from \"@/utils/cn\";\nimport {\n isArgumentElement,\n isNumericElement,\n isSelectElement,\n isTagElement,\n isTemporalElement,\n} from \"@/utils/guards\";\nimport { parseICUMessage } from \"@/utils/icu-tranform\";\n\nimport { SelectVariableEditor } from \"./editors/SelectVariableEditor\";\nimport { TagVariableEditor } from \"./editors/TagVariableEditor\";\nimport { NumericVariablePicker } from \"./pickers/NumericVariablePicker\";\nimport { TemporalElementEditor } from \"./pickers/TemporalElementEditor\";\n\nconst TEMPORAL_ELEMENTS_FLAG = false;\n\n// TODO replace popover with portal below input field\n\nexport function VariableChip({\n node,\n updateAttributes,\n}: ReactNodeViewProps<HTMLElement>) {\n const attrs = node.attrs as VariableMentionNodeAttrs;\n const handleUpdate = (value: string) =>\n updateAttributes({\n icu: value,\n });\n\n const element = useMemo(() => {\n try {\n const [part] = parseICUMessage(attrs.icu);\n if (!part) throw new Error(\"No part found\");\n return part;\n } catch (error) {\n console.error(error);\n throw new Error(`Invalid ICU: ${attrs.icu}`, { cause: error });\n }\n }, [attrs.icu]);\n\n return (\n <Popover.Root>\n <Popover.Trigger asChild>\n <NodeViewWrapper\n as=\"span\"\n className={cn(\n \"inline-flex cursor-pointer items-center rounded-md bg-elevation-250 px-1 hover:bg-elevation-400\",\n {\n \"pointer-events-none\":\n isArgumentElement(element) ||\n (isTemporalElement(element) && !TEMPORAL_ELEMENTS_FLAG),\n },\n )}\n contentEditable={false}\n data-variable={attrs.name}\n data-icu={attrs.icu}\n role=\"button\"\n tabIndex={0}\n >\n {attrs.label}\n </NodeViewWrapper>\n </Popover.Trigger>\n <Popover.Portal>\n <Popover.Content\n side=\"bottom\"\n sideOffset={5}\n align=\"start\"\n className=\"z-50 grid origin-(--radix-hover-card-content-transform-origin) overflow-clip rounded-md border border-border bg-elevation-50 shadow-md outline-hidden empty:hidden data-[side=bottom]:slide-in-from-top-2 data-[side=left]:slide-in-from-right-2 data-[side=right]:slide-in-from-left-2 data-[side=top]:slide-in-from-bottom-2 data-[state=closed]:animate-out data-[state=closed]:fade-out-0 data-[state=closed]:zoom-out-95 data-[state=open]:animate-in data-[state=open]:fade-in-0 data-[state=open]:zoom-in-95\"\n >\n {isNumericElement(element) && (\n <NumericVariablePicker element={element} onUpdate={handleUpdate} />\n )}\n {isSelectElement(element) && (\n <SelectVariableEditor element={element} onUpdate={handleUpdate} />\n )}\n {TEMPORAL_ELEMENTS_FLAG && isTemporalElement(element) && (\n <TemporalElementEditor element={element} onUpdate={handleUpdate} />\n )}\n\n {isTagElement(element) && (\n <TagVariableEditor element={element} onUpdate={handleUpdate} />\n )}\n </Popover.Content>\n </Popover.Portal>\n </Popover.Root>\n );\n}\n"],"names":["TEMPORAL_ELEMENTS_FLAG","VariableChip","node","updateAttributes","attrs","handleUpdate","value","element","useMemo","part","parseICUMessage","error","Popover","NodeViewWrapper","cn","isArgumentElement","isTemporalElement","isNumericElement","NumericVariablePicker","isSelectElement","SelectVariableEditor","isTagElement","TagVariableEditor"],"mappings":";;;;;;;;;AAqBA,MAAMA,IAAyB;AAIxB,SAASC,EAAa;AAAA,EAC3B,MAAAC;AAAA,EACA,kBAAAC;AACF,GAAoC;AAClC,QAAMC,IAAQF,EAAK,OACbG,IAAe,CAACC,MACpBH,EAAiB;AAAA,IACf,KAAKG;AAAA,EAAA,CACN,GAEGC,IAAUC,EAAQ,MAAM;AAC5B,QAAI;AACF,YAAM,CAACC,CAAI,IAAIC,EAAgBN,EAAM,GAAG;AACxC,UAAI,CAACK,EAAM,OAAM,IAAI,MAAM,eAAe;AAC1C,aAAOA;AAAA,IACT,SAASE,GAAO;AACd,oBAAQ,MAAMA,CAAK,GACb,IAAI,MAAM,gBAAgBP,EAAM,GAAG,IAAI,EAAE,OAAOO,GAAO;AAAA,IAC/D;AAAA,EACF,GAAG,CAACP,EAAM,GAAG,CAAC;AAEd,SACE,sBAAA,cAACQ,EAAQ,MAAR,0CACEA,EAAQ,SAAR,EAAgB,SAAO,GAAA,GACtB,sBAAA;AAAA,IAACC;AAAA,IAAA;AAAA,MACC,IAAG;AAAA,MACH,WAAWC;AAAA,QACT;AAAA,QACA;AAAA,UACE,uBACEC,EAAkBR,CAAO,KACxBS,EAAkBT,CAAO,KAAK,CAACP;AAAA,QAAA;AAAA,MACpC;AAAA,MAEF,iBAAiB;AAAA,MACjB,iBAAeI,EAAM;AAAA,MACrB,YAAUA,EAAM;AAAA,MAChB,MAAK;AAAA,MACL,UAAU;AAAA,IAAA;AAAA,IAETA,EAAM;AAAA,EAAA,CAEX,GACA,sBAAA,cAACQ,EAAQ,QAAR,MACC,sBAAA;AAAA,IAACA,EAAQ;AAAA,IAAR;AAAA,MACC,MAAK;AAAA,MACL,YAAY;AAAA,MACZ,OAAM;AAAA,MACN,WAAU;AAAA,IAAA;AAAA,IAETK,EAAiBV,CAAO,yCACtBW,GAAA,EAAsB,SAAAX,GAAkB,UAAUF,GAAc;AAAA,IAElEc,EAAgBZ,CAAO,yCACrBa,GAAA,EAAqB,SAAAb,GAAkB,UAAUF,GAAc;AAAA,IAEjEL;AAAA,IAIAqB,EAAad,CAAO,yCAClBe,GAAA,EAAkB,SAAAf,GAAkB,UAAUF,EAAA,CAAc;AAAA,EAAA,CAGnE,CACF;AAEJ;"}
1
+ {"version":3,"file":"VariableChip.js","sources":["../../../../src/components/inputs/variables/VariableChip.tsx"],"sourcesContent":["import type { VariableMentionNodeAttrs } from \"@/types\";\nimport type { ReactNodeViewProps } from \"@tiptap/react\";\nimport { NodeViewWrapper } from \"@tiptap/react\";\nimport { Popover } from \"radix-ui\";\nimport { useMemo } from \"react\";\n\nimport { cn } from \"@/utils/cn\";\nimport {\n isArgumentElement,\n isNumericElement,\n isSelectElement,\n isTagElement,\n isTemporalElement,\n} from \"@/utils/guards\";\nimport { parseICUMessage } from \"@/utils/icu-tranform\";\n\nimport { SelectVariableEditor } from \"./editors/SelectVariableEditor\";\nimport { TagVariableEditor } from \"./editors/TagVariableEditor\";\nimport { NumericVariablePicker } from \"./pickers/NumericVariablePicker\";\nimport { TemporalElementEditor } from \"./pickers/TemporalElementEditor\";\n\nconst TEMPORAL_ELEMENTS_FLAG = false;\n\n// TODO replace popover with portal below input field\n\nexport function VariableChip({\n node,\n updateAttributes,\n}: ReactNodeViewProps<HTMLElement>) {\n const attrs = node.attrs as VariableMentionNodeAttrs;\n const handleUpdate = (value: string) =>\n updateAttributes({\n icu: value,\n });\n\n const element = useMemo(() => {\n try {\n const [part] = parseICUMessage(attrs.icu);\n if (!part) throw new Error(\"No part found\");\n return part;\n } catch (error) {\n console.error(error);\n throw new Error(`Invalid ICU: ${attrs.icu}`, { cause: error });\n }\n }, [attrs.icu]);\n\n return (\n <Popover.Root>\n <Popover.Trigger asChild>\n <NodeViewWrapper\n as=\"span\"\n className={cn(\n \"inline-flex cursor-pointer items-center rounded-md bg-elevation-250 px-1 hover:bg-elevation-400\",\n {\n \"pointer-events-none\":\n isArgumentElement(element) ||\n (isTemporalElement(element) && !TEMPORAL_ELEMENTS_FLAG),\n },\n )}\n contentEditable={false}\n data-variable={attrs.name}\n data-icu={attrs.icu}\n role=\"button\"\n tabIndex={0}\n >\n {attrs.label}\n </NodeViewWrapper>\n </Popover.Trigger>\n <Popover.Portal>\n <Popover.Content\n side=\"bottom\"\n sideOffset={5}\n align=\"start\"\n className=\"z-50 grid origin-(--radix-hover-card-content-transform-origin) overflow-clip rounded-md border border-border bg-elevation-50 shadow-md outline-hidden empty:hidden data-[side=bottom]:slide-in-from-top-2 data-[side=left]:slide-in-from-right-2 data-[side=right]:slide-in-from-left-2 data-[side=top]:slide-in-from-bottom-2 data-[state=closed]:animate-out data-[state=closed]:fade-out-0 data-[state=closed]:zoom-out-95 data-[state=open]:animate-in data-[state=open]:fade-in-0 data-[state=open]:zoom-in-95\"\n >\n {isNumericElement(element) && (\n <NumericVariablePicker element={element} onUpdate={handleUpdate} />\n )}\n {isSelectElement(element) && (\n <SelectVariableEditor element={element} onUpdate={handleUpdate} />\n )}\n {TEMPORAL_ELEMENTS_FLAG && isTemporalElement(element) && (\n <TemporalElementEditor element={element} onUpdate={handleUpdate} />\n )}\n\n {isTagElement(element) && (\n <TagVariableEditor element={element} onUpdate={handleUpdate} />\n )}\n </Popover.Content>\n </Popover.Portal>\n </Popover.Root>\n );\n}\n"],"names":["TEMPORAL_ELEMENTS_FLAG","VariableChip","node","updateAttributes","attrs","handleUpdate","value","element","useMemo","part","parseICUMessage","error","Popover","NodeViewWrapper","cn","isArgumentElement","isTemporalElement","isNumericElement","NumericVariablePicker","isSelectElement","SelectVariableEditor","isTagElement","TagVariableEditor"],"mappings":";;;;;;;;;;AAqBA,MAAMA,IAAyB;AAIxB,SAASC,EAAa;AAAA,EAC3B,MAAAC;AAAA,EACA,kBAAAC;AACF,GAAoC;AAClC,QAAMC,IAAQF,EAAK,OACbG,IAAe,CAACC,MACpBH,EAAiB;AAAA,IACf,KAAKG;AAAA,EAAA,CACN,GAEGC,IAAUC,EAAQ,MAAM;AAC5B,QAAI;AACF,YAAM,CAACC,CAAI,IAAIC,EAAgBN,EAAM,GAAG;AACxC,UAAI,CAACK,EAAM,OAAM,IAAI,MAAM,eAAe;AAC1C,aAAOA;AAAA,IACT,SAASE,GAAO;AACd,oBAAQ,MAAMA,CAAK,GACb,IAAI,MAAM,gBAAgBP,EAAM,GAAG,IAAI,EAAE,OAAOO,GAAO;AAAA,IAC/D;AAAA,EACF,GAAG,CAACP,EAAM,GAAG,CAAC;AAEd,SACE,sBAAA,cAACQ,EAAQ,MAAR,0CACEA,EAAQ,SAAR,EAAgB,SAAO,GAAA,GACtB,sBAAA;AAAA,IAACC;AAAA,IAAA;AAAA,MACC,IAAG;AAAA,MACH,WAAWC;AAAA,QACT;AAAA,QACA;AAAA,UACE,uBACEC,EAAkBR,CAAO,KACxBS,EAAkBT,CAAO,KAAK,CAACP;AAAA,QAAA;AAAA,MACpC;AAAA,MAEF,iBAAiB;AAAA,MACjB,iBAAeI,EAAM;AAAA,MACrB,YAAUA,EAAM;AAAA,MAChB,MAAK;AAAA,MACL,UAAU;AAAA,IAAA;AAAA,IAETA,EAAM;AAAA,EAAA,CAEX,GACA,sBAAA,cAACQ,EAAQ,QAAR,MACC,sBAAA;AAAA,IAACA,EAAQ;AAAA,IAAR;AAAA,MACC,MAAK;AAAA,MACL,YAAY;AAAA,MACZ,OAAM;AAAA,MACN,WAAU;AAAA,IAAA;AAAA,IAETK,EAAiBV,CAAO,yCACtBW,GAAA,EAAsB,SAAAX,GAAkB,UAAUF,GAAc;AAAA,IAElEc,EAAgBZ,CAAO,yCACrBa,GAAA,EAAqB,SAAAb,GAAkB,UAAUF,GAAc;AAAA,IAEjEL;AAAA,IAIAqB,EAAad,CAAO,yCAClBe,GAAA,EAAkB,SAAAf,GAAkB,UAAUF,EAAA,CAAc;AAAA,EAAA,CAGnE,CACF;AAEJ;"}
@@ -1,5 +1,5 @@
1
1
  import { useState as p, useEffect as f, useImperativeHandle as i } from "react";
2
- import { cn as g } from "@/utils/cn";
2
+ import { cn as g } from "../../../utils/cn.js";
3
3
  function v({
4
4
  items: e,
5
5
  command: a,
@@ -3,8 +3,8 @@ import { IconX as b } from "@tabler/icons-react";
3
3
  import { Popover as n } from "radix-ui";
4
4
  import { useMemo as g, useImperativeHandle as E, Fragment as v } from "react";
5
5
  import { useForm as R, useFieldArray as h, Controller as y } from "react-hook-form";
6
- import { cn as x } from "@/utils/cn";
7
- import { serializeICUMessage as c, parseICUMessage as N } from "@/utils/icu-tranform";
6
+ import { cn as x } from "../../../../utils/cn.js";
7
+ import { serializeICUMessage as c, parseICUMessage as N } from "../../../../utils/icu-tranform.js";
8
8
  const w = ["zero", "one", "two", "few", "many"];
9
9
  function k({
10
10
  variableName: i,
@@ -1,6 +1,6 @@
1
1
  import { useMemo as u, useEffect as f } from "react";
2
2
  import { useForm as d, useFieldArray as E } from "react-hook-form";
3
- import { serializeICUMessage as o, parseICUMessage as g } from "@/utils/icu-tranform";
3
+ import { serializeICUMessage as o, parseICUMessage as g } from "../../../../utils/icu-tranform.js";
4
4
  function N({
5
5
  element: a,
6
6
  onUpdate: s
@@ -1,6 +1,6 @@
1
1
  import { useMemo as i, useEffect as u } from "react";
2
2
  import { useForm as l } from "react-hook-form";
3
- import { serializeICUMessage as t, parseICUMessage as m } from "@/utils/icu-tranform";
3
+ import { serializeICUMessage as t, parseICUMessage as m } from "../../../../utils/icu-tranform.js";
4
4
  function g({
5
5
  element: e,
6
6
  onUpdate: o
@@ -1,9 +1,9 @@
1
1
  import { computePosition as f, shift as c, flip as p } from "@floating-ui/dom";
2
2
  import y from "@tiptap/extension-mention";
3
3
  import { ReactNodeViewRenderer as g, ReactRenderer as b, posToDOMRect as w } from "@tiptap/react";
4
- import { formatVariableLabel as R } from "@/utils/format";
5
- import { isTagElement as s } from "@/utils/guards";
6
- import { serializeICUMessage as h } from "@/utils/icu-tranform";
4
+ import { formatVariableLabel as R } from "../../../utils/format.js";
5
+ import { isTagElement as s } from "@formatjs/icu-messageformat-parser";
6
+ import { serializeICUMessage as h } from "../../../utils/icu-tranform.js";
7
7
  import { VariableChip as v } from "./VariableChip.js";
8
8
  import { VariableSuggestion as x } from "./VariableSuggestion.js";
9
9
  function S(r) {
@@ -1,6 +1,6 @@
1
1
  import { ToggleGroup as l } from "radix-ui";
2
2
  import { useState as i, useRef as c, useEffect as s } from "react";
3
- import { isNumberElement as m, isPluralElement as o } from "@/utils/guards";
3
+ import { isNumberElement as m, isPluralElement as o } from "@formatjs/icu-messageformat-parser";
4
4
  import { PluralVariableEditor as f } from "../editors/PluralVariableEditor.js";
5
5
  const p = [
6
6
  "number",
@@ -1,9 +1,9 @@
1
1
  import { useMemo as s } from "react";
2
- import { useMessagesForm as c } from "@/context/messages-form";
3
- import { cn as p } from "@/utils/cn";
4
- import { toWords as v } from "@/utils/format";
5
- import { parseMessageSchema as f } from "@/utils/schema";
6
- import { createValidator as d } from "@/utils/validate";
2
+ import { useMessagesForm as c } from "../../context/messages-form.js";
3
+ import { cn as p } from "../../utils/cn.js";
4
+ import { toWords as v } from "../../utils/format.js";
5
+ import { parseMessageSchema as f } from "../../utils/schema.js";
6
+ import { createValidator as d } from "../../utils/validate.js";
7
7
  import { MessageController as n } from "../MessageController.js";
8
8
  function y({
9
9
  schema: o,
@@ -2,9 +2,9 @@ import { Button as c } from "@payloadcms/ui";
2
2
  import { get as i } from "lodash-es";
3
3
  import { useCallback as p } from "react";
4
4
  import { useFormState as b } from "react-hook-form";
5
- import { useMessagesForm as u } from "@/context/messages-form";
6
- import { cn as d } from "@/utils/cn";
7
- import { toWords as f } from "@/utils/format";
5
+ import { useMessagesForm as u } from "../../context/messages-form.js";
6
+ import { cn as d } from "../../utils/cn.js";
7
+ import { toWords as f } from "../../utils/format.js";
8
8
  function M({
9
9
  schema: s,
10
10
  activeTab: o,
@@ -2,9 +2,9 @@ import { Collapsible as p } from "@payloadcms/ui";
2
2
  import { get as g } from "lodash-es";
3
3
  import { useCallback as f } from "react";
4
4
  import { useFormState as d } from "react-hook-form";
5
- import { useMessagesForm as E } from "@/context/messages-form";
6
- import { cn as a } from "@/utils/cn";
7
- import { toWords as R } from "@/utils/format";
5
+ import { useMessagesForm as E } from "../../context/messages-form.js";
6
+ import { cn as a } from "../../utils/cn.js";
7
+ import { toWords as R } from "../../utils/format.js";
8
8
  import { MessageField as N } from "./MessageField.js";
9
9
  function b({
10
10
  path: t,
@@ -0,0 +1,26 @@
1
+ "use client";
2
+ import { createContext as n, useContext as c } from "react";
3
+ import { FormProvider as m, useFormContext as a } from "react-hook-form";
4
+ const o = n({
5
+ locales: ["en"]
6
+ });
7
+ function l({
8
+ locales: e,
9
+ form: t,
10
+ richTextEditorOptions: r,
11
+ children: s
12
+ }) {
13
+ return /* @__PURE__ */ React.createElement(o.Provider, { value: { locales: e, richTextEditorOptions: r } }, /* @__PURE__ */ React.createElement(m, { ...t }, s));
14
+ }
15
+ const x = () => {
16
+ const e = c(o), t = a();
17
+ return {
18
+ ...e,
19
+ ...t
20
+ };
21
+ };
22
+ export {
23
+ l as MessagesFormProvider,
24
+ x as useMessagesForm
25
+ };
26
+ //# sourceMappingURL=messages-form.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"messages-form.js","sources":["../../src/context/messages-form.tsx"],"sourcesContent":["\"use client\";\n\nimport type {\n Locales,\n Messages,\n RichTextEditorOptions,\n Translations,\n} from \"@/types\";\nimport type { UseFormReturn } from \"react-hook-form\";\nimport { createContext, useContext } from \"react\";\nimport { FormProvider, useFormContext } from \"react-hook-form\";\n\nexport type FormValues = Translations<Messages>;\n\nconst MessagesFormContext = createContext<{\n locales: Locales;\n richTextEditorOptions?: RichTextEditorOptions;\n}>({\n locales: [\"en\"],\n});\n\ninterface MessagesFormProviderProps {\n locales: Locales;\n form: UseFormReturn<FormValues>;\n richTextEditorOptions?: RichTextEditorOptions;\n}\n\nexport function MessagesFormProvider({\n locales,\n form,\n richTextEditorOptions,\n children,\n}: React.PropsWithChildren<MessagesFormProviderProps>) {\n return (\n <MessagesFormContext.Provider value={{ locales, richTextEditorOptions }}>\n <FormProvider {...form}>{children}</FormProvider>\n </MessagesFormContext.Provider>\n );\n}\n\nexport const useMessagesForm = () => {\n const context = useContext(MessagesFormContext);\n const form = useFormContext<FormValues>();\n return {\n ...context,\n ...form,\n };\n};\n"],"names":["MessagesFormContext","createContext","MessagesFormProvider","locales","form","richTextEditorOptions","children","FormProvider","useMessagesForm","context","useContext","useFormContext"],"mappings":";;;AAcA,MAAMA,IAAsBC,EAGzB;AAAA,EACD,SAAS,CAAC,IAAI;AAChB,CAAC;AAQM,SAASC,EAAqB;AAAA,EACnC,SAAAC;AAAA,EACA,MAAAC;AAAA,EACA,uBAAAC;AAAA,EACA,UAAAC;AACF,GAAuD;AACrD,SACE,sBAAA,cAACN,EAAoB,UAApB,EAA6B,OAAO,EAAE,SAAAG,GAAS,uBAAAE,EAAA,EAAsB,GACpE,sBAAA,cAACE,GAAA,EAAc,GAAGH,EAAA,GAAOE,CAAS,CACpC;AAEJ;AAEO,MAAME,IAAkB,MAAM;AACnC,QAAMC,IAAUC,EAAWV,CAAmB,GACxCI,IAAOO,EAAA;AACb,SAAO;AAAA,IACL,GAAGF;AAAA,IACH,GAAGL;AAAA,EAAA;AAEP;"}
@@ -1,4 +1,4 @@
1
- import { getSupportedLocales as p, getPluginContext as d } from "@/utils/config";
1
+ import { getSupportedLocales as p, getPluginContext as d } from "../utils/config.js";
2
2
  const f = {
3
3
  handler: async (a) => {
4
4
  const { user: c } = await a.payload.auth({ headers: a.headers });
@@ -3,7 +3,7 @@ import { DefaultTemplate as u } from "@payloadcms/next/templates";
3
3
  import { Gutter as E } from "@payloadcms/ui";
4
4
  import { redirect as d, RedirectType as g } from "next/navigation";
5
5
  import { Toaster as v } from "sonner";
6
- import { sanitizeMessages as A } from "@/utils/sanitize";
6
+ import { sanitizeMessages as A } from "../utils/sanitize.js";
7
7
  import { MessagesForm as M } from "../components/MessagesForm.js";
8
8
  import { fetchMessages as h } from "../requests/fetchMessages.js";
9
9
  async function k({
@@ -1,4 +1,4 @@
1
- import { getPluginContext as s } from "@/utils/config";
1
+ import { getPluginContext as s } from "../utils/config.js";
2
2
  async function a(n, e) {
3
3
  const {
4
4
  docs: [r]
package/dist/types.d.ts CHANGED
@@ -3,9 +3,7 @@ import { HeadingOptions } from '@tiptap/extension-heading';
3
3
  import { CollectionConfig, PayloadRequest } from 'payload';
4
4
  import { DeepPartial } from 'react-hook-form';
5
5
  export interface MessagesPluginConfig {
6
- hooks?: MessagesHooks;
7
6
  schema: MessagesSchema;
8
- tabs?: boolean;
9
7
  /**
10
8
  * The slug of the collection to use for the messages.
11
9
  *
@@ -18,6 +16,8 @@ export interface MessagesPluginConfig {
18
16
  * @default `(req) => req.user !== null // Authenticated users only`
19
17
  */
20
18
  editorAccess?: MessagesGuard;
19
+ hooks?: MessagesHooks;
20
+ tabs?: boolean;
21
21
  /**
22
22
  * The options for the rich text editor.
23
23
  */
@@ -0,0 +1,9 @@
1
+ import { clsx as o } from "clsx";
2
+ import { twMerge as t } from "tailwind-merge";
3
+ function n(...r) {
4
+ return t(o(r));
5
+ }
6
+ export {
7
+ n as cn
8
+ };
9
+ //# sourceMappingURL=cn.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"cn.js","sources":["../../src/utils/cn.ts"],"sourcesContent":["import type { ClassValue } from \"clsx\";\nimport { clsx } from \"clsx\";\nimport { twMerge } from \"tailwind-merge\";\n\nexport function cn(...inputs: ClassValue[]) {\n return twMerge(clsx(inputs));\n}\n"],"names":["cn","inputs","twMerge","clsx"],"mappings":";;AAIO,SAASA,KAAMC,GAAsB;AAC1C,SAAOC,EAAQC,EAAKF,CAAM,CAAC;AAC7B;"}
@@ -1,19 +1,18 @@
1
1
  import { z as o } from "zod/v4-mini";
2
- const u = (t) => {
2
+ const c = (t) => {
3
3
  if (!t)
4
4
  throw new Error(
5
5
  'You need to enable "localization" in your Payload config.'
6
6
  );
7
7
  return t.locales.length === 0 ? [t.defaultLocale] : t.locales.map((e) => typeof e == "string" ? e : e.code);
8
- }, r = "intl-plugin";
9
- o.object({
8
+ }, n = "intl-plugin", r = o.object({
10
9
  collectionSlug: o.string()
11
- });
12
- const c = (t, e) => {
13
- t.custom ??= {}, t.custom[r] = e;
14
- };
10
+ }), s = (t, e) => {
11
+ t.custom ??= {}, t.custom[n] = e;
12
+ }, g = (t) => r.parse(t.custom?.[n]);
15
13
  export {
16
- c as attachPluginContext,
17
- u as getSupportedLocales
14
+ s as attachPluginContext,
15
+ g as getPluginContext,
16
+ c as getSupportedLocales
18
17
  };
19
18
  //# sourceMappingURL=config.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"config.js","sources":["../../src/utils/config.ts"],"sourcesContent":["import type { Locales } from \"@/types\";\nimport type { Config, LocalizationConfig, SanitizedConfig } from \"payload\";\nimport { z } from \"zod/v4-mini\";\n\nexport const getSupportedLocales = (\n localization: false | LocalizationConfig | undefined,\n): Locales => {\n if (!localization) {\n throw new Error(\n 'You need to enable \"localization\" in your Payload config.',\n );\n }\n if (localization.locales.length === 0) {\n return [localization.defaultLocale];\n }\n return localization.locales.map((locale) => {\n if (typeof locale === \"string\") {\n return locale;\n }\n return locale.code;\n }) as Locales;\n};\n\nconst PLUGIN_KEY = \"intl-plugin\";\nconst pluginContextSchema = z.object({\n collectionSlug: z.string(),\n});\ntype PluginContext = z.infer<typeof pluginContextSchema>;\n\nexport const attachPluginContext = (config: Config, context: PluginContext) => {\n config.custom ??= {};\n config.custom[PLUGIN_KEY] = context;\n};\n\nexport const getPluginContext = (config: SanitizedConfig): PluginContext =>\n pluginContextSchema.parse(config.custom?.[PLUGIN_KEY]);\n"],"names":["getSupportedLocales","localization","locale","PLUGIN_KEY","z","attachPluginContext","config","context"],"mappings":";AAIO,MAAMA,IAAsB,CACjCC,MACY;AACZ,MAAI,CAACA;AACH,UAAM,IAAI;AAAA,MACR;AAAA,IAAA;AAGJ,SAAIA,EAAa,QAAQ,WAAW,IAC3B,CAACA,EAAa,aAAa,IAE7BA,EAAa,QAAQ,IAAI,CAACC,MAC3B,OAAOA,KAAW,WACbA,IAEFA,EAAO,IACf;AACH,GAEMC,IAAa;AACSC,EAAE,OAAO;AAAA,EACnC,gBAAgBA,EAAE,OAAA;AACpB,CAAC;AAGM,MAAMC,IAAsB,CAACC,GAAgBC,MAA2B;AAC7E,EAAAD,EAAO,WAAW,CAAA,GAClBA,EAAO,OAAOH,CAAU,IAAII;AAC9B;"}
1
+ {"version":3,"file":"config.js","sources":["../../src/utils/config.ts"],"sourcesContent":["import type { Locales } from \"@/types\";\nimport type { Config, LocalizationConfig, SanitizedConfig } from \"payload\";\nimport { z } from \"zod/v4-mini\";\n\nexport const getSupportedLocales = (\n localization: false | LocalizationConfig | undefined,\n): Locales => {\n if (!localization) {\n throw new Error(\n 'You need to enable \"localization\" in your Payload config.',\n );\n }\n if (localization.locales.length === 0) {\n return [localization.defaultLocale];\n }\n return localization.locales.map((locale) => {\n if (typeof locale === \"string\") {\n return locale;\n }\n return locale.code;\n }) as Locales;\n};\n\nconst PLUGIN_KEY = \"intl-plugin\";\nconst pluginContextSchema = z.object({\n collectionSlug: z.string(),\n});\ntype PluginContext = z.infer<typeof pluginContextSchema>;\n\nexport const attachPluginContext = (config: Config, context: PluginContext) => {\n config.custom ??= {};\n config.custom[PLUGIN_KEY] = context;\n};\n\nexport const getPluginContext = (config: SanitizedConfig): PluginContext =>\n pluginContextSchema.parse(config.custom?.[PLUGIN_KEY]);\n"],"names":["getSupportedLocales","localization","locale","PLUGIN_KEY","pluginContextSchema","z","attachPluginContext","config","context","getPluginContext"],"mappings":";AAIO,MAAMA,IAAsB,CACjCC,MACY;AACZ,MAAI,CAACA;AACH,UAAM,IAAI;AAAA,MACR;AAAA,IAAA;AAGJ,SAAIA,EAAa,QAAQ,WAAW,IAC3B,CAACA,EAAa,aAAa,IAE7BA,EAAa,QAAQ,IAAI,CAACC,MAC3B,OAAOA,KAAW,WACbA,IAEFA,EAAO,IACf;AACH,GAEMC,IAAa,eACbC,IAAsBC,EAAE,OAAO;AAAA,EACnC,gBAAgBA,EAAE,OAAA;AACpB,CAAC,GAGYC,IAAsB,CAACC,GAAgBC,MAA2B;AAC7E,EAAAD,EAAO,WAAW,CAAA,GAClBA,EAAO,OAAOJ,CAAU,IAAIK;AAC9B,GAEaC,IAAmB,CAACF,MAC/BH,EAAoB,MAAMG,EAAO,SAASJ,CAAU,CAAC;"}
@@ -0,0 +1,15 @@
1
+ import { isTagElement as l } from "@formatjs/icu-messageformat-parser";
2
+ const m = (t, o = !1) => {
3
+ const i = (r) => r.charAt(0).toUpperCase() + r.slice(1), n = (t || "").trim().split(/[\s-]/), s = [];
4
+ return n.forEach((r) => {
5
+ if (r !== "") {
6
+ const e = r.split(/(?=[A-Z])/).join(" ");
7
+ s.push(i(e));
8
+ }
9
+ }), o ? s.join("").replace(/\s/g, "") : s.join(" ");
10
+ }, u = (t) => l(t) ? `<${t.value}/>` : t.value;
11
+ export {
12
+ u as formatVariableLabel,
13
+ m as toWords
14
+ };
15
+ //# sourceMappingURL=format.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"format.js","sources":["../../src/utils/format.ts"],"sourcesContent":["import type { TemplateVariable } from \"@/types\";\n\nimport { isTagElement } from \"./guards\";\n\nexport const toWords = (inputString: string, joinWords = false): string => {\n const capitalizeFirstLetter = (string: string): string =>\n string.charAt(0).toUpperCase() + string.slice(1);\n const notNullString = inputString || \"\";\n const trimmedString = notNullString.trim();\n const arrayOfStrings = trimmedString.split(/[\\s-]/);\n\n const splitStringsArray: string[] = [];\n arrayOfStrings.forEach((tempString) => {\n if (tempString !== \"\") {\n const splitWords = tempString.split(/(?=[A-Z])/).join(\" \");\n splitStringsArray.push(capitalizeFirstLetter(splitWords));\n }\n });\n\n return joinWords\n ? splitStringsArray.join(\"\").replace(/\\s/g, \"\")\n : splitStringsArray.join(\" \");\n};\n\nexport const formatVariableLabel = (variable: TemplateVariable) => {\n if (isTagElement(variable)) {\n return `<${variable.value}/>`;\n }\n return variable.value;\n};\n"],"names":["toWords","inputString","joinWords","capitalizeFirstLetter","string","arrayOfStrings","splitStringsArray","tempString","splitWords","formatVariableLabel","variable","isTagElement"],"mappings":";AAIO,MAAMA,IAAU,CAACC,GAAqBC,IAAY,OAAkB;AACzE,QAAMC,IAAwB,CAACC,MAC7BA,EAAO,OAAO,CAAC,EAAE,YAAA,IAAgBA,EAAO,MAAM,CAAC,GAG3CC,KAFgBJ,KAAe,IACD,KAAA,EACC,MAAM,OAAO,GAE5CK,IAA8B,CAAA;AACpC,SAAAD,EAAe,QAAQ,CAACE,MAAe;AACrC,QAAIA,MAAe,IAAI;AACrB,YAAMC,IAAaD,EAAW,MAAM,WAAW,EAAE,KAAK,GAAG;AACzD,MAAAD,EAAkB,KAAKH,EAAsBK,CAAU,CAAC;AAAA,IAC1D;AAAA,EACF,CAAC,GAEMN,IACHI,EAAkB,KAAK,EAAE,EAAE,QAAQ,OAAO,EAAE,IAC5CA,EAAkB,KAAK,GAAG;AAChC,GAEaG,IAAsB,CAACC,MAC9BC,EAAaD,CAAQ,IAChB,IAAIA,EAAS,KAAK,OAEpBA,EAAS;"}
@@ -0,0 +1,16 @@
1
+ import { isNumberElement as m, isPluralElement as t, isDateElement as i, isTimeElement as l } from "@formatjs/icu-messageformat-parser";
2
+ import { isArgumentElement as a, isDateElement as u, isLiteralElement as c, isNumberElement as p, isPluralElement as T, isSelectElement as N, isTagElement as b, isTimeElement as f } from "@formatjs/icu-messageformat-parser";
3
+ const n = (e) => m(e) || t(e), E = (e) => i(e) || l(e);
4
+ export {
5
+ a as isArgumentElement,
6
+ u as isDateElement,
7
+ c as isLiteralElement,
8
+ p as isNumberElement,
9
+ n as isNumericElement,
10
+ T as isPluralElement,
11
+ N as isSelectElement,
12
+ b as isTagElement,
13
+ E as isTemporalElement,
14
+ f as isTimeElement
15
+ };
16
+ //# sourceMappingURL=guards.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"guards.js","sources":["../../src/utils/guards.ts"],"sourcesContent":["import type {\n DateElement,\n MessageFormatElement,\n NumberElement,\n PluralElement,\n TimeElement,\n} from \"@formatjs/icu-messageformat-parser\";\nimport {\n isArgumentElement,\n isDateElement,\n isLiteralElement,\n isNumberElement,\n isPluralElement,\n isSelectElement,\n isTagElement,\n isTimeElement,\n} from \"@formatjs/icu-messageformat-parser\";\n\nexport const isNumericElement = (\n element: MessageFormatElement,\n): element is NumberElement | PluralElement =>\n isNumberElement(element) || isPluralElement(element);\n\nexport const isTemporalElement = (\n element: MessageFormatElement,\n): element is DateElement | TimeElement =>\n isDateElement(element) || isTimeElement(element);\n\nexport {\n isLiteralElement,\n isArgumentElement,\n isNumberElement,\n isSelectElement,\n isPluralElement,\n isDateElement,\n isTimeElement,\n isTagElement,\n};\n"],"names":["isNumericElement","element","isNumberElement","isPluralElement","isTemporalElement","isDateElement","isTimeElement"],"mappings":";;AAkBO,MAAMA,IAAmB,CAC9BC,MAEAC,EAAgBD,CAAO,KAAKE,EAAgBF,CAAO,GAExCG,IAAoB,CAC/BH,MAEAI,EAAcJ,CAAO,KAAKK,EAAcL,CAAO;"}
@@ -0,0 +1,110 @@
1
+ import { parse as o, TYPE as r } from "@formatjs/icu-messageformat-parser";
2
+ import { formatVariableLabel as p } from "./format.js";
3
+ const i = (a) => o(a), u = (a) => a.map((t) => {
4
+ switch (t.type) {
5
+ case r.literal:
6
+ return t.value;
7
+ case r.argument:
8
+ return c(t.value);
9
+ case r.number:
10
+ return c(t.value, "number");
11
+ case r.select:
12
+ return c(
13
+ t.value,
14
+ "select",
15
+ Object.entries(t.options).map(
16
+ ([s, e]) => `${s} {${e.value.length > 0 ? u(e.value) : s}}`
17
+ )
18
+ );
19
+ case r.plural:
20
+ return c(t.value, "plural", [
21
+ t.offset < 0 && `offset:${t.offset}`,
22
+ ...Object.entries(t.options).map(
23
+ ([s, e]) => `${s} {${e.value.length > 0 ? u(e.value) : s}}`
24
+ )
25
+ ]);
26
+ case r.tag:
27
+ return `<${t.value}>${u(t.children)}</${t.value}>`;
28
+ case r.date:
29
+ return c(t.value, "date");
30
+ case r.time:
31
+ return c(t.value, "time");
32
+ case r.pound:
33
+ return "#";
34
+ }
35
+ }).join(""), c = (a, t, s = []) => {
36
+ if (t === void 0) return `{${a}}`;
37
+ const e = s.filter(
38
+ (n) => typeof n == "string" && n.length > 0
39
+ );
40
+ return e.length === 0 ? `{${a}, ${t}}` : `{${a}, ${t}, ${e.join(" ")}}`;
41
+ }, f = (a) => {
42
+ try {
43
+ return {
44
+ type: "doc",
45
+ content: [
46
+ {
47
+ type: "paragraph",
48
+ content: i(a).flatMap(
49
+ (e) => {
50
+ switch (e.type) {
51
+ case r.literal:
52
+ return [
53
+ {
54
+ type: "text",
55
+ text: e.value
56
+ }
57
+ ];
58
+ case r.pound:
59
+ return [
60
+ {
61
+ type: "text",
62
+ text: "#"
63
+ }
64
+ ];
65
+ case r.argument:
66
+ case r.number:
67
+ case r.date:
68
+ case r.time:
69
+ case r.select:
70
+ case r.plural:
71
+ case r.tag:
72
+ return [
73
+ {
74
+ type: "variable",
75
+ attrs: {
76
+ name: e.value,
77
+ label: p(e),
78
+ icu: u([e])
79
+ }
80
+ }
81
+ ];
82
+ }
83
+ }
84
+ )
85
+ }
86
+ ]
87
+ };
88
+ } catch {
89
+ return {
90
+ type: "doc",
91
+ content: [
92
+ {
93
+ type: "paragraph",
94
+ content: [
95
+ {
96
+ type: "text",
97
+ text: a
98
+ }
99
+ ]
100
+ }
101
+ ]
102
+ };
103
+ }
104
+ };
105
+ export {
106
+ i as parseICUMessage,
107
+ f as parseIcuToProseMirrorJSON,
108
+ u as serializeICUMessage
109
+ };
110
+ //# sourceMappingURL=icu-tranform.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"icu-tranform.js","sources":["../../src/utils/icu-tranform.ts"],"sourcesContent":["import type { VariableMentionNodeAttrs } from \"@/types\";\nimport type { MessageFormatElement } from \"@formatjs/icu-messageformat-parser\";\nimport { parse, TYPE } from \"@formatjs/icu-messageformat-parser\";\n\nimport { formatVariableLabel } from \"./format\";\n\n/**\n * Parse an ICU message string into a AST array\n */\nexport const parseICUMessage = (message: string): MessageFormatElement[] =>\n parse(message);\n\n/**\n * Serialize an ICU message AST array into a ICU message string\n */\nexport const serializeICUMessage = (elements: MessageFormatElement[]): string =>\n elements\n .map((element) => {\n switch (element.type) {\n case TYPE.literal:\n return element.value;\n case TYPE.argument:\n return stringifyElement(element.value);\n case TYPE.number:\n // TODO serialize element.style\n return stringifyElement(element.value, \"number\");\n case TYPE.select:\n return stringifyElement(\n element.value,\n \"select\",\n Object.entries(element.options).map(\n ([key, option]) =>\n `${key} {${option.value.length > 0 ? serializeICUMessage(option.value) : key}}`,\n ),\n );\n case TYPE.plural:\n return stringifyElement(element.value, \"plural\", [\n element.offset < 0 && `offset:${element.offset}`,\n ...Object.entries(element.options).map(\n ([key, option]) =>\n `${key} {${\n option.value.length > 0\n ? serializeICUMessage(option.value)\n : key\n }}`,\n ),\n ]);\n case TYPE.tag:\n return `<${element.value}>${serializeICUMessage(element.children)}</${element.value}>`;\n case TYPE.date:\n // TODO serialize element.style\n return stringifyElement(element.value, \"date\");\n case TYPE.time:\n // TODO serialize element.style\n return stringifyElement(element.value, \"time\");\n case TYPE.pound:\n return \"#\";\n }\n })\n .join(\"\");\n\nconst stringifyElement = (\n name: string,\n type?: string,\n options: (string | boolean)[] = [],\n) => {\n if (type === undefined) return `{${name}}`;\n\n const filteredOptions = options.filter(\n (option): option is string =>\n typeof option === \"string\" && option.length > 0,\n );\n if (filteredOptions.length === 0) return `{${name}, ${type}}`;\n\n return `{${name}, ${type}, ${filteredOptions.join(\" \")}}`;\n};\n\ntype TextContent = {\n type: \"text\";\n text: string;\n};\n\ntype VariableContent = {\n type: \"variable\";\n attrs: VariableMentionNodeAttrs;\n};\n\ntype ProseMirrorJSONRepresentation = {\n type: \"doc\";\n content: {\n type: \"paragraph\";\n content: (TextContent | VariableContent)[];\n }[];\n};\n\n/**\n * Parse an ICU message string into a ProseMirror JSON representation\n */\nexport const parseIcuToProseMirrorJSON = (\n icuMessage: string,\n): ProseMirrorJSONRepresentation => {\n try {\n const elements = parseICUMessage(icuMessage);\n const content = elements.flatMap<TextContent | VariableContent>(\n (element) => {\n switch (element.type) {\n case TYPE.literal:\n return [\n {\n type: \"text\",\n text: element.value,\n },\n ];\n case TYPE.pound:\n return [\n {\n type: \"text\",\n text: \"#\",\n },\n ];\n case TYPE.argument:\n case TYPE.number:\n case TYPE.date:\n case TYPE.time:\n case TYPE.select:\n case TYPE.plural:\n case TYPE.tag:\n return [\n {\n type: \"variable\",\n attrs: {\n name: element.value,\n label: formatVariableLabel(element),\n icu: serializeICUMessage([element]),\n },\n },\n ];\n }\n },\n );\n\n return {\n type: \"doc\",\n content: [\n {\n type: \"paragraph\",\n content,\n },\n ],\n };\n } catch (error) {\n return {\n type: \"doc\",\n content: [\n {\n type: \"paragraph\",\n content: [\n {\n type: \"text\",\n text: icuMessage,\n },\n ],\n },\n ],\n };\n }\n};\n"],"names":["parseICUMessage","message","parse","serializeICUMessage","elements","element","TYPE","stringifyElement","key","option","name","type","options","filteredOptions","parseIcuToProseMirrorJSON","icuMessage","formatVariableLabel"],"mappings":"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"}
@@ -0,0 +1,19 @@
1
+ function y(s, r) {
2
+ const e = {}, f = c(r) ? r : {};
3
+ for (const t of Object.keys(s)) {
4
+ const i = s[t], n = f[t];
5
+ if (c(i)) {
6
+ const o = y(i, n);
7
+ c(o) && Object.keys(o).length > 0 && (e[t] = o);
8
+ } else
9
+ typeof n == "string" && (e[t] = n);
10
+ }
11
+ return e;
12
+ }
13
+ function c(s) {
14
+ return !!s && typeof s == "object" && !Array.isArray(s);
15
+ }
16
+ export {
17
+ y as sanitizeMessages
18
+ };
19
+ //# sourceMappingURL=sanitize.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"sanitize.js","sources":["../../src/utils/sanitize.ts"],"sourcesContent":["import type { DeepPartial, Messages } from \"@/types\";\n\n/**\n * Sanitize messages data to match the schema.\n * Stored messages might contain keys that are not in the config.\n * This happens when messages in the config were (re)moved.\n *\n * Keep exactly the keys from `shape`, fill values from `source` when present.\n * - Leaf present as string -> included\n * - Leaf missing/non-string -> omitted\n * - Empty nested groups -> omitted\n */\n\n/**\n\n */\nexport function sanitizeMessages(\n config: Messages,\n data: unknown,\n): DeepPartial<Messages> {\n const out: Record<string, unknown> = {};\n const src = isObj(data) ? data : {};\n\n for (const key of Object.keys(config)) {\n const shapeVal = (config as Record<string, unknown>)[key];\n const srcVal = src[key];\n\n if (isObj(shapeVal)) {\n const child = sanitizeMessages(shapeVal as Messages, srcVal);\n if (isObj(child) && Object.keys(child).length > 0) {\n out[key] = child;\n }\n // else: omit empty group\n } else {\n // Leaf: only keep if the source has a string\n if (typeof srcVal === \"string\") {\n out[key] = srcVal;\n }\n // else: omit leaf\n }\n }\n\n return out as DeepPartial<Messages>;\n}\n\nfunction isObj(x: unknown): x is Record<string, unknown> {\n return !!x && typeof x === \"object\" && !Array.isArray(x);\n}\n"],"names":["sanitizeMessages","config","data","out","src","isObj","key","shapeVal","srcVal","child","x"],"mappings":"AAgBO,SAASA,EACdC,GACAC,GACuB;AACvB,QAAMC,IAA+B,CAAA,GAC/BC,IAAMC,EAAMH,CAAI,IAAIA,IAAO,CAAA;AAEjC,aAAWI,KAAO,OAAO,KAAKL,CAAM,GAAG;AACrC,UAAMM,IAAYN,EAAmCK,CAAG,GAClDE,IAASJ,EAAIE,CAAG;AAEtB,QAAID,EAAME,CAAQ,GAAG;AACnB,YAAME,IAAQT,EAAiBO,GAAsBC,CAAM;AAC3D,MAAIH,EAAMI,CAAK,KAAK,OAAO,KAAKA,CAAK,EAAE,SAAS,MAC9CN,EAAIG,CAAG,IAAIG;AAAA,IAGf;AAEE,MAAI,OAAOD,KAAW,aACpBL,EAAIG,CAAG,IAAIE;AAAA,EAIjB;AAEA,SAAOL;AACT;AAEA,SAASE,EAAMK,GAA0C;AACvD,SAAO,CAAC,CAACA,KAAK,OAAOA,KAAM,YAAY,CAAC,MAAM,QAAQA,CAAC;AACzD;"}
@@ -0,0 +1,34 @@
1
+ import { parse as r, TYPE as e } from "@formatjs/icu-messageformat-parser";
2
+ const n = (a) => ({
3
+ description: a.match(/^\[.+\]/)?.[0]?.slice(1, -1),
4
+ type: a === "$RICH$" ? "rich" : "icu",
5
+ variables: i(a)
6
+ }), i = (a) => c(r(a)), c = (a) => a.flatMap((t) => {
7
+ switch (t.type) {
8
+ case e.literal:
9
+ case e.pound:
10
+ return [];
11
+ case e.argument:
12
+ case e.number:
13
+ case e.date:
14
+ case e.time:
15
+ return [t];
16
+ case e.plural:
17
+ case e.select:
18
+ return [
19
+ t,
20
+ ...c(
21
+ Object.values(t.options).flatMap(({ value: s }) => s)
22
+ )
23
+ ];
24
+ case e.tag:
25
+ return [t, ...c(t.children)];
26
+ default:
27
+ return [t];
28
+ }
29
+ });
30
+ export {
31
+ i as extractTemplateVariables,
32
+ n as parseMessageSchema
33
+ };
34
+ //# sourceMappingURL=schema.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"schema.js","sources":["../../src/utils/schema.ts"],"sourcesContent":["import type { MessageFormatElement } from \"@formatjs/icu-messageformat-parser\";\nimport { parse, TYPE } from \"@formatjs/icu-messageformat-parser\";\n\nimport type { MessageSchema, TemplateVariable } from \"@/types\";\n\nexport const parseMessageSchema = (schema: MessageSchema): MessageConfig => {\n const description = schema.match(/^\\[.+\\]/)?.[0];\n // TODO add support for variables description\n // const withoutDescription = schema.replace(description || \"\", \"\").trim();\n // const withoutOptional = withoutDescription.split(\" | \")[0]?.trim();\n\n return {\n description: description?.slice(1, -1),\n type: schema === \"$RICH$\" ? \"rich\" : \"icu\",\n variables: extractTemplateVariables(schema),\n };\n};\n\nexport const extractTemplateVariables = (\n schema: MessageSchema,\n): TemplateVariable[] => collectTemplateVariables(parse(schema));\n\nconst collectTemplateVariables = (\n parts: MessageFormatElement[],\n): TemplateVariable[] =>\n parts.flatMap<TemplateVariable>((part) => {\n switch (part.type) {\n case TYPE.literal:\n case TYPE.pound:\n return [];\n case TYPE.argument:\n case TYPE.number:\n case TYPE.date:\n case TYPE.time:\n return [part];\n case TYPE.plural:\n case TYPE.select:\n return [\n part,\n ...collectTemplateVariables(\n Object.values(part.options).flatMap(({ value }) => value),\n ),\n ];\n case TYPE.tag:\n return [part, ...collectTemplateVariables(part.children)];\n default:\n return [part];\n }\n });\n\n// MARK: Types\n\nexport type MessageType = \"rich\" | \"icu\";\nexport type MessageConfig = {\n description: string | undefined;\n type: MessageType;\n variables: TemplateVariable[];\n};\n"],"names":["parseMessageSchema","schema","extractTemplateVariables","collectTemplateVariables","parse","parts","part","TYPE","value"],"mappings":";AAKO,MAAMA,IAAqB,CAACC,OAM1B;AAAA,EACL,aANkBA,EAAO,MAAM,SAAS,IAAI,CAAC,GAMnB,MAAM,GAAG,EAAE;AAAA,EACrC,MAAMA,MAAW,WAAW,SAAS;AAAA,EACrC,WAAWC,EAAyBD,CAAM;AAAA,IAIjCC,IAA2B,CACtCD,MACuBE,EAAyBC,EAAMH,CAAM,CAAC,GAEzDE,IAA2B,CAC/BE,MAEAA,EAAM,QAA0B,CAACC,MAAS;AACxC,UAAQA,EAAK,MAAA;AAAA,IACX,KAAKC,EAAK;AAAA,IACV,KAAKA,EAAK;AACR,aAAO,CAAA;AAAA,IACT,KAAKA,EAAK;AAAA,IACV,KAAKA,EAAK;AAAA,IACV,KAAKA,EAAK;AAAA,IACV,KAAKA,EAAK;AACR,aAAO,CAACD,CAAI;AAAA,IACd,KAAKC,EAAK;AAAA,IACV,KAAKA,EAAK;AACR,aAAO;AAAA,QACLD;AAAA,QACA,GAAGH;AAAA,UACD,OAAO,OAAOG,EAAK,OAAO,EAAE,QAAQ,CAAC,EAAE,OAAAE,EAAA,MAAYA,CAAK;AAAA,QAAA;AAAA,MAC1D;AAAA,IAEJ,KAAKD,EAAK;AACR,aAAO,CAACD,GAAM,GAAGH,EAAyBG,EAAK,QAAQ,CAAC;AAAA,IAC1D;AACE,aAAO,CAACA,CAAI;AAAA,EAAA;AAElB,CAAC;"}
@@ -0,0 +1,57 @@
1
+ import { TYPE as n } from "@formatjs/icu-messageformat-parser";
2
+ import { isNumericElement as u, isTemporalElement as l } from "./guards.js";
3
+ import { extractTemplateVariables as f } from "./schema.js";
4
+ const v = (o, r) => {
5
+ if (typeof o != "string") return "Invalid value";
6
+ try {
7
+ const a = f(o);
8
+ for (const e of r) {
9
+ const t = a.find(
10
+ (s) => s.value === e.value
11
+ );
12
+ if (t) {
13
+ if (u(e)) {
14
+ if (u(t)) continue;
15
+ return `{${e.value}} has invalid type`;
16
+ }
17
+ if (l(e)) {
18
+ if (l(t)) continue;
19
+ return `{${e.value}} has invalid type`;
20
+ }
21
+ switch (e.type) {
22
+ case n.argument:
23
+ if (t.type === n.argument) continue;
24
+ return `{${e.value}} has invalid type`;
25
+ case n.select: {
26
+ if (t.type !== n.select)
27
+ return `{${e.value}} has invalid type`;
28
+ const s = Object.keys(e.options);
29
+ for (const i of s)
30
+ if (!t.options[i])
31
+ return `{${e.value}} has missing option: ${i}`;
32
+ const p = Object.keys(t.options);
33
+ for (const i of p)
34
+ if (!s.includes(i))
35
+ return `{${e.value}} has unsupported option: ${i}`;
36
+ continue;
37
+ }
38
+ case n.tag:
39
+ if (t.type === n.tag) continue;
40
+ return `{${e.value}} has invalid type`;
41
+ }
42
+ }
43
+ }
44
+ const c = new Set(r.map(({ value: e }) => e));
45
+ for (const e of a)
46
+ if (!c.has(e.value))
47
+ return `{${e.value}} is not supported`;
48
+ return !0;
49
+ } catch (a) {
50
+ return a instanceof Error ? `Invalid syntax: ${a.message}` : !1;
51
+ }
52
+ }, g = (o) => (r) => v(r, o);
53
+ export {
54
+ g as createValidator,
55
+ v as validateMessage
56
+ };
57
+ //# sourceMappingURL=validate.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"validate.js","sources":["../../src/utils/validate.ts"],"sourcesContent":["import type { ValidateResult } from \"react-hook-form\";\nimport { TYPE } from \"@formatjs/icu-messageformat-parser\";\n\nimport type { TemplateVariable } from \"@/types\";\n\nimport { isNumericElement, isTemporalElement } from \"./guards\";\nimport { extractTemplateVariables } from \"./schema\";\n\nexport const validateMessage = (\n value: unknown,\n variables: TemplateVariable[],\n): ValidateResult => {\n if (typeof value !== \"string\") return \"Invalid value\";\n\n try {\n const variableUsages = extractTemplateVariables(value);\n\n for (const allowedVariable of variables) {\n const variableUsage = variableUsages.find(\n (placeholder) => placeholder.value === allowedVariable.value,\n );\n\n if (!variableUsage) continue;\n\n if (isNumericElement(allowedVariable)) {\n if (isNumericElement(variableUsage)) continue;\n return `{${allowedVariable.value}} has invalid type`;\n }\n\n if (isTemporalElement(allowedVariable)) {\n if (isTemporalElement(variableUsage)) continue;\n return `{${allowedVariable.value}} has invalid type`;\n }\n\n switch (allowedVariable.type) {\n case TYPE.argument:\n if (variableUsage.type === TYPE.argument) continue;\n return `{${allowedVariable.value}} has invalid type`;\n case TYPE.select: {\n if (variableUsage.type !== TYPE.select)\n return `{${allowedVariable.value}} has invalid type`;\n\n const allowedOptions = Object.keys(allowedVariable.options);\n for (const option of allowedOptions) {\n if (variableUsage.options[option]) continue;\n return `{${allowedVariable.value}} has missing option: ${option}`;\n }\n const usedOptions = Object.keys(variableUsage.options);\n for (const option of usedOptions) {\n if (allowedOptions.includes(option)) continue;\n return `{${allowedVariable.value}} has unsupported option: ${option}`;\n }\n continue;\n }\n case TYPE.tag:\n if (variableUsage.type === TYPE.tag) continue;\n return `{${allowedVariable.value}} has invalid type`;\n }\n }\n\n const supportedVariables = new Set(variables.map(({ value }) => value));\n\n for (const variableUsage of variableUsages) {\n if (supportedVariables.has(variableUsage.value)) continue;\n return `{${variableUsage.value}} is not supported`;\n }\n\n return true;\n } catch (error) {\n if (!(error instanceof Error)) return false;\n return `Invalid syntax: ${error.message}`;\n }\n};\n\nexport const createValidator =\n (variables: TemplateVariable[]): MessageValidator =>\n (value: unknown) =>\n validateMessage(value, variables);\n\nexport type MessageValidator = (value: unknown) => ValidateResult;\n"],"names":["validateMessage","value","variables","variableUsages","extractTemplateVariables","allowedVariable","variableUsage","placeholder","isNumericElement","isTemporalElement","TYPE","allowedOptions","option","usedOptions","supportedVariables","error","createValidator"],"mappings":";;;AAQO,MAAMA,IAAkB,CAC7BC,GACAC,MACmB;AACnB,MAAI,OAAOD,KAAU,SAAU,QAAO;AAEtC,MAAI;AACF,UAAME,IAAiBC,EAAyBH,CAAK;AAErD,eAAWI,KAAmBH,GAAW;AACvC,YAAMI,IAAgBH,EAAe;AAAA,QACnC,CAACI,MAAgBA,EAAY,UAAUF,EAAgB;AAAA,MAAA;AAGzD,UAAKC,GAEL;AAAA,YAAIE,EAAiBH,CAAe,GAAG;AACrC,cAAIG,EAAiBF,CAAa,EAAG;AACrC,iBAAO,IAAID,EAAgB,KAAK;AAAA,QAClC;AAEA,YAAII,EAAkBJ,CAAe,GAAG;AACtC,cAAII,EAAkBH,CAAa,EAAG;AACtC,iBAAO,IAAID,EAAgB,KAAK;AAAA,QAClC;AAEA,gBAAQA,EAAgB,MAAA;AAAA,UACtB,KAAKK,EAAK;AACR,gBAAIJ,EAAc,SAASI,EAAK,SAAU;AAC1C,mBAAO,IAAIL,EAAgB,KAAK;AAAA,UAClC,KAAKK,EAAK,QAAQ;AAChB,gBAAIJ,EAAc,SAASI,EAAK;AAC9B,qBAAO,IAAIL,EAAgB,KAAK;AAElC,kBAAMM,IAAiB,OAAO,KAAKN,EAAgB,OAAO;AAC1D,uBAAWO,KAAUD;AACnB,kBAAI,CAAAL,EAAc,QAAQM,CAAM;AAChC,uBAAO,IAAIP,EAAgB,KAAK,yBAAyBO,CAAM;AAEjE,kBAAMC,IAAc,OAAO,KAAKP,EAAc,OAAO;AACrD,uBAAWM,KAAUC;AACnB,kBAAI,CAAAF,EAAe,SAASC,CAAM;AAClC,uBAAO,IAAIP,EAAgB,KAAK,6BAA6BO,CAAM;AAErE;AAAA,UACF;AAAA,UACA,KAAKF,EAAK;AACR,gBAAIJ,EAAc,SAASI,EAAK,IAAK;AACrC,mBAAO,IAAIL,EAAgB,KAAK;AAAA,QAAA;AAAA;AAAA,IAEtC;AAEA,UAAMS,IAAqB,IAAI,IAAIZ,EAAU,IAAI,CAAC,EAAE,OAAAD,QAAYA,CAAK,CAAC;AAEtE,eAAWK,KAAiBH;AAC1B,UAAI,CAAAW,EAAmB,IAAIR,EAAc,KAAK;AAC9C,eAAO,IAAIA,EAAc,KAAK;AAGhC,WAAO;AAAA,EACT,SAASS,GAAO;AACd,WAAMA,aAAiB,QAChB,mBAAmBA,EAAM,OAAO,KADD;AAAA,EAExC;AACF,GAEaC,IACX,CAACd,MACD,CAACD,MACCD,EAAgBC,GAAOC,CAAS;"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "payload-intl",
3
- "version": "0.0.1",
3
+ "version": "0.0.3",
4
4
  "description": "Payload Plugin for I18N using ICU Messages",
5
5
  "license": "MIT",
6
6
  "type": "module",
@@ -103,7 +103,6 @@
103
103
  "@tiptap/extension-underline": "^3.0.9",
104
104
  "@tiptap/extensions": "^3.0.9",
105
105
  "@tiptap/react": "^3.0.9",
106
- "@tiptap/starter-kit": "^3.0.9",
107
106
  "clsx": "^2.1.1",
108
107
  "lodash-es": "^4.17.21",
109
108
  "radix-ui": "^1.4.2",